Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
atftp.22713
atftp-0.7-sorcerers_apprentice.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File atftp-0.7-sorcerers_apprentice.patch of Package atftp.22713
Index: tftp_file.c =================================================================== --- tftp_file.c.orig +++ tftp_file.c @@ -49,6 +49,7 @@ #define NB_BLOCK 2048 extern int tftp_cancel; +extern int tftp_prevent_sas; /* * Find a hole in the file bitmap. @@ -605,6 +606,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 +767,20 @@ int tftp_send_file(struct client_data *d connected = 1; } block_number = ntohs(tftphdr->th_block); + + /* if turned on, check whether the block request isn't already fulfilled */ + if (tftp_prevent_sas) { + 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: tftpd_file.c =================================================================== --- tftpd_file.c.orig +++ tftpd_file.c @@ -55,6 +55,7 @@ extern char directory[MAXLEN]; /* read only except for the main thread */ extern int tftpd_cancel; +extern int tftpd_prevent_sas; #ifdef HAVE_PCRE extern tftpd_pcre_self_t *pcre_top; @@ -403,6 +404,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 +787,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 +865,32 @@ 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) + { + 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 +990,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 { Index: tftpd.c =================================================================== --- tftpd.c.orig +++ tftpd.c @@ -62,6 +62,7 @@ int retry_timeout = S_TIMEOUT; int tftpd_daemon = 0; /* By default we are started by inetd */ int tftpd_daemon_no_fork = 0; /* For who want a false daemon mode */ +int tftpd_prevent_sas = 0; /* For who don't want the sorcerer's apprentice syndrome */ short tftpd_port = 0; /* Port atftpd listen to */ char tftpd_addr[MAXLEN] = ""; /* IP address atftpd binds to */ @@ -833,6 +834,7 @@ int tftpd_cmd_line_options(int argc, cha { "mtftp", 1, NULL, OPT_MTFTP }, { "mtftp-port", 1, NULL, OPT_MTFTP_PORT }, #endif + { "prevent-sas", 0, NULL, 'X' }, { "no-source-port-checking", 0, NULL, OPT_PORT_CHECK }, { "mcast-switch-client", 0, NULL, OPT_MCAST_SWITCH }, { "version", 0, NULL, 'V' }, @@ -896,6 +898,9 @@ int tftpd_cmd_line_options(int argc, cha case 'N': tftpd_daemon_no_fork = 1; break; + case 'X': + tftpd_prevent_sas = 1; + break; case 'U': tmp = strtok(optarg, "."); if (tmp != NULL) @@ -1120,6 +1125,7 @@ void tftpd_usage(void) " --pidfile <file> : write PID to this file\n" " --daemon : run atftpd standalone (no inetd)\n" " --no-fork : run as a daemon, don't fork\n" + " --prevent-sas : prevent Sorcerer's Apprentice Syndrome\n" " --user <user[.group]> : default is nobody\n" " --group <group> : default is nogroup\n" " --port <port> : port on which atftp listen\n" Index: tftp.c =================================================================== --- tftp.c.orig +++ tftp.c @@ -57,6 +57,7 @@ /* defined as extern in tftp_file.c and mtftp_file.c, set by the signal handler */ int tftp_cancel = 0; +int tftp_prevent_sas = 0; /* local flags */ int interactive = 1; /* if false, we run in batch mode */ @@ -982,6 +983,7 @@ int tftp_cmd_line_options(int argc, char #endif { "mtftp", 1, NULL, '1'}, { "no-source-port-checking", 0, NULL, '0'}, + { "prevent-sas", 0, NULL, 'X'}, { "verbose", 0, NULL, 'v'}, { "trace", 0, NULL, 'd'}, #if DEBUG @@ -1086,6 +1088,9 @@ int tftp_cmd_line_options(int argc, char case '0': data.checkport = 0; break; + case 'X': + tftp_prevent_sas = 1; + break; case 'v': snprintf(string, sizeof(string), "verbose on"); make_arg(string, &ac, &av); @@ -1182,6 +1187,7 @@ void tftp_usage(void) " --mtftp <\"name value\"> : set mtftp variable to value\n" #endif " --no-source-port-checking: violate RFC, see man page\n" + " --prevent-sas : prevent Sorcerer's Apprentice Syndrome\n" " --verbose : set verbose mode on\n" " --trace : set trace mode on\n" #if DEBUG Index: atftpd.8 =================================================================== --- atftpd.8.orig +++ atftpd.8 @@ -180,6 +180,14 @@ implication. Be aware that this option v option has effect only for non-multicast transfer. .TP +.B \-\-prevent\-sas +Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350. +This RFC requires repeated responses to a single packet to be +rejected. Thus a block will only get retransmitted on a timeout. +For backward compatibility, the default stays to ignore this RFC. +So blocks get transmitted on every request. + +.TP .B \-\-mcast\-switch\-client This option allow the server to proceed with the next multicast client as soon as the current client timeout. When the current master client Index: atftp.1 =================================================================== --- atftp.1.orig +++ atftp.1 @@ -77,6 +77,14 @@ to configure client side port to use. See atftpd's man page. .TP +.B \-\-prevent\-sas +Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350. +This RFC requires repeated responses to a single packet to be +rejected. Thus a block will only get retransmitted on a timeout. +For backward compatibility, the default stays to ignore this RFC. +So blocks get transmitted on every request. + +.TP .B \-\-verbose Instruct atftp to be verbose. It will print more information about what's going on.
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