From: Stefan Eissing Date: Tue, 3 Sep 2024 07:54:59 +0000 (+0200) Subject: cf-socket: fix pollset for listening X-Git-Tag: curl-8_10_0~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a07ba37b5e88a89bf4bcc6b0c927f7a42d7ea4f2;p=thirdparty%2Fcurl.git cf-socket: fix pollset for listening When FTP does an active data connection, the socket connection filter is instantiated with a listening socket. When the filter adjusts its pollset, it needs to POLLIN, not OUT. Bug: https://curl.se/mail/lib-2024-08/0023.html Reported-by: Yoshimasa Ohno Closes #14766 --- diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 68c0278fb0..0e5db5e3ec 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -950,6 +950,7 @@ struct cf_socket_ctx { size_t recv_max; /* max enforced read size */ #endif BIT(got_first_byte); /* if first byte was received */ + BIT(listening); /* socket is listening */ BIT(accepted); /* socket was accepted, not connected */ BIT(sock_connected); /* socket is "connected", e.g. in UDP */ BIT(active); @@ -1409,9 +1410,16 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, if(ctx->sock != CURL_SOCKET_BAD) { if(!cf->connected) { - Curl_pollset_set_out_only(data, ps, ctx->sock); - CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%" - FMT_SOCKET_T, ctx->sock); + if(ctx->listening) { + Curl_pollset_set_in_only(data, ps, ctx->sock); + CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%" + FMT_SOCKET_T, ctx->sock); + } + else { + Curl_pollset_set_out_only(data, ps, ctx->sock); + CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%" + FMT_SOCKET_T, ctx->sock); + } } else if(!ctx->active) { Curl_pollset_add_in(data, ps, ctx->sock); @@ -2054,6 +2062,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, } ctx->transport = conn->transport; ctx->sock = *s; + ctx->listening = TRUE; ctx->accepted = FALSE; result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx); if(result) @@ -2120,8 +2129,10 @@ CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data, return CURLE_FAILED_INIT; ctx = cf->ctx; + DEBUGASSERT(ctx->listening); /* discard the listen socket */ socket_close(data, conn, TRUE, ctx->sock); + ctx->listening = FALSE; ctx->sock = *s; conn->sock[sockindex] = ctx->sock; set_accepted_remote_ip(cf, data);