[Bug 260055] recvmsg / IP_RECVDSTADDR issue

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 26 Nov 2021 06:02:08 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260055

            Bug ID: 260055
           Summary: recvmsg / IP_RECVDSTADDR issue
           Product: Base System
           Version: 12.2-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: eugen@freebsd.org
                CC: kib@FreeBSD.org, mav@FreeBSD.org

Multi-protocol daemon net/mpd5 that includes L2TP server implementation
recently got ability to use IP_RECVDSTADDR IPv4 UDP socket option to support
multi-homed configurations without multiple single-IP sub-configurations.

Since then, users observe strange "hangs" of L2TP server when it stops
processing new incoming connections for hours (if not killed). It may "unhang"
after several hours if left in this state and continue to work normally until
next hang.

This problem observed under FreeBSD versions 11, 12 and 13.

I have it, too. I've rebult binary with debugging symbols and got coredump with
SIGQUIT when problem occured. Here is a backtrace that shows it blocks on
recvmsg() trying to obtain source address of UDP socket:

(gdb) thread apply all bt

Thread 1 (process 100333):
#0  0x2853a6e3 in _recvmsg () from /lib/libc.so.7
#1  0x2844f0c1 in pthread_suspend_all_np () from /lib/libthr.so.3
#2  0x284d118f in recvmsg () from /lib/libc.so.7
#3  0x080dea71 in GetSockDstAddress (sock=24, addr=0x28c484e8) at util.c:1581
#4  0x0806c48a in L2tpServerEvent (type=1, arg=0x28c47048) at l2tp.c:1419
#5  0x080a1e4f in EventHandler (arg=0x28c47068) at event.c:146
#6  0x080ea7de in pevent_ctx_execute (arg=0x28c139b4) at
contrib/libpdel/util/pevent.c:884
#7  0x080ea354 in pevent_ctx_service (ev=0x28c139b4) at
contrib/libpdel/util/pevent.c:773
#8  0x080e9e33 in pevent_ctx_main (arg=0x28a41004) at
contrib/libpdel/util/pevent.c:719
#9  0x2844c2c2 in pthread_create () from /lib/libthr.so.3
#10 0x00000000 in ?? ()
(gdb) frame 3
#3  0x080dea71 in GetSockDstAddress (sock=24, addr=0x28c484e8) at util.c:1581
1581            if ((size = recvmsg(sock, &b.msg, 0)) < 0) {
(gdb) p b
$1 = {msg = {msg_name = 0x0, msg_namelen = 0, msg_iov = 0xbbbfd334, msg_iovlen
= 1,
    msg_control = 0xbbbfd340, msg_controllen = 16, msg_flags = 0}, iov =
{iov_base = 0xbbbfd354,
    iov_len = 1024}}

There is corresponding source code, function GetSockDstAddress()
https://sourceforge.net/p/mpd/svn/HEAD/tree/trunk/src/util.c#l1553

FreeBSD base system has not many consumers of IP_RECVDSTADDR socket options:

src/contrib/pf/tftp-proxy
src/contrib/unbound
contrib/bsnmp/snmpd

None of them is threaded application like net/mpd5. I suspect an issue in
threaded iplementation of this socket option that leads to long time block of
recvmsg().

-- 
You are receiving this mail because:
You are the assignee for the bug.