mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
- Ben Greear brought a patch that fixed the rate limiting logic for TFTP when
the easy interface was used.
This commit is contained in:
parent
a0c3edcc37
commit
e262aaae2b
4
CHANGES
4
CHANGES
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
Changelog
|
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 Stenberg (5 Mar 2010)
|
||||||
- Daniel Johnson provided fixes for building curl with the clang compiler.
|
- Daniel Johnson provided fixes for building curl with the clang compiler.
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ This release includes the following bugfixes:
|
|||||||
o configure fixes for GSSAPI
|
o configure fixes for GSSAPI
|
||||||
o threaded resolver double free when closing curl handle
|
o threaded resolver double free when closing curl handle
|
||||||
o configure fixes for building with the clang compiler
|
o configure fixes for building with the clang compiler
|
||||||
|
o easy interix rate limiting logic
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
|
120
lib/tftp.c
120
lib/tftp.c
@ -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
|
* tftp_easy_statemach
|
||||||
@ -1187,15 +1215,64 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn)
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
|
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 */
|
/* Run the TFTP State Machine */
|
||||||
for(;
|
for(; (state->state != TFTP_STATE_FIN) && (result == CURLE_OK); ) {
|
||||||
(state->state != TFTP_STATE_FIN) && (result == CURLE_OK);
|
|
||||||
result=tftp_state_machine(state, state->event) ) {
|
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 */
|
/* Wait until ready to read or timeout occurs */
|
||||||
rc=Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD,
|
rc=Curl_socket_ready(fd_read, CURL_SOCKET_BAD, timeout_ms);
|
||||||
state->retry_time * 1000);
|
|
||||||
|
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) {
|
if(rc == -1) {
|
||||||
/* bail out */
|
/* bail out */
|
||||||
@ -1203,27 +1280,42 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn)
|
|||||||
failf(data, "%s", Curl_strerror(conn, error));
|
failf(data, "%s", Curl_strerror(conn, error));
|
||||||
state->event = TFTP_EVENT_ERROR;
|
state->event = TFTP_EVENT_ERROR;
|
||||||
}
|
}
|
||||||
else if(rc==0) {
|
else {
|
||||||
/* A timeout occured */
|
|
||||||
|
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;
|
state->event = TFTP_EVENT_TIMEOUT;
|
||||||
|
|
||||||
/* Force a look at transfer timeouts */
|
/* Force a look at transfer timeouts */
|
||||||
check_time = 0;
|
check_time = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue; /* skip state machine */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = tftp_receive_packet(conn);
|
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) {
|
||||||
if(check_time%10==0) {
|
|
||||||
/* ignore the event here as Curl_socket_ready() handles
|
|
||||||
* retransmission timeouts inside the easy state mach */
|
|
||||||
tftp_state_timeout(conn, NULL);
|
tftp_state_timeout(conn, NULL);
|
||||||
|
check_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return(result);
|
return(result);
|
||||||
|
|
||||||
|
result = tftp_state_machine(state, state->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell curl we're done */
|
/* Tell curl we're done */
|
||||||
|
Loading…
Reference in New Issue
Block a user