aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerj Kalichev <serj.kalichev@gmail.com>2016-08-03 00:29:09 +0200
committerDaniel Stenberg <daniel@haxx.se>2016-08-04 00:30:31 +0200
commitedeabf741fed90aecb39bb38dc0eeb68d6e305eb (patch)
tree3ab52b253f65b6f2a2d2f63c0801456be9d1950e
parent600bb4e852e23769efd575c5a6383e9b1988384f (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.c18
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,