]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Fixed a bug in Mtftp4: to allow the block number to roll over to accept transfers...
authorhhuan13 <hhuan13@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 29 Jun 2010 01:26:28 +0000 (01:26 +0000)
committerhhuan13 <hhuan13@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 29 Jun 2010 01:26:28 +0000 (01:26 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10609 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c

index a75587b610e0571b5901c0ddcbafe447a5847ba8..c574f315dfefabc181d05dbb8f28dceeb5f2e997 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Routines to process Rrq (download).\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -145,15 +145,19 @@ Mtftp4RrqSaveBlock (
   UINT16                    Block;\r
   UINT64                    Start;\r
   UINT32                    DataLen;\r
+  UINT64                    TotalBlock;\r
+  BOOLEAN                   Completed;\r
 \r
-  Token   = Instance->Token;\r
-  Block   = NTOHS (Packet->Data.Block);\r
-  DataLen = Len - MTFTP4_DATA_HEAD_LEN;\r
+  Completed = FALSE;\r
+  Token     = Instance->Token;\r
+  Block     = NTOHS (Packet->Data.Block);\r
+  DataLen   = Len - MTFTP4_DATA_HEAD_LEN;\r
 \r
   //\r
   // This is the last block, save the block no\r
   //\r
   if (DataLen < Instance->BlkSize) {\r
+       Completed = TRUE;\r
     Instance->LastBlock = Block;\r
     Mtftp4SetLastBlockNum (&Instance->Blocks, Block);\r
   }\r
@@ -161,8 +165,11 @@ Mtftp4RrqSaveBlock (
   //\r
   // Remove this block number from the file hole. If Mtftp4RemoveBlockNum\r
   // returns EFI_NOT_FOUND, the block has been saved, don't save it again.\r
+  // Note that : For bigger files, allowing the block counter to roll over\r
+  // to accept transfers of unlimited size. So TotalBlock is memorised as \r
+  // continuous block counter.\r
   //\r
-  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block);\r
+  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block, &TotalBlock);\r
 \r
   if (Status == EFI_NOT_FOUND) {\r
     return EFI_SUCCESS;\r
@@ -185,7 +192,7 @@ Mtftp4RrqSaveBlock (
   }\r
 \r
   if (Token->Buffer != NULL) {\r
-    Start = MultU64x32 (Block - 1, Instance->BlkSize);\r
+     Start = MultU64x32 (TotalBlock - 1, Instance->BlkSize);\r
 \r
     if (Start + DataLen <= Token->BufferSize) {\r
       CopyMem ((UINT8 *) Token->Buffer + Start, Packet->Data.Data, DataLen);\r
@@ -193,7 +200,7 @@ Mtftp4RrqSaveBlock (
       //\r
       // Update the file size when received the last block\r
       //\r
-      if (Instance->LastBlock == Block) {\r
+      if ((Instance->LastBlock == Block) && Completed) {\r
         Token->BufferSize = Start + DataLen;\r
       }\r
 \r
index 7414bf226dcc3b154376e45f7ea57037ec3038b3..4dcdf827ea57deb3b287574590f495a6e9586f45 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Support routines for Mtftp.\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -32,7 +32,7 @@ Mtftp4AllocateRange (
 {\r
   MTFTP4_BLOCK_RANGE        *Range;\r
 \r
-  Range = AllocatePool (sizeof (MTFTP4_BLOCK_RANGE));\r
+  Range = AllocateZeroPool (sizeof (MTFTP4_BLOCK_RANGE));\r
 \r
   if (Range == NULL) {\r
     return NULL;\r
@@ -41,6 +41,7 @@ Mtftp4AllocateRange (
   InitializeListHead (&Range->Link);\r
   Range->Start  = Start;\r
   Range->End    = End;\r
+  Range->Bound  = End;\r
 \r
   return Range;\r
 }\r
@@ -157,6 +158,7 @@ Mtftp4SetLastBlockNum (
 \r
   @param  Head                  The block range list to remove from\r
   @param  Num                   The block number to remove\r
+  @param  TotalBlock            The continuous block number in all \r
 \r
   @retval EFI_NOT_FOUND         The block number isn't in the block range list\r
   @retval EFI_SUCCESS           The block number has been removed from the list\r
@@ -166,7 +168,8 @@ Mtftp4SetLastBlockNum (
 EFI_STATUS\r
 Mtftp4RemoveBlockNum (\r
   IN LIST_ENTRY             *Head,\r
-  IN UINT16                 Num\r
+  IN UINT16                 Num,\r
+  OUT UINT64                *TotalBlock\r
   )\r
 {\r
   MTFTP4_BLOCK_RANGE        *Range;\r
@@ -207,6 +210,25 @@ Mtftp4RemoveBlockNum (
     } else if (Range->Start == Num) {\r
       Range->Start++;\r
 \r
+      //\r
+      // Note that: RFC 1350 does not mention block counter roll-over, \r
+      // but several TFTP hosts implement the roll-over be able to accept \r
+      // transfers of unlimited size. There is no consensus, however, whether \r
+      // the counter should wrap around to zero or to one. Many implementations \r
+      // wrap to zero, because this is the simplest to implement. Here we choose \r
+      // this solution.\r
+      //\r
+         *TotalBlock  = Num;\r
+         \r
+      if (Range->Round > 0) {\r
+           *TotalBlock += Range->Bound +  MultU64x32 (Range->Round -1, (UINT32)(Range->Bound + 1)) + 1;\r
+         }\r
+\r
+      if (Range->Start > Range->Bound) {\r
+                 Range->Start = 0;\r
+                 Range->Round ++;\r
+      }\r
+\r
       if (Range->Start > Range->End) {\r
         RemoveEntryList (&Range->Link);\r
         FreePool (Range);\r
index a34764d2272e57e1a506589f3612e6f79a2dcac5..7a712a1a6db17bca9b2dd8be218f0a9350ee31aa 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Support routines for MTFTP.\r
   \r
-Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -24,6 +24,8 @@ typedef struct {
   LIST_ENTRY                Link;\r
   INTN                      Start;\r
   INTN                      End;\r
+  INTN                      Round;\r
+  INTN                      Bound;\r
 } MTFTP4_BLOCK_RANGE;\r
 \r
 \r
@@ -90,6 +92,7 @@ Mtftp4SetLastBlockNum (
 \r
   @param  Head                  The block range list to remove from\r
   @param  Num                   The block number to remove\r
+  @param  TotalBlock            The continuous block number in all \r
 \r
   @retval EFI_NOT_FOUND         The block number isn't in the block range list\r
   @retval EFI_SUCCESS           The block number has been removed from the list\r
@@ -99,7 +102,8 @@ Mtftp4SetLastBlockNum (
 EFI_STATUS\r
 Mtftp4RemoveBlockNum (\r
   IN LIST_ENTRY             *Head,\r
-  IN UINT16                 Num\r
+  IN UINT16                 Num,\r
+  OUT UINT64                *TotalBlock\r
   );\r
 \r
 /**\r
index adc6489243ba3bd0133c19b49dc3ab12dc467e16..4312e18c6f88dc64df25cccba82ac554d4e277c9 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Routines to process Wrq (upload).\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -145,7 +145,8 @@ Mtftp4WrqHandleAck (
 {\r
   UINT16                    AckNum;\r
   INTN                      Expected;\r
-\r
+  UINT64                    TotalBlock;\r
\r
   *Completed  = FALSE;\r
   AckNum      = NTOHS (Packet->Ack.Block[0]);\r
   Expected    = Mtftp4GetNextBlockNum (&Instance->Blocks);\r
@@ -165,7 +166,7 @@ Mtftp4WrqHandleAck (
   // tell the Mtftp4WrqInput to finish the transfer. This is the last\r
   // block number if the block range are empty..\r
   //\r
-  Mtftp4RemoveBlockNum (&Instance->Blocks, AckNum);\r
+  Mtftp4RemoveBlockNum (&Instance->Blocks, AckNum, &TotalBlock);\r
 \r
   Expected = Mtftp4GetNextBlockNum (&Instance->Blocks);\r
 \r