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 netif_list = NULL; 50 netif_default = NULL; 51 tcp_remove_all(); 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 /* start in congestion advoidance */ 426 pcb->ssthresh = pcb->cwnd; 427 428 /* send 6 mss-sized segments */ 429 for (i = 0; i < 6; i++) { 430 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); 431 EXPECT_RET(err == ERR_OK); 432 sent_total += TCP_MSS; 433 } 434 check_seqnos(pcb->unsent, 6, seqnos); 435 EXPECT(pcb->unacked == NULL); 436 err = tcp_output(pcb); 437 EXPECT(txcounters.num_tx_calls == 2); 438 EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); 439 memset(&txcounters, 0, sizeof(txcounters)); 440 441 check_seqnos(pcb->unacked, 2, seqnos); 442 check_seqnos(pcb->unsent, 4, &seqnos[2]); 443 444 /* ACK the first segment */ 445 p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK); 446 test_tcp_input(p, &netif); 447 /* ensure this didn't trigger a retransmission. Only one 448 segment should be transmitted because cwnd opened up by 449 TCP_MSS and a fraction since we are in congestion avoidance */ 450 EXPECT(txcounters.num_tx_calls == 1); 451 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); 452 memset(&txcounters, 0, sizeof(txcounters)); 453 check_seqnos(pcb->unacked, 2, &seqnos[1]); 454 check_seqnos(pcb->unsent, 3, &seqnos[3]); 455 456 /* 3 dupacks */ 457 EXPECT(pcb->dupacks == 0); 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 == 1); 462 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); 463 test_tcp_input(p, &netif); 464 EXPECT(txcounters.num_tx_calls == 0); 465 EXPECT(pcb->dupacks == 2); 466 /* 3rd dupack -> fast rexmit */ 467 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); 468 test_tcp_input(p, &netif); 469 EXPECT(pcb->dupacks == 3); 470 EXPECT(txcounters.num_tx_calls == 4); 471 memset(&txcounters, 0, sizeof(txcounters)); 472 EXPECT(pcb->unsent == NULL); 473 check_seqnos(pcb->unacked, 5, &seqnos[1]); 474 475 /* make sure the pcb is freed */ 476 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); 477 tcp_abort(pcb); 478 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); 479 } 480 END_TEST 481 482 /** Send data with sequence numbers that wrap around the u32_t range. 483 * Then, provoke RTO retransmission and check that all 484 * segment lists are still properly sorted. */ 485 START_TEST(test_tcp_rto_rexmit_wraparound) 486 { 487 struct netif netif; 488 struct test_tcp_txcounters txcounters; 489 struct test_tcp_counters counters; 490 struct tcp_pcb* pcb; 491 ip_addr_t remote_ip, local_ip, netmask; 492 u16_t remote_port = 0x100, local_port = 0x101; 493 err_t err; 494 #define SEQNO1 (0xFFFFFF00 - TCP_MSS) 495 #define ISS 6510 496 u16_t i, sent_total = 0; 497 u32_t seqnos[] = { 498 SEQNO1, 499 SEQNO1 + (1 * TCP_MSS), 500 SEQNO1 + (2 * TCP_MSS), 501 SEQNO1 + (3 * TCP_MSS), 502 SEQNO1 + (4 * TCP_MSS), 503 SEQNO1 + (5 * TCP_MSS)}; 504 LWIP_UNUSED_ARG(_i); 505 506 for (i = 0; i < sizeof(tx_data); i++) { 507 tx_data[i] = (u8_t)i; 508 } 509 510 /* initialize local vars */ 511 IP_ADDR4(&local_ip, 192, 168, 1, 1); 512 IP_ADDR4(&remote_ip, 192, 168, 1, 2); 513 IP_ADDR4(&netmask, 255, 255, 255, 0); 514 test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); 515 memset(&counters, 0, sizeof(counters)); 516 517 /* create and initialize the pcb */ 518 tcp_ticks = 0; 519 tcp_ticks = 0 - tcp_next_iss(NULL); 520 tcp_ticks = SEQNO1 - tcp_next_iss(NULL); 521 pcb = test_tcp_new_counters_pcb(&counters); 522 EXPECT_RET(pcb != NULL); 523 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); 524 pcb->mss = TCP_MSS; 525 /* disable initial congestion window (we don't send a SYN here...) */ 526 pcb->cwnd = 2*TCP_MSS; 527 528 /* send 6 mss-sized segments */ 529 for (i = 0; i < 6; i++) { 530 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); 531 EXPECT_RET(err == ERR_OK); 532 sent_total += TCP_MSS; 533 } 534 check_seqnos(pcb->unsent, 6, seqnos); 535 EXPECT(pcb->unacked == NULL); 536 err = tcp_output(pcb); 537 EXPECT(txcounters.num_tx_calls == 2); 538 EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); 539 memset(&txcounters, 0, sizeof(txcounters)); 540 541 check_seqnos(pcb->unacked, 2, seqnos); 542 check_seqnos(pcb->unsent, 4, &seqnos[2]); 543 544 /* call the tcp timer some times */ 545 for (i = 0; i < 10; i++) { 546 test_tcp_tmr(); 547 EXPECT(txcounters.num_tx_calls == 0); 548 } 549 /* 11th call to tcp_tmr: RTO rexmit fires */ 550 test_tcp_tmr(); 551 EXPECT(txcounters.num_tx_calls == 1); 552 check_seqnos(pcb->unacked, 1, seqnos); 553 check_seqnos(pcb->unsent, 5, &seqnos[1]); 554 555 /* fake greater cwnd */ 556 pcb->cwnd = pcb->snd_wnd; 557 /* send more data */ 558 err = tcp_output(pcb); 559 EXPECT(err == ERR_OK); 560 /* check queues are sorted */ 561 EXPECT(pcb->unsent == NULL); 562 check_seqnos(pcb->unacked, 6, seqnos); 563 564 /* make sure the pcb is freed */ 565 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); 566 tcp_abort(pcb); 567 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); 568 } 569 END_TEST 570 571 /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. 572 * At the end, send more data. */ 573 static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent) 574 { 575 struct netif netif; 576 struct test_tcp_txcounters txcounters; 577 struct test_tcp_counters counters; 578 struct tcp_pcb* pcb; 579 struct pbuf *p; 580 ip_addr_t remote_ip, local_ip, netmask; 581 u16_t remote_port = 0x100, local_port = 0x101; 582 err_t err; 583 u16_t sent_total, i; 584 u8_t expected = 0xFE; 585 586 for (i = 0; i < sizeof(tx_data); i++) { 587 u8_t d = (u8_t)i; 588 if (d == 0xFE) { 589 d = 0xF0; 590 } 591 tx_data[i] = d; 592 } 593 if (zero_window_probe_from_unsent) { 594 tx_data[TCP_WND] = expected; 595 } else { 596 tx_data[0] = expected; 597 } 598 599 /* initialize local vars */ 600 IP_ADDR4(&local_ip, 192, 168, 1, 1); 601 IP_ADDR4(&remote_ip, 192, 168, 1, 2); 602 IP_ADDR4(&netmask, 255, 255, 255, 0); 603 test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); 604 memset(&counters, 0, sizeof(counters)); 605 memset(&txcounters, 0, sizeof(txcounters)); 606 607 /* create and initialize the pcb */ 608 pcb = test_tcp_new_counters_pcb(&counters); 609 EXPECT_RET(pcb != NULL); 610 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); 611 pcb->mss = TCP_MSS; 612 /* disable initial congestion window (we don't send a SYN here...) */ 613 pcb->cwnd = pcb->snd_wnd; 614 615 /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */ 616 sent_total = 0; 617 if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) { 618 u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS; 619 err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY); 620 EXPECT_RET(err == ERR_OK); 621 err = tcp_output(pcb); 622 EXPECT_RET(err == ERR_OK); 623 EXPECT(txcounters.num_tx_calls == 1); 624 EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U); 625 memset(&txcounters, 0, sizeof(txcounters)); 626 sent_total += initial_data_len; 627 } 628 for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) { 629 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); 630 EXPECT_RET(err == ERR_OK); 631 err = tcp_output(pcb); 632 EXPECT_RET(err == ERR_OK); 633 EXPECT(txcounters.num_tx_calls == 1); 634 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); 635 memset(&txcounters, 0, sizeof(txcounters)); 636 } 637 EXPECT(sent_total == (TCP_WND - TCP_MSS)); 638 639 /* now ACK the packet before the first */ 640 p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); 641 test_tcp_input(p, &netif); 642 /* ensure this didn't trigger a retransmission */ 643 EXPECT(txcounters.num_tx_calls == 0); 644 EXPECT(txcounters.num_tx_bytes == 0); 645 646 EXPECT(pcb->persist_backoff == 0); 647 /* send the last packet, now a complete window has been sent */ 648 err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); 649 sent_total += TCP_MSS; 650 EXPECT_RET(err == ERR_OK); 651 err = tcp_output(pcb); 652 EXPECT_RET(err == ERR_OK); 653 EXPECT(txcounters.num_tx_calls == 1); 654 EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); 655 memset(&txcounters, 0, sizeof(txcounters)); 656 EXPECT(pcb->persist_backoff == 0); 657 658 if (zero_window_probe_from_unsent) { 659 /* ACK all data but close the TX window */ 660 p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0); 661 test_tcp_input(p, &netif); 662 /* ensure this didn't trigger any transmission */ 663 EXPECT(txcounters.num_tx_calls == 0); 664 EXPECT(txcounters.num_tx_bytes == 0); 665 EXPECT(pcb->persist_backoff == 1); 666 } 667 668 /* send one byte more (out of window) -> persist timer starts */ 669 err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY); 670 EXPECT_RET(err == ERR_OK); 671 err = tcp_output(pcb); 672 EXPECT_RET(err == ERR_OK); 673 EXPECT(txcounters.num_tx_calls == 0); 674 EXPECT(txcounters.num_tx_bytes == 0); 675 memset(&txcounters, 0, sizeof(txcounters)); 676 if (!zero_window_probe_from_unsent) { 677 /* no persist timer unless a zero window announcement has been received */ 678 EXPECT(pcb->persist_backoff == 0); 679 } else { 680 EXPECT(pcb->persist_backoff == 1); 681 682 /* call tcp_timer some more times to let persist timer count up */ 683 for (i = 0; i < 4; i++) { 684 test_tcp_tmr(); 685 EXPECT(txcounters.num_tx_calls == 0); 686 EXPECT(txcounters.num_tx_bytes == 0); 687 } 688 689 /* this should trigger the zero-window-probe */ 690 txcounters.copy_tx_packets = 1; 691 test_tcp_tmr(); 692 txcounters.copy_tx_packets = 0; 693 EXPECT(txcounters.num_tx_calls == 1); 694 EXPECT(txcounters.num_tx_bytes == 1 + 40U); 695 EXPECT(txcounters.tx_packets != NULL); 696 if (txcounters.tx_packets != NULL) { 697 u8_t sent; 698 u16_t ret; 699 ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U); 700 EXPECT(ret == 1); 701 EXPECT(sent == expected); 702 } 703 if (txcounters.tx_packets != NULL) { 704 pbuf_free(txcounters.tx_packets); 705 txcounters.tx_packets = NULL; 706 } 707 } 708 709 /* make sure the pcb is freed */ 710 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); 711 tcp_abort(pcb); 712 EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); 713 } 714 715 START_TEST(test_tcp_tx_full_window_lost_from_unsent) 716 { 717 LWIP_UNUSED_ARG(_i); 718 test_tcp_tx_full_window_lost(1); 719 } 720 END_TEST 721 722 START_TEST(test_tcp_tx_full_window_lost_from_unacked) 723 { 724 LWIP_UNUSED_ARG(_i); 725 test_tcp_tx_full_window_lost(0); 726 } 727 END_TEST 728 729 /** Create the suite including all tests for this module */ 730 Suite * 731 tcp_suite(void) 732 { 733 testfunc tests[] = { 734 TESTFUNC(test_tcp_new_abort), 735 TESTFUNC(test_tcp_recv_inseq), 736 TESTFUNC(test_tcp_malformed_header), 737 TESTFUNC(test_tcp_fast_retx_recover), 738 TESTFUNC(test_tcp_fast_rexmit_wraparound), 739 TESTFUNC(test_tcp_rto_rexmit_wraparound), 740 TESTFUNC(test_tcp_tx_full_window_lost_from_unacked), 741 TESTFUNC(test_tcp_tx_full_window_lost_from_unsent) 742 }; 743 return create_suite("TCP", tests, sizeof(tests)/sizeof(testfunc), tcp_setup, tcp_teardown); 744 } 745