diff options
author | Yasuharu Shibata <yasuharu.shibata@gmail.com> | 2024-08-14 21:41:07 +0900 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-08-15 11:32:12 -0600 |
commit | dbb6b5a01098ea2b981cc35d21edd52d33b03f50 (patch) | |
tree | 2221420aac0b1f70d4d39352e5babcbfd85aed6f | |
parent | 4f64730f8d00435d6350d9085ed7d38a77e583be (diff) |
sandbox: fix wget test failure after fixing wget issue
After applying the following patch, wget test on sandbox failed[1].
Commit: cab7867cff ("net: wget: Support retransmission a dropped packet")
Here are two reasons why the test is failed and how to fix it:
1. tcp_ack is calculated by the wrong value.
tcp_ack needs to be calculated by the received TCP payload size.
2. wget command may have a problem that HTTP response from server
must be divided into more than two packets.
In this commit, HTTP response is divided into two packets.
In addition, I fixed the HTTP response returned at the correct timing.
[1] https://lore.kernel.org/u-boot/CAFLszThEbk2Jr8OZ6Hj21wPSnJjgJhaDe037RqwHvwt1KjB3_A@mail.gmail.com/
Signed-off-by: Yasuharu Shibata <yasuharu.shibata@gmail.com>
Reported-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | test/cmd/wget.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/test/cmd/wget.c b/test/cmd/wget.c index 356a4dcd8fa..b0feb21dc41 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -26,6 +26,8 @@ #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define LEN_B_TO_DW(x) ((x) >> 2) +int net_set_ack_options(union tcp_build_pkt *b); + static int sb_arp_handler(struct udevice *dev, void *packet, unsigned int len) { @@ -105,6 +107,10 @@ static int sb_ack_handler(struct udevice *dev, void *packet, const char *payload1 = "HTTP/1.1 200 OK\r\n" "Content-Length: 30\r\n\r\n\r\n" "<html><body>Hi</body></html>\r\n"; + union tcp_build_pkt *b = (union tcp_build_pkt *)tcp; + const int recv_payload_len = len - net_set_ack_options(b) - IP_HDR_SIZE - ETHER_HDR_SIZE; + static int next_seq; + const int bottom_payload_len = 10; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -119,13 +125,31 @@ static int sb_ack_handler(struct udevice *dev, void *packet, tcp_send->tcp_dst = tcp->tcp_src; data = (void *)tcp_send + IP_TCP_HDR_SIZE; - if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1) { + if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1 && recv_payload_len == 0) { + // ignore ACK for three-way handshaking + return 0; + } else if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1) { + // recv HTTP request message and reply top half data tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); - tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1); - payload_len = strlen(payload1); + tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + recv_payload_len); + + payload_len = strlen(payload1) - bottom_payload_len; memcpy(data, payload1, payload_len); tcp_send->tcp_flags = TCP_ACK; - } else if (ntohl(tcp->tcp_seq) == 2) { + + next_seq = ntohl(tcp_send->tcp_seq) + payload_len; + } else if (ntohl(tcp->tcp_ack) == next_seq) { + // reply bottom half data + const int top_payload_len = strlen(payload1) - bottom_payload_len; + + tcp_send->tcp_seq = htonl(next_seq); + tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + recv_payload_len); + + payload_len = bottom_payload_len; + memcpy(data, payload1 + top_payload_len, payload_len); + tcp_send->tcp_flags = TCP_ACK; + } else { + // close connection tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1); payload_len = 0; @@ -148,11 +172,9 @@ static int sb_ack_handler(struct udevice *dev, void *packet, pkt_len, IPPROTO_TCP); - if (ntohl(tcp->tcp_seq) == 1 || ntohl(tcp->tcp_seq) == 2) { - priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + IP_TCP_HDR_SIZE + payload_len; - ++priv->recv_packets; - } + priv->recv_packet_length[priv->recv_packets] = + ETHER_HDR_SIZE + IP_TCP_HDR_SIZE + payload_len; + ++priv->recv_packets; return 0; } |