conncontrol: reuse handling

Add protocol handler flag `PROTOPT_CONN_REUSE` to indicate that the
protocol allows reusing connections for other tranfers. Add that
to all handlers that support it.

Create connections with `conn->bits.close = FALSE` and remove all
the `connkeep()` calls in protocol handlers setup/connect implementations.
`PROTOPT_CONN_REUSE` assures that the default behaviour applies
at the end of a transfer without need to juggle the close bit.

`conn->bits.close` now serves as an additional indication that a
connection cannot be reused. Only protocol handles that allow
reuse need to set it to override the default behaviour.

Remove all `connclose()` and `connkeep()` calls from connection
filters. Filters should not modify connection flags. They are
supposed to run in eyeballing situations where a filter is just
one of many determining the outcome.

Fix http response header handling to only honour `Connection: close`
for HTTP/1.x versions.

Closes #19333
This commit is contained in:
Stefan Eissing 2025-11-03 13:12:50 +01:00 committed by Daniel Stenberg
parent a9e7a027ed
commit feea968512
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
21 changed files with 93 additions and 114 deletions

View file

@ -127,7 +127,6 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
Curl_httpchunk_init(data, &ts->ch, TRUE);
*pts = ts;
connkeep(cf->conn, "HTTP proxy CONNECT");
return tunnel_reinit(cf, data, ts);
}
@ -591,7 +590,6 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
CURL_TRC_CF(data, cf, "CONNECT need to close+open");
infof(data, "Connect me again please");
Curl_conn_cf_close(cf, data);
connkeep(conn, "HTTP proxy CONNECT");
result = Curl_conn_cf_connect(cf->next, data, &done);
goto out;
}
@ -612,8 +610,6 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
if(data->info.httpproxycode/100 != 2) {
/* a non-2xx response and we have no next URL to try. */
Curl_safefree(data->req.newurl);
/* failure, close this connection to avoid reuse */
streamclose(conn, "proxy CONNECT failure");
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
return CURLE_RECV_ERROR;

View file

@ -488,10 +488,6 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
return result;
}
if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) {
connclose(cf->conn, "GOAWAY received");
}
return CURLE_OK;
}
@ -1265,7 +1261,7 @@ static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf,
if(ctx->tunnel.error == NGHTTP2_REFUSED_STREAM) {
CURL_TRC_CF(data, cf, "[%d] REFUSED_STREAM, try again on a new "
"connection", ctx->tunnel.stream_id);
connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */
failf(data, "proxy server refused HTTP/2 stream");
return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
}
else if(ctx->tunnel.error != NGHTTP2_NO_ERROR) {

View file

@ -220,7 +220,6 @@ void Curl_cpool_destroy(struct cpool *cpool)
while(conn) {
cpool_remove_conn(cpool, conn);
sigpipe_apply(cpool->idata, &pipe_st);
connclose(conn, "kill all");
cpool_discard_conn(cpool, cpool->idata, conn, FALSE);
conn = cpool_get_first(cpool);
}

View file

@ -270,7 +270,8 @@ const struct Curl_handler Curl_handler_ftp = {
CURLPROTO_FTP, /* family */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
PROTOPT_WILDCARD | PROTOPT_SSL_REUSE /* flags */
PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE /* flags */
};
@ -302,7 +303,8 @@ const struct Curl_handler Curl_handler_ftps = {
CURLPROTO_FTPS, /* protocol */
CURLPROTO_FTP, /* family */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
PROTOPT_CONN_REUSE /* flags */
};
#endif
@ -3183,9 +3185,6 @@ static CURLcode ftp_connect(struct Curl_easy *data,
if(!ftpc)
return CURLE_FAILED_INIT;
pp = &ftpc->pp;
/* We always support persistent connections on ftp */
connkeep(conn, "FTP default");
PINGPONG_SETUP(pp, ftp_pp_statemachine, ftp_endofresp);
if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {

View file

@ -142,7 +142,8 @@ const struct Curl_handler Curl_handler_http = {
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE
};
#ifdef USE_SSL
@ -172,7 +173,7 @@ const struct Curl_handler Curl_handler_https = {
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
PROTOPT_USERPWDCTRL
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE
};
#endif
@ -220,7 +221,6 @@ CURLcode Curl_http_setup_conn(struct Curl_easy *data,
{
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
connkeep(conn, "HTTP default");
if(data->state.http_neg.wanted == CURL_HTTP_V3x) {
/* only HTTP/3, needs to work */
CURLcode result = Curl_conn_may_http3(data, conn, conn->transport_wanted);
@ -1548,12 +1548,6 @@ Curl_compareheader(const char *headerline, /* line to check */
*/
CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
/* We default to persistent connections. We set this already in this connect
function to make the reuse checks properly be able to check this bit. */
connkeep(conn, "HTTP default");
return Curl_conn_connect(data, FIRSTSOCKET, FALSE, done);
}
@ -3257,14 +3251,15 @@ static CURLcode http_header_c(struct Curl_easy *data,
}
return CURLE_OK;
}
if(HD_IS_AND_SAYS(hd, hdlen, "Connection:", "close")) {
if((k->httpversion < 20) &&
HD_IS_AND_SAYS(hd, hdlen, "Connection:", "close")) {
/*
* [RFC 2616, section 8.1.2.1]
* "Connection: close" is HTTP/1.1 language and means that
* the connection will close when this request has been
* served.
*/
streamclose(conn, "Connection: close used");
connclose(conn, "Connection: close used");
return CURLE_OK;
}
if((k->httpversion == 10) &&

View file

@ -2071,7 +2071,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
size_t nread;
if(should_close_session(ctx)) {
CURL_TRC_CF(data, cf, "progress ingress, session is closed");
CURL_TRC_CF(data, cf, "[0] ingress: session is closed");
return CURLE_HTTP2;
}
@ -2128,15 +2128,16 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
result = h2_process_pending_input(cf, data);
if(result)
return result;
CURL_TRC_CF(data, cf, "[0] progress ingress: inbufg=%zu",
CURL_TRC_CF(data, cf, "[0] ingress: nw-in buffered %zu",
Curl_bufq_len(&ctx->inbufq));
}
if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) {
connclose(cf->conn, "GOAWAY received");
connclose(cf->conn, ctx->rcvd_goaway ? "server closed with GOAWAY" :
"server closed abruptly");
}
CURL_TRC_CF(data, cf, "[0] progress ingress: done");
CURL_TRC_CF(data, cf, "[0] ingress: done");
return CURLE_OK;
}

View file

@ -210,9 +210,9 @@ const struct Curl_handler Curl_handler_imap = {
PORT_IMAP, /* defport */
CURLPROTO_IMAP, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION| /* flags */
PROTOPT_URLOPTIONS|
PROTOPT_SSL_REUSE
PROTOPT_CLOSEACTION | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE
};
#ifdef USE_SSL
@ -243,7 +243,7 @@ const struct Curl_handler Curl_handler_imaps = {
CURLPROTO_IMAPS, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_URLOPTIONS
PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE
};
#endif
@ -1680,9 +1680,6 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
if(!imapc)
return CURLE_FAILED_INIT;
/* We always support persistent connections in IMAP */
connkeep(data->conn, "IMAP default");
/* Parse the URL options */
result = imap_parse_url_options(data->conn, imapc);
if(result)

View file

@ -547,6 +547,47 @@ struct multi_done_ctx {
BIT(premature);
};
static bool multi_conn_should_close(struct connectdata *conn,
struct Curl_easy *data,
bool premature)
{
/* if conn->bits.close is TRUE, it means that the connection should be
closed in spite of everything else. */
if(conn->bits.close)
return TRUE;
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this connection. This is ignored for requests taking
place in a NTLM/NEGOTIATE authentication handshake. */
if(data->set.reuse_forbid
#ifdef USE_NTLM
&& !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
#endif
#ifdef USE_SPNEGO
&& !(conn->http_negotiate_state == GSS_AUTHRECV ||
conn->proxy_negotiate_state == GSS_AUTHRECV)
#endif
)
return TRUE;
/* Unless this connection is for a "connect-only" transfer, it
* needs to be closed if the protocol handler does not support reuse. */
if(!data->set.connect_only && conn->handler &&
!(conn->handler->flags & PROTOPT_CONN_REUSE))
return TRUE;
/* if premature is TRUE, it means this connection was said to be DONE before
the entire request operation is complete and thus we cannot know in what
state it is for reusing, so we are forced to close it. In a perfect world
we can add code that keep track of if we really must close it here or not,
but currently we have no such detail knowledge. */
if(premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))
return TRUE;
return FALSE;
}
static void multi_done_locked(struct connectdata *conn,
struct Curl_easy *data,
void *userdata)
@ -587,32 +628,7 @@ static void multi_done_locked(struct connectdata *conn,
Curl_resolv_unlink(data, &data->state.dns[1]);
Curl_dnscache_prune(data);
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this connection. This is ignored for requests taking
place in a NTLM/NEGOTIATE authentication handshake
if conn->bits.close is TRUE, it means that the connection should be
closed in spite of all our efforts to be nice, due to protocol
restrictions in our or the server's end
if premature is TRUE, it means this connection was said to be DONE before
the entire request operation is complete and thus we cannot know in what
state it is for reusing, so we are forced to close it. In a perfect world
we can add code that keep track of if we really must close it here or not,
but currently we have no such detail knowledge.
*/
if((data->set.reuse_forbid
#ifdef USE_NTLM
&& !(conn->http_ntlm_state == NTLMSTATE_TYPE2 ||
conn->proxy_ntlm_state == NTLMSTATE_TYPE2)
#endif
#ifdef USE_SPNEGO
&& !(conn->http_negotiate_state == GSS_AUTHRECV ||
conn->proxy_negotiate_state == GSS_AUTHRECV)
#endif
) || conn->bits.close
|| (mdctx->premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
if(multi_conn_should_close(conn, data, mdctx->premature)) {
#ifndef CURL_DISABLE_VERBOSE_STRINGS
CURL_TRC_M(data, "multi_done, terminating conn #%" FMT_OFF_T " to %s:%d, "
"forbid=%d, close=%d, premature=%d, conn_multiplex=%d",
@ -2127,8 +2143,6 @@ static CURLMcode state_do(struct Curl_easy *data,
}
if(data->set.connect_only && !data->set.connect_only_ws) {
/* keep connection open for application to use the socket */
connkeep(data->conn, "CONNECT_ONLY");
multistate(data, MSTATE_DONE);
rc = CURLM_CALL_MULTI_PERFORM;
}

View file

@ -139,7 +139,8 @@ const struct Curl_handler Curl_handler_ldap = {
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL_REUSE /* flags */
PROTOPT_SSL_REUSE | /* flags */
PROTOPT_CONN_REUSE
};
#ifdef USE_SSL
@ -169,7 +170,8 @@ const struct Curl_handler Curl_handler_ldaps = {
PORT_LDAPS, /* defport */
CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL /* flags */
PROTOPT_SSL | /* flags */
PROTOPT_CONN_REUSE
};
#endif
@ -992,7 +994,6 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done)
if(!li)
return CURLE_FAILED_INIT;
connkeep(conn, "OpenLDAP do");
infof(data, "LDAP local: %s", data->state.url);

View file

@ -200,7 +200,8 @@ const struct Curl_handler Curl_handler_pop3 = {
CURLPROTO_POP3, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE
};
#ifdef USE_SSL
@ -230,8 +231,9 @@ const struct Curl_handler Curl_handler_pop3s = {
PORT_POP3S, /* defport */
CURLPROTO_POP3S, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS |
PROTOPT_CONN_REUSE
};
#endif
@ -1295,9 +1297,6 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
if(!pop3c)
return CURLE_FAILED_INIT;
/* We always support persistent connections in POP3 */
connkeep(conn, "POP3 default");
PINGPONG_SETUP(pp, pop3_statemachine, pop3_endofresp);
/* Set the default preferred authentication type and mechanism */

View file

@ -152,7 +152,7 @@ const struct Curl_handler Curl_handler_rtsp = {
PORT_RTSP, /* defport */
CURLPROTO_RTSP, /* protocol */
CURLPROTO_RTSP, /* family */
PROTOPT_NONE /* flags */
PROTOPT_CONN_REUSE /* flags */
};
#define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */

View file

@ -329,7 +329,7 @@ const struct Curl_handler Curl_handler_smb = {
PORT_SMB, /* defport */
CURLPROTO_SMB, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_NONE /* flags */
PROTOPT_CONN_REUSE /* flags */
};
#ifdef USE_SSL
@ -358,7 +358,7 @@ const struct Curl_handler Curl_handler_smbs = {
PORT_SMBS, /* defport */
CURLPROTO_SMBS, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_SSL /* flags */
PROTOPT_SSL | PROTOPT_CONN_REUSE /* flags */
};
#endif
@ -513,9 +513,6 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
if(!smbc->send_buf)
return CURLE_OUT_OF_MEMORY;
/* Multiple requests are allowed with this connection */
connkeep(conn, "SMB default");
/* Parse the username, domain, and password */
slash = strchr(conn->user, '/');
if(!slash)

View file

@ -205,7 +205,8 @@ const struct Curl_handler Curl_handler_smtp = {
CURLPROTO_SMTP, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE
};
#ifdef USE_SSL
@ -235,8 +236,9 @@ const struct Curl_handler Curl_handler_smtps = {
PORT_SMTPS, /* defport */
CURLPROTO_SMTPS, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS |
PROTOPT_CONN_REUSE
};
#endif
@ -1440,9 +1442,6 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done)
if(!smtpc)
return CURLE_FAILED_INIT;
/* We always support persistent connections in SMTP */
connkeep(data->conn, "SMTP default");
PINGPONG_SETUP(&smtpc->pp, smtp_pp_statemachine, smtp_endofresp);
/* Initialize the SASL storage */

View file

@ -1364,11 +1364,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->connection_id = -1; /* no ID */
conn->remote_port = -1; /* unknown at this point */
/* Default protocol-independent behavior does not support persistent
connections, so we set this to force-close. Protocols that support
this need to set this to FALSE in their "curl_do" functions. */
connclose(conn, "Default to force-close");
/* Store creation time to help future close decision making */
conn->created = curlx_now();
@ -1428,6 +1423,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
#ifdef HAVE_GSSAPI
conn->gssapi_delegation = data->set.gssapi_delegation;
#endif
DEBUGF(infof(data, "alloc connection, bits.close=%d", conn->bits.close));
return conn;
error:
@ -2035,11 +2031,13 @@ static CURLcode setup_connection_internals(struct Curl_easy *data,
int port;
CURLcode result;
DEBUGF(infof(data, "setup connection, bits.close=%d", conn->bits.close));
if(conn->handler->setup_connection) {
result = conn->handler->setup_connection(data, conn);
if(result)
return result;
}
DEBUGF(infof(data, "setup connection, bits.close=%d", conn->bits.close));
/* Now create the destination name */
#ifndef CURL_DISABLE_PROXY
@ -3664,6 +3662,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* We have decided that we want a new connection. However, we may not
be able to do that if we have reached the limit of how many
connections we are allowed to open. */
DEBUGF(infof(data, "new connection, bits.close=%d", conn->bits.close));
if(conn->handler->flags & PROTOPT_ALPN) {
/* The protocol wants it, so set the bits if enabled in the easy handle

View file

@ -567,6 +567,7 @@ struct Curl_handler {
#define PROTOPT_SSL_REUSE (1<<15) /* this protocol may reuse an existing
SSL connection in the same family
without having PROTOPT_SSL. */
#define PROTOPT_CONN_REUSE (1<<16) /* this protocol can reuse connections */
#define CONNCHECK_NONE 0 /* No checks */
#define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */

View file

@ -2647,7 +2647,6 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf,
CURL_TRC_CF(data, cf, "peer verified");
cf->connected = TRUE;
*done = TRUE;
connkeep(cf->conn, "HTTP/3 default");
}
}

View file

@ -1816,7 +1816,6 @@ static CURLcode cf_osslq_connect(struct Curl_cfilter *cf,
CURL_TRC_CF(data, cf, "peer verified");
cf->connected = TRUE;
*done = TRUE;
connkeep(cf->conn, "HTTP/3 default");
}
}
else {

View file

@ -446,7 +446,6 @@ static CURLcode cf_recv_body(struct Curl_cfilter *cf,
stream->closed = TRUE;
stream->reset = TRUE;
stream->send_closed = TRUE;
streamclose(cf->conn, "Reset of stream");
return result;
}
return CURLE_OK;
@ -510,7 +509,6 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf,
stream->closed = TRUE;
stream->reset = TRUE;
stream->send_closed = TRUE;
streamclose(cf->conn, "Reset of stream");
break;
case QUICHE_H3_EVENT_FINISHED:
@ -522,7 +520,6 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf,
stream->resp_hds_complete = TRUE;
}
stream->closed = TRUE;
streamclose(cf->conn, "End of stream");
break;
case QUICHE_H3_EVENT_GOAWAY:
@ -1415,7 +1412,6 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf,
}
cf->connected = TRUE;
*done = TRUE;
connkeep(cf->conn, "HTTP/3 default");
}
}
else if(quiche_conn_is_draining(ctx->qconn)) {

View file

@ -156,7 +156,8 @@ const struct Curl_handler Curl_handler_scp = {
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
};
/*
@ -185,8 +186,8 @@ const struct Curl_handler Curl_handler_sftp = {
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
};
static CURLcode sftp_error_to_CURLE(int err)
@ -2572,10 +2573,6 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
if(!sshc || !ssh)
return CURLE_FAILED_INIT;
/* We default to persistent connections. We set this already in this connect
function to make the reuse checks properly be able to check this bit. */
connkeep(conn, "SSH default");
if(conn->handler->protocol & CURLPROTO_SCP) {
conn->recv[FIRSTSOCKET] = scp_recv;
conn->send[FIRSTSOCKET] = scp_send;

View file

@ -123,8 +123,8 @@ const struct Curl_handler Curl_handler_scp = {
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
};
@ -154,8 +154,8 @@ const struct Curl_handler Curl_handler_sftp = {
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE
};
static void
@ -3323,10 +3323,6 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
if(!sshc)
return CURLE_FAILED_INIT;
/* We default to persistent connections. We set this already in this connect
function to make the reuse checks properly be able to check this bit. */
connkeep(conn, "SSH default");
infof(data, "User: '%s'", conn->user);
#ifdef CURL_LIBSSH2_DEBUG
infof(data, "Password: %s", conn->passwd);

View file

@ -5175,7 +5175,6 @@ static CURLcode ossl_recv(struct Curl_cfilter *cf,
char error_buffer[256];
unsigned long sslerror;
int buffsize;
struct connectdata *conn = cf->conn;
struct ssl_connect_data *connssl = cf->ctx;
struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
CURLcode result = CURLE_OK;
@ -5205,7 +5204,7 @@ static CURLcode ossl_recv(struct Curl_cfilter *cf,
if(cf->sockindex == FIRSTSOCKET)
/* mark the connection for close if it is indeed the control
connection */
connclose(conn, "TLS close_notify");
CURL_TRC_CF(data, cf, "TLS close_notify");
break;
case SSL_ERROR_WANT_READ:
connssl->io_need = CURL_SSL_IO_NEED_RECV;