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
This commit is contained in:
parent
81a3342877
commit
a07ba37b5e
@ -950,6 +950,7 @@ struct cf_socket_ctx {
|
|||||||
size_t recv_max; /* max enforced read size */
|
size_t recv_max; /* max enforced read size */
|
||||||
#endif
|
#endif
|
||||||
BIT(got_first_byte); /* if first byte was received */
|
BIT(got_first_byte); /* if first byte was received */
|
||||||
|
BIT(listening); /* socket is listening */
|
||||||
BIT(accepted); /* socket was accepted, not connected */
|
BIT(accepted); /* socket was accepted, not connected */
|
||||||
BIT(sock_connected); /* socket is "connected", e.g. in UDP */
|
BIT(sock_connected); /* socket is "connected", e.g. in UDP */
|
||||||
BIT(active);
|
BIT(active);
|
||||||
@ -1409,10 +1410,17 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
|||||||
|
|
||||||
if(ctx->sock != CURL_SOCKET_BAD) {
|
if(ctx->sock != CURL_SOCKET_BAD) {
|
||||||
if(!cf->connected) {
|
if(!cf->connected) {
|
||||||
|
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_pollset_set_out_only(data, ps, ctx->sock);
|
||||||
CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%"
|
CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%"
|
||||||
FMT_SOCKET_T, ctx->sock);
|
FMT_SOCKET_T, ctx->sock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(!ctx->active) {
|
else if(!ctx->active) {
|
||||||
Curl_pollset_add_in(data, ps, ctx->sock);
|
Curl_pollset_add_in(data, ps, ctx->sock);
|
||||||
CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%"
|
CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%"
|
||||||
@ -2054,6 +2062,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
ctx->transport = conn->transport;
|
ctx->transport = conn->transport;
|
||||||
ctx->sock = *s;
|
ctx->sock = *s;
|
||||||
|
ctx->listening = TRUE;
|
||||||
ctx->accepted = FALSE;
|
ctx->accepted = FALSE;
|
||||||
result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx);
|
result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx);
|
||||||
if(result)
|
if(result)
|
||||||
@ -2120,8 +2129,10 @@ CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
|
|||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
ctx = cf->ctx;
|
ctx = cf->ctx;
|
||||||
|
DEBUGASSERT(ctx->listening);
|
||||||
/* discard the listen socket */
|
/* discard the listen socket */
|
||||||
socket_close(data, conn, TRUE, ctx->sock);
|
socket_close(data, conn, TRUE, ctx->sock);
|
||||||
|
ctx->listening = FALSE;
|
||||||
ctx->sock = *s;
|
ctx->sock = *s;
|
||||||
conn->sock[sockindex] = ctx->sock;
|
conn->sock[sockindex] = ctx->sock;
|
||||||
set_accepted_remote_ip(cf, data);
|
set_accepted_remote_ip(cf, data);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user