8 #pragma warning(disable: 4307) 11 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS 12 #error "This tests needs TCP- and MEMP-statistics enabled" 14 #if TCP_SND_BUF <= TCP_WND 15 #error "This tests needs TCP_SND_BUF to be > TCP_WND" 18 static u8_t test_tcp_timer;
25 if (++test_tcp_timer & 1) {
37 tcp_ticks = 0 - (tcp_next_iss() - 6510);
62 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
65 fail_unless(pcb !=
NULL);
67 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
69 fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
80 char data[] = {1, 2, 3, 4};
83 u16_t remote_port = 0x100, local_port = 0x101;
89 memset(&netif, 0,
sizeof(netif));
90 IP_ADDR4(&local_ip, 192, 168, 1, 1);
91 IP_ADDR4(&remote_ip, 192, 168, 1, 2);
92 IP_ADDR4(&netmask, 255, 255, 255, 0);
94 data_len =
sizeof(data);
96 memset(&counters, 0,
sizeof(counters));
103 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
119 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
121 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
134 char data1[] = { 1, 2, 3, 4};
135 char data2[] = { 5, 6, 7, 8};
136 char data3[] = { 9, 10, 11, 12};
137 char data4[] = {13, 14, 15, 16};
138 char data5[] = {17, 18, 19, 20};
139 char data6[] = {21, 22, 23, 24};
141 u16_t remote_port = 0x100, local_port = 0x101;
146 IP_ADDR4(&local_ip, 192, 168, 1, 1);
147 IP_ADDR4(&remote_ip, 192, 168, 1, 2);
148 IP_ADDR4(&netmask, 255, 255, 255, 0);
150 memset(&counters, 0,
sizeof(counters));
155 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
158 pcb->cwnd = pcb->snd_wnd;
161 err = tcp_write(pcb, data1,
sizeof(data1), TCP_WRITE_FLAG_COPY);
163 err = tcp_output(pcb);
167 memset(&txcounters, 0,
sizeof(txcounters));
175 err = tcp_write(pcb, data2,
sizeof(data2), TCP_WRITE_FLAG_COPY);
177 err = tcp_output(pcb);
181 memset(&txcounters, 0,
sizeof(txcounters));
189 err = tcp_write(pcb, data3,
sizeof(data3), TCP_WRITE_FLAG_COPY);
191 err = tcp_output(pcb);
196 memset(&txcounters, 0,
sizeof(txcounters));
204 err = tcp_write(pcb, data4,
sizeof(data4), TCP_WRITE_FLAG_COPY);
212 memset(&txcounters, 0,
sizeof(txcounters));
216 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
222 memset(&txcounters, 0,
sizeof(txcounters));
227 err = tcp_write(pcb, data6,
TCP_MSS, TCP_WRITE_FLAG_COPY);
232 err = tcp_output(pcb);
236 memset(&txcounters, 0,
sizeof(txcounters));
239 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
241 err = tcp_output(pcb);
244 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
246 err = tcp_output(pcb);
249 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
251 err = tcp_output(pcb);
254 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
256 err = tcp_output(pcb);
266 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
268 err = tcp_output(pcb);
271 err = tcp_write(pcb, data5,
sizeof(data5), TCP_WRITE_FLAG_COPY);
273 err = tcp_output(pcb);
291 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
293 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
300 check_seqnos(
struct tcp_seg *segs,
int num_expected,
u32_t *seqnos_expected)
302 struct tcp_seg *s = segs;
304 for (i = 0; i < num_expected; i++, s = s->next) {
306 EXPECT(s->tcphdr->seqno ==
htonl(seqnos_expected[i]));
322 u16_t remote_port = 0x100, local_port = 0x101;
324 #define SEQNO1 (0xFFFFFF00 - TCP_MSS) 326 u16_t i, sent_total = 0;
336 for (i = 0; i <
sizeof(tx_data); i++) {
337 tx_data[i] = (
u8_t)i;
341 IP_ADDR4(&local_ip, 192, 168, 1, 1);
342 IP_ADDR4(&remote_ip, 192, 168, 1, 2);
343 IP_ADDR4(&netmask, 255, 255, 255, 0);
345 memset(&counters, 0,
sizeof(counters));
352 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
358 for (i = 0; i < 6; i++) {
359 err = tcp_write(pcb, &tx_data[sent_total],
TCP_MSS, TCP_WRITE_FLAG_COPY);
363 check_seqnos(pcb->unsent, 6, seqnos);
365 err = tcp_output(pcb);
368 memset(&txcounters, 0,
sizeof(txcounters));
370 check_seqnos(pcb->unacked, 2, seqnos);
371 check_seqnos(pcb->unsent, 4, &seqnos[2]);
379 memset(&txcounters, 0,
sizeof(txcounters));
380 check_seqnos(pcb->unacked, 2, &seqnos[1]);
381 check_seqnos(pcb->unsent, 3, &seqnos[3]);
384 EXPECT(pcb->dupacks == 0);
388 EXPECT(pcb->dupacks == 1);
392 EXPECT(pcb->dupacks == 2);
396 EXPECT(pcb->dupacks == 3);
398 memset(&txcounters, 0,
sizeof(txcounters));
400 check_seqnos(pcb->unacked, 5, &seqnos[1]);
403 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
405 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
419 u16_t remote_port = 0x100, local_port = 0x101;
421 #define SEQNO1 (0xFFFFFF00 - TCP_MSS) 423 u16_t i, sent_total = 0;
433 for (i = 0; i <
sizeof(tx_data); i++) {
434 tx_data[i] = (
u8_t)i;
438 IP_ADDR4(&local_ip, 192, 168, 1, 1);
439 IP_ADDR4(&remote_ip, 192, 168, 1, 2);
440 IP_ADDR4(&netmask, 255, 255, 255, 0);
442 memset(&counters, 0,
sizeof(counters));
446 tcp_ticks = 0 - tcp_next_iss();
447 tcp_ticks =
SEQNO1 - tcp_next_iss();
451 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
457 for (i = 0; i < 6; i++) {
458 err = tcp_write(pcb, &tx_data[sent_total],
TCP_MSS, TCP_WRITE_FLAG_COPY);
462 check_seqnos(pcb->unsent, 6, seqnos);
464 err = tcp_output(pcb);
467 memset(&txcounters, 0,
sizeof(txcounters));
469 check_seqnos(pcb->unacked, 2, seqnos);
470 check_seqnos(pcb->unsent, 4, &seqnos[2]);
473 for (i = 0; i < 10; i++) {
480 check_seqnos(pcb->unacked, 1, seqnos);
481 check_seqnos(pcb->unsent, 5, &seqnos[1]);
484 pcb->cwnd = pcb->snd_wnd;
486 err = tcp_output(pcb);
490 check_seqnos(pcb->unacked, 6, seqnos);
493 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
495 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
501 static void test_tcp_tx_full_window_lost(
u8_t zero_window_probe_from_unsent)
509 u16_t remote_port = 0x100, local_port = 0x101;
512 u8_t expected = 0xFE;
514 for (i = 0; i <
sizeof(tx_data); i++) {
521 if (zero_window_probe_from_unsent) {
524 tx_data[0] = expected;
528 IP_ADDR4(&local_ip, 192, 168, 1, 1);
529 IP_ADDR4(&remote_ip, 192, 168, 1, 2);
530 IP_ADDR4(&netmask, 255, 255, 255, 0);
532 memset(&counters, 0,
sizeof(counters));
533 memset(&txcounters, 0,
sizeof(txcounters));
538 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
541 pcb->cwnd = pcb->snd_wnd;
547 err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
549 err = tcp_output(pcb);
553 memset(&txcounters, 0,
sizeof(txcounters));
554 sent_total += initial_data_len;
557 err = tcp_write(pcb, &tx_data[sent_total],
TCP_MSS, TCP_WRITE_FLAG_COPY);
559 err = tcp_output(pcb);
563 memset(&txcounters, 0,
sizeof(txcounters));
574 EXPECT(pcb->persist_backoff == 0);
576 err = tcp_write(pcb, &tx_data[sent_total],
TCP_MSS, TCP_WRITE_FLAG_COPY);
579 err = tcp_output(pcb);
583 memset(&txcounters, 0,
sizeof(txcounters));
584 EXPECT(pcb->persist_backoff == 0);
586 if (zero_window_probe_from_unsent) {
593 EXPECT(pcb->persist_backoff == 1);
597 err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
599 err = tcp_output(pcb);
603 memset(&txcounters, 0,
sizeof(txcounters));
604 if (!zero_window_probe_from_unsent) {
606 EXPECT(pcb->persist_backoff == 0);
608 EXPECT(pcb->persist_backoff == 1);
611 for (i = 0; i < 4; i++) {
638 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
640 EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
646 test_tcp_tx_full_window_lost(1);
653 test_tcp_tx_full_window_lost(0);
664 TESTFUNC(test_tcp_fast_retx_recover),
665 TESTFUNC(test_tcp_fast_rexmit_wraparound),
666 TESTFUNC(test_tcp_rto_rexmit_wraparound),
667 TESTFUNC(test_tcp_tx_full_window_lost_from_unacked),
668 TESTFUNC(test_tcp_tx_full_window_lost_from_unsent)
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
struct netif * netif_list
void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, ip_addr_t *ip_addr, ip_addr_t *netmask)
struct netif * netif_default
END_TEST Suite * tcp_suite(void)
u8_t pbuf_free(struct pbuf *p)
void tcp_remove_all(void)
void tcp_set_state(struct tcp_pcb *pcb, enum tcp_state state, ip_addr_t *local_ip, ip_addr_t *remote_ip, u16_t local_port, u16_t remote_port)
Suite * create_suite(const char *name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
void test_tcp_input(struct pbuf *p, struct netif *inp)
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
START_TEST(test_tcp_new_abort)
struct pbuf * tcp_create_rx_segment_wnd(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd)
#define LWIP_UNUSED_ARG(x)