tftp_rx: handle resends
authorChristian Vogt <christian.vogt@loewe-komp.de>
Fri, 16 Nov 2012 14:30:52 +0000 (15:30 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 16 Nov 2012 14:30:52 +0000 (15:30 +0100)
Re-send ACK for block X in case we receive block X data again while
waiting for block X+1.

Based on an earlier patch by Marcin Adamski.

lib/tftp.c

index 7202b94..832302e 100644 (file)
@@ -591,16 +591,26 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
   case TFTP_EVENT_DATA:
     /* Is this the block we expect? */
     rblock = getrpacketblock(&state->rpacket);
-    if(NEXT_BLOCKNUM(state->block) != rblock) {
-      /* No, log it */
+    if( NEXT_BLOCKNUM(state->block) == rblock ) {
+      /* This is the expected block.  Reset counters and ACK it. */
+      state->retries = 0;
+    }
+    else if( state->block == rblock ) {
+      /* This is the last recently received block again. Log it and ACK it again. */
+      infof(data,
+            "Received last DATA packet block %d again.\n",
+            rblock);
+    }
+    else {
+      /* totally unexpected, just log it */
       infof(data,
             "Received unexpected DATA packet block %d, expecting block %d\n",
             rblock, NEXT_BLOCKNUM(state->block));
       break;
     }
-    /* This is the expected block.  Reset counters and ACK it. */
+
+    /* ACK this block. */
     state->block = (unsigned short)rblock;
-    state->retries = 0;
     setpacketevent(&state->spacket, TFTP_EVENT_ACK);
     setpacketblock(&state->spacket, state->block);
     sbytes = sendto(state->sockfd, (void *)state->spacket.data,