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