mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Tweak recently altered TFTP code.
This commit is contained in:
@@ -1117,8 +1117,9 @@ struct tftp_file {
|
||||
|
||||
struct tftp_transfer {
|
||||
int sockfd;
|
||||
u16 block_hi, ackprev;
|
||||
time_t retransmit, start;
|
||||
unsigned int lastack, block, ackblock, blocksize, windowsize, timeout, expansion;
|
||||
unsigned int lastack, block, blocksize, windowsize, timeout, expansion;
|
||||
off_t offset;
|
||||
union mysockaddr peer;
|
||||
union all_addr source;
|
||||
|
||||
26
src/tftp.c
26
src/tftp.c
@@ -326,7 +326,8 @@ static void tftp_request(struct listener *listen, time_t now)
|
||||
transfer->start = now;
|
||||
transfer->backoff = 1;
|
||||
transfer->block = 1;
|
||||
transfer->ackblock = 0;
|
||||
transfer->ackprev = 0;
|
||||
transfer->block_hi = 0;
|
||||
transfer->blocksize = 512;
|
||||
transfer->windowsize = 1;
|
||||
|
||||
@@ -757,9 +758,7 @@ static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
|
||||
{
|
||||
/* Handle 16-bit block number wrap-around. */
|
||||
u16 new = ntohs(mess->block);
|
||||
u16 prev = transfer->ackblock;
|
||||
|
||||
transfer->ackblock = new | (transfer->ackblock & 0xffff0000);
|
||||
u32 block;
|
||||
|
||||
/* If the last ack received was in the top quarter of a 64k block
|
||||
and this one is in the bottom quarter, assume it has wrapped.
|
||||
@@ -768,26 +767,29 @@ static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
|
||||
need to drop back to a previous segment. Such an ACK is ignored below;
|
||||
here we're just getting the most likely 32 bit value from the
|
||||
16 bits that we have. */
|
||||
if (new <= 0x4000 && prev >= 0xc000)
|
||||
transfer->ackblock += 0x10000;
|
||||
else if (new >= 0xc000 && prev <= 0x4000 && transfer->ackblock != 0)
|
||||
transfer->ackblock -= 0x10000;
|
||||
if (new <= 0x4000 && transfer->ackprev >= 0xc000)
|
||||
transfer->block_hi++;
|
||||
else if (new >= 0xc000 && transfer->ackprev <= 0x4000 && transfer->block_hi != 0)
|
||||
transfer->block_hi--;
|
||||
|
||||
transfer->ackprev = new;
|
||||
block = (((u32)transfer->block_hi) << 16) + (u32)new;
|
||||
|
||||
/* Ignore duplicate ACKs and ACKs for blocks we've not yet sent. */
|
||||
if (transfer->ackblock >= transfer->lastack &&
|
||||
transfer->ackblock <= transfer->block)
|
||||
if (block >= transfer->lastack &&
|
||||
block <= transfer->block)
|
||||
{
|
||||
/* Got ack, move forward and ensure we take the (re)transmit path */
|
||||
transfer->retransmit = transfer->start = now;
|
||||
transfer->backoff = 0;
|
||||
transfer->lastack = transfer->ackblock + 1;
|
||||
transfer->lastack = block + 1;
|
||||
|
||||
/* We have no easy function from block no. to file offset when
|
||||
expanding line breaks in netascii mode, so we update the offset here
|
||||
as each block is acknowledged. This explains why the window size must be
|
||||
one for a netascii transfer; to avoid the block no. doing anything
|
||||
other than incrementing by one. */
|
||||
if (transfer->netascii && transfer->ackblock != 0)
|
||||
if (transfer->netascii && block != 0)
|
||||
transfer->offset += transfer->blocksize - transfer->expansion;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user