Download raw body.
rtorrent crashes
i recently hit the same bug, did a ktrace(1) and found the following
61086 rtorrent CALL socket(AF_INET6,0x2<SOCK_DGRAM>,0)
61086 rtorrent RET socket 16/0x10
61086 rtorrent CALL setsockopt(16,41<ipv6>,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
rtorrent crashes