sendmsg失败,错误代码3(ESRCH)

use*_*794 14 linux udp network-programming

操作系统:Linux 2.6.24(x86)

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

这是因为sendmsg系统调用失败,错误代码3(ESRCH)
sendmsg的手册页没有谈论错误ESRCH

即使在终止应用程序并重新启动它之后,问题也无法解决.
其他端口上的UDP流量工作正常

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

使用内核2.6.11,我没有看到这样的问题.

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

Mic*_*haw 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);
Run Code Online (Sandbox Code Playgroud)

最后,我们最终在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;
}
Run Code Online (Sandbox Code Playgroud)

因此,xfrm_policy_match如果您检查其中的代码,xfrm_lookup_bytype您会发现一个循环,该循环一直持续到迭代器耗尽或返回值xrfm_policy_match不是,看起来错误来自于此ESRCH

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

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

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


长话短说

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

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