Here is a patch that *might* be right.  Unfortunately, it seems that
all tftp servers I could find do not properly handle uploading with
OACK.  Or, there is the very real possibility that my code is broken.

Please consider this for review...I haven't actually successfully
got curl to upload yet, but at least based on packet sniffing, it
*seems* to be doing the right thing.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com

diff --git a/lib/tftp.c b/lib/tftp.c
index c0e5881..746e798 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -399,7 +399,7 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t 
*state,
 
       tsize = strtol( value, NULL, 10 );
       if(!tsize) {
-        failf(data, "invalid tsize value in OACK packet");
+        failf(data, "invalid tsize -:%s:- value in OACK packet", value);
         return CURLE_TFTP_ILLEGAL;
       }
       Curl_pgrsSetDownloadSize(data, tsize);
@@ -701,39 +701,45 @@ static CURLcode tftp_tx(tftp_state_data_t *state, 
tftp_event_t event)
   switch(event) {
 
   case TFTP_EVENT_ACK:
-    /* Ack the packet */
-    rblock = getrpacketblock(&state->rpacket);
-
-    if(rblock != state->block) {
-      /* This isn't the expected block.  Log it and up the retry counter */
-      infof(data, "Received ACK for block %d, expecting %d\n",
-            rblock, state->block);
-      state->retries++;
-      /* Bail out if over the maximum */
-      if(state->retries>state->retry_max) {
-        failf(data, "tftp_tx: giving up waiting for block %d ack",
-              state->block);
-        res = CURLE_SEND_ERROR;
-      }
-      else {
-        /* Re-send the data packet */
-        sbytes = sendto(state->sockfd, (void *)&state->spacket,
-                        4+state->sbytes, SEND_4TH_ARG,
-                        (struct sockaddr *)&state->remote_addr,
-                        state->remote_addrlen);
-        /* Check all sbytes were sent */
-        if(sbytes<0) {
-          failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
-          res = CURLE_SEND_ERROR;
-        }
-      }
-      return res;
+  case TFTP_EVENT_OACK:
+    if (event == TFTP_EVENT_ACK) {
+       /* Ack the packet */
+       rblock = getrpacketblock(&state->rpacket);
+
+       if(rblock != state->block) {
+          /* This isn't the expected block.  Log it and up the retry counter */
+          infof(data, "Received ACK for block %d, expecting %d\n",
+                rblock, state->block);
+          state->retries++;
+          /* Bail out if over the maximum */
+          if(state->retries>state->retry_max) {
+             failf(data, "tftp_tx: giving up waiting for block %d ack",
+                   state->block);
+             res = CURLE_SEND_ERROR;
+          }
+          else {
+             /* Re-send the data packet */
+             sbytes = sendto(state->sockfd, (void *)&state->spacket,
+                             4+state->sbytes, SEND_4TH_ARG,
+                             (struct sockaddr *)&state->remote_addr,
+                             state->remote_addrlen);
+             /* Check all sbytes were sent */
+             if(sbytes<0) {
+                failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+                res = CURLE_SEND_ERROR;
+             }
+          }
+          return res;
+       }
+       /* This is the expected packet.  Reset the counters and send the next
+          block */
+       time(&state->rx_time);
+       state->block++;
+    }
+    else {
+       state->block = 0;
+       state->retries = 0;
     }
-    /* This is the expected packet.  Reset the counters and send the next
-       block */
-    time(&state->rx_time);
-    state->block++;
-    state->retries = 0;
     setpacketevent(&state->spacket, TFTP_EVENT_DATA);
     setpacketblock(&state->spacket, state->block);
     if(state->block > 1 && state->sbytes < (int)state->blksize) {
@@ -798,7 +804,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, 
tftp_event_t event)
     break;
 
   default:
-    failf(data, "%s", "tftp_tx: internal error");
+    failf(data, "tftp_tx: internal error, event: %i", (int)(event));
     break;
   }
 
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to