[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Send data using tcp/udp to devices behind NAT - UDP Hole Punching
- From: Sean Conner <sean@...>
- Date: Fri, 24 Feb 2012 01:07:51 -0500
It was thus said that the Great Satheesh Kumar once stated:
> Yeah I can use UDP.So it would be excellent if I can implement PMP in Lua.
> Can you give any pointers before I try to implement it???
Both sides need to know the public IP address and UDP port number of the
other side, and you need to hope that the NAT system on both ends only
modifies the IP address (from pivate to public) and *NOT* the UDP port
number.
You *can* pick a different UDP port for each side, but that information
needs to be known to the other side by some method. For example, A is
NATted behind the public IP address 198.18.23.45 [1] and will bind to port
4567. B is NATted behind the public IP address of 198.18.100.15 and will
bind to port 7654. In pseudocode, A will do:
s = socket('ip','udp')
laddr = address('0.0.0.0',4567,'udp')
raddr = address('198.18.100.15',7654,'udp')
data = "Some data you want to send"
bind(s,laddr)
send(s,raddr,data)
B will do similar, but reverse the address/port numbers:
s = socket('ip','udp')
laddr = address('0.0.0.0',7654,'udp')
raddr = address(198.18.23.45,4567,'udp')
data = "I got the data"
bind(s,laddr)
send(s,raddr,data)
The trick to all of this is that both A and B have to send something at
the same time. NAT-A will see the outbound packet from A, and will [2] map
replies from NAT-B back to A. The same will happen at NAT-B. Even if you
manage at the "same time", you may need to try a few times until each side
gets a response, so a loop like:
while true do
send(s,raddr,data)
data,err = recv(s,timeout) -- timeout in say, 1/10 second
if err == 0 then break end
if err ~= TIMEOUT then error() end
end
Once you receive data, then you have established a communcations channel
between A and B. If you wait too long [3], you may need to run this bit of
code again.
You don't have to use different ports for both sides---both sides can bind
to the same port. But you do have to make sure there isn't something else
on the system using that port.
-spc (Using an external server means you can coordinate between A and B,
and can use whatever port the system assigned your UDP socket. I'll
leave that up as an exercise for the reader ... )
[1] 198.18.0.0/15 is assigned for network benchmarking, but I thought I
would use addresses out of this range as an example.
[2] generally speaking, unless the NAT has been programmed otherwise
[3] NAT systems will generally "timeout" a UDP-NAT session after half an
hour or so.