source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/lwip-2.1.2/test/unit/tcp/test_tcp.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 53.0 KB
Line 
1#include "test_tcp.h"
2
3#include "lwip/priv/tcp_priv.h"
4#include "lwip/stats.h"
5#include "tcp_helper.h"
6#include "lwip/inet_chksum.h"
7
8#ifdef _MSC_VER
9#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */
10#endif
11
12#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
13#error "This tests needs TCP- and MEMP-statistics enabled"
14#endif
15#if TCP_SND_BUF <= TCP_WND
16#error "This tests needs TCP_SND_BUF to be > TCP_WND"
17#endif
18
19/* used with check_seqnos() */
20#define SEQNO1 (0xFFFFFF00 - TCP_MSS)
21#define ISS 6510
22static u32_t seqnos[] = {
23 SEQNO1,
24 SEQNO1 + (1 * TCP_MSS),
25 SEQNO1 + (2 * TCP_MSS),
26 SEQNO1 + (3 * TCP_MSS),
27 SEQNO1 + (4 * TCP_MSS),
28 SEQNO1 + (5 * TCP_MSS) };
29
30static u8_t test_tcp_timer;
31
32/* our own version of tcp_tmr so we can reset fast/slow timer state */
33static void
34test_tcp_tmr(void)
35{
36 tcp_fasttmr();
37 if (++test_tcp_timer & 1) {
38 tcp_slowtmr();
39 }
40}
41
42/* Setups/teardown functions */
43static struct netif *old_netif_list;
44static struct netif *old_netif_default;
45
46static void
47tcp_setup(void)
48{
49 struct tcp_pcb dummy_pcb; /* we need this for tcp_next_iss() only */
50
51 old_netif_list = netif_list;
52 old_netif_default = netif_default;
53 netif_list = NULL;
54 netif_default = NULL;
55 /* reset iss to default (6510) */
56 tcp_ticks = 0;
57 tcp_ticks = 0 - (tcp_next_iss(&dummy_pcb) - 6510);
58 tcp_next_iss(&dummy_pcb);
59 tcp_ticks = 0;
60
61 test_tcp_timer = 0;
62 tcp_remove_all();
63 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
64}
65
66static void
67tcp_teardown(void)
68{
69 netif_list = NULL;
70 netif_default = NULL;
71 tcp_remove_all();
72 /* restore netif_list for next tests (e.g. loopif) */
73 netif_list = old_netif_list;
74 netif_default = old_netif_default;
75 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
76}
77
78
79/* Test functions */
80
81/** Call tcp_new() and tcp_abort() and test memp stats */
82START_TEST(test_tcp_new_abort)
83{
84 struct tcp_pcb* pcb;
85 LWIP_UNUSED_ARG(_i);
86
87 fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
88
89 pcb = tcp_new();
90 fail_unless(pcb != NULL);
91 if (pcb != NULL) {
92 fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
93 tcp_abort(pcb);
94 fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
95 }
96}
97END_TEST
98
99/** Call tcp_new() and tcp_abort() and test memp stats */
100START_TEST(test_tcp_listen_passive_open)
101{
102 struct tcp_pcb *pcb, *pcbl;
103 struct tcp_pcb_listen *lpcb;
104 struct netif netif;
105 struct test_tcp_txcounters txcounters;
106 struct test_tcp_counters counters;
107 struct pbuf *p;
108 ip_addr_t src_addr;
109 err_t err;
110 LWIP_UNUSED_ARG(_i);
111
112 fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
113
114 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
115 /* initialize counter struct */
116 memset(&counters, 0, sizeof(counters));
117
118 pcb = tcp_new();
119 EXPECT_RET(pcb != NULL);
120 err = tcp_bind(pcb, &netif.ip_addr, 1234);
121 EXPECT(err == ERR_OK);
122 pcbl = tcp_listen(pcb);
123 EXPECT_RET(pcbl != NULL);
124 EXPECT_RET(pcbl != pcb);
125 lpcb = (struct tcp_pcb_listen *)pcbl;
126
127 ip_addr_set_ip4_u32_val(src_addr, lwip_htonl(lwip_ntohl(ip_addr_get_ip4_u32(&lpcb->local_ip)) + 1));
128
129 /* check correct syn packet */
130 p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
131 lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
132 EXPECT(p != NULL);
133 if (p != NULL) {
134 /* pass the segment to tcp_input */
135 test_tcp_input(p, &netif);
136 /* check if counters are as expected */
137 EXPECT(txcounters.num_tx_calls == 1);
138 }
139
140 /* check syn packet with short length */
141 p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
142 lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
143 EXPECT(p != NULL);
144 EXPECT(p->next == NULL);
145 if ((p != NULL) && (p->next == NULL)) {
146 p->len -= 2;
147 p->tot_len -= 2;
148 /* pass the segment to tcp_input */
149 test_tcp_input(p, &netif);
150 /* check if counters are as expected */
151 EXPECT(txcounters.num_tx_calls == 1);
152 }
153
154 tcp_close(pcbl);
155}
156END_TEST
157
158/** Create an ESTABLISHED pcb and check if receive callback is called */
159START_TEST(test_tcp_recv_inseq)
160{
161 struct test_tcp_counters counters;
162 struct tcp_pcb* pcb;
163 struct pbuf* p;
164 char data[] = {1, 2, 3, 4};
165 u16_t data_len;
166 struct netif netif;
167 struct test_tcp_txcounters txcounters;
168 LWIP_UNUSED_ARG(_i);
169
170 /* initialize local vars */
171 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
172 data_len = sizeof(data);
173 /* initialize counter struct */
174 memset(&counters, 0, sizeof(counters));
175 counters.expected_data_len = data_len;
176 counters.expected_data = data;
177
178 /* create and initialize the pcb */
179 pcb = test_tcp_new_counters_pcb(&counters);
180 EXPECT_RET(pcb != NULL);
181 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
182
183 /* create a segment */
184 p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
185 EXPECT(p != NULL);
186 if (p != NULL) {
187 /* pass the segment to tcp_input */
188 test_tcp_input(p, &netif);
189 /* check if counters are as expected */
190 EXPECT(counters.close_calls == 0);
191 EXPECT(counters.recv_calls == 1);
192 EXPECT(counters.recved_bytes == data_len);
193 EXPECT(counters.err_calls == 0);
194 }
195
196 /* make sure the pcb is freed */
197 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
198 tcp_abort(pcb);
199 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
200}
201END_TEST
202
203/** Create an ESTABLISHED pcb and check if receive callback is called if a segment
204 * overlapping rcv_nxt is received */
205START_TEST(test_tcp_recv_inseq_trim)
206{
207 struct test_tcp_counters counters;
208 struct tcp_pcb* pcb;
209 struct pbuf* p;
210 char data[PBUF_POOL_BUFSIZE*2];
211 u16_t data_len;
212 struct netif netif;
213 struct test_tcp_txcounters txcounters;
214 const u32_t new_data_len = 40;
215 LWIP_UNUSED_ARG(_i);
216
217 /* initialize local vars */
218 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
219 data_len = sizeof(data);
220 memset(data, 0, sizeof(data));
221 /* initialize counter struct */
222 memset(&counters, 0, sizeof(counters));
223 counters.expected_data_len = data_len;
224 counters.expected_data = data;
225
226 /* create and initialize the pcb */
227 pcb = test_tcp_new_counters_pcb(&counters);
228 EXPECT_RET(pcb != NULL);
229 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
230
231 /* create a segment (with an overlapping/old seqno so that the new data begins in the 2nd pbuf) */
232 p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, (u32_t)(0-(data_len-new_data_len)), 0, 0);
233 EXPECT(p != NULL);
234 if (p != NULL) {
235 EXPECT(p->next != NULL);
236 if (p->next != NULL) {
237 EXPECT(p->next->next != NULL);
238 }
239 }
240 if ((p != NULL) && (p->next != NULL) && (p->next->next != NULL)) {
241 /* pass the segment to tcp_input */
242 test_tcp_input(p, &netif);
243 /* check if counters are as expected */
244 EXPECT(counters.close_calls == 0);
245 EXPECT(counters.recv_calls == 1);
246 EXPECT(counters.recved_bytes == new_data_len);
247 EXPECT(counters.err_calls == 0);
248 }
249
250 /* make sure the pcb is freed */
251 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
252 tcp_abort(pcb);
253 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
254}
255END_TEST
256
257static err_t test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);
258
259static err_t
260test_tcp_recv_expectclose(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
261{
262 EXPECT_RETX(pcb != NULL, ERR_OK);
263 EXPECT_RETX(err == ERR_OK, ERR_OK);
264 LWIP_UNUSED_ARG(arg);
265
266 if (p != NULL) {
267 fail();
268 } else {
269 /* correct: FIN received; close our end, too */
270 err_t err2 = tcp_close(pcb);
271 fail_unless(err2 == ERR_OK);
272 /* set back to some other rx function, just to not get here again */
273 tcp_recv(pcb, test_tcp_recv_expect1byte);
274 }
275 return ERR_OK;
276}
277
278static err_t
279test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
280{
281 EXPECT_RETX(pcb != NULL, ERR_OK);
282 EXPECT_RETX(err == ERR_OK, ERR_OK);
283 LWIP_UNUSED_ARG(arg);
284
285 if (p != NULL) {
286 if ((p->len == 1) && (p->tot_len == 1)) {
287 tcp_recv(pcb, test_tcp_recv_expectclose);
288 } else {
289 fail();
290 }
291 pbuf_free(p);
292 } else {
293 fail();
294 }
295 return ERR_OK;
296}
297
298START_TEST(test_tcp_passive_close)
299{
300 struct test_tcp_counters counters;
301 struct tcp_pcb* pcb;
302 struct pbuf* p;
303 char data = 0x0f;
304 struct netif netif;
305 struct test_tcp_txcounters txcounters;
306 LWIP_UNUSED_ARG(_i);
307
308 /* initialize local vars */
309 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
310
311 /* initialize counter struct */
312 memset(&counters, 0, sizeof(counters));
313 counters.expected_data_len = 1;
314 counters.expected_data = &data;
315
316 /* create and initialize the pcb */
317 pcb = test_tcp_new_counters_pcb(&counters);
318 EXPECT_RET(pcb != NULL);
319 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
320
321 /* create a segment without data */
322 p = tcp_create_rx_segment(pcb, &data, 1, 0, 0, TCP_FIN);
323 EXPECT(p != NULL);
324 if (p != NULL) {
325 tcp_recv(pcb, test_tcp_recv_expect1byte);
326 /* pass the segment to tcp_input */
327 test_tcp_input(p, &netif);
328 }
329 /* don't free the pcb here (part of the test!) */
330}
331END_TEST
332
333START_TEST(test_tcp_active_abort)
334{
335 struct test_tcp_counters counters;
336 struct tcp_pcb* pcb;
337 char data = 0x0f;
338 struct netif netif;
339 struct test_tcp_txcounters txcounters;
340 LWIP_UNUSED_ARG(_i);
341
342 memset(&txcounters, 0, sizeof(txcounters));
343
344 /* initialize local vars */
345 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
346
347 /* initialize counter struct */
348 memset(&counters, 0, sizeof(counters));
349 counters.expected_data_len = 1;
350 counters.expected_data = &data;
351
352 /* create and initialize the pcb */
353 pcb = test_tcp_new_counters_pcb(&counters);
354 EXPECT_RET(pcb != NULL);
355 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
356
357 /* abort the pcb */
358 EXPECT_RET(txcounters.num_tx_calls == 0);
359 txcounters.copy_tx_packets = 1;
360 tcp_abort(pcb);
361 txcounters.copy_tx_packets = 0;
362 EXPECT(txcounters.num_tx_calls == 1);
363 EXPECT(txcounters.num_tx_bytes == 40U);
364 EXPECT(txcounters.tx_packets != NULL);
365 if (txcounters.tx_packets != NULL) {
366 u16_t ret;
367 struct tcp_hdr tcphdr;
368 ret = pbuf_copy_partial(txcounters.tx_packets, &tcphdr, 20, 20);
369 EXPECT(ret == 20);
370 EXPECT(tcphdr.dest == PP_HTONS(TEST_REMOTE_PORT));
371 EXPECT(tcphdr.src == PP_HTONS(TEST_LOCAL_PORT));
372 pbuf_free(txcounters.tx_packets);
373 txcounters.tx_packets = NULL;
374 }
375
376 /* don't free the pcb here (part of the test!) */
377}
378END_TEST
379
380/** Check that we handle malformed tcp headers, and discard the pbuf(s) */
381START_TEST(test_tcp_malformed_header)
382{
383 struct test_tcp_counters counters;
384 struct tcp_pcb* pcb;
385 struct pbuf* p;
386 char data[] = {1, 2, 3, 4};
387 u16_t data_len, chksum;
388 struct netif netif;
389 struct test_tcp_txcounters txcounters;
390 struct tcp_hdr *hdr;
391 LWIP_UNUSED_ARG(_i);
392
393 /* initialize local vars */
394 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
395 data_len = sizeof(data);
396 /* initialize counter struct */
397 memset(&counters, 0, sizeof(counters));
398 counters.expected_data_len = data_len;
399 counters.expected_data = data;
400
401 /* create and initialize the pcb */
402 pcb = test_tcp_new_counters_pcb(&counters);
403 EXPECT_RET(pcb != NULL);
404 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
405
406 /* create a segment */
407 p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
408
409 pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
410
411 hdr = (struct tcp_hdr *)p->payload;
412 TCPH_HDRLEN_FLAGS_SET(hdr, 15, 0x3d1);
413
414 hdr->chksum = 0;
415
416 chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
417 &test_remote_ip, &test_local_ip);
418
419 hdr->chksum = chksum;
420
421 pbuf_header(p, sizeof(struct ip_hdr));
422
423 EXPECT(p != NULL);
424 EXPECT(p->next == NULL);
425 if (p != NULL) {
426 /* pass the segment to tcp_input */
427 test_tcp_input(p, &netif);
428 /* check if counters are as expected */
429 EXPECT(counters.close_calls == 0);
430 EXPECT(counters.recv_calls == 0);
431 EXPECT(counters.recved_bytes == 0);
432 EXPECT(counters.err_calls == 0);
433 }
434
435 /* make sure the pcb is freed */
436 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
437 tcp_abort(pcb);
438 EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
439}
440END_TEST
441
442
443/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
444 * At the end, send more data. */
445START_TEST(test_tcp_fast_retx_recover)
446{
447 struct netif netif;
448 struct test_tcp_txcounters txcounters;
449 struct test_tcp_counters counters;
450 struct tcp_pcb* pcb;
451 struct pbuf* p;
452 char data1[] = { 1, 2, 3, 4};
453 char data2[] = { 5, 6, 7, 8};
454 char data3[] = { 9, 10, 11, 12};
455 char data4[] = {13, 14, 15, 16};
456 char data5[] = {17, 18, 19, 20};
457 char data6[TCP_MSS] = {21, 22, 23, 24};
458 err_t err;
459 LWIP_UNUSED_ARG(_i);
460
461 /* initialize local vars */
462 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
463 memset(&counters, 0, sizeof(counters));
464
465 /* create and initialize the pcb */
466 pcb = test_tcp_new_counters_pcb(&counters);
467 EXPECT_RET(pcb != NULL);
468 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
469 pcb->mss = TCP_MSS;
470 /* disable initial congestion window (we don't send a SYN here...) */
471 pcb->cwnd = pcb->snd_wnd;
472
473 /* send data1 */
474 err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
475 EXPECT_RET(err == ERR_OK);
476 err = tcp_output(pcb);
477 EXPECT_RET(err == ERR_OK);
478 EXPECT_RET(txcounters.num_tx_calls == 1);
479 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
480 memset(&txcounters, 0, sizeof(txcounters));
481 /* "recv" ACK for data1 */
482 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
483 EXPECT_RET(p != NULL);
484 test_tcp_input(p, &netif);
485 EXPECT_RET(txcounters.num_tx_calls == 0);
486 EXPECT_RET(pcb->unacked == NULL);
487 /* send data2 */
488 err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
489 EXPECT_RET(err == ERR_OK);
490 err = tcp_output(pcb);
491 EXPECT_RET(err == ERR_OK);
492 EXPECT_RET(txcounters.num_tx_calls == 1);
493 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
494 memset(&txcounters, 0, sizeof(txcounters));
495 /* duplicate ACK for data1 (data2 is lost) */
496 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
497 EXPECT_RET(p != NULL);
498 test_tcp_input(p, &netif);
499 EXPECT_RET(txcounters.num_tx_calls == 0);
500 EXPECT_RET(pcb->dupacks == 1);
501 /* send data3 */
502 err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
503 EXPECT_RET(err == ERR_OK);
504 err = tcp_output(pcb);
505 EXPECT_RET(err == ERR_OK);
506 /* nagle enabled, no tx calls */
507 EXPECT_RET(txcounters.num_tx_calls == 0);
508 EXPECT_RET(txcounters.num_tx_bytes == 0);
509 memset(&txcounters, 0, sizeof(txcounters));
510 /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
511 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
512 EXPECT_RET(p != NULL);
513 test_tcp_input(p, &netif);
514 EXPECT_RET(txcounters.num_tx_calls == 0);
515 EXPECT_RET(pcb->dupacks == 2);
516 /* queue data4, don't send it (unsent-oversize is != 0) */
517 err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
518 EXPECT_RET(err == ERR_OK);
519 /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
520 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
521 EXPECT_RET(p != NULL);
522 test_tcp_input(p, &netif);
523 /*EXPECT_RET(txcounters.num_tx_calls == 1);*/
524 EXPECT_RET(pcb->dupacks == 3);
525 memset(&txcounters, 0, sizeof(txcounters));
526 /* @todo: check expected data?*/
527
528 /* send data5, not output yet */
529 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
530 EXPECT_RET(err == ERR_OK);
531 /*err = tcp_output(pcb);
532 EXPECT_RET(err == ERR_OK);*/
533 EXPECT_RET(txcounters.num_tx_calls == 0);
534 EXPECT_RET(txcounters.num_tx_bytes == 0);
535 memset(&txcounters, 0, sizeof(txcounters));
536 {
537 int i = 0;
538 do
539 {
540 err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
541 i++;
542 }while(err == ERR_OK);
543 EXPECT_RET(err != ERR_OK);
544 }
545 err = tcp_output(pcb);
546 EXPECT_RET(err == ERR_OK);
547 /*EXPECT_RET(txcounters.num_tx_calls == 0);
548 EXPECT_RET(txcounters.num_tx_bytes == 0);*/
549 memset(&txcounters, 0, sizeof(txcounters));
550
551 /* send even more data */
552 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
553 EXPECT_RET(err == ERR_OK);
554 err = tcp_output(pcb);
555 EXPECT_RET(err == ERR_OK);
556 /* ...and even more data */
557 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
558 EXPECT_RET(err == ERR_OK);
559 err = tcp_output(pcb);
560 EXPECT_RET(err == ERR_OK);
561 /* ...and even more data */
562 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
563 EXPECT_RET(err == ERR_OK);
564 err = tcp_output(pcb);
565 EXPECT_RET(err == ERR_OK);
566 /* ...and even more data */
567 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
568 EXPECT_RET(err == ERR_OK);
569 err = tcp_output(pcb);
570 EXPECT_RET(err == ERR_OK);
571
572 /* send ACKs for data2 and data3 */
573 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
574 EXPECT_RET(p != NULL);
575 test_tcp_input(p, &netif);
576 /*EXPECT_RET(txcounters.num_tx_calls == 0);*/
577
578 /* ...and even more data */
579 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
580 EXPECT_RET(err == ERR_OK);
581 err = tcp_output(pcb);
582 EXPECT_RET(err == ERR_OK);
583 /* ...and even more data */
584 err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
585 EXPECT_RET(err == ERR_OK);
586 err = tcp_output(pcb);
587 EXPECT_RET(err == ERR_OK);
588
589#if 0
590 /* create expected segment */
591 p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
592 EXPECT_RET(p != NULL);
593 if (p != NULL) {
594 /* pass the segment to tcp_input */
595 test_tcp_input(p, &netif);
596 /* check if counters are as expected */
597 EXPECT_RET(counters.close_calls == 0);
598 EXPECT_RET(counters.recv_calls == 1);
599 EXPECT_RET(counters.recved_bytes == data_len);
600 EXPECT_RET(counters.err_calls == 0);
601 }
602#endif
603 /* make sure the pcb is freed */
604 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
605 tcp_abort(pcb);
606 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
607}
608END_TEST
609
610static u8_t tx_data[TCP_WND*2];
611
612static void
613check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
614{
615 struct tcp_seg *s = segs;
616 int i;
617 for (i = 0; i < num_expected; i++, s = s->next) {
618 EXPECT_RET(s != NULL);
619 EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i]));
620 }
621 EXPECT(s == NULL);
622}
623
624/** Send data with sequence numbers that wrap around the u32_t range.
625 * Then, provoke fast retransmission by duplicate ACKs and check that all
626 * segment lists are still properly sorted. */
627START_TEST(test_tcp_fast_rexmit_wraparound)
628{
629 struct netif netif;
630 struct test_tcp_txcounters txcounters;
631 struct test_tcp_counters counters;
632 struct tcp_pcb* pcb;
633 struct pbuf* p;
634 err_t err;
635 size_t i;
636 u16_t sent_total = 0;
637 LWIP_UNUSED_ARG(_i);
638
639 for (i = 0; i < sizeof(tx_data); i++) {
640 tx_data[i] = (u8_t)i;
641 }
642
643 /* initialize local vars */
644 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
645 memset(&counters, 0, sizeof(counters));
646
647 /* create and initialize the pcb */
648 tcp_ticks = SEQNO1 - ISS;
649 pcb = test_tcp_new_counters_pcb(&counters);
650 EXPECT_RET(pcb != NULL);
651 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
652 pcb->mss = TCP_MSS;
653 /* disable initial congestion window (we don't send a SYN here...) */
654 pcb->cwnd = 2*TCP_MSS;
655 /* start in congestion advoidance */
656 pcb->ssthresh = pcb->cwnd;
657
658 /* send 6 mss-sized segments */
659 for (i = 0; i < 6; i++) {
660 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
661 EXPECT_RET(err == ERR_OK);
662 sent_total += TCP_MSS;
663 }
664 check_seqnos(pcb->unsent, 6, seqnos);
665 EXPECT(pcb->unacked == NULL);
666 err = tcp_output(pcb);
667 EXPECT(txcounters.num_tx_calls == 2);
668 EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
669 memset(&txcounters, 0, sizeof(txcounters));
670
671 check_seqnos(pcb->unacked, 2, seqnos);
672 check_seqnos(pcb->unsent, 4, &seqnos[2]);
673
674 /* ACK the first segment */
675 p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
676 test_tcp_input(p, &netif);
677 /* ensure this didn't trigger a retransmission. Only one
678 segment should be transmitted because cwnd opened up by
679 TCP_MSS and a fraction since we are in congestion avoidance */
680 EXPECT(txcounters.num_tx_calls == 1);
681 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
682 memset(&txcounters, 0, sizeof(txcounters));
683 check_seqnos(pcb->unacked, 2, &seqnos[1]);
684 check_seqnos(pcb->unsent, 3, &seqnos[3]);
685
686 /* 3 dupacks */
687 EXPECT(pcb->dupacks == 0);
688 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
689 test_tcp_input(p, &netif);
690 EXPECT(txcounters.num_tx_calls == 0);
691 EXPECT(pcb->dupacks == 1);
692 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
693 test_tcp_input(p, &netif);
694 EXPECT(txcounters.num_tx_calls == 0);
695 EXPECT(pcb->dupacks == 2);
696 /* 3rd dupack -> fast rexmit */
697 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
698 test_tcp_input(p, &netif);
699 EXPECT(pcb->dupacks == 3);
700 EXPECT(txcounters.num_tx_calls == 4);
701 memset(&txcounters, 0, sizeof(txcounters));
702 EXPECT(pcb->unsent == NULL);
703 check_seqnos(pcb->unacked, 5, &seqnos[1]);
704
705 /* make sure the pcb is freed */
706 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
707 tcp_abort(pcb);
708 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
709}
710END_TEST
711
712/** Send data with sequence numbers that wrap around the u32_t range.
713 * Then, provoke RTO retransmission and check that all
714 * segment lists are still properly sorted. */
715START_TEST(test_tcp_rto_rexmit_wraparound)
716{
717 struct netif netif;
718 struct test_tcp_txcounters txcounters;
719 struct test_tcp_counters counters;
720 struct tcp_pcb* pcb;
721 struct tcp_pcb dummy_pcb_for_iss; /* we need this for tcp_next_iss() only */
722 err_t err;
723 size_t i;
724 u16_t sent_total = 0;
725 LWIP_UNUSED_ARG(_i);
726
727 for (i = 0; i < sizeof(tx_data); i++) {
728 tx_data[i] = (u8_t)i;
729 }
730
731 /* initialize local vars */
732 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
733 memset(&counters, 0, sizeof(counters));
734
735 /* create and initialize the pcb */
736 tcp_ticks = 0;
737 tcp_ticks = 0 - tcp_next_iss(&dummy_pcb_for_iss);
738 tcp_ticks = SEQNO1 - tcp_next_iss(&dummy_pcb_for_iss);
739 pcb = test_tcp_new_counters_pcb(&counters);
740 EXPECT_RET(pcb != NULL);
741 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
742 pcb->mss = TCP_MSS;
743 /* disable initial congestion window (we don't send a SYN here...) */
744 pcb->cwnd = 2*TCP_MSS;
745
746 /* send 6 mss-sized segments */
747 for (i = 0; i < 6; i++) {
748 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
749 EXPECT_RET(err == ERR_OK);
750 sent_total += TCP_MSS;
751 }
752 check_seqnos(pcb->unsent, 6, seqnos);
753 EXPECT(pcb->unacked == NULL);
754 err = tcp_output(pcb);
755 EXPECT(txcounters.num_tx_calls == 2);
756 EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
757 memset(&txcounters, 0, sizeof(txcounters));
758
759 check_seqnos(pcb->unacked, 2, seqnos);
760 check_seqnos(pcb->unsent, 4, &seqnos[2]);
761
762 /* call the tcp timer some times */
763 for (i = 0; i < 10; i++) {
764 test_tcp_tmr();
765 EXPECT(txcounters.num_tx_calls == 0);
766 }
767 /* 11th call to tcp_tmr: RTO rexmit fires */
768 test_tcp_tmr();
769 EXPECT(txcounters.num_tx_calls == 1);
770 check_seqnos(pcb->unacked, 1, seqnos);
771 check_seqnos(pcb->unsent, 5, &seqnos[1]);
772
773 /* fake greater cwnd */
774 pcb->cwnd = pcb->snd_wnd;
775 /* send more data */
776 err = tcp_output(pcb);
777 EXPECT(err == ERR_OK);
778 /* check queues are sorted */
779 EXPECT(pcb->unsent == NULL);
780 check_seqnos(pcb->unacked, 6, seqnos);
781
782 /* make sure the pcb is freed */
783 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
784 tcp_abort(pcb);
785 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
786}
787END_TEST
788
789/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
790 * At the end, send more data. */
791static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
792{
793 struct netif netif;
794 struct test_tcp_txcounters txcounters;
795 struct test_tcp_counters counters;
796 struct tcp_pcb* pcb;
797 struct pbuf *p;
798 err_t err;
799 size_t i;
800 u16_t sent_total;
801 u8_t expected = 0xFE;
802
803 for (i = 0; i < sizeof(tx_data); i++) {
804 u8_t d = (u8_t)i;
805 if (d == 0xFE) {
806 d = 0xF0;
807 }
808 tx_data[i] = d;
809 }
810 if (zero_window_probe_from_unsent) {
811 tx_data[TCP_WND] = expected;
812 } else {
813 tx_data[0] = expected;
814 }
815
816 /* initialize local vars */
817 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
818 memset(&counters, 0, sizeof(counters));
819
820 /* create and initialize the pcb */
821 pcb = test_tcp_new_counters_pcb(&counters);
822 EXPECT_RET(pcb != NULL);
823 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
824 pcb->mss = TCP_MSS;
825 /* disable initial congestion window (we don't send a SYN here...) */
826 pcb->cwnd = pcb->snd_wnd;
827
828 /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */
829 sent_total = 0;
830 if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) {
831 u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS;
832 err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
833 EXPECT_RET(err == ERR_OK);
834 err = tcp_output(pcb);
835 EXPECT_RET(err == ERR_OK);
836 EXPECT(txcounters.num_tx_calls == 1);
837 EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U);
838 memset(&txcounters, 0, sizeof(txcounters));
839 sent_total += initial_data_len;
840 }
841 for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) {
842 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
843 EXPECT_RET(err == ERR_OK);
844 err = tcp_output(pcb);
845 EXPECT_RET(err == ERR_OK);
846 EXPECT(txcounters.num_tx_calls == 1);
847 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
848 memset(&txcounters, 0, sizeof(txcounters));
849 }
850 EXPECT(sent_total == (TCP_WND - TCP_MSS));
851
852 /* now ACK the packet before the first */
853 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
854 test_tcp_input(p, &netif);
855 /* ensure this didn't trigger a retransmission */
856 EXPECT(txcounters.num_tx_calls == 0);
857 EXPECT(txcounters.num_tx_bytes == 0);
858
859 EXPECT(pcb->persist_backoff == 0);
860 /* send the last packet, now a complete window has been sent */
861 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
862 sent_total += TCP_MSS;
863 EXPECT_RET(err == ERR_OK);
864 err = tcp_output(pcb);
865 EXPECT_RET(err == ERR_OK);
866 EXPECT(txcounters.num_tx_calls == 1);
867 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
868 memset(&txcounters, 0, sizeof(txcounters));
869 EXPECT(pcb->persist_backoff == 0);
870
871 if (zero_window_probe_from_unsent) {
872 /* ACK all data but close the TX window */
873 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0);
874 test_tcp_input(p, &netif);
875 /* ensure this didn't trigger any transmission */
876 EXPECT(txcounters.num_tx_calls == 0);
877 EXPECT(txcounters.num_tx_bytes == 0);
878 /* window is completely full, but persist timer is off since send buffer is empty */
879 EXPECT(pcb->snd_wnd == 0);
880 EXPECT(pcb->persist_backoff == 0);
881 }
882
883 /* send one byte more (out of window) -> persist timer starts */
884 err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
885 EXPECT_RET(err == ERR_OK);
886 err = tcp_output(pcb);
887 EXPECT_RET(err == ERR_OK);
888 EXPECT(txcounters.num_tx_calls == 0);
889 EXPECT(txcounters.num_tx_bytes == 0);
890 memset(&txcounters, 0, sizeof(txcounters));
891 if (!zero_window_probe_from_unsent) {
892 /* no persist timer unless a zero window announcement has been received */
893 EXPECT(pcb->persist_backoff == 0);
894 } else {
895 EXPECT(pcb->persist_backoff == 1);
896
897 /* call tcp_timer some more times to let persist timer count up */
898 for (i = 0; i < 4; i++) {
899 test_tcp_tmr();
900 EXPECT(txcounters.num_tx_calls == 0);
901 EXPECT(txcounters.num_tx_bytes == 0);
902 }
903
904 /* this should trigger the zero-window-probe */
905 txcounters.copy_tx_packets = 1;
906 test_tcp_tmr();
907 txcounters.copy_tx_packets = 0;
908 EXPECT(txcounters.num_tx_calls == 1);
909 EXPECT(txcounters.num_tx_bytes == 1 + 40U);
910 EXPECT(txcounters.tx_packets != NULL);
911 if (txcounters.tx_packets != NULL) {
912 u8_t sent;
913 u16_t ret;
914 ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U);
915 EXPECT(ret == 1);
916 EXPECT(sent == expected);
917 }
918 if (txcounters.tx_packets != NULL) {
919 pbuf_free(txcounters.tx_packets);
920 txcounters.tx_packets = NULL;
921 }
922 }
923
924 /* make sure the pcb is freed */
925 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
926 tcp_abort(pcb);
927 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
928}
929
930START_TEST(test_tcp_tx_full_window_lost_from_unsent)
931{
932 LWIP_UNUSED_ARG(_i);
933 test_tcp_tx_full_window_lost(1);
934}
935END_TEST
936
937START_TEST(test_tcp_tx_full_window_lost_from_unacked)
938{
939 LWIP_UNUSED_ARG(_i);
940 test_tcp_tx_full_window_lost(0);
941}
942END_TEST
943
944/** Send data, provoke retransmission and then add data to a segment
945 * that already has been sent before. */
946START_TEST(test_tcp_retx_add_to_sent)
947{
948 struct netif netif;
949 struct test_tcp_txcounters txcounters;
950 struct test_tcp_counters counters;
951 struct tcp_pcb* pcb;
952 struct pbuf* p;
953 char data1a[] = { 1, 2, 3};
954 char data1b[] = { 4};
955 char data2a[] = { 5, 6, 7, 8};
956 char data2b[] = { 5, 6, 7};
957 char data3[] = { 9, 10, 11, 12, 12};
958 char data4[] = { 13, 14, 15, 16,17};
959 err_t err;
960 int i;
961 LWIP_UNUSED_ARG(_i);
962
963 /* initialize local vars */
964 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
965 memset(&counters, 0, sizeof(counters));
966
967 /* create and initialize the pcb */
968 pcb = test_tcp_new_counters_pcb(&counters);
969 EXPECT_RET(pcb != NULL);
970 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
971 pcb->mss = TCP_MSS;
972 /* disable initial congestion window (we don't send a SYN here...) */
973 pcb->cwnd = pcb->snd_wnd;
974
975 /* send data1 */
976 err = tcp_write(pcb, data1a, sizeof(data1a), TCP_WRITE_FLAG_COPY);
977 EXPECT_RET(err == ERR_OK);
978 err = tcp_write(pcb, data1b, sizeof(data1b), TCP_WRITE_FLAG_COPY);
979 EXPECT_RET(err == ERR_OK);
980 err = tcp_output(pcb);
981 EXPECT_RET(err == ERR_OK);
982 EXPECT_RET(txcounters.num_tx_calls == 1);
983 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1a) + sizeof(data1b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
984 memset(&txcounters, 0, sizeof(txcounters));
985 /* "recv" ACK for data1 */
986 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
987 EXPECT_RET(p != NULL);
988 test_tcp_input(p, &netif);
989 EXPECT_RET(txcounters.num_tx_calls == 0);
990 EXPECT_RET(pcb->unacked == NULL);
991 /* send data2 */
992 err = tcp_write(pcb, data2a, sizeof(data2a), TCP_WRITE_FLAG_COPY);
993 EXPECT_RET(err == ERR_OK);
994 err = tcp_write(pcb, data2b, sizeof(data2b), TCP_WRITE_FLAG_COPY);
995 EXPECT_RET(err == ERR_OK);
996 err = tcp_output(pcb);
997 EXPECT_RET(err == ERR_OK);
998 EXPECT_RET(txcounters.num_tx_calls == 1);
999 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
1000 memset(&txcounters, 0, sizeof(txcounters));
1001 /* send data3 */
1002 err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
1003 EXPECT_RET(err == ERR_OK);
1004 err = tcp_output(pcb);
1005 EXPECT_RET(err == ERR_OK);
1006 EXPECT_RET(txcounters.num_tx_calls == 0);
1007 EXPECT_RET(txcounters.num_tx_bytes == 0);
1008 memset(&txcounters, 0, sizeof(txcounters));
1009
1010 /* data3 not sent yet (nagle) */
1011 EXPECT_RET(pcb->unacked != NULL);
1012 EXPECT_RET(pcb->unsent != NULL);
1013
1014 /* disable nagle for this test so data to sent segment can be added below... */
1015 tcp_nagle_disable(pcb);
1016
1017 /* call the tcp timer some times */
1018 for (i = 0; i < 20; i++) {
1019 test_tcp_tmr();
1020 if (txcounters.num_tx_calls != 0) {
1021 break;
1022 }
1023 }
1024 /* data3 sent */
1025 EXPECT_RET(txcounters.num_tx_calls == 1);
1026 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
1027 EXPECT_RET(pcb->unacked != NULL);
1028 EXPECT_RET(pcb->unsent == NULL);
1029 memset(&txcounters, 0, sizeof(txcounters));
1030
1031 tcp_nagle_enable(pcb);
1032
1033 /* call the tcp timer some times */
1034 for (i = 0; i < 20; i++) {
1035 test_tcp_tmr();
1036 if (txcounters.num_tx_calls != 0) {
1037 break;
1038 }
1039 }
1040 /* RTO: rexmit of data2 */
1041 EXPECT_RET(txcounters.num_tx_calls == 1);
1042 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
1043 EXPECT_RET(pcb->unacked != NULL);
1044 EXPECT_RET(pcb->unsent != NULL);
1045 memset(&txcounters, 0, sizeof(txcounters));
1046
1047 /* send data4 */
1048 err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
1049 EXPECT_RET(err == ERR_OK);
1050 /* disable nagle for this test so data to transmit without further ACKs... */
1051 tcp_nagle_disable(pcb);
1052 err = tcp_output(pcb);
1053 EXPECT_RET(err == ERR_OK);
1054 /* nagle enabled, no tx calls */
1055 EXPECT_RET(txcounters.num_tx_calls == 1);
1056 EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(data4) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
1057 memset(&txcounters, 0, sizeof(txcounters));
1058 /* make sure the pcb is freed */
1059 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
1060 tcp_abort(pcb);
1061 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1062}
1063END_TEST
1064
1065START_TEST(test_tcp_rto_tracking)
1066{
1067 struct netif netif;
1068 struct test_tcp_txcounters txcounters;
1069 struct test_tcp_counters counters;
1070 struct tcp_pcb* pcb;
1071 struct pbuf* p;
1072 err_t err;
1073 size_t i;
1074 u16_t sent_total = 0;
1075 LWIP_UNUSED_ARG(_i);
1076
1077 for (i = 0; i < sizeof(tx_data); i++) {
1078 tx_data[i] = (u8_t)i;
1079 }
1080
1081 /* initialize local vars */
1082 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
1083 memset(&counters, 0, sizeof(counters));
1084
1085 /* create and initialize the pcb */
1086 tcp_ticks = SEQNO1 - ISS;
1087 pcb = test_tcp_new_counters_pcb(&counters);
1088 EXPECT_RET(pcb != NULL);
1089 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
1090 pcb->mss = TCP_MSS;
1091 /* Set congestion window large enough to send all our segments */
1092 pcb->cwnd = 5*TCP_MSS;
1093
1094 /* send 5 mss-sized segments */
1095 for (i = 0; i < 5; i++) {
1096 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
1097 EXPECT_RET(err == ERR_OK);
1098 sent_total += TCP_MSS;
1099 }
1100 check_seqnos(pcb->unsent, 5, seqnos);
1101 EXPECT(pcb->unacked == NULL);
1102 err = tcp_output(pcb);
1103 EXPECT(txcounters.num_tx_calls == 5);
1104 EXPECT(txcounters.num_tx_bytes == 5 * (TCP_MSS + 40U));
1105 memset(&txcounters, 0, sizeof(txcounters));
1106 /* Check all 5 are in-flight */
1107 EXPECT(pcb->unsent == NULL);
1108 check_seqnos(pcb->unacked, 5, seqnos);
1109
1110 /* Force us into retransmisson timeout */
1111 while (!(pcb->flags & TF_RTO)) {
1112 test_tcp_tmr();
1113 }
1114 /* Ensure 4 remaining segments are back on unsent, ready for retransmission */
1115 check_seqnos(pcb->unsent, 4, &seqnos[1]);
1116 /* Ensure 1st segment is on unacked (already retransmitted) */
1117 check_seqnos(pcb->unacked, 1, seqnos);
1118 EXPECT(txcounters.num_tx_calls == 1);
1119 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
1120 memset(&txcounters, 0, sizeof(txcounters));
1121 /* Ensure rto_end points to next byte */
1122 EXPECT(pcb->rto_end == seqnos[5]);
1123 EXPECT(pcb->rto_end == pcb->snd_nxt);
1124 /* Check cwnd was reset */
1125 EXPECT(pcb->cwnd == pcb->mss);
1126
1127 /* Add another segment to send buffer which is outside of RTO */
1128 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
1129 EXPECT_RET(err == ERR_OK);
1130 sent_total += TCP_MSS;
1131 check_seqnos(pcb->unsent, 5, &seqnos[1]);
1132 /* Ensure no new data was sent */
1133 EXPECT(txcounters.num_tx_calls == 0);
1134 EXPECT(txcounters.num_tx_bytes == 0);
1135 EXPECT(pcb->rto_end == pcb->snd_nxt);
1136
1137 /* ACK first segment */
1138 p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
1139 test_tcp_input(p, &netif);
1140 /* Next two retranmissions should go out, due to cwnd in slow start */
1141 EXPECT(txcounters.num_tx_calls == 2);
1142 EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
1143 memset(&txcounters, 0, sizeof(txcounters));
1144 check_seqnos(pcb->unacked, 2, &seqnos[1]);
1145 check_seqnos(pcb->unsent, 3, &seqnos[3]);
1146 /* RTO should still be marked */
1147 EXPECT(pcb->flags & TF_RTO);
1148 /* cwnd should have only grown by 1 MSS */
1149 EXPECT(pcb->cwnd == (tcpwnd_size_t)(2 * pcb->mss));
1150 /* Ensure no new data was sent */
1151 EXPECT(pcb->rto_end == pcb->snd_nxt);
1152
1153 /* ACK the next two segments */
1154 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
1155 test_tcp_input(p, &netif);
1156 /* Final 2 retransmissions and 1 new data should go out */
1157 EXPECT(txcounters.num_tx_calls == 3);
1158 EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
1159 memset(&txcounters, 0, sizeof(txcounters));
1160 check_seqnos(pcb->unacked, 3, &seqnos[3]);
1161 EXPECT(pcb->unsent == NULL);
1162 /* RTO should still be marked */
1163 EXPECT(pcb->flags & TF_RTO);
1164 /* cwnd should have only grown by 1 MSS */
1165 EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
1166 /* snd_nxt should have been advanced past rto_end */
1167 EXPECT(TCP_SEQ_GT(pcb->snd_nxt, pcb->rto_end));
1168
1169 /* ACK the next two segments, finishing our RTO, leaving new segment unacked */
1170 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
1171 test_tcp_input(p, &netif);
1172 EXPECT(!(pcb->flags & TF_RTO));
1173 check_seqnos(pcb->unacked, 1, &seqnos[5]);
1174 /* We should be in ABC congestion avoidance, so no change in cwnd */
1175 EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
1176 EXPECT(pcb->cwnd >= pcb->ssthresh);
1177 /* Ensure ABC congestion avoidance is tracking bytes acked */
1178 EXPECT(pcb->bytes_acked == (tcpwnd_size_t)(2 * pcb->mss));
1179
1180 /* make sure the pcb is freed */
1181 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
1182 tcp_abort(pcb);
1183 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1184}
1185END_TEST
1186
1187static void test_tcp_rto_timeout_impl(int link_down)
1188{
1189 struct netif netif;
1190 struct test_tcp_txcounters txcounters;
1191 struct test_tcp_counters counters;
1192 struct tcp_pcb *pcb, *cur;
1193 err_t err;
1194 size_t i;
1195 const size_t max_wait_ctr = 1024 * 1024;
1196
1197 /* Setup data for a single segment */
1198 for (i = 0; i < TCP_MSS; i++) {
1199 tx_data[i] = (u8_t)i;
1200 }
1201
1202 /* initialize local vars */
1203 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
1204 memset(&counters, 0, sizeof(counters));
1205
1206 /* create and initialize the pcb */
1207 tcp_ticks = SEQNO1 - ISS;
1208 pcb = test_tcp_new_counters_pcb(&counters);
1209 EXPECT_RET(pcb != NULL);
1210 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
1211 pcb->mss = TCP_MSS;
1212 pcb->cwnd = TCP_MSS;
1213
1214 /* send our segment */
1215 err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
1216 EXPECT_RET(err == ERR_OK);
1217 err = tcp_output(pcb);
1218 EXPECT(txcounters.num_tx_calls == 1);
1219 EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
1220 memset(&txcounters, 0, sizeof(txcounters));
1221
1222 /* ensure no errors have been recorded */
1223 EXPECT(counters.err_calls == 0);
1224 EXPECT(counters.last_err == ERR_OK);
1225
1226 /* Force us into retransmisson timeout */
1227 for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
1228 test_tcp_tmr();
1229 }
1230 EXPECT(i < max_wait_ctr);
1231
1232 /* check first rexmit */
1233 EXPECT(pcb->nrtx == 1);
1234 EXPECT(txcounters.num_tx_calls == 1);
1235 EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
1236
1237 /* still no error expected */
1238 EXPECT(counters.err_calls == 0);
1239 EXPECT(counters.last_err == ERR_OK);
1240
1241 if (link_down) {
1242 netif_set_link_down(&netif);
1243 }
1244
1245 /* keep running the timer till we hit our maximum RTO */
1246 for (i = 0; counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
1247 test_tcp_tmr();
1248 }
1249 EXPECT(i < max_wait_ctr);
1250
1251 /* check number of retransmissions */
1252 if (link_down) {
1253 EXPECT(txcounters.num_tx_calls == 1);
1254 EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
1255 } else {
1256 EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
1257 EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (TCP_MSS + 40U));
1258 }
1259
1260 /* check the connection (pcb) has been aborted */
1261 EXPECT(counters.err_calls == 1);
1262 EXPECT(counters.last_err == ERR_ABRT);
1263 /* check our pcb is no longer active */
1264 for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
1265 EXPECT(cur != pcb);
1266 }
1267 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1268}
1269
1270START_TEST(test_tcp_rto_timeout)
1271{
1272 LWIP_UNUSED_ARG(_i);
1273 test_tcp_rto_timeout_impl(0);
1274}
1275END_TEST
1276
1277START_TEST(test_tcp_rto_timeout_link_down)
1278{
1279 LWIP_UNUSED_ARG(_i);
1280 test_tcp_rto_timeout_impl(1);
1281}
1282END_TEST
1283
1284static void test_tcp_rto_timeout_syn_sent_impl(int link_down)
1285{
1286 struct netif netif;
1287 struct test_tcp_txcounters txcounters;
1288 struct test_tcp_counters counters;
1289 struct tcp_pcb *pcb, *cur;
1290 err_t err;
1291 size_t i;
1292 const size_t max_wait_ctr = 1024 * 1024;
1293 const u16_t tcp_syn_opts_len = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_MSS|TF_SEG_OPTS_WND_SCALE|TF_SEG_OPTS_SACK_PERM|TF_SEG_OPTS_TS);
1294
1295 /* Setup data for a single segment */
1296 for (i = 0; i < TCP_MSS; i++) {
1297 tx_data[i] = (u8_t)i;
1298 }
1299
1300 /* initialize local vars */
1301 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
1302 memset(&counters, 0, sizeof(counters));
1303
1304 /* create and initialize the pcb */
1305 tcp_ticks = SEQNO1 - ISS;
1306 pcb = test_tcp_new_counters_pcb(&counters);
1307 EXPECT_RET(pcb != NULL);
1308 err = tcp_connect(pcb, &netif.gw, 123, NULL);
1309 EXPECT_RET(err == ERR_OK);
1310 EXPECT_RET(pcb->state == SYN_SENT);
1311 EXPECT(txcounters.num_tx_calls == 1);
1312 EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
1313
1314 /* ensure no errors have been recorded */
1315 EXPECT(counters.err_calls == 0);
1316 EXPECT(counters.last_err == ERR_OK);
1317
1318 txcounters.num_tx_calls = 0;
1319 txcounters.num_tx_bytes = 0;
1320
1321 /* Force us into retransmisson timeout */
1322 for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
1323 test_tcp_tmr();
1324 }
1325 EXPECT(i < max_wait_ctr);
1326
1327 /* check first rexmit */
1328 EXPECT(pcb->nrtx == 1);
1329 EXPECT(txcounters.num_tx_calls == 1);
1330 EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len); /* 40: headers; >=: options */
1331
1332 /* still no error expected */
1333 EXPECT(counters.err_calls == 0);
1334 EXPECT(counters.last_err == ERR_OK);
1335
1336 if (link_down) {
1337 /* set link down and check what happens to the RTO counter */
1338 netif_set_link_down(&netif);
1339 }
1340
1341 /* keep running the timer till we hit our maximum RTO */
1342 for (i = 0; counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
1343 test_tcp_tmr();
1344 }
1345 EXPECT(i < max_wait_ctr);
1346
1347 /* check number of retransmissions */
1348 if (link_down) {
1349 EXPECT(txcounters.num_tx_calls == 1);
1350 EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
1351 } else {
1352 EXPECT(txcounters.num_tx_calls == TCP_SYNMAXRTX);
1353 EXPECT(txcounters.num_tx_bytes == TCP_SYNMAXRTX * (tcp_syn_opts_len + 40U));
1354 }
1355
1356 /* check the connection (pcb) has been aborted */
1357 EXPECT(counters.err_calls == 1);
1358 EXPECT(counters.last_err == ERR_ABRT);
1359 /* check our pcb is no longer active */
1360 for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
1361 EXPECT(cur != pcb);
1362 }
1363 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1364}
1365
1366START_TEST(test_tcp_rto_timeout_syn_sent)
1367{
1368 LWIP_UNUSED_ARG(_i);
1369 test_tcp_rto_timeout_syn_sent_impl(0);
1370}
1371END_TEST
1372
1373START_TEST(test_tcp_rto_timeout_syn_sent_link_down)
1374{
1375 LWIP_UNUSED_ARG(_i);
1376 test_tcp_rto_timeout_syn_sent_impl(1);
1377}
1378END_TEST
1379
1380static void test_tcp_zwp_timeout_impl(int link_down)
1381{
1382 struct netif netif;
1383 struct test_tcp_txcounters txcounters;
1384 struct test_tcp_counters counters;
1385 struct tcp_pcb *pcb, *cur;
1386 struct pbuf* p;
1387 err_t err;
1388 size_t i;
1389
1390 /* Setup data for two segments */
1391 for (i = 0; i < 2*TCP_MSS; i++) {
1392 tx_data[i] = (u8_t)i;
1393 }
1394
1395 /* initialize local vars */
1396 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
1397 memset(&counters, 0, sizeof(counters));
1398
1399 /* create and initialize the pcb */
1400 tcp_ticks = SEQNO1 - ISS;
1401 pcb = test_tcp_new_counters_pcb(&counters);
1402 EXPECT_RET(pcb != NULL);
1403 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
1404 pcb->mss = TCP_MSS;
1405 pcb->cwnd = TCP_MSS;
1406
1407 /* send first segment */
1408 err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
1409 EXPECT(err == ERR_OK);
1410 err = tcp_output(pcb);
1411 EXPECT(err == ERR_OK);
1412
1413 /* verify segment is in-flight */
1414 EXPECT(pcb->unsent == NULL);
1415 check_seqnos(pcb->unacked, 1, seqnos);
1416 EXPECT(txcounters.num_tx_calls == 1);
1417 EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
1418 memset(&txcounters, 0, sizeof(txcounters));
1419
1420 /* ACK the segment and close the TX window */
1421 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK, 0);
1422 test_tcp_input(p, &netif);
1423 EXPECT(pcb->unacked == NULL);
1424 EXPECT(pcb->unsent == NULL);
1425 /* send buffer empty, persist should be off */
1426 EXPECT(pcb->persist_backoff == 0);
1427 EXPECT(pcb->snd_wnd == 0);
1428
1429 /* send second segment, should be buffered */
1430 err = tcp_write(pcb, &tx_data[TCP_MSS], TCP_MSS, TCP_WRITE_FLAG_COPY);
1431 EXPECT(err == ERR_OK);
1432 err = tcp_output(pcb);
1433 EXPECT(err == ERR_OK);
1434
1435 /* ensure it is buffered and persist timer started */
1436 EXPECT(pcb->unacked == NULL);
1437 check_seqnos(pcb->unsent, 1, &seqnos[1]);
1438 EXPECT(txcounters.num_tx_calls == 0);
1439 EXPECT(txcounters.num_tx_bytes == 0);
1440 EXPECT(pcb->persist_backoff == 1);
1441
1442 /* ensure no errors have been recorded */
1443 EXPECT(counters.err_calls == 0);
1444 EXPECT(counters.last_err == ERR_OK);
1445
1446 /* run timer till first probe */
1447 EXPECT(pcb->persist_probe == 0);
1448 while (pcb->persist_probe == 0) {
1449 test_tcp_tmr();
1450 }
1451 EXPECT(txcounters.num_tx_calls == 1);
1452 EXPECT(txcounters.num_tx_bytes == (1 + 40U));
1453 memset(&txcounters, 0, sizeof(txcounters));
1454
1455 /* respond to probe with remote's current SEQ, ACK, and zero-window */
1456 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 0, TCP_ACK, 0);
1457 test_tcp_input(p, &netif);
1458 /* ensure zero-window is still active, but probe count reset */
1459 EXPECT(pcb->persist_backoff > 1);
1460 EXPECT(pcb->persist_probe == 0);
1461 EXPECT(pcb->snd_wnd == 0);
1462
1463 /* ensure no errors have been recorded */
1464 EXPECT(counters.err_calls == 0);
1465 EXPECT(counters.last_err == ERR_OK);
1466
1467 if (link_down) {
1468 netif_set_link_down(&netif);
1469 }
1470
1471 /* now run the timer till we hit our maximum probe count */
1472 while (counters.last_err == ERR_OK) {
1473 test_tcp_tmr();
1474 }
1475
1476 if (link_down) {
1477 EXPECT(txcounters.num_tx_calls == 0);
1478 EXPECT(txcounters.num_tx_bytes == 0);
1479 } else {
1480 /* check maximum number of 1 byte probes were sent */
1481 EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
1482 EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (1 + 40U));
1483 }
1484
1485 /* check the connection (pcb) has been aborted */
1486 EXPECT(counters.err_calls == 1);
1487 EXPECT(counters.last_err == ERR_ABRT);
1488 /* check our pcb is no longer active */
1489 for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
1490 EXPECT(cur != pcb);
1491 }
1492 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1493}
1494
1495START_TEST(test_tcp_zwp_timeout)
1496{
1497 LWIP_UNUSED_ARG(_i);
1498 test_tcp_zwp_timeout_impl(0);
1499}
1500END_TEST
1501
1502START_TEST(test_tcp_zwp_timeout_link_down)
1503{
1504 LWIP_UNUSED_ARG(_i);
1505 test_tcp_zwp_timeout_impl(1);
1506}
1507END_TEST
1508
1509START_TEST(test_tcp_persist_split)
1510{
1511 struct netif netif;
1512 struct test_tcp_txcounters txcounters;
1513 struct test_tcp_counters counters;
1514 struct tcp_pcb *pcb;
1515 struct pbuf* p;
1516 err_t err;
1517 size_t i;
1518 LWIP_UNUSED_ARG(_i);
1519
1520 /* Setup data for four segments */
1521 for (i = 0; i < 4 * TCP_MSS; i++) {
1522 tx_data[i] = (u8_t)i;
1523 }
1524
1525 /* initialize local vars */
1526 test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
1527 memset(&counters, 0, sizeof(counters));
1528
1529 /* create and initialize the pcb */
1530 tcp_ticks = SEQNO1 - ISS;
1531 pcb = test_tcp_new_counters_pcb(&counters);
1532 EXPECT_RET(pcb != NULL);
1533 tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
1534 pcb->mss = TCP_MSS;
1535 /* set window to three segments */
1536 pcb->cwnd = 3 * TCP_MSS;
1537 pcb->snd_wnd = 3 * TCP_MSS;
1538 pcb->snd_wnd_max = 3 * TCP_MSS;
1539
1540 /* send four segments. Fourth should stay buffered and is a 3/4 MSS segment to
1541 get coverage on the oversized segment case */
1542 err = tcp_write(pcb, &tx_data[0], (3 * TCP_MSS) + (TCP_MSS - (TCP_MSS / 4)), TCP_WRITE_FLAG_COPY);
1543 EXPECT(err == ERR_OK);
1544 err = tcp_output(pcb);
1545 EXPECT(err == ERR_OK);
1546
1547 /* verify 3 segments are in-flight */
1548 EXPECT(pcb->unacked != NULL);
1549 check_seqnos(pcb->unacked, 3, seqnos);
1550 EXPECT(txcounters.num_tx_calls == 3);
1551 EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
1552 memset(&txcounters, 0, sizeof(txcounters));
1553 /* verify 4th segment is on unsent */
1554 EXPECT(pcb->unsent != NULL);
1555 EXPECT(pcb->unsent->len == TCP_MSS - (TCP_MSS / 4));
1556 check_seqnos(pcb->unsent, 1, &seqnos[3]);
1557#if TCP_OVERSIZE
1558 EXPECT(pcb->unsent_oversize == TCP_MSS / 4);
1559#if TCP_OVERSIZE_DBGCHECK
1560 EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
1561#endif /* TCP_OVERSIZE_DBGCHECK */
1562#endif /* TCP_OVERSIZE */
1563
1564 /* ACK the 3 segments and update the window to only 1/2 TCP_MSS.
1565 4th segment should stay on unsent because it's bigger than 1/2 MSS */
1566 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 3 * TCP_MSS, TCP_ACK, TCP_MSS / 2);
1567 test_tcp_input(p, &netif);
1568 EXPECT(pcb->unacked == NULL);
1569 EXPECT(pcb->snd_wnd == TCP_MSS / 2);
1570 EXPECT(pcb->unsent != NULL);
1571 check_seqnos(pcb->unsent, 1, &seqnos[3]);
1572 EXPECT(txcounters.num_tx_calls == 0);
1573 EXPECT(txcounters.num_tx_bytes == 0);
1574 /* persist timer should be started since 4th segment is stuck waiting on snd_wnd */
1575 EXPECT(pcb->persist_backoff == 1);
1576
1577 /* ensure no errors have been recorded */
1578 EXPECT(counters.err_calls == 0);
1579 EXPECT(counters.last_err == ERR_OK);
1580
1581 /* call tcp_timer some more times to let persist timer count up */
1582 for (i = 0; i < 4; i++) {
1583 test_tcp_tmr();
1584 EXPECT(txcounters.num_tx_calls == 0);
1585 EXPECT(txcounters.num_tx_bytes == 0);
1586 }
1587
1588 /* this should be the first timer shot, which should split the
1589 * segment and send a runt (of the remaining window size) */
1590 txcounters.copy_tx_packets = 1;
1591 test_tcp_tmr();
1592 txcounters.copy_tx_packets = 0;
1593 /* persist will be disabled as RTO timer takes over */
1594 EXPECT(pcb->persist_backoff == 0);
1595 EXPECT(txcounters.num_tx_calls == 1);
1596 EXPECT(txcounters.num_tx_bytes == ((TCP_MSS /2) + 40U));
1597 /* verify 1/2 MSS segment sent, 1/4 MSS still buffered */
1598 EXPECT(pcb->unsent != NULL);
1599 EXPECT(pcb->unsent->len == TCP_MSS / 4);
1600 EXPECT(pcb->unacked != NULL);
1601 EXPECT(pcb->unacked->len == TCP_MSS / 2);
1602#if TCP_OVERSIZE
1603 /* verify there is no oversized remaining since during the
1604 segment split, the remainder pbuf is always the exact length */
1605 EXPECT(pcb->unsent_oversize == 0);
1606#if TCP_OVERSIZE_DBGCHECK
1607 /* Split segment already transmitted, should be at 0 */
1608 EXPECT(pcb->unacked->oversize_left == 0);
1609 /* Remainder segement should match pcb value (which is 0) */
1610 EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
1611#endif /* TCP_OVERSIZE_DBGCHECK */
1612#endif /* TCP_OVERSIZE */
1613
1614 /* verify first half segment */
1615 EXPECT(txcounters.tx_packets != NULL);
1616 if (txcounters.tx_packets != NULL) {
1617 u8_t sent[TCP_MSS / 2];
1618 u16_t ret;
1619 ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 2, 40U);
1620 EXPECT(ret == TCP_MSS / 2);
1621 EXPECT(memcmp(sent, &tx_data[3 * TCP_MSS], TCP_MSS / 2) == 0);
1622 }
1623 if (txcounters.tx_packets != NULL) {
1624 pbuf_free(txcounters.tx_packets);
1625 txcounters.tx_packets = NULL;
1626 }
1627 memset(&txcounters, 0, sizeof(txcounters));
1628
1629 /* ACK the half segment, leave window at half segment */
1630 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS / 2, TCP_ACK, TCP_MSS / 2);
1631 txcounters.copy_tx_packets = 1;
1632 test_tcp_input(p, &netif);
1633 txcounters.copy_tx_packets = 0;
1634 /* ensure remaining segment was sent */
1635 EXPECT(txcounters.num_tx_calls == 1);
1636 EXPECT(txcounters.num_tx_bytes == ((TCP_MSS / 4) + 40U));
1637 EXPECT(pcb->unsent == NULL);
1638 EXPECT(pcb->unacked != NULL);
1639 EXPECT(pcb->unacked->len == TCP_MSS / 4);
1640 EXPECT(pcb->snd_wnd == TCP_MSS / 2);
1641
1642 /* verify remainder segment */
1643 EXPECT(txcounters.tx_packets != NULL);
1644 if (txcounters.tx_packets != NULL) {
1645 u8_t sent[TCP_MSS / 4];
1646 u16_t ret;
1647 ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 4, 40U);
1648 EXPECT(ret == TCP_MSS / 4);
1649 EXPECT(memcmp(sent, &tx_data[(3 * TCP_MSS) + TCP_MSS / 2], TCP_MSS / 4) == 0);
1650 }
1651 if (txcounters.tx_packets != NULL) {
1652 pbuf_free(txcounters.tx_packets);
1653 txcounters.tx_packets = NULL;
1654 }
1655
1656 /* ensure no errors have been recorded */
1657 EXPECT(counters.err_calls == 0);
1658 EXPECT(counters.last_err == ERR_OK);
1659
1660 /* make sure the pcb is freed */
1661 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
1662 tcp_abort(pcb);
1663 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
1664}
1665END_TEST
1666
1667/** Create the suite including all tests for this module */
1668Suite *
1669tcp_suite(void)
1670{
1671 testfunc tests[] = {
1672 TESTFUNC(test_tcp_new_abort),
1673 TESTFUNC(test_tcp_listen_passive_open),
1674 TESTFUNC(test_tcp_recv_inseq),
1675 TESTFUNC(test_tcp_recv_inseq_trim),
1676 TESTFUNC(test_tcp_passive_close),
1677 TESTFUNC(test_tcp_active_abort),
1678 TESTFUNC(test_tcp_malformed_header),
1679 TESTFUNC(test_tcp_fast_retx_recover),
1680 TESTFUNC(test_tcp_fast_rexmit_wraparound),
1681 TESTFUNC(test_tcp_rto_rexmit_wraparound),
1682 TESTFUNC(test_tcp_tx_full_window_lost_from_unacked),
1683 TESTFUNC(test_tcp_tx_full_window_lost_from_unsent),
1684 TESTFUNC(test_tcp_retx_add_to_sent),
1685 TESTFUNC(test_tcp_rto_tracking),
1686 TESTFUNC(test_tcp_rto_timeout),
1687 TESTFUNC(test_tcp_rto_timeout_link_down),
1688 TESTFUNC(test_tcp_rto_timeout_syn_sent),
1689 TESTFUNC(test_tcp_rto_timeout_syn_sent_link_down),
1690 TESTFUNC(test_tcp_zwp_timeout),
1691 TESTFUNC(test_tcp_zwp_timeout_link_down),
1692 TESTFUNC(test_tcp_persist_split)
1693 };
1694 return create_suite("TCP", tests, sizeof(tests)/sizeof(testfunc), tcp_setup, tcp_teardown);
1695}
Note: See TracBrowser for help on using the repository browser.