无法使用python将UDP数据包发送到本地端口,无法根据WireShark进行校验和
我一直在为这件事发愁。我正试图用Python编写一个SOCKS5服务器来隧道UDP流量。我绑定到一个端口,并接收数据。然后我解析socks5udp报头(不是典型的UDP报头),并将数据报转发到请求的端点 一切都很好。然后,我侦听端点的响应(如果超时,则重新发送),并获得响应。太好了 这就是我失去理智的地方- 我从端点获取数据报。我根据重新封装返回的数据报,它与以前的UDP报头相同,只是我现在将目标地址和端口更改为原始调用者。我使用:无法使用python将UDP数据包发送到本地端口,无法根据WireShark进行校验和,python,sockets,networking,udp,socks,Python,Sockets,Networking,Udp,Socks,我一直在为这件事发愁。我正试图用Python编写一个SOCKS5服务器来隧道UDP流量。我绑定到一个端口,并接收数据。然后我解析socks5udp报头(不是典型的UDP报头),并将数据报转发到请求的端点 一切都很好。然后,我侦听端点的响应(如果超时,则重新发送),并获得响应。太好了 这就是我失去理智的地方- 我从端点获取数据报。我根据重新封装返回的数据报,它与以前的UDP报头相同,只是我现在将目标地址和端口更改为原始调用者。我使用: sock_client = socket.socket(soc
sock_client = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock_client.sendto(packed_datagram, (self.client_ip, self.client_port))
将数据报发送回客户端。客户从未收到回复!永远
查看WireShark,它说:头校验和:0x0000[不正确,应该是0xcd1f(可能是由“IP校验和卸载”引起的)]
设置了socket.DGRAM的python套接字实现不应该自动将我的数据正确打包到UDP头中并计算适当的校验和吗?为什么设置为0x0000?我用十六进制检查了有效负载,校验和确实设置错误。到底是怎么回事?校验和计算是由操作系统中的驱动程序完成的。在可能的情况下,计算是由网卡本身完成的。IIRC,Wireshark在本地数据包被传送到网络堆栈之前抓取它们。所有本地生成的数据包都会出现校验和错误。如果我正确理解了您的代码部分,您可以创建一个新套接字将数据发送回客户端。因此,这将是一个具有随机源IP的新套接字,例如,从客户端的角度来看,您有以下数据包流:
client_ip:client_port -> socks5_ip:socks_port
client_ip:client_port <- socks5_ip:random_port
client\u ip:client\u port->socks5\u ip:socks\u port
client_ip:client_port我没有准确地遵循SOCKS5规范的两个部分
UDP关联在UDP连接终止时终止
员工请求已于终止时到达
我在完成UDP中继握手后立即终止TCP套接字。TCP必须保持打开状态,直到来回完成
UDP中继服务器从远程服务器接收应答数据报时
主机,它必须使用上述UDP请求封装该数据报
标头和任何依赖于身份验证方法的封装
我使用客户端的IP和端口作为数据报中的值。它需要是远程服务器的IP和端口,本质上UDP报头封装是客户端传入内容的克隆
解决这两个问题后,SOCKS5服务器将按预期工作。使用linux命令关闭tx校验和:
ethtool -K eth0 tx off
或者使用此函数计算校验和
def checksum(data):
s = 0
n = len(data) % 2
for i in range(0, len(data)-n, 2):
s+= ord(data[i]) + (ord(data[i+1]) << 8)
if n:
s+= ord(data[i+1])
while (s >> 16):
s = (s & 0xFFFF) + (s >> 16)
s = ~s & 0xffff
return s
def校验和(数据):
s=0
n=长度(数据)%2
对于范围内的i(0,len(数据)-n,2):
s+=ord(数据[i])+(ord(数据[i+1])>16):
s=(s&0xFFFF)+(s>>16)
s=~s&0xffff
返回s
其中数据是伪头,这很有意义,但意味着我真的不知道本地主机为什么没有接收到我的udp数据包。如果我从一个线程发送它们有关系吗?我在这里真的是在捞救命稻草。这不重要,因为UDP套接字可以想象成孔而不是管道。无论数据的来源是什么,一旦数据被推入孔中,它就会被传递(UDP是无连接的,不像TCP)。也就是说,我按照您的建议重用了接收数据的同一个套接字,但仍然不走运。根据一位同事的建议,我还尝试将SOCKS5服务器和UDP中继服务器绑定到网络上的本地IP,而不是127.0.0.1,并将客户端设置为通过本地IP连接到它。仍然不走运:(请提供客户端和socks服务器之间连接的tcpdump。感谢您的时间,我在回答的问题中解决了我的问题。