How's this for a blast from the past. I posted this to the iGlance Yahoo group. You can read the original here, which has a couple follow-up replies:http://tech.groups.yahoo.com/group/iglance/message/52 But here's the text itself for your reading pleasure: ----------------------------------------------------------------------- Hi, thanks for writing. NAT penetration is a very tricky subject, so let me first give an overview of what the obstacles are, and then I'll explain my approach for circumventing them.(Note, the 'STUN' protocol I'm using is home-brewed -- it's not not truly compliant with RFC3489, for reasons I can get into if you care to hear. However, it accomplishes the same thing.)First, assume the following network:+--------+ +-----+ +--------+ | Client | ---> | NAT | ---> | Server | +--------+ +-----+ +--------+The client is connected to the NAT, and the NAT is connected (via the internet) to the server. The client is generally on some LAN, and thus has a "private" IP address. However, the NAT is generally on the internet, and thus has a "public" internet IP address. Thus while the client cannot send packets directly to the server (because the client isn't on the internet), the client can send it "through" the NAT.Now, UDP packets indicate from which address they originated. But which address does the packet appear to be from when the server receives it: the client, or the NAT? The answer is the NAT -- NAT stands for "Network Address Translator" because it translates "private" addresses (such as on a LAN) to "public" addresses (such as on the internet).So the client sends a packet from the LAN address (call it privateIP) but the server thinks it's coming from an internet address (call it publicIP) due to the NAT's translation. So long as the client is simply sending to the server, there's no problem -- if the server is only receiving, it doesn't care what address the packet comes from. But the moment the server wants to reply, then things get tricky.In the easy case when a server is replying to a client request, the server just sends back to the address the request packet appeared to come from (ie, the publicIP). And when the NAT receives it, it forwards it back to the client. In this way, when a client establishes a connection with a server, the client and server can talk back and forth without trouble.However, the reverse is not so easy. Now, when the client initiates a connection with the server, it 'punches a hole' through the NAT. This hole (also called a 'mapping') is what the server uses to talk back with the client. However, if the client doesn't punch the hole to the server first, the server can't contact the client. Indeed, if the server sends a packet to 'publicIP' before the client punches the hole through the NAT, the NAT will just silently disregard the message and it'll never arrive.Thus a NAT is a bit like a one-way mirror: a client behind a NAT can contact servers without restriction, but servers can't do the same. Many people like this behavior for security reasons. But obviously, in a P2P network this is less desirable because if you're behind a NAT, a remote client can't contact you until you contact it. But if it's also behind a NAT, you can't contact it until it contacts you. A seemingly intractable problem.To solve this problem, iGlance uses a directory server that acts as an intermediary to help clients behind NATs and firewalls connect directly. The process works as follows:1) Client A connects to the global server and registers its IP 2) Client B connects to the global server and asks for the IP for A 3) The server informs A that B is trying to contact it 4) Client A begins trying to contact B 5) Client B begins trying to contact A 6) Eventually a direct connection is establishedAs mentioned before, whether A tries to contact B or B tries to contact A, both will fail independently. But when they both try to contact each other simultaneously, they both "punch holes" through their NATs and firewalls, and thus both let the other's communications through. This technique of simultaneous hole punching is the essence of NAT-to-NAT traversal.However, recall that each client typically only knows its "private" IP address -- ie, the IP address on its private LAN. But just as the server sees only a client's "public" IP address, so do peers only see other peers' public IPs. Thus before client A can attempt to contact client B, A needs to learn B's public IP.This process of a client determining whether or not it is behind a NAT (and if so, finding its public IP address) is called the 'STUN' process -- named after the IETF standard RFC3489. (iGlance doesn't use this protocol, but is heavily influenced by it.) The precise technique iGlance uses is as follows:1) STUN server is assigned 3 IP addresses -- STUN0-22) Client sends STUN request to STUN03) Client punches hole to STUN14) The STUN server attempts to contact the client *from* STUN0-2Thus the STUN server sends *three* responses from *three* different IP:port combinations, to the *same* IP:port from which the client request originated. Depending on the NAT and firewall in place, the client might successfully receive up to 3 responses, one each from a different IP:port on the STUN server. Based on which requests succeed, we can guess which type of NAT is between the client and the STUN server. This is used to set the 'Connection_Class' as follows:FIREWALL: (0 responses) Something is blocking either all outbound or inbound UDP traffic.SYMMETRIC: (1 response from STUN0) The client can receive UDP only from the exact IP it sends to.RESTRICTED: (2 responses, from STUN0 and STUN1) The client can receive UDP only from remote IP:ports for which holes have explicitly been punched.UNRESTRICTED: (3 responses) Once a hole is punched through the NAT, any remote IP:port can use it to contact the client.PUBLIC: (3 responses) The client is not behind a NAT and thus can receive from any IP:port.Furthermore, the server returns in the STUN response the apparent IP:port from which the client's request appeared to originate. Recall, the client sends from its 'private' address, while the server receives from the client's 'public' address. If these are different, we know a NAT must be in place. But if they are the same, then we can assume there is no NAT in place and thus the client is connected to the internet directly. (This is how iGlance distinguishes between the UNRESTRICTED and PUBLIC states.)(All this logic is contained in the file GDispatchService.cpp. The STUN request is sent in the function GDispatchService::_requestStun( ), and the responses are processed by GDispatchService::_onInput( ) in the GDSS_STUN state.) So clients with PUBLIC, UNRESTRICTED, or RESTRICTED NATs know they can receive UDP directly from another peer. And clients behind SYMMETRIC NATs or UDP-blocking FIREWALL know they can't (they must establish a 'TURN' connection with the server, which simply listens for UDP traffic and sends back over HTTP). Armed with this information, clients can ensure they are able to be contacted by remote peers, whether behind a NAT or FIREWALL, or directly on the internet. Does this answer your question?-david
posted by David Barrett at 10:31 PM on Jan 24, 2011
"NAT penetration algorithm from iGlance, circa 2005"
No comments yet. -