Changes:
 * update to new tcp stack
 * fix zero values for ISS and IRS issue (see RFC 9293)

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevets...@iopsys.eu>
Reviewed-by: Simon Glass <s...@chromium.org>
---
 arch/sandbox/include/asm/eth.h |  4 +++
 test/cmd/wget.c                | 58 ++++++++++++++++------------------
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h
index f042a5f3b92..083a7371a3f 100644
--- a/arch/sandbox/include/asm/eth.h
+++ b/arch/sandbox/include/asm/eth.h
@@ -77,6 +77,8 @@ typedef int sandbox_eth_tx_hand_f(struct udevice *dev, void 
*pkt,
  * fake_host_hwaddr - MAC address of mocked machine
  * fake_host_ipaddr - IP address of mocked machine
  * disabled - Will not respond
+ * irs - tcp initial receive sequence
+ * iss - tcp initial send sequence
  * recv_packet_buffer - buffers of the packet returned as received
  * recv_packet_length - lengths of the packet returned as received
  * recv_packets - number of packets returned
@@ -87,6 +89,8 @@ struct eth_sandbox_priv {
        uchar fake_host_hwaddr[ARP_HLEN];
        struct in_addr fake_host_ipaddr;
        bool disabled;
+       u32 irs;
+       u32 iss;
        uchar * recv_packet_buffer[PKTBUFSRX];
        int recv_packet_length[PKTBUFSRX];
        int recv_packets;
diff --git a/test/cmd/wget.c b/test/cmd/wget.c
index 7570c065a10..d51650d5854 100644
--- a/test/cmd/wget.c
+++ b/test/cmd/wget.c
@@ -25,8 +25,7 @@
 
 #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);
+#define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2)
 
 static int sb_arp_handler(struct udevice *dev, void *packet,
                          unsigned int len)
@@ -64,12 +63,14 @@ static int sb_syn_handler(struct udevice *dev, void *packet,
        eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
        memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
        memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+       priv->irs = ntohl(tcp->tcp_seq);
+       priv->iss = ~priv->irs; /* just to differ from irs */
        eth_send->et_protlen = htons(PROT_IP);
        tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
        tcp_send->tcp_src = tcp->tcp_dst;
        tcp_send->tcp_dst = tcp->tcp_src;
-       tcp_send->tcp_seq = htonl(0);
-       tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
+       tcp_send->tcp_seq = htonl(priv->iss);
+       tcp_send->tcp_ack = htonl(priv->irs + 1);
        tcp_send->tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
        tcp_send->tcp_flags = TCP_SYN | TCP_ACK;
        tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE);
@@ -104,13 +105,11 @@ static int sb_ack_handler(struct udevice *dev, void 
*packet,
        void *data;
        int pkt_len;
        int payload_len = 0;
+       u32 tcp_seq, tcp_ack;
+       int tcp_data_len;
        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)
@@ -125,35 +124,32 @@ 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 && 
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) + 
recv_payload_len);
+       tcp_seq = ntohl(tcp->tcp_seq) - priv->irs;
+       tcp_ack = ntohl(tcp->tcp_ack) - priv->iss;
+       tcp_data_len = len - ETHER_HDR_SIZE - IP_HDR_SIZE - 
GET_TCP_HDR_LEN_IN_BYTES(tcp->tcp_hlen);
 
-               payload_len = strlen(payload1) - bottom_payload_len;
-               memcpy(data, payload1, payload_len);
-               tcp_send->tcp_flags = TCP_ACK;
+       if (tcp->tcp_flags & TCP_FIN)
+               tcp_data_len++;
 
-               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(ntohl(tcp->tcp_ack));
+       tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + tcp_data_len);
 
-               tcp_send->tcp_seq = htonl(next_seq);
-               tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 
recv_payload_len);
+       if (tcp_seq == 1 && tcp_ack == 1) {
+               if (tcp_data_len == 0) {
+                       /* no data, wait for GET request */
+                       return -1;
+               }
 
-               payload_len = bottom_payload_len;
-               memcpy(data, payload1 + top_payload_len, payload_len);
+               /* reply to GET request */
+               payload_len = strlen(payload1);
+               memcpy(data, payload1, 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);
+       } else if (tcp_ack == 1 + strlen(payload1)) {
                payload_len = 0;
                tcp_send->tcp_flags = TCP_ACK | TCP_FIN;
+       } else if (tcp_ack == 2 + strlen(payload1)) {
+               payload_len = 0;
+               tcp_send->tcp_flags = TCP_ACK;
        }
 
        tcp_send->tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
@@ -217,7 +213,7 @@ static int net_test_wget(struct unit_test_state *uts)
        env_set("ethrotate", "no");
        env_set("loadaddr", "0x20000");
        ut_assertok(run_command("wget ${loadaddr} 1.1.2.2:/index.html", 0));
-       ut_assert_nextline("HTTP/1.1 200 OK");
+       ut_assert_nextline_empty();
        ut_assert_nextline("Packets received 5, Transfer Successful");
        ut_assert_nextline("Bytes transferred = 32 (20 hex)");
 
-- 
2.45.2

Reply via email to