fix: ESPIPE "illegal seek" error while seeding (#3137)

* fix: ESPIPE "illegal seek" error while seeding

The root cause is createSocket returning `{}` instead of `TR_BAD_SOCKET`
when we have too many peers in use. This defaulted to fd 0, which wound
up closing stdin.

Commit also includes some const-correctness changes made while tracking
the problem down.
This commit is contained in:
Charles Kerr 2022-05-25 18:16:15 -05:00 committed by GitHub
parent b4624cc775
commit 46eb379205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 12 additions and 14 deletions

View File

@ -313,7 +313,7 @@ static tr_socket_t createSocket(tr_session* session, int domain, int type)
if ((evutil_make_socket_nonblocking(sockfd) == -1) || !session->incPeerCount()) if ((evutil_make_socket_nonblocking(sockfd) == -1) || !session->incPeerCount())
{ {
tr_netClose(session, sockfd); tr_netClose(session, sockfd);
return {}; return TR_BAD_SOCKET;
} }
if (static bool buf_logged = false; !buf_logged) if (static bool buf_logged = false; !buf_logged)
@ -474,7 +474,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool
static int const domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 }; static int const domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
struct sockaddr_storage sock; struct sockaddr_storage sock;
tr_socket_t const fd = socket(domains[addr->type], SOCK_STREAM, 0); auto const fd = socket(domains[addr->type], SOCK_STREAM, 0);
if (fd == TR_BAD_SOCKET) if (fd == TR_BAD_SOCKET)
{ {
*errOut = sockerrno; *errOut = sockerrno;
@ -573,7 +573,7 @@ bool tr_net_hasIPv6(tr_port port)
if (!alreadyDone) if (!alreadyDone)
{ {
int err = 0; int err = 0;
tr_socket_t fd = tr_netBindTCPImpl(&tr_in6addr_any, port, true, &err); auto const fd = tr_netBindTCPImpl(&tr_in6addr_any, port, true, &err);
if (fd != TR_BAD_SOCKET || err != EAFNOSUPPORT) /* we support ipv6 */ if (fd != TR_BAD_SOCKET || err != EAFNOSUPPORT) /* we support ipv6 */
{ {
@ -600,7 +600,7 @@ tr_socket_t tr_netAccept(tr_session* session, tr_socket_t listening_sockfd, tr_a
// accept the incoming connection // accept the incoming connection
struct sockaddr_storage sock; struct sockaddr_storage sock;
socklen_t len = sizeof(struct sockaddr_storage); socklen_t len = sizeof(struct sockaddr_storage);
auto sockfd = accept(listening_sockfd, (struct sockaddr*)&sock, &len); auto const sockfd = accept(listening_sockfd, (struct sockaddr*)&sock, &len);
if (sockfd == TR_BAD_SOCKET) if (sockfd == TR_BAD_SOCKET)
{ {
return TR_BAD_SOCKET; return TR_BAD_SOCKET;
@ -655,7 +655,7 @@ static int get_source_address(struct sockaddr const* dst, socklen_t dst_len, str
return 0; return 0;
} }
int save = errno; auto const save = errno;
evutil_closesocket(s); evutil_closesocket(s);
errno = save; errno = save;
return -1; return -1;

View File

@ -26,7 +26,7 @@ union tr_peer_socket_handle
struct tr_peer_socket struct tr_peer_socket
{ {
enum tr_peer_socket_type type; enum tr_peer_socket_type type = TR_PEER_SOCKET_TYPE_NONE;
union tr_peer_socket_handle handle; union tr_peer_socket_handle handle;
}; };

View File

@ -59,9 +59,9 @@ struct tr_fdInfo;
struct tr_bindinfo struct tr_bindinfo
{ {
int socket; tr_socket_t socket = TR_BAD_SOCKET;
tr_address addr; tr_address addr = {};
struct event* ev; struct event* ev = nullptr;
}; };
struct tr_turtle_info struct tr_turtle_info
@ -343,8 +343,8 @@ public:
/* The UDP sockets used for the DHT and uTP. */ /* The UDP sockets used for the DHT and uTP. */
tr_port udp_port; tr_port udp_port;
tr_socket_t udp_socket; tr_socket_t udp_socket = TR_BAD_SOCKET;
tr_socket_t udp6_socket; tr_socket_t udp6_socket = TR_BAD_SOCKET;
unsigned char* udp6_bound; unsigned char* udp6_bound;
struct event* udp_event; struct event* udp_event;
struct event* udp6_event; struct event* udp6_event;

View File

@ -14,7 +14,6 @@
using in_port_t = uint16_t; /* all missing */ using in_port_t = uint16_t; /* all missing */
#else #else
#include <ctime> #include <ctime>
#include <unistd.h> /* close() */
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> /* socket(), bind() */ #include <sys/socket.h> /* socket(), bind() */
#include <netinet/in.h> /* sockaddr_in */ #include <netinet/in.h> /* sockaddr_in */

View File

@ -118,7 +118,6 @@ static void rebind_ipv6(tr_session* ss, bool force)
{ {
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
unsigned char const* ipv6 = tr_globalIPv6(ss); unsigned char const* ipv6 = tr_globalIPv6(ss);
tr_socket_t s = TR_BAD_SOCKET;
int rc = -1; int rc = -1;
int one = 1; int one = 1;
@ -140,7 +139,7 @@ static void rebind_ipv6(tr_session* ss, bool force)
return; return;
} }
s = socket(PF_INET6, SOCK_DGRAM, 0); auto const s = socket(PF_INET6, SOCK_DGRAM, 0);
if (s == TR_BAD_SOCKET) if (s == TR_BAD_SOCKET)
{ {