mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 04:36:13 +02:00
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>
This commit is contained in:
parent
4f64730f8d
commit
dbb6b5a010
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user