Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 编写NAT时的想法或算法_Python_Sockets_Networking_Nat - Fatal编程技术网

Python 编写NAT时的想法或算法

Python 编写NAT时的想法或算法,python,sockets,networking,nat,Python,Sockets,Networking,Nat,我正在使用TUNTAP进行Python隧道工程。TUNTAP接口上接收的数据包含原始IP数据包,包括所有报头。我可以做两件事中的一件 在输入端,我用Twisted收听。在输出端,我将有一个原始套接字,用于转储IP数据包。在转储数据包之前,程序将源地址与服务器地址交换。它还重新计算TCP和UDP校验和。它还使用以下方法之一交换端口。此信息在NAT表中跟踪 1) 每个用户使用一个端口,例如 US.ER.01.IP:10000 ----> SE.RV.ER.IP:3000 ----> f

我正在使用TUNTAP进行Python隧道工程。TUNTAP接口上接收的数据包含原始IP数据包,包括所有报头。我可以做两件事中的一件

在输入端,我用Twisted收听。在输出端,我将有一个原始套接字,用于转储IP数据包。在转储数据包之前,程序将源地址与服务器地址交换。它还重新计算TCP和UDP校验和。它还使用以下方法之一交换端口。此信息在NAT表中跟踪

1) 每个用户使用一个端口,例如

 US.ER.01.IP:10000 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
 US.ER.01.IP:10001 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
 US.ER.02.IP:3000 ----> SE.RV.ER.IP:3001 ----> facebook.com:80
如果第二个用户同时请求facebook,这会导致问题吗?系统如何知道如何发送facebook的回复。它在端口3000上传入,因此它属于user1,但它是否映射回10000或10001

2) 为每个连接使用唯一的端口,例如

 US.ER.01.IP:10000 ----> SE.RV.ER.IP:3000 ----> facebook.com:80
 US.ER.01.IP:10001 ----> SE.RV.ER.IP:3001 ----> facebook.com:80
 US.ER.02.IP:3000 ----> SE.RV.ER.IP:3002 ----> remoteHost.com:22
我如何知道何时从NAT表中删除条目?使用这种方法,我可以看到NAT表很快填满。解决办法是:

  I could wit for FIN packets from the server.  This will not work with UDP though.
  I could age the NAT entry on each hit.  I could then run garbage collection 
     every N seconds.  I see this being an issue if garbage collection runs
     and how would a server's delayed response get to the proper host if it gets
     deleted from the table.
还存在从原始套接字读取的问题。我知道如何发送一个,但是否有可能接收单独的IP数据包。原始套接字是否可以每个套接字接收一个数据包。receive(65535)调用是否可能接收多个IP数据包

哪种实现最好?还有其他我应该注意的提示或事情吗

编辑:

好的,我有N个客户。如果您误解了我的意思,请使用enitre/30 在客户机和自身之间。这只是建造隧道的一个抽象概念 可能的我也不认为这有什么关系,但websocket实际上通过LAN上的“代理”(IPdata是 只需重新打包到一个新的websocket中,映射是唯一的)。我不想把解释弄得如此混乱。我看不出这有什么改变

      Client PC     CLIENT PC              Client PC----->LAN                               INTERNET    
 Client 1: 10.1.1.2 ----> 10.1.1.1 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
 Client 2: 10.1.1.4 ----> 10.1.1.3 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
 Client 3: 10.1.1.6 ----> 10.1.1.5 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP
每个客户端都将其默认路由设置为隧道端点(例如10.1.1.1)。客户端获取IP数据报,并将其放入 在websocket中,将websocket发送到LAN上的浏览器,然后浏览器将其发送到服务器(或者其他代理)。websocket的内部包含 原始IP数据报(源为10.1.1.2或其他一些内部IP)

需要注意的是,服务器从internet接收到一条websocket消息,其中包含货物(带有专用源地址)。python服务器将如何使用它?自己创建一个新的隧道,然后将原始数据包转储到隧道中,并进行适当的路由

或者我可以使用映射

我怎样才能在这个WebSocket链上“映射”一个隧道抽象呢?客户端没有到服务器的路由 互联网,但可以达到“浏览器”可以进入互联网。这似乎与VPN隧道的情况相同。这个 抽象如下:

 Client 1: 10.1.1.2 ----> 10.1.1.1 ----> Websocket(IPdata) ----> Browser ---> newWebSocket(IPData) ----> SE.RV.ER.IP -> Internet
           10.1.2.2------------------------------------------------------------------------------------> 10.1.2.1 ----> Internet
如果你知道任何资源,让我在正确的轨道上,那将是伟大的

实现NAT 您必须为每个连接使用一个唯一的端口,而不是每个用户使用一个端口,这正是您在问题中概述的原因:如果您不这样做,那么您可以(并且将!)使用相同的5元组(协议、本地地址、本地端口、远程地址、远程端口)创建多个连接,并且您将无法消除它们之间的歧义

此外,如果您想很好地使用一些进行NAT遍历的协议,那么您应该尽可能不重新映射原始源端口,也就是说,如果它与您正在跟踪的现有连接冲突,则只重新映射(到新的随机端口)

要正确实现NAT,必须跟踪每个连接的状态

对于TCP,这意味着观察标志,当看到
SYN
时设置新状态,当从两侧看到
FIN
时拆除状态。跟踪的状态必须至少包含原始源端口和重新映射的源端口(可能相同,请参见上文)。如果您想支持FTP,那么您还必须嗅探FTP TCP控制连接的内容并重写其中包含的IP地址(这意味着您需要跟踪更多的状态,因为有时可能需要放大TCP段,这意味着您需要开始重新映射序列号)。您还应该有一个与每个跟踪连接相关联的超时,以便在端点消失而未正确关闭连接的情况下将其清除

对于UDP,这意味着监视本地和远程端口号的组合,并为您看到的每个唯一组合(地址和端口的4元组)创建状态。由于UDP是无连接的,因此必须根据超时使此状态信息过期。此超时将比TCP使用的超时短得多(以分钟而不是小时为单位),以防止状态表变得过大

对于ICMP回显请求,您应该以类似于UDP的方式进行,ICMP_id扮演端口号的角色

对于其他类型的ICMP(如无法到达目的地),您必须检查ICMP数据包,以查看它是否是您正在跟踪的TCP或UDP连接的一部分,并尝试将其转换回原始源

为了防止路由循环,在转发转换后的数据包时,还应该减少IP TTL

可能还有一些更重要的部分我忘记了。简言之,实现NAT非常类似于为路由器实现IP堆栈!这就是为什么NAT是虚拟的,总是固定在内核中的IP堆栈上,而不是在用户空间中实现

发送和接收数据包 因此,我所理解的架构是:

  • 客户机发起一个数据包,该数据包进入TUNTAP接口
  • 您的软件获取此数据包,将其封装在Websocket消息中,然后发送出去
  • 你的Twisted服务器得到了它并发挥了它的魔力
  • Th