From 967cd543e515b8f8419820c6d3a299c7dca6c5c6f361069d2c2d33590fe04271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=C4=9Bzslav=20=C4=8C=C3=AD=C5=BEek?= Date: Thu, 14 Feb 2013 10:50:57 +0000 Subject: [PATCH] Accepting request 155400 from home:vitezslav_cizek:branches:network - create capabilites provided by both tftp and atftp (bnc#801481 or bnc#725378) - change ownership of /srv/tftpboot, because atftpd running as tftp:tftp can't write to that directory - create pid directory on service start - manpage changes: * substitute /tftpboot with /srv/tftpboot * default user is now tftp:tftp * added patches: atftp-0.7-default_user_man.patch atftp-0.7-default_dir_man.patch - use Vladimir Nadvornik's heuristic for packet retransmission by default (see bnc#774376) The RFC1350 compliant behaviour stays optional. (added atftp-0.7-ack_heuristic.patch) - merged the two sorcerer's apprentice syndrome patches to one (removed atftp-0.7-prevent-sas.patch) OBS-URL: https://build.opensuse.org/request/show/155400 OBS-URL: https://build.opensuse.org/package/show/network/atftp?expand=0&rev=18 --- atftp-0.7-ack_heuristic.patch | 163 +++++++++++++++++++ atftp-0.7-default_dir_man.patch | 13 ++ atftp-0.7-default_user_man.patch | 37 +++++ atftp-0.7-prevent-sas.patch | 219 ------------------------- atftp-0.7-sorcerers_apprentice.patch | 229 ++++++++++++++++++++++----- atftp.changes | 29 ++++ atftp.spec | 19 ++- atftpd.init.d | 15 +- 8 files changed, 448 insertions(+), 276 deletions(-) create mode 100644 atftp-0.7-ack_heuristic.patch create mode 100644 atftp-0.7-default_dir_man.patch create mode 100644 atftp-0.7-default_user_man.patch delete mode 100644 atftp-0.7-prevent-sas.patch diff --git a/atftp-0.7-ack_heuristic.patch b/atftp-0.7-ack_heuristic.patch new file mode 100644 index 0000000..1297ffb --- /dev/null +++ b/atftp-0.7-ack_heuristic.patch @@ -0,0 +1,163 @@ +Index: atftp-0.7/tftpd_file.c +=================================================================== +--- atftp-0.7.orig/tftpd_file.c 2013-02-06 16:15:50.178332917 +0100 ++++ atftp-0.7/tftpd_file.c 2013-02-06 16:16:49.608140471 +0100 +@@ -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_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 = %d>", last_requested_block, block_number); ++ logger(LOG_DEBUG, "received duplicated ACK = %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 ", last_requested_block + 1, block_number); ++ logger(LOG_DEBUG, "received out of order ACK ", 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 + { diff --git a/atftp-0.7-default_dir_man.patch b/atftp-0.7-default_dir_man.patch new file mode 100644 index 0000000..637011e --- /dev/null +++ b/atftp-0.7-default_dir_man.patch @@ -0,0 +1,13 @@ +Index: atftp-0.7/atftpd.8 +=================================================================== +--- atftp-0.7.orig/atftpd.8 2012-11-16 11:50:17.618281568 +0100 ++++ atftp-0.7/atftpd.8 2013-01-03 14:27:00.913280412 +0100 +@@ -210,7 +210,7 @@ Show summary of options. + .B path + This is the root directory used by the TFTP server. All requested + files from a TFTP client must reside in this directory. If not +-specified, the directory defaults to /tftpboot. Since ++specified, the directory defaults to /srv/tftpboot. Since + atftpd run as the tftp user, the permission of the directory + must be set properly to allow file reading and writing. + diff --git a/atftp-0.7-default_user_man.patch b/atftp-0.7-default_user_man.patch new file mode 100644 index 0000000..bef7aa3 --- /dev/null +++ b/atftp-0.7-default_user_man.patch @@ -0,0 +1,37 @@ +Index: atftp-0.7/atftpd.8 +=================================================================== +--- atftp-0.7.orig/atftpd.8 2012-11-16 11:46:18.798067178 +0100 ++++ atftp-0.7/atftpd.8 2012-11-16 11:50:17.618281568 +0100 +@@ -80,10 +80,10 @@ acknowledging the 'multicast' request by + + .TP + .B \-\-logfile +-Log to a specific file instead of only syslog. 'nobody' (or any user ++Log to a specific file instead of only syslog. 'tftp' (or any user + used to run the server) must have permissions on the given + file. Assuming the file is /var/log/atftpd.log, simply run: "touch +-/var/log/atftpd.log" and then "chown nobody.nogroup ++/var/log/atftpd.log" and then "chown tftp.tftp + /var/log/atftpd.log". When the server is ran in daemon mode, + /dev/stdout or /dev/stderr can be used. + +@@ -105,8 +105,8 @@ specialized usage. + + .TP + .B \-\-user +-By default, the server change identity to the user nobody and group +-nogroup. Specify an alternate user.group with this option. ++By default, the server change identity to the user tftp and group ++tftp. Specify an alternate user.group with this option. + + .TP + .B \-\-group +@@ -211,7 +211,7 @@ Show summary of options. + This is the root directory used by the TFTP server. All requested + files from a TFTP client must reside in this directory. If not + specified, the directory defaults to /tftpboot. Since +-atftpd run as the nobody user, the permission of the directory ++atftpd run as the tftp user, the permission of the directory + must be set properly to allow file reading and writing. + + .SH STATS diff --git a/atftp-0.7-prevent-sas.patch b/atftp-0.7-prevent-sas.patch deleted file mode 100644 index 89adb46..0000000 --- a/atftp-0.7-prevent-sas.patch +++ /dev/null @@ -1,219 +0,0 @@ -Index: atftp-0.7/tftpd.c -=================================================================== ---- atftp-0.7.orig/tftpd.c 2012-09-11 13:55:28.303292010 +0200 -+++ atftp-0.7/tftpd.c 2012-09-11 13:58:20.701437613 +0200 -@@ -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 : 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 : default is nobody\n" - " --group : default is nogroup\n" - " --port : port on which atftp listen\n" -Index: atftp-0.7/tftpd_file.c -=================================================================== ---- atftp-0.7.orig/tftpd_file.c 2012-09-11 13:55:28.405295054 +0200 -+++ atftp-0.7/tftpd_file.c 2012-09-11 13:55:28.422295562 +0200 -@@ -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; -@@ -863,31 +864,31 @@ int tftpd_send_file(struct thread_data * - logger(LOG_DEBUG, "received ACK ", block_number); - } - -- /* check whether the block request isn't already fulfilled */ -- -- /* multicast, block numbers could contain gaps */ -- if (multicast) { -- if (last_requested_block >= block_number) -- { -- if (data->trace) -- logger(LOG_DEBUG, "received duplicated ACK = %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 ", last_requested_block + 1, block_number); -- break; -+ /* 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 = %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 ", last_requested_block + 1, block_number); -+ break; -+ } -+ else -+ last_requested_block = block_number; - } -- else -- last_requested_block = block_number; - } - -- - if (ntohs(tftphdr->th_block) == 65535) - { - block_loops++; -Index: atftp-0.7/tftp_file.c -=================================================================== ---- atftp-0.7.orig/tftp_file.c 2012-09-11 13:55:28.387294518 +0200 -+++ atftp-0.7/tftp_file.c 2012-09-11 13:55:28.422295562 +0200 -@@ -49,6 +49,7 @@ - #define NB_BLOCK 2048 - - extern int tftp_cancel; -+extern int tftp_prevent_sas; - - /* - * Find a hole in the file bitmap. -@@ -767,15 +768,18 @@ int tftp_send_file(struct client_data *d - } - block_number = ntohs(tftphdr->th_block); - -- if (last_requested_block >= block_number) -- { -- if (data->trace) -- fprintf(stderr, "received duplicated ACK = %ld>\n", -- last_requested_block, block_number); -- break; -+ /* 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 = %ld>\n", -+ last_requested_block, block_number); -+ break; -+ } -+ else -+ last_requested_block = block_number; - } -- else -- last_requested_block = block_number; - - if (data->trace) - fprintf(stderr, "received ACK \n", -Index: atftp-0.7/tftp.c -=================================================================== ---- atftp-0.7.orig/tftp.c 2012-09-11 13:55:28.255290577 +0200 -+++ atftp-0.7/tftp.c 2012-09-11 14:01:13.437593304 +0200 -@@ -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: atftp-0.7/atftpd.8 -=================================================================== ---- atftp-0.7.orig/atftpd.8 2004-03-06 21:41:40.000000000 +0100 -+++ atftp-0.7/atftpd.8 2012-09-11 13:55:28.423295591 +0200 -@@ -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-0.7/atftp.1 -=================================================================== ---- atftp-0.7.orig/atftp.1 2004-03-06 21:41:40.000000000 +0100 -+++ atftp-0.7/atftp.1 2012-09-11 13:55:28.423295591 +0200 -@@ -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. diff --git a/atftp-0.7-sorcerers_apprentice.patch b/atftp-0.7-sorcerers_apprentice.patch index fcbc671..a188c83 100644 --- a/atftp-0.7-sorcerers_apprentice.patch +++ b/atftp-0.7-sorcerers_apprentice.patch @@ -1,8 +1,15 @@ -Index: atftp-0.7/tftp_file.c -=================================================================== ---- atftp-0.7.orig/tftp_file.c 2011-11-22 15:12:53.792744083 +0100 -+++ atftp-0.7/tftp_file.c 2011-11-22 15:13:51.706421893 +0100 -@@ -605,6 +605,7 @@ +diff -u atftp-0.7/tftp_file.c atftp-0.7/tftp_file.c +--- atftp-0.7/tftp_file.c 2012-03-27 11:39:59.441167084 +0200 ++++ atftp-0.7/tftp_file.c 2012-09-11 13:55:28.422295562 +0200 +@@ -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 timeout_state = state; /* what state should we go on when timeout */ int result; long block_number = 0; @@ -10,29 +17,39 @@ Index: atftp-0.7/tftp_file.c long last_block = -1; int data_size; /* size of data received */ int sockfd = data->sockfd; /* just to simplify calls */ -@@ -765,6 +766,17 @@ +@@ -765,6 +767,20 @@ connected = 1; } block_number = ntohs(tftphdr->th_block); + -+ if (last_requested_block >= block_number) -+ { -+ if (data->trace) -+ fprintf(stderr, "received duplicated ACK = %ld>\n", -+ last_requested_block, block_number); -+ break; ++ /* 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 = %ld>\n", ++ last_requested_block, block_number); ++ break; ++ } ++ else ++ last_requested_block = block_number; + } -+ else -+ last_requested_block = block_number; + if (data->trace) fprintf(stderr, "received ACK \n", block_number); -Index: atftp-0.7/tftpd_file.c -=================================================================== ---- atftp-0.7.orig/tftpd_file.c 2011-11-22 15:12:53.793744112 +0100 -+++ atftp-0.7/tftpd_file.c 2011-11-22 15:15:04.617534260 +0100 -@@ -403,6 +403,7 @@ +diff -u atftp-0.7/tftpd_file.c atftp-0.7/tftpd_file.c +--- atftp-0.7/tftpd_file.c 2012-03-30 14:02:04.335089843 +0200 ++++ atftp-0.7/tftpd_file.c 2012-09-11 13:55:28.422295562 +0200 +@@ -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 timeout_state = state; int result; long block_number = 0; @@ -40,40 +57,50 @@ Index: atftp-0.7/tftpd_file.c long last_block = -1; int block_loops = 0; int data_size; -@@ -859,6 +860,32 @@ - { +@@ -785,6 +787,10 @@ + 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; + } +@@ -858,5 +864,31 @@ logger(LOG_DEBUG, "received ACK ", block_number); } + -+ /* check whether the block request isn't already fulfilled */ -+ -+ /* multicast, block numbers could contain gaps */ -+ if (multicast) { -+ if (last_requested_block >= block_number) -+ { -+ if (data->trace) -+ logger(LOG_DEBUG, "received duplicated ACK = %d>", last_requested_block, block_number); -+ break; ++ /* 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 = %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 ", last_requested_block + 1, block_number); ++ break; ++ } ++ else ++ last_requested_block = block_number; + } -+ 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 ", last_requested_block + 1, block_number); -+ break; -+ } -+ else -+ last_requested_block = block_number; + } -+ + if (ntohs(tftphdr->th_block) == 65535) { block_loops++; -@@ -958,6 +985,8 @@ +@@ -958,6 +990,8 @@ /* nedd to send an oack to that client */ state = S_SEND_OACK; fseek(fp, 0, SEEK_SET); @@ -82,3 +109,117 @@ Index: atftp-0.7/tftpd_file.c } else { +only in patch2: +unchanged: +--- atftp-0.7.orig/tftpd.c 2012-09-11 13:55:28.303292010 +0200 ++++ atftp-0.7/tftpd.c 2012-09-11 13:58:20.701437613 +0200 +@@ -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 : 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 : default is nobody\n" + " --group : default is nogroup\n" + " --port : port on which atftp listen\n" +only in patch2: +unchanged: +--- atftp-0.7.orig/tftp.c 2012-09-11 13:55:28.255290577 +0200 ++++ atftp-0.7/tftp.c 2012-09-11 14:01:13.437593304 +0200 +@@ -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 +only in patch2: +unchanged: +--- atftp-0.7.orig/atftpd.8 2004-03-06 21:41:40.000000000 +0100 ++++ atftp-0.7/atftpd.8 2012-09-11 13:55:28.423295591 +0200 +@@ -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 +only in patch2: +unchanged: +--- atftp-0.7.orig/atftp.1 2004-03-06 21:41:40.000000000 +0100 ++++ atftp-0.7/atftp.1 2012-09-11 13:55:28.423295591 +0200 +@@ -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. diff --git a/atftp.changes b/atftp.changes index 659f92a..f4f8d28 100644 --- a/atftp.changes +++ b/atftp.changes @@ -1,3 +1,32 @@ +------------------------------------------------------------------- +Thu Feb 7 13:05:52 UTC 2013 - vcizek@suse.com + +- create capabilites provided by both tftp and atftp + (bnc#801481 or bnc#725378) + +------------------------------------------------------------------- +Thu Jan 3 13:28:02 UTC 2013 - vcizek@suse.com + +- change ownership of /srv/tftpboot, because atftpd running as + tftp:tftp can't write to that directory +- create pid directory on service start +- manpage changes: + * substitute /tftpboot with /srv/tftpboot + * default user is now tftp:tftp + * added patches: + atftp-0.7-default_user_man.patch + atftp-0.7-default_dir_man.patch + +------------------------------------------------------------------- +Mon Oct 8 08:49:53 UTC 2012 - vcizek@suse.com + +- use Vladimir Nadvornik's heuristic for packet retransmission + by default (see bnc#774376) + The RFC1350 compliant behaviour stays optional. + (added atftp-0.7-ack_heuristic.patch) +- merged the two sorcerer's apprentice syndrome patches to one + (removed atftp-0.7-prevent-sas.patch) + ------------------------------------------------------------------- Tue Sep 11 13:01:20 UTC 2012 - vcizek@suse.com diff --git a/atftp.spec b/atftp.spec index 7f06d12..2bf24c1 100644 --- a/atftp.spec +++ b/atftp.spec @@ -1,7 +1,7 @@ # # spec file for package atftp # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -44,8 +44,14 @@ Patch8: atftpd-0.7_circumvent_tftp_size_restrictions.patch Patch9: atftp-0.7-sorcerers_apprentice.patch # PATCH-FIX-SUSE server receive thread race (bnc#599856) Patch10: atftp-0.7-server_receive_race.patch -Patch11: atftp-0.7-prevent-sas.patch +# PATCH-FIX-SUSE drop one duplicated ACK each round (bnc#774376) +Patch12: atftp-0.7-ack_heuristic.patch +Patch13: atftp-0.7-default_user_man.patch +# PATCH-FIX-SUSE update default directory in man (bnc#507011) +Patch14: atftp-0.7-default_dir_man.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build +Provides: tftp(client) +Provides: tftp(server) PreReq: %insserv_prereq %fillup_prereq PreReq: pwdutils BuildRequires: autoconf @@ -77,7 +83,9 @@ boot of hundreds of machines simultaneously. %patch8 %patch9 -p1 %patch10 -p0 -%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 %build autoreconf -fi @@ -134,7 +142,8 @@ fi %{_mandir}/man8/atftpd.8.gz %{_mandir}/man8/in.tftpd.8.gz %config %{_fwdefdir}/atftp -%dir %attr(0750,root,tftp) /srv/tftpboot -%dir %attr(0750,tftp,root) /var/log/atftpd/ +%dir %attr(0750,tftp,tftp) /srv/tftpboot +%dir %attr(0750,tftp,tftp) /var/log/atftpd/ +%ghost %dir /var/run/atftpd %changelog diff --git a/atftpd.init.d b/atftpd.init.d index a53500f..315f7c1 100644 --- a/atftpd.init.d +++ b/atftpd.init.d @@ -74,13 +74,12 @@ ATFTP_BIND=${ATFTP_BIND_ADDRESSES:=""} # start as daemon with some default opts ATFTP_DEF_OPTS="--daemon --user $ATFTP_USR --group $ATFTP_GRP --logfile $ATFTP_LOG_FILE" -# set correct perm on log_dir/pid_dir -# IN: $ATFTP_USR -set_perm(){ - [ ! -f "$ATFTP_LOG_FILE" ] && touch "$ATFTP_LOG_FILE"; - chown -R ${1}:root "$ATFTP_LOG_DIR" - [ ! -d "$ATFTP_PID_DIR" ] && /usr/bin/install -d "$ATFTP_PID_DIR"; - chown -R ${1}:root "$ATFTP_PID_DIR" +# create logfile and PID directory if they don't exist +create_logfile_and_piddir(){ + # /var/run is mounted as tmpfs on openSUSE >= 11.4 + [ ! -d "$ATFTP_PID_DIR" ] && /usr/bin/install -o ${ATFTP_USR} -g ${ATFTP_GRP} -d "$ATFTP_PID_DIR"; + # must exist otherwise atftp will log to syslog + [ ! -f "$ATFTP_PID_DIR" ] && /usr/bin/install -m 0644 -o ${ATFTP_USR} -g ${ATFTP_GRP} /dev/null "$ATFTP_LOG_FILE" } if [ "$ATFTP_USE_INETD" = "yes" ]; then @@ -90,7 +89,7 @@ fi case "$1" in start) - set_perm "${ATFTP_USR}" + create_logfile_and_piddir if [ -n "$ATFTP_BIND" ]; then for IP in $ATFTP_BIND; do echo -n "Starting Advanced Trivial FTP server on $IP: "