diff options
author | Serj Kalichev <serj.kalichev@gmail.com> | 2016-08-03 00:29:09 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2016-08-04 00:30:31 +0200 |
commit | edeabf741fed90aecb39bb38dc0eeb68d6e305eb (patch) | |
tree | 3ab52b253f65b6f2a2d2f63c0801456be9d1950e | |
parent | 600bb4e852e23769efd575c5a6383e9b1988384f (diff) |
TFTP: Fix upload problem with piped input
When input stream for curl is stdin and input stream is not a file but
generated by a script then curl can truncate data transfer to arbitrary
size since a partial packet is treated as end of transfer by TFTP.
Fixes #857
-rw-r--r-- | lib/tftp.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/tftp.c b/lib/tftp.c index d7ff94f73..c97039620 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -705,6 +705,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) int rblock; CURLcode result = CURLE_OK; struct SingleRequest *k = &data->req; + int cb; /* Bytes currently read */ switch(event) { @@ -762,9 +763,20 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) return CURLE_OK; } - result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes); - if(result) - return result; + /* TFTP considers data block size < 512 bytes as an end of session. So + * in some cases we must wait for additional data to build full (512 bytes) + * data block. + * */ + state->sbytes = 0; + state->conn->data->req.upload_fromhere = (char *)state->spacket.data+4; + do { + result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes, + &cb); + if(result) + return result; + state->sbytes += cb; + state->conn->data->req.upload_fromhere += cb; + } while(state->sbytes < state->blksize && cb != 0); sbytes = sendto(state->sockfd, (void *) state->spacket.data, 4 + state->sbytes, SEND_4TH_ARG, |