pingpong: ignore regular timeout in disconnect phase

The timeout set with CURLOPT_TIMEOUT is no longer used when
disconnecting from one of the pingpong protocols (FTP, IMAP, SMTP,
POP3).

Reported-by: jasal82 on github

Fixes #3264
Closes #3374
This commit is contained in:
Daniel Stenberg 2018-12-14 09:21:47 +01:00
Родитель 9e6518481c
Коммит 154a17b6ee
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
6 изменённых файлов: 29 добавлений и 24 удалений

Просмотреть файл

@ -655,7 +655,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
while(!*ftpcode && !result) { while(!*ftpcode && !result) {
/* check and reset timeout value every lap */ /* check and reset timeout value every lap */
time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */ time_t timeout = Curl_pp_state_timeout(pp, FALSE);
time_t interval_ms; time_t interval_ms;
if(timeout <= 0) { if(timeout <= 0) {
@ -3054,7 +3054,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn,
bool *done) bool *done)
{ {
struct ftp_conn *ftpc = &conn->proto.ftpc; struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE); CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE);
/* Check for the state outside of the Curl_socket_check() return code checks /* Check for the state outside of the Curl_socket_check() return code checks
since at times we are in fact already in this state when this function since at times we are in fact already in this state when this function
@ -3071,7 +3071,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
while(ftpc->state != FTP_STOP) { while(ftpc->state != FTP_STOP) {
result = Curl_pp_statemach(pp, TRUE); result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */);
if(result) if(result)
break; break;
} }

Просмотреть файл

