From d3d90ad9c00530d0ab8154b51050da12500b44bd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 22 Mar 2021 15:39:27 +0100 Subject: [PATCH] tftp: remove the 3600 second default timeout ... it was never meant to be there. Reported-by: Tomas Berger Fixes #6774 Closes #6776 --- lib/tftp.c | 60 ++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/lib/tftp.c b/lib/tftp.c index a85f297a7..ecba348d9 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -217,35 +217,20 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) return CURLE_OPERATION_TIMEDOUT; } - if(start) { + /* timeout in milliseconds */ + state->max_time = timeout_ms; + if(timeout_ms > 0) maxtime = (time_t)(timeout_ms + 500) / 1000; - state->max_time = state->start_time + maxtime; + else + maxtime = 3600; /* use for calculating block timeouts */ - /* Set per-block timeout to total */ - timeout = maxtime; + /* Set per-block timeout to total */ + timeout = maxtime; - /* Average restart after 5 seconds */ - state->retry_max = (int)timeout/5; + /* Average reposting an ACK after 5 seconds */ + state->retry_max = (int)timeout/5; - if(state->retry_max < 1) - /* avoid division by zero below */ - state->retry_max = 1; - } - else { - if(timeout_ms > 0) - maxtime = (time_t)(timeout_ms + 500) / 1000; - else - maxtime = 3600; - - state->max_time = state->start_time + maxtime; - - /* Set per-block timeout to total */ - timeout = maxtime; - - /* Average reposting an ACK after 5 seconds */ - state->retry_max = (int)timeout/5; - } /* But bound the total number */ if(state->retry_max<3) state->retry_max = 3; @@ -259,9 +244,9 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) state->retry_time = 1; infof(state->data, - "set timeouts for state %d; Total %ld, retry %d maxtry %d\n", - (int)state->state, (long)(state->max_time-state->start_time), - state->retry_time, state->retry_max); + "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T + ", retry %d maxtry %d\n", + (int)state->state, timeout_ms, state->retry_time, state->retry_max); /* init RX time */ time(&state->rx_time); @@ -1209,33 +1194,32 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) * Check if timeouts have been reached * **********************************************************/ -static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event) +static timediff_t tftp_state_timeout(struct Curl_easy *data, + tftp_event_t *event) { time_t current; struct connectdata *conn = data->conn; struct tftp_state_data *state = conn->proto.tftpc; + timediff_t timeout_ms; if(event) *event = TFTP_EVENT_NONE; - time(¤t); - if(current > state->max_time) { - DEBUGF(infof(data, "timeout: %ld > %ld\n", - (long)current, (long)state->max_time)); + timeout_ms = Curl_timeleft(state->data, NULL, + (state->state == TFTP_STATE_START)); + if(timeout_ms < 0) { state->error = TFTP_ERR_TIMEOUT; state->state = TFTP_STATE_FIN; return 0; } + time(¤t); if(current > state->rx_time + state->retry_time) { if(event) *event = TFTP_EVENT_TIMEOUT; time(&state->rx_time); /* update even though we received nothing */ } - /* there's a typecast below here since 'time_t' may in fact be larger than - 'long', but we estimate that a 'long' will still be able to hold number - of seconds even if "only" 32 bit */ - return (long)(state->max_time - current); + return timeout_ms; } /********************************************************** @@ -1251,11 +1235,11 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; struct tftp_state_data *state = conn->proto.tftpc; - long timeout_ms = tftp_state_timeout(data, &event); + timediff_t timeout_ms = tftp_state_timeout(data, &event); *done = FALSE; - if(timeout_ms <= 0) { + if(timeout_ms < 0) { failf(data, "TFTP response timeout"); return CURLE_OPERATION_TIMEDOUT; }