Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.0:Ports
atftp
atftp-0.7-ack_heuristic.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File atftp-0.7-ack_heuristic.patch of Package atftp
Index: tftpd_file.c =================================================================== --- tftpd_file.c.orig +++ tftpd_file.c @@ -402,7 +402,6 @@ 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; @@ -430,6 +429,11 @@ int tftpd_send_file(struct thread_data * long prev_file_pos = 0; int temp = 0; + long prev_sent_block = -1; + int prev_sent_count = 0; + int prev_ack_count = 0; + int curr_sent_count = 0; + /* look for mode option */ if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0) { @@ -786,8 +790,8 @@ int tftpd_send_file(struct thread_data * ntohs(client_info->client.sin_port)); sa = &client_info->client; - /* rewind the last_requested_block counter */ - last_requested_block = -1; + /* rewind the prev_sent_block counter */ + prev_sent_block = -1; state = S_SEND_OACK; break; @@ -856,6 +860,7 @@ int tftpd_send_file(struct thread_data * "source port mismatch, check bypassed"); } } + /* The ACK is from the current client */ number_of_timeout = 0; block_number = (block_loops * 65536) + ntohs(tftphdr->th_block); @@ -864,28 +869,88 @@ int tftpd_send_file(struct thread_data * logger(LOG_DEBUG, "received ACK <block: %d>", block_number); } - /* if turned on, check whether the block request isn't already fulfilled */ - if (tftpd_prevent_sas) { - /* multicast, block numbers could contain gaps */ - if (multicast) { - if (last_requested_block >= block_number) + /* Now check the ACK number and possibly ignore the request */ + + /* multicast, block numbers could contain gaps */ + if (multicast) { + /* if turned on, check whether the block request isn't already fulfilled */ + if (tftpd_prevent_sas) { + if (prev_sent_block >= block_number) { if (data->trace) - logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", last_requested_block, block_number); + logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", prev_sent_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) + prev_sent_block = block_number; + } + /* don't prevent thes SAS */ + /* use a heuristic suggested by Vladimir Nadvornik */ + else { + /* here comes the ACK again */ + if (prev_sent_block == block_number) + { + /* drop if number of ACKs == times of previous block sending */ + if (++prev_ack_count == prev_sent_count) { + logger(LOG_DEBUG, "ACK count (%d) == previous block transmission count -> dropping ACK", prev_ack_count); + break; + } + /* else resend the block */ + logger(LOG_DEBUG, "resending block %d", block_number + 1); + } + /* received ACK to sent block -> move on to next block */ + else if (prev_sent_block < block_number) { + prev_sent_block = block_number; + prev_sent_count = curr_sent_count; + curr_sent_count = 0; + prev_ack_count = 1; + } + /* block with low number -> ignore it completely */ + else { + logger(LOG_DEBUG, "ignoring ACK %d", block_number); + break; + } + } + /* unicast, blocks should be requested one after another */ + } else { + /* if turned on, check whether the block request isn't already fulfilled */ + if (tftpd_prevent_sas) { + if (prev_sent_block + 1 != block_number) { + logger(LOG_WARNING, "timeout: retrying..."); if (data->trace) - logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", last_requested_block + 1, block_number); + logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", prev_sent_block + 1, block_number); + break; + } + else { + prev_sent_block = block_number; + } + /* don't prevent thes SAS */ + /* use a heuristic suggested by Vladimir Nadvornik */ + } else { + /* here comes the ACK again */ + if (prev_sent_block == block_number) + { + /* drop if number of ACKs == times of previous block sending */ + if (++prev_ack_count == prev_sent_count) { + logger(LOG_DEBUG, "ACK count (%d) == previous block transmission count -> dropping ACK", prev_ack_count); + break; + } + /* else resend the block */ + logger(LOG_DEBUG, "resending block %d", block_number + 1); + } + /* received ACK to sent block -> move on to next block */ + else if (prev_sent_block < block_number) { + prev_sent_block = block_number; + prev_sent_count = curr_sent_count; + curr_sent_count = 0; + prev_ack_count = 1; + } + /* nor previous nor current block number -> ignore it completely */ + else { + logger(LOG_DEBUG, "ignoring ACK %d", block_number); break; } - else - last_requested_block = block_number; } } @@ -898,6 +963,8 @@ int tftpd_send_file(struct thread_data * state = S_END; break; } + + curr_sent_count++; state = S_SEND_DATA; break; case GET_ERROR: @@ -989,7 +1056,7 @@ int tftpd_send_file(struct thread_data * state = S_SEND_OACK; fseek(fp, 0, SEEK_SET); /* reset the last block received counter */ - last_requested_block = -1; + prev_sent_block = -1; } else {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor