操作系统:Linux 2.6.24(x86)
我的应用程序在多个客户端在UDP端口4500上连接到它的服务器上运行 间歇性地,应用程序无法将UDP流量发送到UDP端口4500上的客户端
这是因为sendmsg系统调用失败,错误代码为3(ESRCH)
sendmsg的手册页不讨论错误ESRCH
即使在终止应用程序并重新启动它之后,问题也无法解决 其他端口上的UDP流量正常工作
重新启动服务器是唯一的解决方案。
使用内核2.6.11,我没有看到这样的问题。
关于如何调试此问题的任何想法?
答案 0 :(得分:2)
要调试此问题,根据可用信息,我认为最好的起点是查看sendmsg
是否可以返回ESRCH
。首先,我们需要获得您遇到问题的特定内核版本的源代码,我发现它here
经过一番挖掘,我们可以看到以下链可能会执行:
net/ipv4/udp.c:646:
err = ip_route_output_flow(&rt, &fl, sk, 1);
net/ipv4/route.c:2421:
err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
net/xfrm/xfrm_policy.c:1380:
pols[1] = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN,
fl, family,
XFRM_POLICY_OUT);
net/xfrm/xfrm_policy.c:890:
err = xfrm_policy_match(pol, fl, type, family, dir);
最后,我们最终到了net/xfrm/xfrm_policy.c:854:xrfm_policy_match
/*
* Find policy to apply to this flow.
*
* Returns 0 if policy found, else an -errno.
*/
static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl,
u8 type, u16 family, int dir)
{
struct xfrm_selector *sel = &pol->selector;
int match, ret = -ESRCH;
if (pol->family != family ||
pol->type != type)
return ret;
match = xfrm_selector_match(sel, fl, family);
if (match)
ret = security_xfrm_policy_lookup(pol, fl->secid, dir);
return ret;
}
所以,看起来错误来自xfrm_policy_match
,如果你检查xfrm_lookup_bytype
中的代码,你会发现一个循环一直持续到迭代器耗尽或返回值为xrfm_policy_match
不是ESRCH
。
这告诉我们您的sendmsg调用失败,因为您的端口没有xfrm策略。当您声明它有效时,则会发生错误并持续存在,这表明系统上的xfrm策略正在调整或损坏。
通过查看xfrm手册页here,我们可以看到有一些工具可用于调查策略。从阅读手册页开始,当问题没有发生时以及发生问题并比较输出后,我的下一步将运行ip xfrm state list
。不幸的是,我没有一个运行2.6.24内核的系统可以深入挖掘。
请注意,我没有任何技巧可以得出这个结论,它是通过检查代码,点击和查找来确定的。这可能需要花费大量的时间和精力,尤其是当您不熟悉代码库时。为了解决问题,而不是调试它,我会尝试不同的内核版本,然后再深入研究。
看起来ESRCH
错误来自名为xfrm
的网络子系统,有一组用于调查xfrm
的工具,可以在其手册页{{3}上找到}
错误似乎很可能是由于您尝试发送的地址/端口缺少策略。这可能是由于系统运行时的配置更改或导致xfrm策略损坏的错误。
答案 1 :(得分:0)
当我的局域网上的主机无法访问(以太网未插入)时,我在OSX上遇到此错误。因此,它似乎可能由各种条件触发。可能(机场)路由器生成了ICMP。