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