lontivero/Open.NAT

upnpNatDevice = NatDiscoverer.DiscoverDeviceAsync.Result ...... never returns

Closed this issue · 1 comments

Hi Everyone, Apologies if this is the incorrect place to seek assistance. If it is can you please point me in the correct direction.
If this is the correct place, the following code below seems to execute 100% correct in a Console base 3.1 Core app and Framework 4.5 Console but for Framework 4.5 Forms it seems to freeze on the DiscoverDeviceAsync line and never returns, not even a timeout? Is there some sort of Underlaying thread issue that may be causing a problem by me selecting Windows Forms as my startup project vs. a Console app?

Any assistance would be appreciated.


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Console.WriteLine("Hello World!")
        StartUpUpnp().Wait()
    End Sub
Dim upnpNatDevice As Open.Nat.NatDevice
    Friend Async Function StartUpUpnp() As Task
        Dim natDiscoverer As NatDiscoverer = New NatDiscoverer()
        Dim cts As System.Threading.CancellationTokenSource = New System.Threading.CancellationTokenSource(5000)

        upnpNatDevice = NatDiscoverer.DiscoverDeviceAsync.Result

        Await upnpNatDevice.CreatePortMapAsync(New Mapping(Protocol.Tcp, 1600, 1700, "Open.Nat (temporary)"))
        Await upnpNatDevice.CreatePortMapAsync(New Mapping(Protocol.Tcp, 1601, 1701, "Open.Nat (Session lifetime)"))
    End Function

    Friend Async Function ShutdownUpnp() As Task
        Await upnpNatDevice.DeletePortMapAsync(New Mapping(Protocol.Tcp, 1600, 1700))
        Await upnpNatDevice.DeletePortMapAsync(New Mapping(Protocol.Tcp, 1601, 1701))
    End Function

    Friend Async Function DumpUPNPTable() As Task
        Dim stringBuilder As StringBuilder = New StringBuilder()
        Dim iPAddress As IPAddress = Await upnpNatDevice.GetExternalIPAsync()
        stringBuilder.AppendFormat(vbLf & "Your IP: {0}", iPAddress)
        stringBuilder.AppendFormat(vbLf & "Added mapping: {0}:1700 -> 127.0.0.1:1600" & vbLf, iPAddress)
        stringBuilder.AppendFormat(vbLf & "+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+", New Object(-1) {})
        stringBuilder.AppendFormat(vbLf & "| PROT | PUBLIC (Reacheable)" & vbTab & vbTab & "   | PRIVATE (Your computer)" & vbTab & vbTab & "| Descriptopn" & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "|" & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & " |", New Object(-1) {})
        stringBuilder.AppendFormat(vbLf & "+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+", New Object(-1) {})
        stringBuilder.AppendFormat(vbLf & "|" & vbTab & "  | IP Address" & vbTab & vbTab & "   | Port   | IP Address" & vbTab & vbTab & vbTab & "| Port   |" & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & vbTab & "| Expires" & vbTab & vbTab & vbTab & vbTab & " |", New Object(-1) {})
        stringBuilder.AppendFormat(vbLf & "+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+", New Object(-1) {})
        For Each mapping As Mapping In Await upnpNatDevice.GetAllMappingsAsync()
            stringBuilder.AppendFormat(vbLf & "|  {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|", New Object() {iPAddress, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, If((mapping.Protocol = Protocol.Tcp), "TCP", "UDP"), mapping.Expiration.ToLocalTime()})
        Next
        stringBuilder.AppendFormat(vbLf & "+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+", New Object(-1) {})
        stringBuilder.AppendFormat(vbLf & "[Removing TCP mapping] {0}:1700 -> 127.0.0.1:1600", iPAddress)
        stringBuilder.AppendFormat(vbLf & "[Done]", New Object(-1) {})
        Console.WriteLine(stringBuilder.ToString())
    End Function

This has nothing to do with Open.NAT, you have a well-known deadlock because you are locking in a WinForm application that needs to synchronize back with the UI synchronization context. Google it.