mirror of
https://github.com/curl/curl.git
synced 2026-08-25 02:53:32 +03:00
connection: shutdown TLS (for FTP) better
This adds connection shutdown infrastructure and first use for FTP. FTP
data connections, when not encountering an error, are now shut down in a
blocking way with a 2sec timeout.
- add cfilter `Curl_cft_shutdown` callback
- keep a shutdown start timestamp and timeout at connectdata
- provide shutdown timeout default and member in
`data->set.shutdowntimeout`.
- provide methods for starting, interrogating and clearing
shutdown timers
- provide `Curl_conn_shutdown_blocking()` to shutdown the
`sockindex` filter chain in a blocking way. Use that in FTP.
- add `Curl_conn_cf_poll()` to wait for socket events during
shutdown of a connection filter chain.
This gets the monitoring sockets and events via the filters
"adjust_pollset()" methods. This gives correct behaviour when
shutting down a TLS connection through a HTTP/2 proxy.
- Implement shutdown for all socket filters
- for HTTP/2 and h2 proxying to send GOAWAY
- for TLS backends to the best of their capabilities
- for tcp socket filter to make a final, nonblocking
receive to avoid unwanted RST states
- add shutdown forwarding to happy eyeballers and
https connect ballers when applicable.
Closes #13904
This commit is contained in:
parent
7d934267ab
commit
c31041b17e
33 changed files with 1161 additions and 465 deletions
23
lib/ftp.c
23
lib/ftp.c
|
|
@ -290,12 +290,15 @@ const struct Curl_handler Curl_handler_ftps = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static void close_secondarysocket(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
static void close_secondarysocket(struct Curl_easy *data, bool premature)
|
||||
{
|
||||
if(!premature) {
|
||||
CURL_TRC_FTP(data, "[%s] shutting down DATA connection", FTP_DSTATE(data));
|
||||
Curl_conn_shutdown_blocking(data, SECONDARYSOCKET);
|
||||
}
|
||||
CURL_TRC_FTP(data, "[%s] closing DATA connection", FTP_DSTATE(data));
|
||||
Curl_conn_close(data, SECONDARYSOCKET);
|
||||
Curl_conn_cf_discard_all(data, conn, SECONDARYSOCKET);
|
||||
Curl_conn_cf_discard_all(data, data->conn, SECONDARYSOCKET);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -475,7 +478,7 @@ static CURLcode AcceptServerConnect(struct Curl_easy *data)
|
|||
Curl_set_in_callback(data, false);
|
||||
|
||||
if(error) {
|
||||
close_secondarysocket(data, conn);
|
||||
close_secondarysocket(data, TRUE);
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
|
|
@ -2980,7 +2983,13 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
|||
case FTP_CCC:
|
||||
if(ftpcode < 500) {
|
||||
/* First shut down the SSL layer (note: this call will block) */
|
||||
result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET);
|
||||
/* This has only been tested on the proftpd server, and the mod_tls
|
||||
* code sends a close notify alert without waiting for a close notify
|
||||
* alert in response. Thus we wait for a close notify alert from the
|
||||
* server, but we do not send one. Let's hope other servers do
|
||||
* the same... */
|
||||
result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET,
|
||||
(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE));
|
||||
|
||||
if(result)
|
||||
failf(data, "Failed to clear the command channel (CCC)");
|
||||
|
|
@ -3457,7 +3466,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
|||
}
|
||||
}
|
||||
|
||||
close_secondarysocket(data, conn);
|
||||
close_secondarysocket(data, result != CURLE_OK);
|
||||
}
|
||||
|
||||
if(!result && (ftp->transfer == PPTRANSFER_BODY) && ftpc->ctl_valid &&
|
||||
|
|
@ -4425,7 +4434,7 @@ static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected)
|
|||
CURLcode result = ftp_do_more(data, &completed);
|
||||
|
||||
if(result) {
|
||||
close_secondarysocket(data, conn);
|
||||
close_secondarysocket(data, TRUE);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue