alanmcgovern / Mono.Nat

UPNP and NAT-PMP port forwarding for .NET
https://github.com/mono/Mono.Nat
MIT License
160 stars 156 forks source link

Device.CreatePortMapAsync(Mapping) creates a deadlock #34

Closed NaolShow closed 3 years ago

NaolShow commented 3 years ago

The problem is that the code will just block indefinitely at the line:

Mapping = await Device.CreatePortMapAsync(mapping);

So I just looked into the CreatePortMapAsync method and I just found that the code block at: (It's in the UpnpNatDevice class)

var response = await SendMessageAsync (message).ConfigureAwait (false);

So I looked in the SendMessageAsync method and I found that is blocks at:

using (var response = await request.GetResponseAsync().ConfigureAwait(false))

Do you have a solution for this problem ? (My modem supports UPnP) I am using Unity with the target as .NET Standard 2.0

Thanks for your help !

and: Here's my code with the Start() function my entry point.

public static class NatTraversal {

        public static INatDevice Device;
        public static Mapping Mapping;

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        public static void Start() {

            // Subscribe to the quitting event
            Application.quitting += Stop;
            // Subscribe to the device found event
            NatUtility.DeviceFound += OnDeviceFound;

            NatUtility.StartDiscovery();

            Debug.Log("[NAT] Started discovery");

        }

        public async static void Stop() {

            // If we found a device
            if (Mapping != null && Device != null) {

                // Delete the port map
                await Device.DeletePortMapAsync(Mapping);

            }

            // Unsubscribe from the quitting event
            Application.quitting -= Stop;

            // Stop the discovery
            NatUtility.StopDiscovery();

            Debug.Log("[NAT] Stopped discovery");

        }

        public static async void OnDeviceFound(object sender, DeviceEventArgs e) {

            // Stop the discovery
            NatUtility.StopDiscovery();

            Debug.Log("[NAT] Found a device, stop discovery");

            // Create the mapping
            Mapping mapping = new Mapping(Protocol.Udp, 7777, 7777, int.MaxValue, "NetworkPrototyping");

            Debug.Log("[NAT] Mapping created");

            Device = e.Device;

            Mapping = await Device.CreatePortMapAsync(mapping);

            Debug.Log("[NAT] Mapping created and applied");

        }

    }
NaolShow commented 3 years ago

Edit:

I am just stupid. I just found out that the problem is that it throws an Exception. And for no reason unity do not forwards them in the debug console..

manutoo commented 1 year ago

@NaolShow , I use Open.NAT (forked from Mono.Nat), and I got a user having a deadlock when using Open.NAT. I traced the deadlock to CreatePortMapAsync() . Could you tell me how did you solve yours exactly ? Thanks in advance for your answer ! :-)