Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ Changelog Daniel Stenberg (6 Mar 2010) - Ben Greear brought a patch that fixed the rate limiting logic for TFTP when the easy interface was used. Daniel Stenberg (5 Mar 2010) - Daniel Johnson provided fixes for building curl with the clang compiler. Loading RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ This release includes the following bugfixes: o configure fixes for GSSAPI o threaded resolver double free when closing curl handle o configure fixes for building with the clang compiler o easy interix rate limiting logic This release includes the following known bugs: Loading lib/tftp.c +109 −17 Original line number Diff line number Diff line Loading @@ -1173,6 +1173,34 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event) } } static curl_off_t sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps, int pkt_size) { curl_off_t min_sleep = 0; curl_off_t rv = 0; if (rate_bps == 0) return 0; if (cur_rate_bps > (rate_bps + (rate_bps >> 10))) { /* running too fast */ rate_bps -= rate_bps >> 6; min_sleep = 1; } else if (cur_rate_bps < (rate_bps - (rate_bps >> 10))) { /* running too slow */ rate_bps += rate_bps >> 6; } rv = ((curl_off_t)((pkt_size * 8) * 1000) / rate_bps); if (rv < min_sleep) rv = min_sleep; return rv; } /********************************************************** * * tftp_easy_statemach Loading @@ -1187,15 +1215,64 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn) CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; int fd_read; curl_off_t timeout_ms; struct SingleRequest *k = &data->req; struct timeval transaction_start = Curl_tvnow(); k->start = transaction_start; k->now = transaction_start; /* Run the TFTP State Machine */ for(; (state->state != TFTP_STATE_FIN) && (result == CURLE_OK); result=tftp_state_machine(state, state->event) ) { for(; (state->state != TFTP_STATE_FIN) && (result == CURLE_OK); ) { timeout_ms = state->retry_time * 1000; if (data->set.upload) { if (data->set.max_send_speed && (data->progress.ulspeed > data->set.max_send_speed)) { fd_read = CURL_SOCKET_BAD; timeout_ms = sleep_time(data->set.max_send_speed, data->progress.ulspeed, state->blksize); } else { fd_read = state->sockfd; } } else { if (data->set.max_recv_speed && (data->progress.dlspeed > data->set.max_recv_speed)) { fd_read = CURL_SOCKET_BAD; timeout_ms = sleep_time(data->set.max_recv_speed, data->progress.dlspeed, state->blksize); } else { fd_read = state->sockfd; } } if(data->set.timeout) { timeout_ms = data->set.timeout - Curl_tvdiff(k->now, k->start); if (timeout_ms > state->retry_time * 1000) timeout_ms = state->retry_time * 1000; else if(timeout_ms < 0) timeout_ms = 0; } /* Wait until ready to read or timeout occurs */ rc=Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000); rc=Curl_socket_ready(fd_read, CURL_SOCKET_BAD, timeout_ms); k->now = Curl_tvnow(); /* Force a progress callback if it's been too long */ if (Curl_tvdiff(k->now, k->start) >= data->set.timeout) { if(Curl_pgrsUpdate(conn)) { tftp_state_machine(state, TFTP_EVENT_ERROR); return CURLE_ABORTED_BY_CALLBACK; } k->start = k->now; } if(rc == -1) { /* bail out */ Loading @@ -1203,27 +1280,42 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn) failf(data, "%s", Curl_strerror(conn, error)); state->event = TFTP_EVENT_ERROR; } else if(rc==0) { /* A timeout occured */ state->event = TFTP_EVENT_TIMEOUT; else { if(rc==0) { /* A timeout occured, but our timeout is variable, so maybe just continue? */ long rtms = state->retry_time * 1000; if (Curl_tvdiff(k->now, transaction_start) > rtms) { state->event = TFTP_EVENT_TIMEOUT; /* Force a look at transfer timeouts */ check_time = 0; check_time = 1; } else { continue; /* skip state machine */ } } else { result = tftp_receive_packet(conn); if (result == CURLE_OK) transaction_start = Curl_tvnow(); if(k->bytecountp) *k->bytecountp = k->bytecount; /* read count */ if(k->writebytecountp) *k->writebytecountp = k->writebytecount; /* write count */ } } /* Check for transfer timeout every 10 blocks, or after timeout */ if(check_time%10==0) { /* ignore the event here as Curl_socket_ready() handles * retransmission timeouts inside the easy state mach */ if(check_time) { tftp_state_timeout(conn, NULL); check_time = 0; } if(result) return(result); result = tftp_state_machine(state, state->event); } /* Tell curl we're done */ Loading Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ Changelog Daniel Stenberg (6 Mar 2010) - Ben Greear brought a patch that fixed the rate limiting logic for TFTP when the easy interface was used. Daniel Stenberg (5 Mar 2010) - Daniel Johnson provided fixes for building curl with the clang compiler. Loading
RELEASE-NOTES +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ This release includes the following bugfixes: o configure fixes for GSSAPI o threaded resolver double free when closing curl handle o configure fixes for building with the clang compiler o easy interix rate limiting logic This release includes the following known bugs: Loading
lib/tftp.c +109 −17 Original line number Diff line number Diff line Loading @@ -1173,6 +1173,34 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event) } } static curl_off_t sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps, int pkt_size) { curl_off_t min_sleep = 0; curl_off_t rv = 0; if (rate_bps == 0) return 0; if (cur_rate_bps > (rate_bps + (rate_bps >> 10))) { /* running too fast */ rate_bps -= rate_bps >> 6; min_sleep = 1; } else if (cur_rate_bps < (rate_bps - (rate_bps >> 10))) { /* running too slow */ rate_bps += rate_bps >> 6; } rv = ((curl_off_t)((pkt_size * 8) * 1000) / rate_bps); if (rv < min_sleep) rv = min_sleep; return rv; } /********************************************************** * * tftp_easy_statemach Loading @@ -1187,15 +1215,64 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn) CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; int fd_read; curl_off_t timeout_ms; struct SingleRequest *k = &data->req; struct timeval transaction_start = Curl_tvnow(); k->start = transaction_start; k->now = transaction_start; /* Run the TFTP State Machine */ for(; (state->state != TFTP_STATE_FIN) && (result == CURLE_OK); result=tftp_state_machine(state, state->event) ) { for(; (state->state != TFTP_STATE_FIN) && (result == CURLE_OK); ) { timeout_ms = state->retry_time * 1000; if (data->set.upload) { if (data->set.max_send_speed && (data->progress.ulspeed > data->set.max_send_speed)) { fd_read = CURL_SOCKET_BAD; timeout_ms = sleep_time(data->set.max_send_speed, data->progress.ulspeed, state->blksize); } else { fd_read = state->sockfd; } } else { if (data->set.max_recv_speed && (data->progress.dlspeed > data->set.max_recv_speed)) { fd_read = CURL_SOCKET_BAD; timeout_ms = sleep_time(data->set.max_recv_speed, data->progress.dlspeed, state->blksize); } else { fd_read = state->sockfd; } } if(data->set.timeout) { timeout_ms = data->set.timeout - Curl_tvdiff(k->now, k->start); if (timeout_ms > state->retry_time * 1000) timeout_ms = state->retry_time * 1000; else if(timeout_ms < 0) timeout_ms = 0; } /* Wait until ready to read or timeout occurs */ rc=Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000); rc=Curl_socket_ready(fd_read, CURL_SOCKET_BAD, timeout_ms); k->now = Curl_tvnow(); /* Force a progress callback if it's been too long */ if (Curl_tvdiff(k->now, k->start) >= data->set.timeout) { if(Curl_pgrsUpdate(conn)) { tftp_state_machine(state, TFTP_EVENT_ERROR); return CURLE_ABORTED_BY_CALLBACK; } k->start = k->now; } if(rc == -1) { /* bail out */ Loading @@ -1203,27 +1280,42 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn) failf(data, "%s", Curl_strerror(conn, error)); state->event = TFTP_EVENT_ERROR; } else if(rc==0) { /* A timeout occured */ state->event = TFTP_EVENT_TIMEOUT; else { if(rc==0) { /* A timeout occured, but our timeout is variable, so maybe just continue? */ long rtms = state->retry_time * 1000; if (Curl_tvdiff(k->now, transaction_start) > rtms) { state->event = TFTP_EVENT_TIMEOUT; /* Force a look at transfer timeouts */ check_time = 0; check_time = 1; } else { continue; /* skip state machine */ } } else { result = tftp_receive_packet(conn); if (result == CURLE_OK) transaction_start = Curl_tvnow(); if(k->bytecountp) *k->bytecountp = k->bytecount; /* read count */ if(k->writebytecountp) *k->writebytecountp = k->writebytecount; /* write count */ } } /* Check for transfer timeout every 10 blocks, or after timeout */ if(check_time%10==0) { /* ignore the event here as Curl_socket_ready() handles * retransmission timeouts inside the easy state mach */ if(check_time) { tftp_state_timeout(conn, NULL); check_time = 0; } if(result) return(result); result = tftp_state_machine(state, state->event); } /* Tell curl we're done */ Loading