P2P UDP penetration NAT principle and implementation (attachment code)
Author: shootingstars (tolerance is a virtue, desire is just) Date: 2004-5-25
Source: P2P China (PPCN.NET) Original
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 increasingly lacking in the IP address, the 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 RFC 1631
Another NAT is called NAPT, which we can also see from the name, NAPT will change 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:1234 v |
|
Client a
10.0.0.1:1234
There is a private network 10. *. *. *, Client A is one of the computers. The external network IP of this network (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:7:7:1235
| | |
| | |
--------------------------------------------
|
^ Session 1 (A-S1) ^ | ^ session 2 (A-S2) ^
| 18.181.0.31:1235 | | | 138.76.29.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.29.7:1235 |
v 10.0.0.1:1234 V | v 10.0.0.1:1234 v
|
Client a
10.0.0.1:1234
Connected to the above example, if the original Socket (the UDP socket that binds 1234 port) is then sent to another Server S2, the UDP package will be through 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. (Can you celebrate, now the vast majority of NAT belongs to the latter, namely CONE NAT)
Ok, we see that the computer in the subnet is easy to connect to the outside (NAT is equivalent to transparent, the computer in the subnet does not need to know 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 process of P2P software, the following figure is:
Server S (219.237.60.1)
|
|
--------------------------------------------
| | |
NAT A (external network IP: 202.187.45.3) NAT B (external network IP: 187.34.1.56)
(Net 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 not run 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 can be solved by the two sides try connecting the other party's intranet IP, but this code is just to verify the principle, There is no processing of these issues), and the computer that will be logged in can get the username of the first login computer, and the login recorded the message through the format of Send UserName Message. If the send is successful, you have achieved successful connection directly to the other party.
The program now supports three commands: Send, Getu, EXIT
Send format: send username message
Function: Send information to username
Getu format: Getu
Function: Get the current server user list
EXIT format: exit
Function: Logout and server connection (server does not automatically monitor whether customers hang)
The code is very short, I believe it is easy to understand, if there is any problem, I can send me an email zhouhuis2@sina.com or send a short message on 9CBS. At the same time, welcome this article, but hope to retain author copyright 8-).
Finally, I would like to thank 9CBS netizen PiggyXP and SEILFER test help.
Source code download:
http://www.ppcn.net/upload/2004_05/04052509317298.rar