diff options
-rw-r--r-- | meta-networking/recipes-daemons/atftp/atftp_git.bb | 1 | ||||
-rw-r--r-- | meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch | 94 |
2 files changed, 95 insertions, 0 deletions
diff --git a/meta-networking/recipes-daemons/atftp/atftp_git.bb b/meta-networking/recipes-daemons/atftp/atftp_git.bb index 6156bb1c7..ffc0bc874 100644 --- a/meta-networking/recipes-daemons/atftp/atftp_git.bb +++ b/meta-networking/recipes-daemons/atftp/atftp_git.bb | |||
@@ -13,6 +13,7 @@ SRC_URI = "git://git.code.sf.net/p/atftp/code \ | |||
13 | file://atftpd-0.7_unprotected_assignments_crash.patch \ | 13 | file://atftpd-0.7_unprotected_assignments_crash.patch \ |
14 | file://atftpd.init \ | 14 | file://atftpd.init \ |
15 | file://atftpd.service \ | 15 | file://atftpd.service \ |
16 | file://atftp-0.7-sorcerers_apprentice.patch \ | ||
16 | " | 17 | " |
17 | S = "${WORKDIR}/git" | 18 | S = "${WORKDIR}/git" |
18 | 19 | ||
diff --git a/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch b/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch new file mode 100644 index 000000000..fc64291cd --- /dev/null +++ b/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch | |||
@@ -0,0 +1,94 @@ | |||
1 | atftp exhibits the well known "Sorcerer's Apprentice Syndrome"(SAS) problem. | ||
2 | According to RFC 1350, the fix to SAS is quite simple: further copies of the | ||
3 | acknowledgment for a particular data block would be ignored. | ||
4 | |||
5 | Patch originally from OpenSUSE: | ||
6 | https://build.opensuse.org/package/view_file?file=atftp-0.7-sorcerers_apprentice.patch&package=atftp.539&project=openSUSE%3A12.1%3AUpdate&rev=84569792975e00573d7df597d2a6e895 | ||
7 | |||
8 | Upstream-Status: Pending | ||
9 | |||
10 | Signed-off-by: Roy.Li <rongqing.li@windriver.com> | ||
11 | Index: atftp-0.7/tftp_file.c | ||
12 | =================================================================== | ||
13 | --- atftp-0.7.orig/tftp_file.c 2011-11-22 15:12:53.792744083 +0100 | ||
14 | +++ atftp-0.7/tftp_file.c 2011-11-22 15:13:51.706421893 +0100 | ||
15 | @@ -605,6 +605,7 @@ | ||
16 | int timeout_state = state; /* what state should we go on when timeout */ | ||
17 | int result; | ||
18 | long block_number = 0; | ||
19 | + long last_requested_block = -1; | ||
20 | long last_block = -1; | ||
21 | int data_size; /* size of data received */ | ||
22 | int sockfd = data->sockfd; /* just to simplify calls */ | ||
23 | @@ -765,6 +766,17 @@ | ||
24 | connected = 1; | ||
25 | } | ||
26 | block_number = ntohs(tftphdr->th_block); | ||
27 | + | ||
28 | + if (last_requested_block >= block_number) | ||
29 | + { | ||
30 | + if (data->trace) | ||
31 | + fprintf(stderr, "received duplicated ACK <block: %ld >= %ld>\n", | ||
32 | + last_requested_block, block_number); | ||
33 | + break; | ||
34 | + } | ||
35 | + else | ||
36 | + last_requested_block = block_number; | ||
37 | + | ||
38 | if (data->trace) | ||
39 | fprintf(stderr, "received ACK <block: %ld>\n", | ||
40 | block_number); | ||
41 | Index: atftp-0.7/tftpd_file.c | ||
42 | =================================================================== | ||
43 | --- atftp-0.7.orig/tftpd_file.c 2011-11-22 15:12:53.793744112 +0100 | ||
44 | +++ atftp-0.7/tftpd_file.c 2011-11-22 15:15:04.617534260 +0100 | ||
45 | @@ -403,6 +403,7 @@ | ||
46 | int timeout_state = state; | ||
47 | int result; | ||
48 | long block_number = 0; | ||
49 | + long last_requested_block = -1; | ||
50 | long last_block = -1; | ||
51 | int block_loops = 0; | ||
52 | int data_size; | ||
53 | @@ -859,6 +860,32 @@ | ||
54 | { | ||
55 | logger(LOG_DEBUG, "received ACK <block: %d>", block_number); | ||
56 | } | ||
57 | + | ||
58 | + /* check whether the block request isn't already fulfilled */ | ||
59 | + | ||
60 | + /* multicast, block numbers could contain gaps */ | ||
61 | + if (multicast) { | ||
62 | + if (last_requested_block >= block_number) | ||
63 | + { | ||
64 | + if (data->trace) | ||
65 | + logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", last_requested_block, block_number); | ||
66 | + break; | ||
67 | + } | ||
68 | + else | ||
69 | + last_requested_block = block_number; | ||
70 | + /* unicast, blocks should be requested one after another */ | ||
71 | + } else { | ||
72 | + if (last_requested_block + 1 != block_number && last_requested_block != -1) | ||
73 | + { | ||
74 | + if (data->trace) | ||
75 | + logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", last_requested_block + 1, block_number); | ||
76 | + break; | ||
77 | + } | ||
78 | + else | ||
79 | + last_requested_block = block_number; | ||
80 | + } | ||
81 | + | ||
82 | + | ||
83 | if (ntohs(tftphdr->th_block) == 65535) | ||
84 | { | ||
85 | block_loops++; | ||
86 | @@ -958,6 +985,8 @@ | ||
87 | /* nedd to send an oack to that client */ | ||
88 | state = S_SEND_OACK; | ||
89 | fseek(fp, 0, SEEK_SET); | ||
90 | + /* reset the last block received counter */ | ||
91 | + last_requested_block = -1; | ||
92 | } | ||
93 | else | ||
94 | { | ||