@ -1362,19 +1362,20 @@ static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
return result; return result;
} }
result = Curl_pp_statemach(&imapc->pp, FALSE); result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE);
*done = (imapc->state == IMAP_STOP) ? TRUE : FALSE; *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
return result; return result;
} }
static CURLcode imap_block_statemach(struct connectdata *conn) static CURLcode imap_block_statemach(struct connectdata *conn,
bool disconnecting)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc; struct imap_conn *imapc = &conn->proto.imapc;
while(imapc->state != IMAP_STOP && !result) while(imapc->state != IMAP_STOP && !result)
result = Curl_pp_statemach(&imapc->pp, TRUE); result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting);
return result; return result;
} }
@ -1497,7 +1498,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
non-blocking DONE operations! non-blocking DONE operations!
*/ */
if(!result) if(!result)
result = imap_block_statemach(conn); result = imap_block_statemach(conn, FALSE);
} }
/* Cleanup our per-request based variables */ /* Cleanup our per-request based variables */
@ -1635,7 +1636,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
point! */ point! */
if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart) if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
if(!imap_perform_logout(conn)) if(!imap_perform_logout(conn))
(void)imap_block_statemach(conn); /* ignore errors on LOGOUT */ (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */
/* Disconnect from the server */ /* Disconnect from the server */
Curl_pp_disconnect(&imapc->pp); Curl_pp_disconnect(&imapc->pp);

Просмотреть файл

@ -44,7 +44,7 @@
/* Returns timeout in ms. 0 or negative number means the timeout has already /* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */ triggered */
time_t Curl_pp_state_timeout(struct pingpong *pp) time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
{ {
struct connectdata *conn = pp->conn; struct connectdata *conn = pp->conn;
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
@ -62,7 +62,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
timeout_ms = response_time - timeout_ms = response_time -
Curl_timediff(Curl_now(), pp->response); /* spent time */ Curl_timediff(Curl_now(), pp->response); /* spent time */
if(data->set.timeout) { if(data->set.timeout && !disconnecting) {
/* if timeout is requested, find out how much remaining time we have */ /* if timeout is requested, find out how much remaining time we have */
time_t timeout2_ms = data->set.timeout - /* timeout time */ time_t timeout2_ms = data->set.timeout - /* timeout time */
Curl_timediff(Curl_now(), conn->now); /* spent time */ Curl_timediff(Curl_now(), conn->now); /* spent time */
@ -77,13 +77,14 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
/* /*
* Curl_pp_statemach() * Curl_pp_statemach()
*/ */
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block) CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
bool disconnecting)
{ {
struct connectdata *conn = pp->conn; struct connectdata *conn = pp->conn;
curl_socket_t sock = conn->sock[FIRSTSOCKET]; curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc; int rc;
time_t interval_ms; time_t interval_ms;
time_t timeout_ms = Curl_pp_state_timeout(pp); time_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;

Просмотреть файл

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -81,14 +81,15 @@ struct pingpong {
* called repeatedly until done. Set 'wait' to make it wait a while on the * called repeatedly until done. Set 'wait' to make it wait a while on the
* socket if there's no traffic. * socket if there's no traffic.
*/ */
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block); CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
bool disconnecting);
/* initialize stuff to prepare for reading a fresh new response */ /* initialize stuff to prepare for reading a fresh new response */
void Curl_pp_init(struct pingpong *pp); void Curl_pp_init(struct pingpong *pp);
/* Returns timeout in ms. 0 or negative number means the timeout has already /* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */ triggered */
time_t Curl_pp_state_timeout(struct pingpong *pp); time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
/*********************************************************************** /***********************************************************************

Просмотреть файл

@ -1025,19 +1025,20 @@ static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
return result; return result;
} }
result = Curl_pp_statemach(&pop3c->pp, FALSE); result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE);
*done = (pop3c->state == POP3_STOP) ? TRUE : FALSE; *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
return result; return result;
} }
static CURLcode pop3_block_statemach(struct connectdata *conn) static CURLcode pop3_block_statemach(struct connectdata *conn,
bool disconnecting)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c; struct pop3_conn *pop3c = &conn->proto.pop3c;
while(pop3c->state != POP3_STOP && !result) while(pop3c->state != POP3_STOP && !result)
result = Curl_pp_statemach(&pop3c->pp, TRUE); result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting);
return result; return result;
} }
@ -1235,7 +1236,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
point! */ point! */
if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart) if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
if(!pop3_perform_quit(conn)) if(!pop3_perform_quit(conn))
(void)pop3_block_statemach(conn); /* ignore errors on QUIT */ (void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */
/* Disconnect from the server */ /* Disconnect from the server */
Curl_pp_disconnect(&pop3c->pp); Curl_pp_disconnect(&pop3c->pp);

Просмотреть файл

@ -1080,19 +1080,20 @@ static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
return result; return result;
} }
result = Curl_pp_statemach(&smtpc->pp, FALSE); result = Curl_pp_statemach(&smtpc->pp, FALSE, FALSE);
*done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE; *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE;
return result; return result;
} }
static CURLcode smtp_block_statemach(struct connectdata *conn) static CURLcode smtp_block_statemach(struct connectdata *conn,
bool disconnecting)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
while(smtpc->state != SMTP_STOP && !result) while(smtpc->state != SMTP_STOP && !result)
result = Curl_pp_statemach(&smtpc->pp, TRUE); result = Curl_pp_statemach(&smtpc->pp, TRUE, disconnecting);
return result; return result;
} }
@ -1253,7 +1254,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
the smtp_multi_statemach function but we have no general support for the smtp_multi_statemach function but we have no general support for
non-blocking DONE operations! non-blocking DONE operations!
*/ */
result = smtp_block_statemach(conn); result = smtp_block_statemach(conn, FALSE);
} }
/* Clear the transfer mode for the next request */ /* Clear the transfer mode for the next request */
@ -1360,7 +1361,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
point! */ point! */
if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart) if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
if(!smtp_perform_quit(conn)) if(!smtp_perform_quit(conn))
(void)smtp_block_statemach(conn); /* ignore errors on QUIT */ (void)smtp_block_statemach(conn, TRUE); /* ignore errors on QUIT */
/* Disconnect from the server */ /* Disconnect from the server */
Curl_pp_disconnect(&smtpc->pp); Curl_pp_disconnect(&smtpc->pp);