diff --git a/lib/ftp.c b/lib/ftp.c index 49e157138..8e370c5d2 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -136,7 +136,7 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done); static CURLcode ftp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode ftp_connect(struct connectdata *conn, bool *done); -static CURLcode ftp_disconnect(struct connectdata *conn); +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode ftp_nextconnect(struct connectdata *conn); static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); static int ftp_getsock(struct connectdata *conn, @@ -3840,7 +3840,7 @@ static CURLcode ftp_quit(struct connectdata *conn) * Disconnect from an FTP server. Cleanup protocol-specific per-connection * resources. BLOCKING. */ -static CURLcode ftp_disconnect(struct connectdata *conn) +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) { struct ftp_conn *ftpc= &conn->proto.ftpc; struct pingpong *pp = &ftpc->pp; @@ -3852,6 +3852,8 @@ static CURLcode ftp_disconnect(struct connectdata *conn) ftp_quit() will check the state of ftp->ctl_valid. If it's ok it will try to send the QUIT command, otherwise it will just return. */ + if(dead_connection) + ftpc->ctl_valid = FALSE; /* The FTP session may or may not have been allocated/setup at this point! */ (void)ftp_quit(conn); /* ignore errors on the QUIT */ diff --git a/lib/imap.c b/lib/imap.c index cdadd1713..9c39625b3 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -100,7 +100,7 @@ static CURLcode imap_do(struct connectdata *conn, bool *done); static CURLcode imap_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode imap_connect(struct connectdata *conn, bool *done); -static CURLcode imap_disconnect(struct connectdata *conn); +static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done); static int imap_getsock(struct connectdata *conn, curl_socket_t *socks, @@ -877,13 +877,13 @@ static CURLcode imap_logout(struct connectdata *conn) * Disconnect from an IMAP server. Cleanup protocol-specific per-connection * resources. BLOCKING. */ -static CURLcode imap_disconnect(struct connectdata *conn) +static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) { struct imap_conn *imapc= &conn->proto.imapc; /* The IMAP session may or may not have been allocated/setup at this point! */ - if (imapc->pp.conn) + if(!dead_connection && imapc->pp.conn) (void)imap_logout(conn); /* ignore errors on the LOGOUT */ Curl_pp_disconnect(&imapc->pp); diff --git a/lib/multi.c b/lib/multi.c index b57724e62..7be479bd4 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1634,7 +1634,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(disconnect_conn) { - Curl_disconnect(easy->easy_conn); /* disconnect properly */ + /* disconnect properly */ + Curl_disconnect(easy->easy_conn, /* dead_connection */ FALSE); /* This is where we make sure that the easy_conn pointer is reset. We don't have to do this in every case block above where a @@ -1759,7 +1760,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle) for(i=0; i< multi->connc->num; i++) { if(multi->connc->connects[i] && multi->connc->connects[i]->protocol & PROT_CLOSEACTION) { - Curl_disconnect(multi->connc->connects[i]); + Curl_disconnect(multi->connc->connects[i], /* dead_connection */ FALSE); multi->connc->connects[i] = NULL; } } @@ -2665,7 +2666,7 @@ static void multi_connc_remove_handle(struct Curl_multi *multi, data->state.shared_conn = multi; else { /* out of memory - so much for graceful shutdown */ - Curl_disconnect(conn); + Curl_disconnect(conn, /* dead_connection */ FALSE); multi->connc->connects[i] = NULL; } } diff --git a/lib/openldap.c b/lib/openldap.c index e9dcfcc71..7010da6c2 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -61,7 +61,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done); static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool); static CURLcode ldap_connect(struct connectdata *conn, bool *done); static CURLcode ldap_connecting(struct connectdata *conn, bool *done); -static CURLcode ldap_disconnect(struct connectdata *conn); +static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection); static Curl_recv ldap_recv; @@ -344,9 +344,10 @@ retry: return CURLE_OK; } -static CURLcode ldap_disconnect(struct connectdata *conn) +static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) { ldapconninfo *li = conn->proto.generic; + (void) dead_connection; if (li) { if (li->ld) { diff --git a/lib/pop3.c b/lib/pop3.c index 9609b6249..9f6744363 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -101,7 +101,7 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done); static CURLcode pop3_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode pop3_connect(struct connectdata *conn, bool *done); -static CURLcode pop3_disconnect(struct connectdata *conn); +static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done); static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, @@ -817,7 +817,7 @@ static CURLcode pop3_quit(struct connectdata *conn) * Disconnect from an POP3 server. Cleanup protocol-specific per-connection * resources. BLOCKING. */ -static CURLcode pop3_disconnect(struct connectdata *conn) +static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection) { struct pop3_conn *pop3c= &conn->proto.pop3c; @@ -828,7 +828,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn) /* The POP3 session may or may not have been allocated/setup at this point! */ - if(pop3c->pp.conn) + if(!dead_connection && pop3c->pp.conn) (void)pop3_quit(conn); /* ignore errors on the LOGOUT */ diff --git a/lib/rtsp.c b/lib/rtsp.c index 1254c7389..066e10fe3 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -117,7 +117,9 @@ CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done) return httpStatus; } -CURLcode Curl_rtsp_disconnect(struct connectdata *conn) { +CURLcode Curl_rtsp_disconnect(struct connectdata *conn, bool dead_connection) +{ + (void) dead_connection; Curl_safefree(conn->proto.rtspc.rtp_buf); return CURLE_OK; } diff --git a/lib/rtsp.h b/lib/rtsp.h index c3f8bd749..82e07068d 100644 --- a/lib/rtsp.h +++ b/lib/rtsp.h @@ -43,7 +43,7 @@ CURLcode Curl_rtsp_rtp_readwrite(struct SessionHandle *data, CURLcode Curl_rtsp(struct connectdata *conn, bool *done); CURLcode Curl_rtsp_done(struct connectdata *conn, CURLcode, bool premature); CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done); -CURLcode Curl_rtsp_disconnect(struct connectdata *conn); +CURLcode Curl_rtsp_disconnect(struct connectdata *conn, bool dead_connection); CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header); diff --git a/lib/smtp.c b/lib/smtp.c index a0082fc79..82621a42b 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -107,7 +107,7 @@ static CURLcode smtp_do(struct connectdata *conn, bool *done); static CURLcode smtp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode smtp_connect(struct connectdata *conn, bool *done); -static CURLcode smtp_disconnect(struct connectdata *conn); +static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done); static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, @@ -1310,7 +1310,7 @@ static CURLcode smtp_quit(struct connectdata *conn) * Disconnect from an SMTP server. Cleanup protocol-specific per-connection * resources. BLOCKING. */ -static CURLcode smtp_disconnect(struct connectdata *conn) +static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection) { struct smtp_conn *smtpc= &conn->proto.smtpc; @@ -1321,7 +1321,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn) /* The SMTP session may or may not have been allocated/setup at this point! */ - if(smtpc->pp.conn) + if(!dead_connection && smtpc->pp.conn) (void)smtp_quit(conn); /* ignore errors on the LOGOUT */ Curl_pp_disconnect(&smtpc->pp); diff --git a/lib/ssh.c b/lib/ssh.c index 81f5f6420..ffcb48b42 100644 --- a/lib/ssh.c +++ b/lib/ssh.c @@ -135,13 +135,13 @@ static CURLcode scp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode scp_disconnect(struct connectdata *conn); +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode sftp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode sftp_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode sftp_disconnect(struct connectdata *conn); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode sftp_perform(struct connectdata *conn, bool *connected, @@ -2689,10 +2689,11 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done) /* BLOCKING, but the function is using the state machine so the only reason this is still blocking is that the multi interface code has no support for disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct connectdata *conn) +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) { CURLcode result = CURLE_OK; struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; Curl_safefree(conn->data->state.proto.ssh); conn->data->state.proto.ssh = NULL; @@ -2853,9 +2854,10 @@ static CURLcode sftp_doing(struct connectdata *conn, /* BLOCKING, but the function is using the state machine so the only reason this is still blocking is that the multi interface code has no support for disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct connectdata *conn) +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) { CURLcode result = CURLE_OK; + (void) dead_connection; DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); diff --git a/lib/tftp.c b/lib/tftp.c index 46ed2a71e..fc741c941 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -166,7 +166,7 @@ typedef struct tftp_state_data { static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ; static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ; static CURLcode tftp_connect(struct connectdata *conn, bool *done); -static CURLcode tftp_disconnect(struct connectdata *conn); +static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection); static CURLcode tftp_do(struct connectdata *conn, bool *done); static CURLcode tftp_done(struct connectdata *conn, CURLcode, bool premature); @@ -925,9 +925,10 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state, * The disconnect callback * **********************************************************/ -static CURLcode tftp_disconnect(struct connectdata *conn) +static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection) { tftp_state_data_t *state = conn->proto.tftpc; + (void) dead_connection; /* done, free dynamically allocated pkt buffers */ if(state) { diff --git a/lib/transfer.c b/lib/transfer.c index ead3a4deb..e4e3405d3 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1959,7 +1959,7 @@ connect_host(struct SessionHandle *data, res = Curl_async_resolved(*conn, &protocol_done); else /* if we can't resolve, we kill this "connection" now */ - (void)Curl_disconnect(*conn); + (void)Curl_disconnect(*conn, /* dead_connection */ FALSE); } return res; diff --git a/lib/url.c b/lib/url.c index f1ab21c2d..93a56002d 100644 --- a/lib/url.c +++ b/lib/url.c @@ -651,7 +651,7 @@ CURLcode Curl_ch_connc(struct SessionHandle *data, close handles not in use. */ for(i=newamount; i< c->num; i++) - Curl_disconnect(c->connects[i]); + Curl_disconnect(c->connects[i], /* dead_connection */ FALSE); /* If the most recent connection is no longer valid, mark it invalid. */ @@ -2587,7 +2587,7 @@ static void conn_free(struct connectdata *conn) free(conn); /* free all the connection oriented data */ } -CURLcode Curl_disconnect(struct connectdata *conn) +CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) { struct SessionHandle *data; if(!conn) @@ -2647,7 +2647,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) if(conn->handler->disconnect) /* This is set if protocol-specific cleanups should be made */ - conn->handler->disconnect(conn); + conn->handler->disconnect(conn, dead_connection); if(-1 != conn->connectindex) { /* unlink ourselves! */ @@ -2915,7 +2915,8 @@ ConnectionExists(struct SessionHandle *data, check->data = data; infof(data, "Connection #%ld seems to be dead!\n", i); - Curl_disconnect(check); /* disconnect resources */ + /* disconnect resources */ + Curl_disconnect(check, /* dead_connection */ TRUE); data->state.connc->connects[i]=NULL; /* nothing here */ continue; @@ -3102,7 +3103,7 @@ ConnectionKillOne(struct SessionHandle *data) conn->data = data; /* the winner gets the honour of being disconnected */ - (void)Curl_disconnect(conn); + (void)Curl_disconnect(conn, /* dead_connection */ FALSE); /* clean the array entry */ data->state.connc->connects[connindex] = NULL; @@ -5116,7 +5117,7 @@ CURLcode Curl_connect(struct SessionHandle *data, if(code && *in_connect) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ - Curl_disconnect(*in_connect); /* close the connection */ + Curl_disconnect(*in_connect, FALSE); /* close the connection */ *in_connect = NULL; /* return a NULL */ } @@ -5236,7 +5237,7 @@ CURLcode Curl_done(struct connectdata **connp, */ if(data->set.reuse_forbid || conn->bits.close || premature || (-1 == conn->connectindex)) { - CURLcode res2 = Curl_disconnect(conn); /* close the connection */ + CURLcode res2 = Curl_disconnect(conn, FALSE); /* close the connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ diff --git a/lib/url.h b/lib/url.h index 63d7f2c48..241dc28c0 100644 --- a/lib/url.h +++ b/lib/url.h @@ -42,7 +42,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn, CURLcode Curl_do(struct connectdata **, bool *done); CURLcode Curl_do_more(struct connectdata *); CURLcode Curl_done(struct connectdata **, CURLcode, bool premature); -CURLcode Curl_disconnect(struct connectdata *); +CURLcode Curl_disconnect(struct connectdata *, bool dead_connection); CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); diff --git a/lib/urldata.h b/lib/urldata.h index 62dabebd8..f4f678620 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -646,9 +646,11 @@ struct Curl_handler { int numsocks); /* This function *MAY* be set to a protocol-dependent function that is run - * by the curl_disconnect(), as a step in the disconnection. + * by the curl_disconnect(), as a step in the disconnection. If the handler + * is called because the connection has been considered dead, dead_connection + * is set to TRUE. */ - CURLcode (*disconnect)(struct connectdata *); + CURLcode (*disconnect)(struct connectdata *, bool dead_connection); long defport; /* Default port. */ long protocol; /* PROT_* flags concerning the protocol set */