mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
httpd: retransmit a continued chunk from where it was sent
A file larger than the output buffer is sent in two phases: the first buffer goes out in MSS-sized pieces, with o_idx walking through it, and what is left is then streamed from flash a chunk at a time into outbuf from offset 0. The continuation branch never reset o_idx, so it kept the offset the first phase had left it at, while uip_rexmit() retransmits from outbuf + o_idx. A lost continuation segment was therefore retransmitted as the bytes 1460 further into the buffer, which the client accepts as the missing data, and with o_idx + slen past the 2500-byte buffer it also read whatever xdata follows outbuf. Reproduced on a SWTGW218AS by dropping 15% of the switch's TCP segments: seven of eight fetches of a 21 kB static came back the right length and the wrong content, each first differing at a fixed phase of the 1460-byte chunk. With o_idx reset the retransmission repeats the chunk it sent. The o_idx += slen right after slen = 0 went too: it added nothing. (cherry picked from commit 789d29423288f89411a41673e26ce1854b296c3d)
This commit is contained in:
1 parent
6488433584
commit
8d7faf5312
1 file changed
+2
-2
+2
-2
@@ -865,7 +865,6 @@ void httpd_appcall(void)
|
|||||||
o_idx += uip_mss();
|
o_idx += uip_mss();
|
||||||
} else {
|
} else {
|
||||||
slen = 0;
|
slen = 0;
|
||||||
o_idx += slen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s->tstate = TSTATE_ACKED;
|
s->tstate = TSTATE_ACKED;
|
||||||
@@ -886,7 +885,8 @@ void httpd_appcall(void)
|
|||||||
flash_region.addr = cont_addr;
|
flash_region.addr = cont_addr;
|
||||||
flash_region.len = slen;
|
flash_region.len = slen;
|
||||||
flash_read_bulk(outbuf);
|
flash_read_bulk(outbuf);
|
||||||
uip_send(outbuf, slen);
|
o_idx = 0;
|
||||||
|
uip_send(outbuf + o_idx, slen);
|
||||||
cont_len -= slen;
|
cont_len -= slen;
|
||||||
cont_addr += slen;
|
cont_addr += slen;
|
||||||
s->tstate = TSTATE_TX;
|
s->tstate = TSTATE_TX;
|
||||||
|
|||||||
Reference in new issue
Block a user