From: "Thomas L." Subject: Re: rtorrent crashes To: Jan Stary Cc: Klemens Nanni , "Anthony J. Bentley" , ports@openbsd.org Date: Mon, 25 Aug 2025 16:42:52 +0200 i recently hit the same bug, did a ktrace(1) and found the following 61086 rtorrent CALL socket(AF_INET6,0x2,0) 61086 rtorrent RET socket 16/0x10 61086 rtorrent CALL setsockopt(16,41,27,0x71f9b0bf3e24,4) 61086 rtorrent RET setsockopt -1 errno 22 Invalid argument 61086 rtorrent CALL kbind(0x71f9b0bf3d30,24,0xa7ad56a04777c55) 61086 rtorrent RET kbind 0 61086 rtorrent CALL close(16) 61086 rtorrent RET close 0 61086 rtorrent CALL close(16) 61086 rtorrent RET close -1 errno 9 Bad file descriptor so i set a breakpoint on setsockopt(2) and found in libtorrents src/net/socket_fd.cc bool SocketFd::set_ipv6_v6only(bool state) { check_valid(); if (!m_ipv6_socket) return false; int opt = state; return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == 0; } bool SocketFd::open_datagram() { m_fd = socket(rak::socket_address::pf_inet6, SOCK_DGRAM, 0); if (m_fd == -1) { m_ipv6_socket = false; return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; } m_ipv6_socket = true; if (!set_ipv6_v6only(false)) { close(); return false; } return true; } OpenBSD does not support dualstack sockets, so setting IPV6_V6ONLY to false fails. instead of using two sockets or at least falling back to IPv4-only, libtorrent gives up completely and closes the socket. however, m_fd is not set to -1, so later in TrackerUdp::close_directly() SocketFd::is_valid() returns true and SocketFd::close() is called again, which leads to the crash. the patch below changes SocketFd::open_datagram() to fall back to IPv4, like already done for SocketFd::open_stream(). proper dualstack support would need a bigger refactoring. diff --git net/libtorrent/Makefile net/libtorrent/Makefile index 7bd433cd6b5..880218060e1 100644 --- net/libtorrent/Makefile +++ net/libtorrent/Makefile @@ -7,7 +7,7 @@ BROKEN-sh = undefined references to __sync atomic ops NOT_FOR_ARCHS= ${GCC3_ARCHS} DISTNAME= libtorrent-0.14.0 -REVISION= 1 +REVISION= 2 EPOCH= 0 SHARED_LIBS += torrent 22.1 # .18.0 CATEGORIES= net devel diff --git net/libtorrent/patches/patch-src_net_socket_fd_cc net/libtorrent/patches/patch-src_net_socket_fd_cc index 7f0b78aa71f..ad7dc8c1350 100644 --- net/libtorrent/patches/patch-src_net_socket_fd_cc +++ net/libtorrent/patches/patch-src_net_socket_fd_cc @@ -1,7 +1,7 @@ Index: src/net/socket_fd.cc --- src/net/socket_fd.cc.orig +++ src/net/socket_fd.cc -@@ -126,21 +126,8 @@ SocketFd::get_error() const { +@@ -126,40 +126,14 @@ SocketFd::get_error() const { bool SocketFd::open_stream() { @@ -25,3 +25,24 @@ Index: src/net/socket_fd.cc } bool + SocketFd::open_datagram() { +- m_fd = socket(rak::socket_address::pf_inet6, SOCK_DGRAM, 0); +- +- if (m_fd == -1) { +- m_ipv6_socket = false; +- return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; +- } +- +- m_ipv6_socket = true; +- +- if (!set_ipv6_v6only(false)) { +- close(); +- return false; +- } +- +- return true; ++ m_ipv6_socket = false; ++ return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; + } + + bool