xref: /nrf52832-nimble/rt-thread/components/net/lwip-1.4.1/test/unit/tcp/test_tcp.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero #include "test_tcp.h"
2*10465441SEvalZero 
3*10465441SEvalZero #include "lwip/tcp_impl.h"
4*10465441SEvalZero #include "lwip/stats.h"
5*10465441SEvalZero #include "tcp_helper.h"
6*10465441SEvalZero 
7*10465441SEvalZero #ifdef _MSC_VER
8*10465441SEvalZero #pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */
9*10465441SEvalZero #endif
10*10465441SEvalZero 
11*10465441SEvalZero #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
12*10465441SEvalZero #error "This tests needs TCP- and MEMP-statistics enabled"
13*10465441SEvalZero #endif
14*10465441SEvalZero #if TCP_SND_BUF <= TCP_WND
15*10465441SEvalZero #error "This tests needs TCP_SND_BUF to be > TCP_WND"
16*10465441SEvalZero #endif
17*10465441SEvalZero 
18*10465441SEvalZero static u8_t test_tcp_timer;
19*10465441SEvalZero 
20*10465441SEvalZero /* our own version of tcp_tmr so we can reset fast/slow timer state */
21*10465441SEvalZero static void
test_tcp_tmr(void)22*10465441SEvalZero test_tcp_tmr(void)
23*10465441SEvalZero {
24*10465441SEvalZero   tcp_fasttmr();
25*10465441SEvalZero   if (++test_tcp_timer & 1) {
26*10465441SEvalZero     tcp_slowtmr();
27*10465441SEvalZero   }
28*10465441SEvalZero }
29*10465441SEvalZero 
30*10465441SEvalZero /* Setups/teardown functions */
31*10465441SEvalZero 
32*10465441SEvalZero static void
tcp_setup(void)33*10465441SEvalZero tcp_setup(void)
34*10465441SEvalZero {
35*10465441SEvalZero   /* reset iss to default (6510) */
36*10465441SEvalZero   tcp_ticks = 0;
37*10465441SEvalZero   tcp_ticks = 0 - (tcp_next_iss() - 6510);
38*10465441SEvalZero   tcp_next_iss();
39*10465441SEvalZero   tcp_ticks = 0;
40*10465441SEvalZero 
41*10465441SEvalZero   test_tcp_timer = 0;
42*10465441SEvalZero   tcp_remove_all();
43*10465441SEvalZero }
44*10465441SEvalZero 
45*10465441SEvalZero static void
tcp_teardown(void)46*10465441SEvalZero tcp_teardown(void)
47*10465441SEvalZero {
48*10465441SEvalZero   netif_list = NULL;
49*10465441SEvalZero   tcp_remove_all();
50*10465441SEvalZero }
51*10465441SEvalZero 
52*10465441SEvalZero 
53*10465441SEvalZero /* Test functions */
54*10465441SEvalZero 
55*10465441SEvalZero /** Call tcp_new() and tcp_abort() and test memp stats */
START_TEST(test_tcp_new_abort)56*10465441SEvalZero START_TEST(test_tcp_new_abort)
57*10465441SEvalZero {
58*10465441SEvalZero   struct tcp_pcb* pcb;
59*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
60*10465441SEvalZero 
61*10465441SEvalZero   fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
62*10465441SEvalZero 
63*10465441SEvalZero   pcb = tcp_new();
64*10465441SEvalZero   fail_unless(pcb != NULL);
65*10465441SEvalZero   if (pcb != NULL) {
66*10465441SEvalZero     fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
67*10465441SEvalZero     tcp_abort(pcb);
68*10465441SEvalZero     fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
69*10465441SEvalZero   }
70*10465441SEvalZero }
71*10465441SEvalZero END_TEST
72*10465441SEvalZero 
73*10465441SEvalZero /** Create an ESTABLISHED pcb and check if receive callback is called */
START_TEST(test_tcp_recv_inseq)74*10465441SEvalZero START_TEST(test_tcp_recv_inseq)
75*10465441SEvalZero {
76*10465441SEvalZero   struct test_tcp_counters counters;
77*10465441SEvalZero   struct tcp_pcb* pcb;
78*10465441SEvalZero   struct pbuf* p;
79*10465441SEvalZero   char data[] = {1, 2, 3, 4};
80*10465441SEvalZero   ip_addr_t remote_ip, local_ip;
81*10465441SEvalZero   u16_t data_len;
82*10465441SEvalZero   u16_t remote_port = 0x100, local_port = 0x101;
83*10465441SEvalZero   struct netif netif;
84*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
85*10465441SEvalZero 
86*10465441SEvalZero   /* initialize local vars */
87*10465441SEvalZero   memset(&netif, 0, sizeof(netif));
88*10465441SEvalZero   IP4_ADDR(&local_ip, 192, 168, 1, 1);
89*10465441SEvalZero   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
90*10465441SEvalZero   data_len = sizeof(data);
91*10465441SEvalZero   /* initialize counter struct */
92*10465441SEvalZero   memset(&counters, 0, sizeof(counters));
93*10465441SEvalZero   counters.expected_data_len = data_len;
94*10465441SEvalZero   counters.expected_data = data;
95*10465441SEvalZero 
96*10465441SEvalZero   /* create and initialize the pcb */
97*10465441SEvalZero   pcb = test_tcp_new_counters_pcb(&counters);
98*10465441SEvalZero   EXPECT_RET(pcb != NULL);
99*10465441SEvalZero   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
100*10465441SEvalZero 
101*10465441SEvalZero   /* create a segment */
102*10465441SEvalZero   p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
103*10465441SEvalZero   EXPECT(p != NULL);
104*10465441SEvalZero   if (p != NULL) {
105*10465441SEvalZero     /* pass the segment to tcp_input */
106*10465441SEvalZero     test_tcp_input(p, &netif);
107*10465441SEvalZero     /* check if counters are as expected */
108*10465441SEvalZero     EXPECT(counters.close_calls == 0);
109*10465441SEvalZero     EXPECT(counters.recv_calls == 1);
110*10465441SEvalZero     EXPECT(counters.recved_bytes == data_len);
111*10465441SEvalZero     EXPECT(counters.err_calls == 0);
112*10465441SEvalZero   }
113*10465441SEvalZero 
114*10465441SEvalZero   /* make sure the pcb is freed */
115*10465441SEvalZero   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
116*10465441SEvalZero   tcp_abort(pcb);
117*10465441SEvalZero   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
118*10465441SEvalZero }
119*10465441SEvalZero END_TEST
120*10465441SEvalZero 
121*10465441SEvalZero /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
122*10465441SEvalZero  * At the end, send more data. */
START_TEST(test_tcp_fast_retx_recover)123*10465441SEvalZero START_TEST(test_tcp_fast_retx_recover)
124*10465441SEvalZero {
125*10465441SEvalZero   struct netif netif;
126*10465441SEvalZero   struct test_tcp_txcounters txcounters;
127*10465441SEvalZero   struct test_tcp_counters counters;
128*10465441SEvalZero   struct tcp_pcb* pcb;
129*10465441SEvalZero   struct pbuf* p;
130*10465441SEvalZero   char data1[] = { 1,  2,  3,  4};
131*10465441SEvalZero   char data2[] = { 5,  6,  7,  8};
132*10465441SEvalZero   char data3[] = { 9, 10, 11, 12};
133*10465441SEvalZero   char data4[] = {13, 14, 15, 16};
134*10465441SEvalZero   char data5[] = {17, 18, 19, 20};
135*10465441SEvalZero   char data6[] = {21, 22, 23, 24};
136*10465441SEvalZero   ip_addr_t remote_ip, local_ip, netmask;
137*10465441SEvalZero   u16_t remote_port = 0x100, local_port = 0x101;
138*10465441SEvalZero   err_t err;
139*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
140*10465441SEvalZero 
141*10465441SEvalZero   /* initialize local vars */
142*10465441SEvalZero   IP4_ADDR(&local_ip,  192, 168,   1, 1);
143*10465441SEvalZero   IP4_ADDR(&remote_ip, 192, 168,   1, 2);
144*10465441SEvalZero   IP4_ADDR(&netmask,   255, 255, 255, 0);
145*10465441SEvalZero   test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
146*10465441SEvalZero   memset(&counters, 0, sizeof(counters));
147*10465441SEvalZero 
148*10465441SEvalZero   /* create and initialize the pcb */
149*10465441SEvalZero   pcb = test_tcp_new_counters_pcb(&counters);
150*10465441SEvalZero   EXPECT_RET(pcb != NULL);
151*10465441SEvalZero   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
152*10465441SEvalZero   pcb->mss = TCP_MSS;
153*10465441SEvalZero   /* disable initial congestion window (we don't send a SYN here...) */
154*10465441SEvalZero   pcb->cwnd = pcb->snd_wnd;
155*10465441SEvalZero 
156*10465441SEvalZero   /* send data1 */
157*10465441SEvalZero   err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
158*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
159*10465441SEvalZero   err = tcp_output(pcb);
160*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
161*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 1);
162*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
163*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
164*10465441SEvalZero  /* "recv" ACK for data1 */
165*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
166*10465441SEvalZero   EXPECT_RET(p != NULL);
167*10465441SEvalZero   test_tcp_input(p, &netif);
168*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 0);
169*10465441SEvalZero   EXPECT_RET(pcb->unacked == NULL);
170*10465441SEvalZero   /* send data2 */
171*10465441SEvalZero   err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
172*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
173*10465441SEvalZero   err = tcp_output(pcb);
174*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
175*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 1);
176*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
177*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
178*10465441SEvalZero   /* duplicate ACK for data1 (data2 is lost) */
179*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
180*10465441SEvalZero   EXPECT_RET(p != NULL);
181*10465441SEvalZero   test_tcp_input(p, &netif);
182*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 0);
183*10465441SEvalZero   EXPECT_RET(pcb->dupacks == 1);
184*10465441SEvalZero   /* send data3 */
185*10465441SEvalZero   err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
186*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
187*10465441SEvalZero   err = tcp_output(pcb);
188*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
189*10465441SEvalZero   /* nagle enabled, no tx calls */
190*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 0);
191*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_bytes == 0);
192*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
193*10465441SEvalZero   /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
194*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
195*10465441SEvalZero   EXPECT_RET(p != NULL);
196*10465441SEvalZero   test_tcp_input(p, &netif);
197*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 0);
198*10465441SEvalZero   EXPECT_RET(pcb->dupacks == 2);
199*10465441SEvalZero   /* queue data4, don't send it (unsent-oversize is != 0) */
200*10465441SEvalZero   err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
201*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
202*10465441SEvalZero   /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
203*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
204*10465441SEvalZero   EXPECT_RET(p != NULL);
205*10465441SEvalZero   test_tcp_input(p, &netif);
206*10465441SEvalZero   /*EXPECT_RET(txcounters.num_tx_calls == 1);*/
207*10465441SEvalZero   EXPECT_RET(pcb->dupacks == 3);
208*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
209*10465441SEvalZero   /* TODO: check expected data?*/
210*10465441SEvalZero 
211*10465441SEvalZero   /* send data5, not output yet */
212*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
213*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
214*10465441SEvalZero   /*err = tcp_output(pcb);
215*10465441SEvalZero   EXPECT_RET(err == ERR_OK);*/
216*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_calls == 0);
217*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_bytes == 0);
218*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
219*10465441SEvalZero   {
220*10465441SEvalZero     int i = 0;
221*10465441SEvalZero     do
222*10465441SEvalZero     {
223*10465441SEvalZero       err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
224*10465441SEvalZero       i++;
225*10465441SEvalZero     }while(err == ERR_OK);
226*10465441SEvalZero     EXPECT_RET(err != ERR_OK);
227*10465441SEvalZero   }
228*10465441SEvalZero   err = tcp_output(pcb);
229*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
230*10465441SEvalZero   /*EXPECT_RET(txcounters.num_tx_calls == 0);
231*10465441SEvalZero   EXPECT_RET(txcounters.num_tx_bytes == 0);*/
232*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
233*10465441SEvalZero 
234*10465441SEvalZero   /* send even more data */
235*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
236*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
237*10465441SEvalZero   err = tcp_output(pcb);
238*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
239*10465441SEvalZero   /* ...and even more data */
240*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
241*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
242*10465441SEvalZero   err = tcp_output(pcb);
243*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
244*10465441SEvalZero   /* ...and even more data */
245*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
246*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
247*10465441SEvalZero   err = tcp_output(pcb);
248*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
249*10465441SEvalZero   /* ...and even more data */
250*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
251*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
252*10465441SEvalZero   err = tcp_output(pcb);
253*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
254*10465441SEvalZero 
255*10465441SEvalZero   /* send ACKs for data2 and data3 */
256*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
257*10465441SEvalZero   EXPECT_RET(p != NULL);
258*10465441SEvalZero   test_tcp_input(p, &netif);
259*10465441SEvalZero   /*EXPECT_RET(txcounters.num_tx_calls == 0);*/
260*10465441SEvalZero 
261*10465441SEvalZero   /* ...and even more data */
262*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
263*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
264*10465441SEvalZero   err = tcp_output(pcb);
265*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
266*10465441SEvalZero   /* ...and even more data */
267*10465441SEvalZero   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
268*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
269*10465441SEvalZero   err = tcp_output(pcb);
270*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
271*10465441SEvalZero 
272*10465441SEvalZero #if 0
273*10465441SEvalZero   /* create expected segment */
274*10465441SEvalZero   p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
275*10465441SEvalZero   EXPECT_RET(p != NULL);
276*10465441SEvalZero   if (p != NULL) {
277*10465441SEvalZero     /* pass the segment to tcp_input */
278*10465441SEvalZero     test_tcp_input(p, &netif);
279*10465441SEvalZero     /* check if counters are as expected */
280*10465441SEvalZero     EXPECT_RET(counters.close_calls == 0);
281*10465441SEvalZero     EXPECT_RET(counters.recv_calls == 1);
282*10465441SEvalZero     EXPECT_RET(counters.recved_bytes == data_len);
283*10465441SEvalZero     EXPECT_RET(counters.err_calls == 0);
284*10465441SEvalZero   }
285*10465441SEvalZero #endif
286*10465441SEvalZero   /* make sure the pcb is freed */
287*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
288*10465441SEvalZero   tcp_abort(pcb);
289*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
290*10465441SEvalZero }
291*10465441SEvalZero END_TEST
292*10465441SEvalZero 
293*10465441SEvalZero static u8_t tx_data[TCP_WND*2];
294*10465441SEvalZero 
295*10465441SEvalZero static void
check_seqnos(struct tcp_seg * segs,int num_expected,u32_t * seqnos_expected)296*10465441SEvalZero check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
297*10465441SEvalZero {
298*10465441SEvalZero   struct tcp_seg *s = segs;
299*10465441SEvalZero   int i;
300*10465441SEvalZero   for (i = 0; i < num_expected; i++, s = s->next) {
301*10465441SEvalZero     EXPECT_RET(s != NULL);
302*10465441SEvalZero     EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i]));
303*10465441SEvalZero   }
304*10465441SEvalZero   EXPECT(s == NULL);
305*10465441SEvalZero }
306*10465441SEvalZero 
307*10465441SEvalZero /** Send data with sequence numbers that wrap around the u32_t range.
308*10465441SEvalZero  * Then, provoke fast retransmission by duplicate ACKs and check that all
309*10465441SEvalZero  * segment lists are still properly sorted. */
START_TEST(test_tcp_fast_rexmit_wraparound)310*10465441SEvalZero START_TEST(test_tcp_fast_rexmit_wraparound)
311*10465441SEvalZero {
312*10465441SEvalZero   struct netif netif;
313*10465441SEvalZero   struct test_tcp_txcounters txcounters;
314*10465441SEvalZero   struct test_tcp_counters counters;
315*10465441SEvalZero   struct tcp_pcb* pcb;
316*10465441SEvalZero   struct pbuf* p;
317*10465441SEvalZero   ip_addr_t remote_ip, local_ip, netmask;
318*10465441SEvalZero   u16_t remote_port = 0x100, local_port = 0x101;
319*10465441SEvalZero   err_t err;
320*10465441SEvalZero #define SEQNO1 (0xFFFFFF00 - TCP_MSS)
321*10465441SEvalZero #define ISS    6510
322*10465441SEvalZero   u16_t i, sent_total = 0;
323*10465441SEvalZero   u32_t seqnos[] = {
324*10465441SEvalZero     SEQNO1,
325*10465441SEvalZero     SEQNO1 + (1 * TCP_MSS),
326*10465441SEvalZero     SEQNO1 + (2 * TCP_MSS),
327*10465441SEvalZero     SEQNO1 + (3 * TCP_MSS),
328*10465441SEvalZero     SEQNO1 + (4 * TCP_MSS),
329*10465441SEvalZero     SEQNO1 + (5 * TCP_MSS)};
330*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
331*10465441SEvalZero 
332*10465441SEvalZero   for (i = 0; i < sizeof(tx_data); i++) {
333*10465441SEvalZero     tx_data[i] = (u8_t)i;
334*10465441SEvalZero   }
335*10465441SEvalZero 
336*10465441SEvalZero   /* initialize local vars */
337*10465441SEvalZero   IP4_ADDR(&local_ip,  192, 168,   1, 1);
338*10465441SEvalZero   IP4_ADDR(&remote_ip, 192, 168,   1, 2);
339*10465441SEvalZero   IP4_ADDR(&netmask,   255, 255, 255, 0);
340*10465441SEvalZero   test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
341*10465441SEvalZero   memset(&counters, 0, sizeof(counters));
342*10465441SEvalZero 
343*10465441SEvalZero   /* create and initialize the pcb */
344*10465441SEvalZero   tcp_ticks = SEQNO1 - ISS;
345*10465441SEvalZero   pcb = test_tcp_new_counters_pcb(&counters);
346*10465441SEvalZero   EXPECT_RET(pcb != NULL);
347*10465441SEvalZero   EXPECT(pcb->lastack == SEQNO1);
348*10465441SEvalZero   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
349*10465441SEvalZero   pcb->mss = TCP_MSS;
350*10465441SEvalZero   /* disable initial congestion window (we don't send a SYN here...) */
351*10465441SEvalZero   pcb->cwnd = 2*TCP_MSS;
352*10465441SEvalZero 
353*10465441SEvalZero   /* send 6 mss-sized segments */
354*10465441SEvalZero   for (i = 0; i < 6; i++) {
355*10465441SEvalZero     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
356*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
357*10465441SEvalZero     sent_total += TCP_MSS;
358*10465441SEvalZero   }
359*10465441SEvalZero   check_seqnos(pcb->unsent, 6, seqnos);
360*10465441SEvalZero   EXPECT(pcb->unacked == NULL);
361*10465441SEvalZero   err = tcp_output(pcb);
362*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 2);
363*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
364*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
365*10465441SEvalZero 
366*10465441SEvalZero   check_seqnos(pcb->unacked, 2, seqnos);
367*10465441SEvalZero   check_seqnos(pcb->unsent, 4, &seqnos[2]);
368*10465441SEvalZero 
369*10465441SEvalZero   /* ACK the first segment */
370*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
371*10465441SEvalZero   test_tcp_input(p, &netif);
372*10465441SEvalZero   /* ensure this didn't trigger a retransmission */
373*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 1);
374*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
375*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
376*10465441SEvalZero   check_seqnos(pcb->unacked, 2, &seqnos[1]);
377*10465441SEvalZero   check_seqnos(pcb->unsent, 3, &seqnos[3]);
378*10465441SEvalZero 
379*10465441SEvalZero   /* 3 dupacks */
380*10465441SEvalZero   EXPECT(pcb->dupacks == 0);
381*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
382*10465441SEvalZero   test_tcp_input(p, &netif);
383*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 0);
384*10465441SEvalZero   EXPECT(pcb->dupacks == 1);
385*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
386*10465441SEvalZero   test_tcp_input(p, &netif);
387*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 0);
388*10465441SEvalZero   EXPECT(pcb->dupacks == 2);
389*10465441SEvalZero   /* 3rd dupack -> fast rexmit */
390*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
391*10465441SEvalZero   test_tcp_input(p, &netif);
392*10465441SEvalZero   EXPECT(pcb->dupacks == 3);
393*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 4);
394*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
395*10465441SEvalZero   EXPECT(pcb->unsent == NULL);
396*10465441SEvalZero   check_seqnos(pcb->unacked, 5, &seqnos[1]);
397*10465441SEvalZero 
398*10465441SEvalZero   /* make sure the pcb is freed */
399*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
400*10465441SEvalZero   tcp_abort(pcb);
401*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
402*10465441SEvalZero }
403*10465441SEvalZero END_TEST
404*10465441SEvalZero 
405*10465441SEvalZero /** Send data with sequence numbers that wrap around the u32_t range.
406*10465441SEvalZero  * Then, provoke RTO retransmission and check that all
407*10465441SEvalZero  * segment lists are still properly sorted. */
START_TEST(test_tcp_rto_rexmit_wraparound)408*10465441SEvalZero START_TEST(test_tcp_rto_rexmit_wraparound)
409*10465441SEvalZero {
410*10465441SEvalZero   struct netif netif;
411*10465441SEvalZero   struct test_tcp_txcounters txcounters;
412*10465441SEvalZero   struct test_tcp_counters counters;
413*10465441SEvalZero   struct tcp_pcb* pcb;
414*10465441SEvalZero   ip_addr_t remote_ip, local_ip, netmask;
415*10465441SEvalZero   u16_t remote_port = 0x100, local_port = 0x101;
416*10465441SEvalZero   err_t err;
417*10465441SEvalZero #define SEQNO1 (0xFFFFFF00 - TCP_MSS)
418*10465441SEvalZero #define ISS    6510
419*10465441SEvalZero   u16_t i, sent_total = 0;
420*10465441SEvalZero   u32_t seqnos[] = {
421*10465441SEvalZero     SEQNO1,
422*10465441SEvalZero     SEQNO1 + (1 * TCP_MSS),
423*10465441SEvalZero     SEQNO1 + (2 * TCP_MSS),
424*10465441SEvalZero     SEQNO1 + (3 * TCP_MSS),
425*10465441SEvalZero     SEQNO1 + (4 * TCP_MSS),
426*10465441SEvalZero     SEQNO1 + (5 * TCP_MSS)};
427*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
428*10465441SEvalZero 
429*10465441SEvalZero   for (i = 0; i < sizeof(tx_data); i++) {
430*10465441SEvalZero     tx_data[i] = (u8_t)i;
431*10465441SEvalZero   }
432*10465441SEvalZero 
433*10465441SEvalZero   /* initialize local vars */
434*10465441SEvalZero   IP4_ADDR(&local_ip,  192, 168,   1, 1);
435*10465441SEvalZero   IP4_ADDR(&remote_ip, 192, 168,   1, 2);
436*10465441SEvalZero   IP4_ADDR(&netmask,   255, 255, 255, 0);
437*10465441SEvalZero   test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
438*10465441SEvalZero   memset(&counters, 0, sizeof(counters));
439*10465441SEvalZero 
440*10465441SEvalZero   /* create and initialize the pcb */
441*10465441SEvalZero   tcp_ticks = 0;
442*10465441SEvalZero   tcp_ticks = 0 - tcp_next_iss();
443*10465441SEvalZero   tcp_ticks = SEQNO1 - tcp_next_iss();
444*10465441SEvalZero   pcb = test_tcp_new_counters_pcb(&counters);
445*10465441SEvalZero   EXPECT_RET(pcb != NULL);
446*10465441SEvalZero   EXPECT(pcb->lastack == SEQNO1);
447*10465441SEvalZero   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
448*10465441SEvalZero   pcb->mss = TCP_MSS;
449*10465441SEvalZero   /* disable initial congestion window (we don't send a SYN here...) */
450*10465441SEvalZero   pcb->cwnd = 2*TCP_MSS;
451*10465441SEvalZero 
452*10465441SEvalZero   /* send 6 mss-sized segments */
453*10465441SEvalZero   for (i = 0; i < 6; i++) {
454*10465441SEvalZero     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
455*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
456*10465441SEvalZero     sent_total += TCP_MSS;
457*10465441SEvalZero   }
458*10465441SEvalZero   check_seqnos(pcb->unsent, 6, seqnos);
459*10465441SEvalZero   EXPECT(pcb->unacked == NULL);
460*10465441SEvalZero   err = tcp_output(pcb);
461*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 2);
462*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
463*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
464*10465441SEvalZero 
465*10465441SEvalZero   check_seqnos(pcb->unacked, 2, seqnos);
466*10465441SEvalZero   check_seqnos(pcb->unsent, 4, &seqnos[2]);
467*10465441SEvalZero 
468*10465441SEvalZero   /* call the tcp timer some times */
469*10465441SEvalZero   for (i = 0; i < 10; i++) {
470*10465441SEvalZero     test_tcp_tmr();
471*10465441SEvalZero     EXPECT(txcounters.num_tx_calls == 0);
472*10465441SEvalZero   }
473*10465441SEvalZero   /* 11th call to tcp_tmr: RTO rexmit fires */
474*10465441SEvalZero   test_tcp_tmr();
475*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 1);
476*10465441SEvalZero   check_seqnos(pcb->unacked, 1, seqnos);
477*10465441SEvalZero   check_seqnos(pcb->unsent, 5, &seqnos[1]);
478*10465441SEvalZero 
479*10465441SEvalZero   /* fake greater cwnd */
480*10465441SEvalZero   pcb->cwnd = pcb->snd_wnd;
481*10465441SEvalZero   /* send more data */
482*10465441SEvalZero   err = tcp_output(pcb);
483*10465441SEvalZero   EXPECT(err == ERR_OK);
484*10465441SEvalZero   /* check queues are sorted */
485*10465441SEvalZero   EXPECT(pcb->unsent == NULL);
486*10465441SEvalZero   check_seqnos(pcb->unacked, 6, seqnos);
487*10465441SEvalZero 
488*10465441SEvalZero   /* make sure the pcb is freed */
489*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
490*10465441SEvalZero   tcp_abort(pcb);
491*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
492*10465441SEvalZero }
493*10465441SEvalZero END_TEST
494*10465441SEvalZero 
495*10465441SEvalZero /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
496*10465441SEvalZero  * At the end, send more data. */
test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)497*10465441SEvalZero static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
498*10465441SEvalZero {
499*10465441SEvalZero   struct netif netif;
500*10465441SEvalZero   struct test_tcp_txcounters txcounters;
501*10465441SEvalZero   struct test_tcp_counters counters;
502*10465441SEvalZero   struct tcp_pcb* pcb;
503*10465441SEvalZero   struct pbuf *p;
504*10465441SEvalZero   ip_addr_t remote_ip, local_ip, netmask;
505*10465441SEvalZero   u16_t remote_port = 0x100, local_port = 0x101;
506*10465441SEvalZero   err_t err;
507*10465441SEvalZero   u16_t sent_total, i;
508*10465441SEvalZero   u8_t expected = 0xFE;
509*10465441SEvalZero 
510*10465441SEvalZero   for (i = 0; i < sizeof(tx_data); i++) {
511*10465441SEvalZero     u8_t d = (u8_t)i;
512*10465441SEvalZero     if (d == 0xFE) {
513*10465441SEvalZero       d = 0xF0;
514*10465441SEvalZero     }
515*10465441SEvalZero     tx_data[i] = d;
516*10465441SEvalZero   }
517*10465441SEvalZero   if (zero_window_probe_from_unsent) {
518*10465441SEvalZero     tx_data[TCP_WND] = expected;
519*10465441SEvalZero   } else {
520*10465441SEvalZero     tx_data[0] = expected;
521*10465441SEvalZero   }
522*10465441SEvalZero 
523*10465441SEvalZero   /* initialize local vars */
524*10465441SEvalZero   IP4_ADDR(&local_ip,  192, 168,   1, 1);
525*10465441SEvalZero   IP4_ADDR(&remote_ip, 192, 168,   1, 2);
526*10465441SEvalZero   IP4_ADDR(&netmask,   255, 255, 255, 0);
527*10465441SEvalZero   test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask);
528*10465441SEvalZero   memset(&counters, 0, sizeof(counters));
529*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
530*10465441SEvalZero 
531*10465441SEvalZero   /* create and initialize the pcb */
532*10465441SEvalZero   pcb = test_tcp_new_counters_pcb(&counters);
533*10465441SEvalZero   EXPECT_RET(pcb != NULL);
534*10465441SEvalZero   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
535*10465441SEvalZero   pcb->mss = TCP_MSS;
536*10465441SEvalZero   /* disable initial congestion window (we don't send a SYN here...) */
537*10465441SEvalZero   pcb->cwnd = pcb->snd_wnd;
538*10465441SEvalZero 
539*10465441SEvalZero   /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */
540*10465441SEvalZero   sent_total = 0;
541*10465441SEvalZero   if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) {
542*10465441SEvalZero     u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS;
543*10465441SEvalZero     err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
544*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
545*10465441SEvalZero     err = tcp_output(pcb);
546*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
547*10465441SEvalZero     EXPECT(txcounters.num_tx_calls == 1);
548*10465441SEvalZero     EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U);
549*10465441SEvalZero     memset(&txcounters, 0, sizeof(txcounters));
550*10465441SEvalZero     sent_total += initial_data_len;
551*10465441SEvalZero   }
552*10465441SEvalZero   for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) {
553*10465441SEvalZero     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
554*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
555*10465441SEvalZero     err = tcp_output(pcb);
556*10465441SEvalZero     EXPECT_RET(err == ERR_OK);
557*10465441SEvalZero     EXPECT(txcounters.num_tx_calls == 1);
558*10465441SEvalZero     EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
559*10465441SEvalZero     memset(&txcounters, 0, sizeof(txcounters));
560*10465441SEvalZero   }
561*10465441SEvalZero   EXPECT(sent_total == (TCP_WND - TCP_MSS));
562*10465441SEvalZero 
563*10465441SEvalZero   /* now ACK the packet before the first */
564*10465441SEvalZero   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
565*10465441SEvalZero   test_tcp_input(p, &netif);
566*10465441SEvalZero   /* ensure this didn't trigger a retransmission */
567*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 0);
568*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == 0);
569*10465441SEvalZero 
570*10465441SEvalZero   EXPECT(pcb->persist_backoff == 0);
571*10465441SEvalZero   /* send the last packet, now a complete window has been sent */
572*10465441SEvalZero   err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
573*10465441SEvalZero   sent_total += TCP_MSS;
574*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
575*10465441SEvalZero   err = tcp_output(pcb);
576*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
577*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 1);
578*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
579*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
580*10465441SEvalZero   EXPECT(pcb->persist_backoff == 0);
581*10465441SEvalZero 
582*10465441SEvalZero   if (zero_window_probe_from_unsent) {
583*10465441SEvalZero     /* ACK all data but close the TX window */
584*10465441SEvalZero     p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0);
585*10465441SEvalZero     test_tcp_input(p, &netif);
586*10465441SEvalZero     /* ensure this didn't trigger any transmission */
587*10465441SEvalZero     EXPECT(txcounters.num_tx_calls == 0);
588*10465441SEvalZero     EXPECT(txcounters.num_tx_bytes == 0);
589*10465441SEvalZero     EXPECT(pcb->persist_backoff == 1);
590*10465441SEvalZero   }
591*10465441SEvalZero 
592*10465441SEvalZero   /* send one byte more (out of window) -> persist timer starts */
593*10465441SEvalZero   err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
594*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
595*10465441SEvalZero   err = tcp_output(pcb);
596*10465441SEvalZero   EXPECT_RET(err == ERR_OK);
597*10465441SEvalZero   EXPECT(txcounters.num_tx_calls == 0);
598*10465441SEvalZero   EXPECT(txcounters.num_tx_bytes == 0);
599*10465441SEvalZero   memset(&txcounters, 0, sizeof(txcounters));
600*10465441SEvalZero   if (!zero_window_probe_from_unsent) {
601*10465441SEvalZero     /* no persist timer unless a zero window announcement has been received */
602*10465441SEvalZero     EXPECT(pcb->persist_backoff == 0);
603*10465441SEvalZero   } else {
604*10465441SEvalZero     EXPECT(pcb->persist_backoff == 1);
605*10465441SEvalZero 
606*10465441SEvalZero     /* call tcp_timer some more times to let persist timer count up */
607*10465441SEvalZero     for (i = 0; i < 4; i++) {
608*10465441SEvalZero       test_tcp_tmr();
609*10465441SEvalZero       EXPECT(txcounters.num_tx_calls == 0);
610*10465441SEvalZero       EXPECT(txcounters.num_tx_bytes == 0);
611*10465441SEvalZero     }
612*10465441SEvalZero 
613*10465441SEvalZero     /* this should trigger the zero-window-probe */
614*10465441SEvalZero     txcounters.copy_tx_packets = 1;
615*10465441SEvalZero     test_tcp_tmr();
616*10465441SEvalZero     txcounters.copy_tx_packets = 0;
617*10465441SEvalZero     EXPECT(txcounters.num_tx_calls == 1);
618*10465441SEvalZero     EXPECT(txcounters.num_tx_bytes == 1 + 40U);
619*10465441SEvalZero     EXPECT(txcounters.tx_packets != NULL);
620*10465441SEvalZero     if (txcounters.tx_packets != NULL) {
621*10465441SEvalZero       u8_t sent;
622*10465441SEvalZero       u16_t ret;
623*10465441SEvalZero       ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U);
624*10465441SEvalZero       EXPECT(ret == 1);
625*10465441SEvalZero       EXPECT(sent == expected);
626*10465441SEvalZero     }
627*10465441SEvalZero     if (txcounters.tx_packets != NULL) {
628*10465441SEvalZero       pbuf_free(txcounters.tx_packets);
629*10465441SEvalZero       txcounters.tx_packets = NULL;
630*10465441SEvalZero     }
631*10465441SEvalZero   }
632*10465441SEvalZero 
633*10465441SEvalZero   /* make sure the pcb is freed */
634*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
635*10465441SEvalZero   tcp_abort(pcb);
636*10465441SEvalZero   EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
637*10465441SEvalZero }
638*10465441SEvalZero 
START_TEST(test_tcp_tx_full_window_lost_from_unsent)639*10465441SEvalZero START_TEST(test_tcp_tx_full_window_lost_from_unsent)
640*10465441SEvalZero {
641*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
642*10465441SEvalZero   test_tcp_tx_full_window_lost(1);
643*10465441SEvalZero }
644*10465441SEvalZero END_TEST
645*10465441SEvalZero 
START_TEST(test_tcp_tx_full_window_lost_from_unacked)646*10465441SEvalZero START_TEST(test_tcp_tx_full_window_lost_from_unacked)
647*10465441SEvalZero {
648*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
649*10465441SEvalZero   test_tcp_tx_full_window_lost(0);
650*10465441SEvalZero }
651*10465441SEvalZero END_TEST
652*10465441SEvalZero 
653*10465441SEvalZero /** Create the suite including all tests for this module */
654*10465441SEvalZero Suite *
tcp_suite(void)655*10465441SEvalZero tcp_suite(void)
656*10465441SEvalZero {
657*10465441SEvalZero   TFun tests[] = {
658*10465441SEvalZero     test_tcp_new_abort,
659*10465441SEvalZero     test_tcp_recv_inseq,
660*10465441SEvalZero     test_tcp_fast_retx_recover,
661*10465441SEvalZero     test_tcp_fast_rexmit_wraparound,
662*10465441SEvalZero     test_tcp_rto_rexmit_wraparound,
663*10465441SEvalZero     test_tcp_tx_full_window_lost_from_unacked,
664*10465441SEvalZero     test_tcp_tx_full_window_lost_from_unsent
665*10465441SEvalZero   };
666*10465441SEvalZero   return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown);
667*10465441SEvalZero }
668