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