Networking sendto()返回错误代码
我遇到了非常奇怪的情况 在我的程序中,Networking sendto()返回错误代码,networking,packet,Networking,Packet,我遇到了非常奇怪的情况 在我的程序中,sendto() 只有当UDP流通过多个网关连接到其他网络时,才会发生这种情况。这并不总是,有时也会发生。 如果在同一个子网络下运行相同的代码,则不会出现类似enedown的错误 因此,我将sendto()函数跟踪到内核区域。 iop_output.c的ip_finish_output2()中的neigh_hh_output()函数调用hh->hh_output()并返回enedown错误代码 在正常操作下,hh->hh\u output()函数被分配给de
sendto()
只有当UDP流通过多个网关连接到其他网络时,才会发生这种情况。这并不总是,有时也会发生。
如果在同一个子网络下运行相同的代码,则不会出现类似enedown
的错误
因此,我将sendto()
函数跟踪到内核区域。
iop_output.c
的ip_finish_output2()
中的neigh_hh_output()
函数调用hh->hh_output()
并返回enedown
错误代码
在正常操作下,hh->hh\u output()
函数被分配给dev.c
的dev\u queue\u xmit()
,数据包被发送到网络
当问题发生时,它似乎被分配到neigh\u blackhole()
函数中neigh\u destroy()
的neigh\u neigh.c
。neigh_blackhole()
返回-enedown
代码
但是,我不知道什么时候调用neigh_destroy()
,以及调用该函数的原因
我为这个问题挣扎了好几个星期 据称,邻居将因各种原因被删除,包括主机在保留其第3层地址的同时更改了其第2层地址或不再可访问。看见如果邻居的网关发送ICMP重定向,并且内核中启用了重定向处理,则也可以删除它
如果邻居正在被删除,则数据包被发送到neigh_blackhole,neigh_blackhole无条件返回-enetton
。请参阅代码
sendto()
的手册页会让您相信在这种情况下不应该获得-enetton
,但这似乎是不正确的
发生这种情况时,我会尝试获取网络捕获,并查找表明无法到达目的地的ICMP消息,或目的地的MAC地址(或可能是重复的IP地址)有无更改通过ARP数据包或来自目的地的到达数据包上的MAC地址。我的测试机器的放置方式如下所述。
测试机---网关(1.1.1.1)--防火墙(1.1.1.2)--网络----目的地
第一次,在我的测试机器和目标之间建立UDP连接,我的测试机器的网关地址是1.1.1.1。
测试机器目标之间的通信量没有问题。一段时间后或之后,突然,传输流量失败,出现“网络关闭”错误(错误号100,网络关闭)。
此时,如果我在测试机器中尝试ping到目的地,ping响应OK。
当我捕获测试机器前面的数据包时,ICMP重定向消息来自网关(1.1.1.1)。其信息为“主机重定向”,新的门地址为“1.1.1.2”。
当我的测试机的操作系统(Linux 3.0.35)收到ICMP重定向消息时,它将hh->hh_output()的虚拟函数指针从ev_queue_xmit()更改为neigh_blackhole()。最后,neigh_blackhole()返回-ENETDOWN代码
所以,将我的测试机器的门地址更改为1.1.1.2。此后,“网络关闭”错误不再发生
我认为这是一个奇怪的操作。sendto()函数不会将ENETDOWN代码作为手册页返回。但是,这是返回代码。
无论如何,如果sendto()函数返回-enetton,即使网络接口已更新,如何克服此错误?我是否重新连接UDP流
我想知道这个问题是Linux内核3.0.35的bug
如果我知道或发现关于这个问题的事情,我会在这里更新。
如果有人与我有类似问题,请参考我的案例。如果我的程序运行的机器收到ICMP重定向消息,邻居是否能够删除?我可以看到ICMP重定向消息,其中包含“主机重定向”代码和新的网关地址。我还没有查看内核代码以确定ICMP重定向是否会导致此问题,但这当然是可能的。我建议将-ENETDOWN错误视为暂时性错误,然后重试,可能会有延迟,也可能会有退避。我还建议您理解为什么主机会收到ICMP重定向。不清楚您是否希望通过ICMP重定向获得网络学习路线。这可能是一个安全问题。祝你好运。@shin2011如果内核中启用了ICMP重定向,ICMP重定向将查找并释放邻居。看见