14

操作系统:Linux 2.6.24 (x86)

我的应用程序在服务器上运行,其中有多个客户端通过 UDP 端口 4500 连接到它。
间歇性地,应用程序无法将 UDP 流量发送到 UDP 端口 4500 上的客户端

这是因为 sendmsg 系统调用失败并出现错误代码 3 (ESRCH)
sendmsg 的手册页没有提及错误 ESRCH

即使杀死应用程序并重新启动它,问题也没有解决。
其他端口上的 UDP 流量工作正常

重新启动服务器是唯一的解决方案。

对于内核 2.6.11,我还没有看到这样的问题。

关于如何调试此问题的任何想法?

4

2 回答 2

2

要调试此问题,鉴于可用的信息,我认为最好的起点是查看是否有sendmsg可以返回的方法ESRCH。首先,我们需要获取您看到问题的特定内核版本的源代码,我在这里找到了它

经过一番挖掘,我们可以看到以下链可能会执行:

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_matchis not ESRCH

这告诉我们您的 sendmsg 调用失败,因为您的端口没有 xfrm 策略。当您声明它有效时,错误就会发生并持续存在,这表明您系统上的 xfrm 策略正在被调整或损坏。

通过查看此处的 xfrm 手册页,我们可以看到有一些用于调查策略的工具。通过阅读手册页,我的下一步将ip xfrm state list在问题未发生和发生后运行并比较输出。不幸的是,我没有一个正在运行的带有 2.6.24 内核的系统来进行更深入的研究。

请注意,我没有任何技巧可以得出这个结论,它是通过检查代码、grepping 和查找来确定的。这可能需要花费大量时间和精力,尤其是当您不熟悉代码库时。为了解决这个问题而不是调试它,我会在深入挖掘之前尝试不同的内核版本。


TL;博士

看起来ESRCH错误来自一个名为 的网络子系统xfrm,有一组用于调查的工具xfrm可以在其手册页上找到

错误似乎很可能是由于您尝试发送到的地址/端口缺少策略。这可能是由于系统运行时配置更改或导致 xfrm 策略损坏的错误。

于 2015-07-02T14:47:26.287 回答
0

当我的 LAN 上的主机无法访问(以太网拔出)时,我刚刚在 OSX 上收到此错误。因此,它似乎可能由多种条件触发。(机场)路由器可能生成了 ICMP。

于 2015-11-16T17:14:40.107 回答