P2P UDP penetration NAT principle and implementation (attachment code) Original: shangingstars reference: http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt
On the forum, there is often discussions on P2P principles, but discussing, rarely having substantial things (source code). Oh, here I use the source code you implement to illustrate the principle of UDP crossing NAT.
First introduce some basic concepts: NAT (Network Address Translators), Network Address Conversion: Network Address Transformation is increasing in the case where IP addresses are increasing, and its main purpose is to be able to be reused. NAT is divided into two categories, basic NAT and Napt (Network Address / Port Translators). The first NAT is a functional module running on the router. The first proposed is the basic NAT, which produces only the following fact: only a few nodes in a private network (domain) need to connect to the external network (Oh, this is proposed in the mid-1990s) . Then there is only a few nodes in this subnet that require a world's unique IP address, and the IP address of other nodes should be reused. Therefore, the basic NAT implementation is simple, and a reserved IP subnet section is used in the subnet, which is invisible to these IPs. Only a few IP addresses in the subnet can correspond to the real world unique IP address. If these nodes need to access the external network, the basic NAT is responsible for transforming the subnet IP of this node into a world unique IP and then sending out. (Basic NAT will change the original IP address in the IP package, but will not change the port in the IP package) About basic NAT can see the RFC 1631 another NAT called Napt, from the name we can also see, NAPT Not only will the IP address of the IP datagram passed through this NAT device, but also change the TCP / UDP port of the IP datagram. Basic NAT's equipment may have no more (huh, I have not seen it), Napt is the protagonist of our truly discussed. Look at the picture below: Server S1 18.181.0.31:1235 | ^ session 1 (a-s1) ^ | | 18.181.0.31:1235 | | v 155.99.25.11:62000 V | | NAT 155.99.25.11 | ^ session 1 (A- S1) ^ | | 18.181.0.31:1235 | V 10.0.0.1:0.1234 V | | Client A 10.0.0.1:1234 There is a private network 10. *. *. *, Client A is one of the computers, this The external network IP of the network's gateway (a NAT device) is 155.99.25.11 (there should be an intranet IP address, such as 10.0.0.10).
If a process in Client A (this process creates a UDP socket, this socket binding 1234 port) wants to access the 1235 port of the external network host 18.181.0.31, then what happens when the data package is passed by NAT? First, NAT will change the original IP address of this packet, change to 155.99.25.11. Then NAT will create a session for this transmission (Session is an abstract concept, if it is TCP, maybe the session starts by a SYN package, ending with a FIN package. And the first one of this IP UDP starts, end, huh, maybe it's a few minutes, maybe it's a few hours, this depends on the specific implementation) and assigns a port to this session, such as 62000, then change the source port of this packet 62000. So the data (10.0.0.1: 1234->18.181.0.0.31:1235) packaged to the Internet (155.99.25.11:62000-18.181.0.31:1235). Once NAT creates a session, NAT will remember that the 62000 port corresponds to the 1234 port of 10.0.0.1, and the data sent from 18.181.0.31 to 62000 port will be forwarded to 10.0.0.1. (Note: This is a data that is sent to 62000 port 18.181.0.31 will be forwarded, and the data sent to this port will be abandoned by NAT) so that Client A is established with Server S1 to connect.
Oh, the basics above may know many people, then the following is a key part. Take a look at the situation below: Server S1 Server S2 18.181.0.31:1235 138.76.29.7:735 | | | | ---------------------- - -------------------- | ^ session 1 (A-S1) ^ | ^ session 2 (A-S2) ^ | 18.181.0.31:1235 | | | 138.76.99.7:1235 | V 155.99.25.11:62000 V | v 155.99.25.11:62000 V | CONE NAT 155.99.25.11 | SESSION 1 (A-S1) ^ | ^ session 2 (A-S2) ^ | 18.181. 0.31: 1235 | | | 138.76.0.0.1:1234 V | v 10.0.0.1:1234 V | Client A 10.0.0.1:1234 Connecting the above example, if Client A is the original socket (binding The UDP socket of the 1234 port is then followed by another S ERVER S2 sends a UDP package, then how will this UDP package when passing Nat? There are two cases that may occur at this time, one is NAT to create a session again, and allocate a port number for this session (such as: 62001). The other is NAT to create a session again, but will not be allocated a port number, but the port number 62000 allocated. The previous NAT is called Symmetric Nat, and the latter is called CONE NAT. We expect our NAT to be the second, huh, if your NAT is just the first, then there will be a lot of P2P software failure. (It is fortunate that the vast majority of NAT belongs to the latter, namely, CONE NAT is ok, we see, the computer in the NAT and subnet is easy (NAT is equivalent to transparent, The computer of the network and the external network don't have to know the case of NAT). But if the external computer wants to access the computer in the subnet (this is also required for P2P).
So if we want to send a data to the intranet from the outside to the intra computer? First, we must play a "hole" on the NAT of the intranet (that is, we said in the NAT to establish a session). This hole cannot be hit by the outside, can only be hit by the host in the intranet. And this hole is a direction, such as a UDP package from an internal host (such as: 192.168.0.10) to the outside, such as: 219.237.60.1), then play on the NAT device of this intranet "Cave" in a direction of 219.237.60.1 (this is called UDP HOLE PUNCHING) After 219.237.60.1, it can be contacted by 192.168.0.10 through this hole. (However, other IPs cannot take advantage of this hole). Oh, now the round to our topic P2P. With the theory of the above, the host communication of the two intangnet is the last step: That is the problem of eggs or egg growth chops, no connection requests on both sides, no one knows the public network address , How can we play this hole? We need a middleman to contact these two intranet hosts. Now let's take a look at a P2P software process. The following figure is: Server S (219.237.60.1) | | -------------------- - --------------------- | | NAT A (外网 i:: 202.187.45.3) NAT B (external network IP: 187.34.1.56) | IP: 192.168.0.1) | (Net IP: 192.168.0.1) | | Client A (192.168.0.20:4000) Client B (192.168.0.10:40000)
First, the Client A logs in the server, NAT A is assigned a port 60000 for this session, then the address of the Client A received by Server S is 202.187.45.3:60000, which is the outer network address of Client a. Similarly, Client B logs in Server S, NAT B is 40000 assigned to this session, then the address received by Server S is 187.34.1.56:40000. At this point, Client A and Client B can communicate with Server S. If Client A wants to send information directly to Client B, then he can get B's public network address 187.34.1.56:40000 from Server S, is it CLIENT A to send information to this address CLIENT B? Can you receive it? The answer is not, because if this is sent, NAT B will discard this information (because such information is not please, most NAT will perform discarding action). Now we need to play a hole in Nat B to 202.187.45.3 (ie the outer network address of Client a), then the Client A is sent to the information of 187.34.1.56:40000, and Client B can be received. Who is from anyone command, huh, Of course, Server S. Summarize this process: If Client A wants to send information to the Client B, the Client A sends a command to Server S, request the Server S command Client B to hoist in the direction of the client. Oh, is it very winding, but it doesn't matter, I want to think very clearly. Let's also have source code. (Hou teacher said: There is no secret 8 in front of the source code), then Client A can pass Client B The external network address is communicated with the Client B. Note: The above process is only suitable for CONE NAT. If it is Symmetric Nat, then when Client B has a hole in the CLIENT A hole has been redistributed, Client B will not know this port (if the port of Symmetric Nat is sequentially assigned Then we may guess this port number, but because there are too many factors that may lead to failure, we do not recommend this way to guess ports). Below is a source code for analog P2P chat, the process is simple, P2PServer runs on a computer with public IP, and P2PClient is running after two different NATs (note that if the two clients run after a NAT This program is likely to be normal, depending on whether your NAT supports loopback translation, see http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt, of course, this problem It can be solved by both sides to try to connect the other party's intranet IP, but this code is just to verify the principle, there is no processing of these issues), and the login computer can get the username of the first login computer, and the computer is logged over by Send UserName Message. Format to send a message. If the send is successful, you have achieved successful connection directly to the other party.