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