File atftp-0.7-sorcerers_apprentice.patch of Package atftp.539

Index: atftp-0.7/tftp_file.c
===================================================================
--- atftp-0.7.orig/tftp_file.c	2012-03-27 11:39:59.426166638 +0200
+++ atftp-0.7/tftp_file.c	2012-03-27 11:39:59.441167084 +0200
@@ -605,6 +605,7 @@ int tftp_send_file(struct client_data *d
      int timeout_state = state; /* what state should we go on when timeout */
      int result;
      long block_number = 0;
+     long last_requested_block = -1;
      long last_block = -1;
      int data_size;             /* size of data received */
      int sockfd = data->sockfd; /* just to simplify calls */
@@ -765,6 +766,17 @@ int tftp_send_file(struct client_data *d
                          connected = 1;
                     }
                     block_number = ntohs(tftphdr->th_block);
+
+                    if (last_requested_block >= block_number)
+                    {
+                        if (data->trace)
+                            fprintf(stderr, "received duplicated ACK <block: %ld >= %ld>\n",
+                                    last_requested_block, block_number);
+                        break;
+                    }
+                    else
+                        last_requested_block = block_number;
+
                     if (data->trace)
                          fprintf(stderr, "received ACK <block: %ld>\n",
                                  block_number);
Index: atftp-0.7/tftpd_file.c
===================================================================
--- atftp-0.7.orig/tftpd_file.c	2012-03-27 11:39:59.427166668 +0200
+++ atftp-0.7/tftpd_file.c	2012-03-30 14:02:04.335089843 +0200
@@ -403,6 +403,7 @@ int tftpd_send_file(struct thread_data *
      int timeout_state = state;
      int result;
      long block_number = 0;
+     long last_requested_block = -1;
      long last_block = -1;
      int block_loops = 0;
      int data_size;
@@ -785,6 +786,10 @@ int tftpd_send_file(struct thread_data *
                                           inet_ntoa(client_info->client.sin_addr),
                                           ntohs(client_info->client.sin_port));
                                    sa = &client_info->client;
+
+                                   /* rewind the last_requested_block counter */
+                                   last_requested_block = -1;
+
                                    state = S_SEND_OACK;
                                    break;
                               }
@@ -859,6 +864,32 @@ int tftpd_send_file(struct thread_data *
                     {
                          logger(LOG_DEBUG, "received ACK <block: %d>", block_number);
                     }
+
+		    /* check whether the block request isn't already fulfilled */
+
+                    /* multicast, block numbers could contain gaps */
+                    if (multicast) {
+                        if (last_requested_block >= block_number)
+                        {
+                            if (data->trace)
+                                logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", last_requested_block, block_number);
+                            break;
+                        }
+                        else
+                            last_requested_block = block_number;
+                    /* unicast, blocks should be requested one after another */
+		    } else {
+                        if (last_requested_block + 1 != block_number && last_requested_block != -1)
+                        {
+                            if (data->trace)
+                                logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", last_requested_block + 1, block_number);
+                            break;
+                        }
+                        else
+                            last_requested_block = block_number;
+                    }
+
+
                     if (ntohs(tftphdr->th_block) == 65535)
                     {
                          block_loops++;
@@ -958,6 +989,8 @@ int tftpd_send_file(struct thread_data *
                          /* nedd to send an oack to that client */
                          state = S_SEND_OACK;                
                          fseek(fp, 0, SEEK_SET);
+			 /* reset the last block received counter */
+			 last_requested_block = -1;
                     }
                     else
                     {