2

I have a somewhat unique situation where I require the ability to perform NAT hole punching for a multi node peer to peer type application; where all nodes must reference each other from publicly accessible IP addresses, even when some of those nodes might reside on the local subnet.

I have been able to successfully map ports with help from this question (UDP hole punching implementation) using Open.Nat.

My code is basically as simple as this:

var discoverer = new NatDiscoverer();
var device = await discoverer.DiscoverDeviceAsync();
await device.CreatePortMapAsync(new Mapping(Open.Nat.Protocol.Tcp, port, port));

This successfully creates a map in my router

enter image description here

I can now successfully connect to this IP and port number from an external network (tested on mobile data connection) by doing something like this

TcpClient client = new TcpClient();
client.Connect("publicip", 6968);

However when I attempt to connect to the same public ip address from the local subnet the connection will fail with 'No connection could be made because the target machine actively refused it?'.

I have used wireshark to see if any packets land to the target machine and it appears they do not.

Obviously it is clear that the router is probably failing to forward/route the connections correctly on the local subnet, so what I am trying to understand is if this is a known limitation of the UPnP protocol or specific to my router? Perhaps there is a trick when you create the mappings that I have missed?

I note that my router appears to use MiniUPnP http://miniupnp.free.fr/ Version 20160321

I realise this is a tricky question to answer but hoping that we can get some clarification of what UPnP should be doing in this situation from an expert.

EDIT:

A bit more context to my question; let me elaborate why I have such a requirement. I am using Akka.NET clusters on mobile devices across network boundaries, the key point to remember with Akka clusters is to successfully get a Akka.NET cluster to form all members of the cluster must be bio-directionally reachable to one another.

Now consider a situation like this

enter image description here

My goal is to only have to assign a static ip to the server node and allow all the cluster nodes to move in and out the network boundaries seamlessly. The ideal way to achieve this is to assign publicly reachable addresses to each node on the network regardless of where it is physically located.

Maxim Gershkovich
  • 45,951
  • 44
  • 147
  • 243
  • 1
    I don't believe there are any requirements around this at all: the router can do what it wants. That said, its behaviour here does seem unusual. – canton7 Feb 06 '20 at 15:04
  • @canton7 I should get a chance to test this behaviour properly with other devices soon and will report back with results – Maxim Gershkovich Feb 07 '20 at 10:48
  • 1
    we got the very same requirement for a project of ours, can be something very trivial like the firewall, have u tried disabling it ? – L.Trabacchin Feb 07 '20 at 10:55
  • 1
    no wait, i gave a better reading to it, so you are trying to use the public address and the the upnp port to connect on the same local subnet... Why don't you just connect directly ? that is loooking for trubles, upnp is not made for that, it could technically work, but it's not what it's meant for... – L.Trabacchin Feb 07 '20 at 11:00
  • @L.Trabacchin I've provided a bit more context about why I have taken this approach in my case. – Maxim Gershkovich Feb 07 '20 at 12:49

1 Answers1

2

This isn't really something you can fix, and it isn't really specific to C#. Most routers will only match NAT packets that arrive on their internet facing interface. If you want to allow for multiple nodes running behind the same NAT to connect directly to each other, you will need to implement another solution.

For example, you could share each node's private interface addresses. Then attempt to connect directly if the public address matches.

Jeremy Lakeman
  • 9,515
  • 25
  • 29
  • In the end I've taken everyones comments and settled on an approach where, when the nodes are on the local subnet they are given static IP addresses. Thanks for your input. – Maxim Gershkovich Feb 14 '20 at 05:40