Thank you, this makes rtorrent no longer crash on my amd64 Jan
On Aug 25 16:42:52, [email protected] wrote: > 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 > >
