Linux UDP套接字sendto:操作不允许。

10
我正在尝试诊断OpenSIPS(一种SIP代理)应用程序的问题。
当向相同的IP和端口发送两个不同的UDP数据包时,一个呼叫失败并显示-1 EPERM(操作不允许),而另一个则正常。
这两个呼叫都是从同一个进程(至少是相同的PID)发出的。
有关疑问的代码在github上
以下是strace输出:
strace -e sendto
sendto(7, "SIP/2.0 100 Giving a try\r\nVia: S"..., 315, 0, {sa_family=AF_INET, sin_port=htons(5060), sin_addr=inet_addr("yyy.yyy.yyy.yyy")}, 16) = 315
sendto(7, "INVITE sip:myHomeDesktop@xxx"..., 1253, 0, {sa_family=AF_INET, sin_port=htons(5060), sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, 16) = 1253
sendto(7, "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP"..., 707, 0, {sa_family=AF_INET, sin_port=htons(5060), sin_addr=inet_addr("yyy.yyy.yyy.yyy")}, 16) = -1 EPERM (Operation not permitted)

你在使用Wireshark追踪数据包时有没有发现任何线索?比如说有没有收到任何ICMP消息? - nos
很不幸,没有任何ICMP消息返回。tcpdump也没有显示未能发送的数据包出去,但我想这并不奇怪。 - Eosis
1个回答

18

原来内核的连接跟踪模块在丢弃数据包,导致系统调用收到 EPERM 错误并未发送数据包。

我在查看系统日志后发现了这个问题:

May 26 10:59:45 localhost kernel: nf_ct_sip: dropping packet: cannot add expectation for voice

我完全不知道自己在使用SIP连接跟踪模块,在我的系统上它没有被动态加载(lsmod显示为空)。

我通过关闭我的SIP流量的连接跟踪来绕过这个问题:

iptables -I OUTPUT -t raw -p udp --sport 5060 -j CT --notrack
iptables -I PREROUTING -t raw -p udp --dport 5060 -j CT --notrack

"conntrack" 是关键词。谢谢,节省了很多时间! - Kirzilla
根据手册,-j CT --notrack 可以被 -j NOTRACK 替换。 - Adrien Clerc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接