sendto()返回错误代码ENETDOWN

时间:2017-01-10 08:11:23

标签: networking packet

我遇到了很奇怪的情况。

在我的程序中,sendto()函数返回错误代码ENETDOWN(Network is down),即使网络已启动并且ping尝试成功。

仅当 UDP 流通过多个网关连接到其他网络时才会发生这种情况。它并不总是有时发生。 如果我在相同的子网络下运行相同的代码,则不会出现ENETDOWN等错误。

因此,我将sendto()函数跟踪到内核区域neigh_hh_output() ip_finish_output2()中的iop_output.c函数调用hh->hh_output()并返回ENETDOWN错误代码。

在正常操作下,hh->hh_output()功能被分配给dev_queue_xmit() dev.c并且数据包被发送到网络。

问题发生时,它似乎已分配给neigh_blackhole() neigh_destroy() neighbour.c中的neigh_blackhole()功能。 -ENETDOWN会返回neigh_destroy()代码。

但是,我不知道何时调用std::string str("foo"); std::stringstream ss(str); float f = 0; if ((ss >> f) == false) std::cout << "Parse error\n"; 以及调用该函数的原因。

我几周来一直在努力解决这个问题。

2 个答案:

答案 0 :(得分:1)

我的测试机器放置如下所述。 试验机---网关(1.1.1.1)---防火墙(1.1.1.2)---网络----目的地。

第一次,在我的测试机器和目标之间建立UDP连接,我的测试机器的网关地址是1.1.1.1。 测试机器目的地之间的流量没有问题。经过一段时间或之后,突然,传输流量因“网络已关闭”错误而失败(错误号100,ENETDOWN)。 此时,如果我在我的测试机器中尝试ping到目标,则ping响应OK。 当我捕获测试机器的数据包前端时,ICMP重定向消息来自网关(1.1.1.1)。其信息是“Redirect for Host”,新的门地址是“1.1.1.2”。 当我的测试机器的OS(Linux 3.0.35)收到ICMP重定向消息时,它将hh-&gt; hh_output()的虚函数指针从ev_queue_xmit()更改为neigh_blackhole()。最终,neigh_blackhole()返回-ENETDOWN代码。

因此,将我的测试机器的门地址更改为1.1.1.2。之后,“网络已关闭”错误不再发生。

我认为这是奇怪的操作。 sendto()函数不返回ENETDOWN代码作为手册页。但是,它返回ENETDOWN代码。 无论如何,如果sendto()函数返回-ENETDOWN即使网络接口更新,如何克服此错误?我是否重新连接UDP流?

我想知道这个问题是Linux内核3.0.35的错误。

如果我知道或找到关于这个问题的事情,我会在这里更新。 如果有人和我有类似的问题,请参考我的案例。

答案 1 :(得分:0)

据称,由于各种原因将删除邻居,包括主机更改其第2层地址,同时保留其第3层地址或不再可访问。见this。如果邻居的网关发送ICMP重定向并且在内核中启用了重定向处理,也可以删除它。

如果邻居正在被删除,那么该数据包将被分派到neigh_blackhole,无条件地返回-ENETDOWN。请参阅代码here

sendto()的手册页会让您相信在这种情况下您不应该-ENETDOWN,但这似乎是不正确的。

我会尝试在发生这种情况时获取网络捕获并查找指示目标无法访问的ICMP消息,或者通过ARP数据包或MAC查找目标的MAC地址(或可能是重复的IP地址)来自目的地的到达数据包的地址。