SHA256
1
0
forked from pool/atftp
atftp/atftp-0.7-sorcerers_apprentice.patch
Vítězslav Čížek 967cd543e5 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
2013-02-14 10:50:57 +00:00

226 lines
9.3 KiB
Diff

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;
+ 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 @@
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);
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;
+ long last_requested_block = -1;
long last_block = -1;
int block_loops = 0;
int data_size;
@@ -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: %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 @@
/* 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
{
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 <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"
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.