[457] | 1 | #include "test_tcp_oos.h"
|
---|
| 2 |
|
---|
| 3 | #include "lwip/priv/tcp_priv.h"
|
---|
| 4 | #include "lwip/stats.h"
|
---|
| 5 | #include "tcp_helper.h"
|
---|
| 6 |
|
---|
| 7 | #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
|
---|
| 8 | #error "This tests needs TCP- and MEMP-statistics enabled"
|
---|
| 9 | #endif
|
---|
| 10 | #if !TCP_QUEUE_OOSEQ
|
---|
| 11 | #error "This tests needs TCP_QUEUE_OOSEQ enabled"
|
---|
| 12 | #endif
|
---|
| 13 |
|
---|
| 14 | /** CHECK_SEGMENTS_ON_OOSEQ:
|
---|
| 15 | * 1: check count, seqno and len of segments on pcb->ooseq (strict)
|
---|
| 16 | * 0: only check that bytes are received in correct order (less strict) */
|
---|
| 17 | #define CHECK_SEGMENTS_ON_OOSEQ 1
|
---|
| 18 |
|
---|
| 19 | #if CHECK_SEGMENTS_ON_OOSEQ
|
---|
| 20 | #define EXPECT_OOSEQ(x) EXPECT(x)
|
---|
| 21 | #else
|
---|
| 22 | #define EXPECT_OOSEQ(x)
|
---|
| 23 | #endif
|
---|
| 24 |
|
---|
| 25 | /* helper functions */
|
---|
| 26 |
|
---|
| 27 | /** Get the numbers of segments on the ooseq list */
|
---|
| 28 | static int tcp_oos_count(struct tcp_pcb* pcb)
|
---|
| 29 | {
|
---|
| 30 | int num = 0;
|
---|
| 31 | struct tcp_seg* seg = pcb->ooseq;
|
---|
| 32 | while(seg != NULL) {
|
---|
| 33 | num++;
|
---|
| 34 | seg = seg->next;
|
---|
| 35 | }
|
---|
| 36 | return num;
|
---|
| 37 | }
|
---|
| 38 |
|
---|
| 39 | #if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
---|
| 40 | /** Get the numbers of pbufs on the ooseq list */
|
---|
| 41 | static int tcp_oos_pbuf_count(struct tcp_pcb* pcb)
|
---|
| 42 | {
|
---|
| 43 | int num = 0;
|
---|
| 44 | struct tcp_seg* seg = pcb->ooseq;
|
---|
| 45 | while(seg != NULL) {
|
---|
| 46 | num += pbuf_clen(seg->p);
|
---|
| 47 | seg = seg->next;
|
---|
| 48 | }
|
---|
| 49 | return num;
|
---|
| 50 | }
|
---|
| 51 | #endif
|
---|
| 52 |
|
---|
| 53 | /** Get the seqno of a segment (by index) on the ooseq list
|
---|
| 54 | *
|
---|
| 55 | * @param pcb the pcb to check for ooseq segments
|
---|
| 56 | * @param seg_index index of the segment on the ooseq list
|
---|
| 57 | * @return seqno of the segment
|
---|
| 58 | */
|
---|
| 59 | static u32_t
|
---|
| 60 | tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
|
---|
| 61 | {
|
---|
| 62 | int num = 0;
|
---|
| 63 | struct tcp_seg* seg = pcb->ooseq;
|
---|
| 64 |
|
---|
| 65 | /* then check the actual segment */
|
---|
| 66 | while(seg != NULL) {
|
---|
| 67 | if(num == seg_index) {
|
---|
| 68 | return seg->tcphdr->seqno;
|
---|
| 69 | }
|
---|
| 70 | num++;
|
---|
| 71 | seg = seg->next;
|
---|
| 72 | }
|
---|
| 73 | fail();
|
---|
| 74 | return 0;
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
|
---|
| 78 | *
|
---|
| 79 | * @param pcb the pcb to check for ooseq segments
|
---|
| 80 | * @param seg_index index of the segment on the ooseq list
|
---|
| 81 | * @return tcplen of the segment
|
---|
| 82 | */
|
---|
| 83 | static int
|
---|
| 84 | tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
|
---|
| 85 | {
|
---|
| 86 | int num = 0;
|
---|
| 87 | struct tcp_seg* seg = pcb->ooseq;
|
---|
| 88 |
|
---|
| 89 | /* then check the actual segment */
|
---|
| 90 | while(seg != NULL) {
|
---|
| 91 | if(num == seg_index) {
|
---|
| 92 | return TCP_TCPLEN(seg);
|
---|
| 93 | }
|
---|
| 94 | num++;
|
---|
| 95 | seg = seg->next;
|
---|
| 96 | }
|
---|
| 97 | fail();
|
---|
| 98 | return -1;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
|
---|
| 102 | *
|
---|
| 103 | * @param pcb the pcb to check for ooseq segments
|
---|
| 104 | * @return tcplen of all segment
|
---|
| 105 | */
|
---|
| 106 | static int
|
---|
| 107 | tcp_oos_tcplen(struct tcp_pcb* pcb)
|
---|
| 108 | {
|
---|
| 109 | int len = 0;
|
---|
| 110 | struct tcp_seg* seg = pcb->ooseq;
|
---|
| 111 |
|
---|
| 112 | /* then check the actual segment */
|
---|
| 113 | while(seg != NULL) {
|
---|
| 114 | len += TCP_TCPLEN(seg);
|
---|
| 115 | seg = seg->next;
|
---|
| 116 | }
|
---|
| 117 | return len;
|
---|
| 118 | }
|
---|
| 119 |
|
---|
| 120 | /* Setup/teardown functions */
|
---|
| 121 | static struct netif *old_netif_list;
|
---|
| 122 | static struct netif *old_netif_default;
|
---|
| 123 |
|
---|
| 124 | static void
|
---|
| 125 | tcp_oos_setup(void)
|
---|
| 126 | {
|
---|
| 127 | old_netif_list = netif_list;
|
---|
| 128 | old_netif_default = netif_default;
|
---|
| 129 | netif_list = NULL;
|
---|
| 130 | netif_default = NULL;
|
---|
| 131 | tcp_remove_all();
|
---|
| 132 | lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
|
---|
| 133 | }
|
---|
| 134 |
|
---|
| 135 | static void
|
---|
| 136 | tcp_oos_teardown(void)
|
---|
| 137 | {
|
---|
| 138 | netif_list = NULL;
|
---|
| 139 | netif_default = NULL;
|
---|
| 140 | tcp_remove_all();
|
---|
| 141 | /* restore netif_list for next tests (e.g. loopif) */
|
---|
| 142 | netif_list = old_netif_list;
|
---|
| 143 | netif_default = old_netif_default;
|
---|
| 144 | lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 |
|
---|
| 148 |
|
---|
| 149 | /* Test functions */
|
---|
| 150 |
|
---|
| 151 | /** create multiple segments and pass them to tcp_input in a wrong
|
---|
| 152 | * order to see if ooseq-caching works correctly
|
---|
| 153 | * FIN is received in out-of-sequence segments only */
|
---|
| 154 | START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
---|
| 155 | {
|
---|
| 156 | struct test_tcp_counters counters;
|
---|
| 157 | struct tcp_pcb* pcb;
|
---|
| 158 | struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
|
---|
| 159 | char data[] = {
|
---|
| 160 | 1, 2, 3, 4,
|
---|
| 161 | 5, 6, 7, 8,
|
---|
| 162 | 9, 10, 11, 12,
|
---|
| 163 | 13, 14, 15, 16};
|
---|
| 164 | u16_t data_len;
|
---|
| 165 | struct netif netif;
|
---|
| 166 | LWIP_UNUSED_ARG(_i);
|
---|
| 167 |
|
---|
| 168 | /* initialize local vars */
|
---|
| 169 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 170 | data_len = sizeof(data);
|
---|
| 171 | /* initialize counter struct */
|
---|
| 172 | memset(&counters, 0, sizeof(counters));
|
---|
| 173 | counters.expected_data_len = data_len;
|
---|
| 174 | counters.expected_data = data;
|
---|
| 175 |
|
---|
| 176 | /* create and initialize the pcb */
|
---|
| 177 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 178 | EXPECT_RET(pcb != NULL);
|
---|
| 179 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 180 |
|
---|
| 181 | /* create segments */
|
---|
| 182 | /* pinseq is sent as last segment! */
|
---|
| 183 | pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
|
---|
| 184 | /* p1: 8 bytes before FIN */
|
---|
| 185 | /* seqno: 8..16 */
|
---|
| 186 | p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN);
|
---|
| 187 | /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
|
---|
| 188 | /* seqno: 4..11 */
|
---|
| 189 | p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
|
---|
| 190 | /* p3: same as p2 but 2 bytes longer */
|
---|
| 191 | /* seqno: 4..13 */
|
---|
| 192 | p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
|
---|
| 193 | /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
|
---|
| 194 | /* seqno: 2..15 */
|
---|
| 195 | p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
|
---|
| 196 | /* FIN, seqno 16 */
|
---|
| 197 | p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN);
|
---|
| 198 | EXPECT(pinseq != NULL);
|
---|
| 199 | EXPECT(p_8_9 != NULL);
|
---|
| 200 | EXPECT(p_4_8 != NULL);
|
---|
| 201 | EXPECT(p_4_10 != NULL);
|
---|
| 202 | EXPECT(p_2_14 != NULL);
|
---|
| 203 | EXPECT(p_fin != NULL);
|
---|
| 204 | if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
|
---|
| 205 | /* pass the segment to tcp_input */
|
---|
| 206 | test_tcp_input(p_8_9, &netif);
|
---|
| 207 | /* check if counters are as expected */
|
---|
| 208 | EXPECT(counters.close_calls == 0);
|
---|
| 209 | EXPECT(counters.recv_calls == 0);
|
---|
| 210 | EXPECT(counters.recved_bytes == 0);
|
---|
| 211 | EXPECT(counters.err_calls == 0);
|
---|
| 212 | /* check ooseq queue */
|
---|
| 213 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 214 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
|
---|
| 215 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
|
---|
| 216 |
|
---|
| 217 | /* pass the segment to tcp_input */
|
---|
| 218 | test_tcp_input(p_4_8, &netif);
|
---|
| 219 | /* check if counters are as expected */
|
---|
| 220 | EXPECT(counters.close_calls == 0);
|
---|
| 221 | EXPECT(counters.recv_calls == 0);
|
---|
| 222 | EXPECT(counters.recved_bytes == 0);
|
---|
| 223 | EXPECT(counters.err_calls == 0);
|
---|
| 224 | /* check ooseq queue */
|
---|
| 225 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
---|
| 226 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
|
---|
| 227 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
|
---|
| 228 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
---|
| 229 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
---|
| 230 |
|
---|
| 231 | /* pass the segment to tcp_input */
|
---|
| 232 | test_tcp_input(p_4_10, &netif);
|
---|
| 233 | /* check if counters are as expected */
|
---|
| 234 | EXPECT(counters.close_calls == 0);
|
---|
| 235 | EXPECT(counters.recv_calls == 0);
|
---|
| 236 | EXPECT(counters.recved_bytes == 0);
|
---|
| 237 | EXPECT(counters.err_calls == 0);
|
---|
| 238 | /* ooseq queue: unchanged */
|
---|
| 239 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
---|
| 240 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
|
---|
| 241 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
|
---|
| 242 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
|
---|
| 243 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
---|
| 244 |
|
---|
| 245 | /* pass the segment to tcp_input */
|
---|
| 246 | test_tcp_input(p_2_14, &netif);
|
---|
| 247 | /* check if counters are as expected */
|
---|
| 248 | EXPECT(counters.close_calls == 0);
|
---|
| 249 | EXPECT(counters.recv_calls == 0);
|
---|
| 250 | EXPECT(counters.recved_bytes == 0);
|
---|
| 251 | EXPECT(counters.err_calls == 0);
|
---|
| 252 | /* check ooseq queue */
|
---|
| 253 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 254 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
---|
| 255 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
---|
| 256 |
|
---|
| 257 | /* pass the segment to tcp_input */
|
---|
| 258 | test_tcp_input(p_fin, &netif);
|
---|
| 259 | /* check if counters are as expected */
|
---|
| 260 | EXPECT(counters.close_calls == 0);
|
---|
| 261 | EXPECT(counters.recv_calls == 0);
|
---|
| 262 | EXPECT(counters.recved_bytes == 0);
|
---|
| 263 | EXPECT(counters.err_calls == 0);
|
---|
| 264 | /* ooseq queue: unchanged */
|
---|
| 265 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 266 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
|
---|
| 267 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
---|
| 268 |
|
---|
| 269 | /* pass the segment to tcp_input */
|
---|
| 270 | test_tcp_input(pinseq, &netif);
|
---|
| 271 | /* check if counters are as expected */
|
---|
| 272 | EXPECT(counters.close_calls == 1);
|
---|
| 273 | EXPECT(counters.recv_calls == 1);
|
---|
| 274 | EXPECT(counters.recved_bytes == data_len);
|
---|
| 275 | EXPECT(counters.err_calls == 0);
|
---|
| 276 | EXPECT(pcb->ooseq == NULL);
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | /* make sure the pcb is freed */
|
---|
| 280 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 281 | tcp_abort(pcb);
|
---|
| 282 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 283 | }
|
---|
| 284 | END_TEST
|
---|
| 285 |
|
---|
| 286 |
|
---|
| 287 | /** create multiple segments and pass them to tcp_input in a wrong
|
---|
| 288 | * order to see if ooseq-caching works correctly
|
---|
| 289 | * FIN is received IN-SEQUENCE at the end */
|
---|
| 290 | START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
---|
| 291 | {
|
---|
| 292 | struct test_tcp_counters counters;
|
---|
| 293 | struct tcp_pcb* pcb;
|
---|
| 294 | struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
|
---|
| 295 | char data[] = {
|
---|
| 296 | 1, 2, 3, 4,
|
---|
| 297 | 5, 6, 7, 8,
|
---|
| 298 | 9, 10, 11, 12,
|
---|
| 299 | 13, 14, 15, 16};
|
---|
| 300 | u16_t data_len;
|
---|
| 301 | struct netif netif;
|
---|
| 302 | LWIP_UNUSED_ARG(_i);
|
---|
| 303 |
|
---|
| 304 | /* initialize local vars */
|
---|
| 305 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 306 | data_len = sizeof(data);
|
---|
| 307 | /* initialize counter struct */
|
---|
| 308 | memset(&counters, 0, sizeof(counters));
|
---|
| 309 | counters.expected_data_len = data_len;
|
---|
| 310 | counters.expected_data = data;
|
---|
| 311 |
|
---|
| 312 | /* create and initialize the pcb */
|
---|
| 313 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 314 | EXPECT_RET(pcb != NULL);
|
---|
| 315 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 316 |
|
---|
| 317 | /* create segments */
|
---|
| 318 | /* p1: 7 bytes - 2 before FIN */
|
---|
| 319 | /* seqno: 1..2 */
|
---|
| 320 | p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
|
---|
| 321 | /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
|
---|
| 322 | /* seqno: 4..11 */
|
---|
| 323 | p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
|
---|
| 324 | /* p3: same as p2 but 2 bytes longer and one byte more at the front */
|
---|
| 325 | /* seqno: 3..13 */
|
---|
| 326 | p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
|
---|
| 327 | /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
|
---|
| 328 | /* seqno: 2..13 */
|
---|
| 329 | p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
|
---|
| 330 | /* pinseq is the first segment that is held back to create ooseq! */
|
---|
| 331 | /* seqno: 0..3 */
|
---|
| 332 | pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
|
---|
| 333 | /* p5: last byte before FIN */
|
---|
| 334 | /* seqno: 15 */
|
---|
| 335 | p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
|
---|
| 336 | /* p6: same as p5, should be ignored */
|
---|
| 337 | p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
|
---|
| 338 | /* pinseqFIN: last 2 bytes plus FIN */
|
---|
| 339 | /* only segment containing seqno 14 and FIN */
|
---|
| 340 | pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
|
---|
| 341 | EXPECT(pinseq != NULL);
|
---|
| 342 | EXPECT(p_1_2 != NULL);
|
---|
| 343 | EXPECT(p_4_8 != NULL);
|
---|
| 344 | EXPECT(p_3_11 != NULL);
|
---|
| 345 | EXPECT(p_2_12 != NULL);
|
---|
| 346 | EXPECT(p_15_1 != NULL);
|
---|
| 347 | EXPECT(p_15_1a != NULL);
|
---|
| 348 | EXPECT(pinseqFIN != NULL);
|
---|
| 349 | if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
|
---|
| 350 | && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
|
---|
| 351 | /* pass the segment to tcp_input */
|
---|
| 352 | test_tcp_input(p_1_2, &netif);
|
---|
| 353 | /* check if counters are as expected */
|
---|
| 354 | EXPECT(counters.close_calls == 0);
|
---|
| 355 | EXPECT(counters.recv_calls == 0);
|
---|
| 356 | EXPECT(counters.recved_bytes == 0);
|
---|
| 357 | EXPECT(counters.err_calls == 0);
|
---|
| 358 | /* check ooseq queue */
|
---|
| 359 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 360 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
---|
| 361 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
|
---|
| 362 |
|
---|
| 363 | /* pass the segment to tcp_input */
|
---|
| 364 | test_tcp_input(p_4_8, &netif);
|
---|
| 365 | /* check if counters are as expected */
|
---|
| 366 | EXPECT(counters.close_calls == 0);
|
---|
| 367 | EXPECT(counters.recv_calls == 0);
|
---|
| 368 | EXPECT(counters.recved_bytes == 0);
|
---|
| 369 | EXPECT(counters.err_calls == 0);
|
---|
| 370 | /* check ooseq queue */
|
---|
| 371 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
---|
| 372 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
---|
| 373 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
|
---|
| 374 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
|
---|
| 375 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
|
---|
| 376 |
|
---|
| 377 | /* pass the segment to tcp_input */
|
---|
| 378 | test_tcp_input(p_3_11, &netif);
|
---|
| 379 | /* check if counters are as expected */
|
---|
| 380 | EXPECT(counters.close_calls == 0);
|
---|
| 381 | EXPECT(counters.recv_calls == 0);
|
---|
| 382 | EXPECT(counters.recved_bytes == 0);
|
---|
| 383 | EXPECT(counters.err_calls == 0);
|
---|
| 384 | /* check ooseq queue */
|
---|
| 385 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
---|
| 386 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
---|
| 387 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
|
---|
| 388 | /* p_3_11 has removed p_4_8 from ooseq */
|
---|
| 389 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
|
---|
| 390 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
|
---|
| 391 |
|
---|
| 392 | /* pass the segment to tcp_input */
|
---|
| 393 | test_tcp_input(p_2_12, &netif);
|
---|
| 394 | /* check if counters are as expected */
|
---|
| 395 | EXPECT(counters.close_calls == 0);
|
---|
| 396 | EXPECT(counters.recv_calls == 0);
|
---|
| 397 | EXPECT(counters.recved_bytes == 0);
|
---|
| 398 | EXPECT(counters.err_calls == 0);
|
---|
| 399 | /* check ooseq queue */
|
---|
| 400 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
|
---|
| 401 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
|
---|
| 402 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
---|
| 403 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
|
---|
| 404 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
|
---|
| 405 |
|
---|
| 406 | /* pass the segment to tcp_input */
|
---|
| 407 | test_tcp_input(pinseq, &netif);
|
---|
| 408 | /* check if counters are as expected */
|
---|
| 409 | EXPECT(counters.close_calls == 0);
|
---|
| 410 | EXPECT(counters.recv_calls == 1);
|
---|
| 411 | EXPECT(counters.recved_bytes == 14);
|
---|
| 412 | EXPECT(counters.err_calls == 0);
|
---|
| 413 | EXPECT(pcb->ooseq == NULL);
|
---|
| 414 |
|
---|
| 415 | /* pass the segment to tcp_input */
|
---|
| 416 | test_tcp_input(p_15_1, &netif);
|
---|
| 417 | /* check if counters are as expected */
|
---|
| 418 | EXPECT(counters.close_calls == 0);
|
---|
| 419 | EXPECT(counters.recv_calls == 1);
|
---|
| 420 | EXPECT(counters.recved_bytes == 14);
|
---|
| 421 | EXPECT(counters.err_calls == 0);
|
---|
| 422 | /* check ooseq queue */
|
---|
| 423 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 424 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
|
---|
| 425 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
---|
| 426 |
|
---|
| 427 | /* pass the segment to tcp_input */
|
---|
| 428 | test_tcp_input(p_15_1a, &netif);
|
---|
| 429 | /* check if counters are as expected */
|
---|
| 430 | EXPECT(counters.close_calls == 0);
|
---|
| 431 | EXPECT(counters.recv_calls == 1);
|
---|
| 432 | EXPECT(counters.recved_bytes == 14);
|
---|
| 433 | EXPECT(counters.err_calls == 0);
|
---|
| 434 | /* check ooseq queue: unchanged */
|
---|
| 435 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
|
---|
| 436 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
|
---|
| 437 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
---|
| 438 |
|
---|
| 439 | /* pass the segment to tcp_input */
|
---|
| 440 | test_tcp_input(pinseqFIN, &netif);
|
---|
| 441 | /* check if counters are as expected */
|
---|
| 442 | EXPECT(counters.close_calls == 1);
|
---|
| 443 | EXPECT(counters.recv_calls == 2);
|
---|
| 444 | EXPECT(counters.recved_bytes == data_len);
|
---|
| 445 | EXPECT(counters.err_calls == 0);
|
---|
| 446 | EXPECT(pcb->ooseq == NULL);
|
---|
| 447 | }
|
---|
| 448 |
|
---|
| 449 | /* make sure the pcb is freed */
|
---|
| 450 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 451 | tcp_abort(pcb);
|
---|
| 452 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 453 | }
|
---|
| 454 | END_TEST
|
---|
| 455 |
|
---|
| 456 | static char data_full_wnd[TCP_WND + TCP_MSS];
|
---|
| 457 |
|
---|
| 458 | /** create multiple segments and pass them to tcp_input with the first segment missing
|
---|
| 459 | * to simulate overruning the rxwin with ooseq queueing enabled */
|
---|
| 460 | START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
|
---|
| 461 | {
|
---|
| 462 | #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
|
---|
| 463 | int i, k;
|
---|
| 464 | struct test_tcp_counters counters;
|
---|
| 465 | struct tcp_pcb* pcb;
|
---|
| 466 | struct pbuf *pinseq, *p_ovr;
|
---|
| 467 | struct netif netif;
|
---|
| 468 | int datalen = 0;
|
---|
| 469 | int datalen2;
|
---|
| 470 |
|
---|
| 471 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
|
---|
| 472 | data_full_wnd[i] = (char)i;
|
---|
| 473 | }
|
---|
| 474 |
|
---|
| 475 | /* initialize local vars */
|
---|
| 476 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 477 | /* initialize counter struct */
|
---|
| 478 | memset(&counters, 0, sizeof(counters));
|
---|
| 479 | counters.expected_data_len = TCP_WND;
|
---|
| 480 | counters.expected_data = data_full_wnd;
|
---|
| 481 |
|
---|
| 482 | /* create and initialize the pcb */
|
---|
| 483 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 484 | EXPECT_RET(pcb != NULL);
|
---|
| 485 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 486 | pcb->rcv_nxt = 0x8000;
|
---|
| 487 |
|
---|
| 488 | /* create segments */
|
---|
| 489 | /* pinseq is sent as last segment! */
|
---|
| 490 | pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
|
---|
| 491 |
|
---|
| 492 | for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
|
---|
| 493 | int count, expected_datalen;
|
---|
| 494 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
|
---|
| 495 | TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
---|
| 496 | EXPECT_RET(p != NULL);
|
---|
| 497 | /* pass the segment to tcp_input */
|
---|
| 498 | test_tcp_input(p, &netif);
|
---|
| 499 | /* check if counters are as expected */
|
---|
| 500 | EXPECT(counters.close_calls == 0);
|
---|
| 501 | EXPECT(counters.recv_calls == 0);
|
---|
| 502 | EXPECT(counters.recved_bytes == 0);
|
---|
| 503 | EXPECT(counters.err_calls == 0);
|
---|
| 504 | /* check ooseq queue */
|
---|
| 505 | count = tcp_oos_count(pcb);
|
---|
| 506 | EXPECT_OOSEQ(count == k+1);
|
---|
| 507 | datalen = tcp_oos_tcplen(pcb);
|
---|
| 508 | if (i + TCP_MSS < TCP_WND) {
|
---|
| 509 | expected_datalen = (k+1)*TCP_MSS;
|
---|
| 510 | } else {
|
---|
| 511 | expected_datalen = TCP_WND - TCP_MSS;
|
---|
| 512 | }
|
---|
| 513 | if (datalen != expected_datalen) {
|
---|
| 514 | EXPECT_OOSEQ(datalen == expected_datalen);
|
---|
| 515 | }
|
---|
| 516 | }
|
---|
| 517 |
|
---|
| 518 | /* pass in one more segment, cleary overrunning the rxwin */
|
---|
| 519 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
---|
| 520 | EXPECT_RET(p_ovr != NULL);
|
---|
| 521 | /* pass the segment to tcp_input */
|
---|
| 522 | test_tcp_input(p_ovr, &netif);
|
---|
| 523 | /* check if counters are as expected */
|
---|
| 524 | EXPECT(counters.close_calls == 0);
|
---|
| 525 | EXPECT(counters.recv_calls == 0);
|
---|
| 526 | EXPECT(counters.recved_bytes == 0);
|
---|
| 527 | EXPECT(counters.err_calls == 0);
|
---|
| 528 | /* check ooseq queue */
|
---|
| 529 | EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
|
---|
| 530 | datalen2 = tcp_oos_tcplen(pcb);
|
---|
| 531 | EXPECT_OOSEQ(datalen == datalen2);
|
---|
| 532 |
|
---|
| 533 | /* now pass inseq */
|
---|
| 534 | test_tcp_input(pinseq, &netif);
|
---|
| 535 | EXPECT(pcb->ooseq == NULL);
|
---|
| 536 |
|
---|
| 537 | /* make sure the pcb is freed */
|
---|
| 538 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 539 | tcp_abort(pcb);
|
---|
| 540 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 541 | #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
|
---|
| 542 | LWIP_UNUSED_ARG(_i);
|
---|
| 543 | }
|
---|
| 544 | END_TEST
|
---|
| 545 |
|
---|
| 546 | /** similar to above test, except seqno starts near the max rxwin */
|
---|
| 547 | START_TEST(test_tcp_recv_ooseq_overrun_rxwin_edge)
|
---|
| 548 | {
|
---|
| 549 | #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
|
---|
| 550 | int i, k;
|
---|
| 551 | struct test_tcp_counters counters;
|
---|
| 552 | struct tcp_pcb* pcb;
|
---|
| 553 | struct pbuf *pinseq, *p_ovr;
|
---|
| 554 | struct netif netif;
|
---|
| 555 | int datalen = 0;
|
---|
| 556 | int datalen2;
|
---|
| 557 |
|
---|
| 558 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
|
---|
| 559 | data_full_wnd[i] = (char)i;
|
---|
| 560 | }
|
---|
| 561 |
|
---|
| 562 | /* initialize local vars */
|
---|
| 563 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 564 | /* initialize counter struct */
|
---|
| 565 | memset(&counters, 0, sizeof(counters));
|
---|
| 566 | counters.expected_data_len = TCP_WND;
|
---|
| 567 | counters.expected_data = data_full_wnd;
|
---|
| 568 |
|
---|
| 569 | /* create and initialize the pcb */
|
---|
| 570 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 571 | EXPECT_RET(pcb != NULL);
|
---|
| 572 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 573 | pcb->rcv_nxt = 0xffffffff - (TCP_WND / 2);
|
---|
| 574 |
|
---|
| 575 | /* create segments */
|
---|
| 576 | /* pinseq is sent as last segment! */
|
---|
| 577 | pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
|
---|
| 578 |
|
---|
| 579 | for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
|
---|
| 580 | int count, expected_datalen;
|
---|
| 581 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
|
---|
| 582 | TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
---|
| 583 | EXPECT_RET(p != NULL);
|
---|
| 584 | /* pass the segment to tcp_input */
|
---|
| 585 | test_tcp_input(p, &netif);
|
---|
| 586 | /* check if counters are as expected */
|
---|
| 587 | EXPECT(counters.close_calls == 0);
|
---|
| 588 | EXPECT(counters.recv_calls == 0);
|
---|
| 589 | EXPECT(counters.recved_bytes == 0);
|
---|
| 590 | EXPECT(counters.err_calls == 0);
|
---|
| 591 | /* check ooseq queue */
|
---|
| 592 | count = tcp_oos_count(pcb);
|
---|
| 593 | EXPECT_OOSEQ(count == k+1);
|
---|
| 594 | datalen = tcp_oos_tcplen(pcb);
|
---|
| 595 | if (i + TCP_MSS < TCP_WND) {
|
---|
| 596 | expected_datalen = (k+1)*TCP_MSS;
|
---|
| 597 | } else {
|
---|
| 598 | expected_datalen = TCP_WND - TCP_MSS;
|
---|
| 599 | }
|
---|
| 600 | if (datalen != expected_datalen) {
|
---|
| 601 | EXPECT_OOSEQ(datalen == expected_datalen);
|
---|
| 602 | }
|
---|
| 603 | }
|
---|
| 604 |
|
---|
| 605 | /* pass in one more segment, cleary overrunning the rxwin */
|
---|
| 606 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
---|
| 607 | EXPECT_RET(p_ovr != NULL);
|
---|
| 608 | /* pass the segment to tcp_input */
|
---|
| 609 | test_tcp_input(p_ovr, &netif);
|
---|
| 610 | /* check if counters are as expected */
|
---|
| 611 | EXPECT(counters.close_calls == 0);
|
---|
| 612 | EXPECT(counters.recv_calls == 0);
|
---|
| 613 | EXPECT(counters.recved_bytes == 0);
|
---|
| 614 | EXPECT(counters.err_calls == 0);
|
---|
| 615 | /* check ooseq queue */
|
---|
| 616 | EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
|
---|
| 617 | datalen2 = tcp_oos_tcplen(pcb);
|
---|
| 618 | EXPECT_OOSEQ(datalen == datalen2);
|
---|
| 619 |
|
---|
| 620 | /* now pass inseq */
|
---|
| 621 | test_tcp_input(pinseq, &netif);
|
---|
| 622 | EXPECT(pcb->ooseq == NULL);
|
---|
| 623 |
|
---|
| 624 | /* make sure the pcb is freed */
|
---|
| 625 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 626 | tcp_abort(pcb);
|
---|
| 627 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 628 | #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
|
---|
| 629 | LWIP_UNUSED_ARG(_i);
|
---|
| 630 | }
|
---|
| 631 | END_TEST
|
---|
| 632 |
|
---|
| 633 | START_TEST(test_tcp_recv_ooseq_max_bytes)
|
---|
| 634 | {
|
---|
| 635 | #if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
---|
| 636 | int i, k;
|
---|
| 637 | struct test_tcp_counters counters;
|
---|
| 638 | struct tcp_pcb* pcb;
|
---|
| 639 | struct pbuf *p_ovr;
|
---|
| 640 | struct netif netif;
|
---|
| 641 | int datalen = 0;
|
---|
| 642 | int datalen2;
|
---|
| 643 |
|
---|
| 644 | for(i = 0; i < sizeof(data_full_wnd); i++) {
|
---|
| 645 | data_full_wnd[i] = (char)i;
|
---|
| 646 | }
|
---|
| 647 |
|
---|
| 648 | /* initialize local vars */
|
---|
| 649 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 650 | /* initialize counter struct */
|
---|
| 651 | memset(&counters, 0, sizeof(counters));
|
---|
| 652 | counters.expected_data_len = TCP_WND;
|
---|
| 653 | counters.expected_data = data_full_wnd;
|
---|
| 654 |
|
---|
| 655 | /* create and initialize the pcb */
|
---|
| 656 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 657 | EXPECT_RET(pcb != NULL);
|
---|
| 658 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 659 | pcb->rcv_nxt = 0x8000;
|
---|
| 660 |
|
---|
| 661 | /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
|
---|
| 662 |
|
---|
| 663 | /* create segments and 'recv' them */
|
---|
| 664 | for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) {
|
---|
| 665 | int count;
|
---|
| 666 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k],
|
---|
| 667 | TCP_MSS, k, 0, TCP_ACK);
|
---|
| 668 | EXPECT_RET(p != NULL);
|
---|
| 669 | EXPECT_RET(p->next == NULL);
|
---|
| 670 | /* pass the segment to tcp_input */
|
---|
| 671 | test_tcp_input(p, &netif);
|
---|
| 672 | /* check if counters are as expected */
|
---|
| 673 | EXPECT(counters.close_calls == 0);
|
---|
| 674 | EXPECT(counters.recv_calls == 0);
|
---|
| 675 | EXPECT(counters.recved_bytes == 0);
|
---|
| 676 | EXPECT(counters.err_calls == 0);
|
---|
| 677 | /* check ooseq queue */
|
---|
| 678 | count = tcp_oos_pbuf_count(pcb);
|
---|
| 679 | EXPECT_OOSEQ(count == i);
|
---|
| 680 | datalen = tcp_oos_tcplen(pcb);
|
---|
| 681 | EXPECT_OOSEQ(datalen == (i * TCP_MSS));
|
---|
| 682 | }
|
---|
| 683 |
|
---|
| 684 | /* pass in one more segment, overrunning the limit */
|
---|
| 685 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK);
|
---|
| 686 | EXPECT_RET(p_ovr != NULL);
|
---|
| 687 | /* pass the segment to tcp_input */
|
---|
| 688 | test_tcp_input(p_ovr, &netif);
|
---|
| 689 | /* check if counters are as expected */
|
---|
| 690 | EXPECT(counters.close_calls == 0);
|
---|
| 691 | EXPECT(counters.recv_calls == 0);
|
---|
| 692 | EXPECT(counters.recved_bytes == 0);
|
---|
| 693 | EXPECT(counters.err_calls == 0);
|
---|
| 694 | /* check ooseq queue (ensure the new segment was not accepted) */
|
---|
| 695 | EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
|
---|
| 696 | datalen2 = tcp_oos_tcplen(pcb);
|
---|
| 697 | EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS));
|
---|
| 698 |
|
---|
| 699 | /* make sure the pcb is freed */
|
---|
| 700 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 701 | tcp_abort(pcb);
|
---|
| 702 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 703 | #endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */
|
---|
| 704 | LWIP_UNUSED_ARG(_i);
|
---|
| 705 | }
|
---|
| 706 | END_TEST
|
---|
| 707 |
|
---|
| 708 | START_TEST(test_tcp_recv_ooseq_max_pbufs)
|
---|
| 709 | {
|
---|
| 710 | #if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
|
---|
| 711 | int i;
|
---|
| 712 | struct test_tcp_counters counters;
|
---|
| 713 | struct tcp_pcb* pcb;
|
---|
| 714 | struct pbuf *p_ovr;
|
---|
| 715 | struct netif netif;
|
---|
| 716 | int datalen = 0;
|
---|
| 717 | int datalen2;
|
---|
| 718 |
|
---|
| 719 | for(i = 0; i < sizeof(data_full_wnd); i++) {
|
---|
| 720 | data_full_wnd[i] = (char)i;
|
---|
| 721 | }
|
---|
| 722 |
|
---|
| 723 | /* initialize local vars */
|
---|
| 724 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 725 | /* initialize counter struct */
|
---|
| 726 | memset(&counters, 0, sizeof(counters));
|
---|
| 727 | counters.expected_data_len = TCP_WND;
|
---|
| 728 | counters.expected_data = data_full_wnd;
|
---|
| 729 |
|
---|
| 730 | /* create and initialize the pcb */
|
---|
| 731 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 732 | EXPECT_RET(pcb != NULL);
|
---|
| 733 | tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 734 | pcb->rcv_nxt = 0x8000;
|
---|
| 735 |
|
---|
| 736 | /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
|
---|
| 737 |
|
---|
| 738 | /* create segments and 'recv' them */
|
---|
| 739 | for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) {
|
---|
| 740 | int count;
|
---|
| 741 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i],
|
---|
| 742 | 1, i, 0, TCP_ACK);
|
---|
| 743 | EXPECT_RET(p != NULL);
|
---|
| 744 | EXPECT_RET(p->next == NULL);
|
---|
| 745 | /* pass the segment to tcp_input */
|
---|
| 746 | test_tcp_input(p, &netif);
|
---|
| 747 | /* check if counters are as expected */
|
---|
| 748 | EXPECT(counters.close_calls == 0);
|
---|
| 749 | EXPECT(counters.recv_calls == 0);
|
---|
| 750 | EXPECT(counters.recved_bytes == 0);
|
---|
| 751 | EXPECT(counters.err_calls == 0);
|
---|
| 752 | /* check ooseq queue */
|
---|
| 753 | count = tcp_oos_pbuf_count(pcb);
|
---|
| 754 | EXPECT_OOSEQ(count == i);
|
---|
| 755 | datalen = tcp_oos_tcplen(pcb);
|
---|
| 756 | EXPECT_OOSEQ(datalen == i);
|
---|
| 757 | }
|
---|
| 758 |
|
---|
| 759 | /* pass in one more segment, overrunning the limit */
|
---|
| 760 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK);
|
---|
| 761 | EXPECT_RET(p_ovr != NULL);
|
---|
| 762 | /* pass the segment to tcp_input */
|
---|
| 763 | test_tcp_input(p_ovr, &netif);
|
---|
| 764 | /* check if counters are as expected */
|
---|
| 765 | EXPECT(counters.close_calls == 0);
|
---|
| 766 | EXPECT(counters.recv_calls == 0);
|
---|
| 767 | EXPECT(counters.recved_bytes == 0);
|
---|
| 768 | EXPECT(counters.err_calls == 0);
|
---|
| 769 | /* check ooseq queue (ensure the new segment was not accepted) */
|
---|
| 770 | EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
|
---|
| 771 | datalen2 = tcp_oos_tcplen(pcb);
|
---|
| 772 | EXPECT_OOSEQ(datalen2 == (i-1));
|
---|
| 773 |
|
---|
| 774 | /* make sure the pcb is freed */
|
---|
| 775 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 776 | tcp_abort(pcb);
|
---|
| 777 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 778 | #endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */
|
---|
| 779 | LWIP_UNUSED_ARG(_i);
|
---|
| 780 | }
|
---|
| 781 | END_TEST
|
---|
| 782 |
|
---|
| 783 | static void
|
---|
| 784 | check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls,
|
---|
| 785 | u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
|
---|
| 786 | {
|
---|
| 787 | int oos_len;
|
---|
| 788 | EXPECT(counters->close_calls == exp_close_calls);
|
---|
| 789 | EXPECT(counters->recv_calls == exp_rx_calls);
|
---|
| 790 | EXPECT(counters->recved_bytes == exp_rx_bytes);
|
---|
| 791 | EXPECT(counters->err_calls == exp_err_calls);
|
---|
| 792 | /* check that pbuf is queued in ooseq */
|
---|
| 793 | EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count);
|
---|
| 794 | oos_len = tcp_oos_tcplen(pcb);
|
---|
| 795 | EXPECT_OOSEQ(exp_oos_len == oos_len);
|
---|
| 796 | }
|
---|
| 797 |
|
---|
| 798 | /* this test uses 4 packets:
|
---|
| 799 | * - data (len=TCP_MSS)
|
---|
| 800 | * - FIN
|
---|
| 801 | * - data after FIN (len=1) (invalid)
|
---|
| 802 | * - 2nd FIN (invalid)
|
---|
| 803 | *
|
---|
| 804 | * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
|
---|
| 805 | */
|
---|
| 806 | static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
|
---|
| 807 | {
|
---|
| 808 | int i, k;
|
---|
| 809 | struct test_tcp_counters counters;
|
---|
| 810 | struct tcp_pcb* pcb;
|
---|
| 811 | struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq;
|
---|
| 812 | struct netif netif;
|
---|
| 813 | u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0;
|
---|
| 814 | int first_dropped = 0xff;
|
---|
| 815 |
|
---|
| 816 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) {
|
---|
| 817 | data_full_wnd[i] = (char)i;
|
---|
| 818 | }
|
---|
| 819 |
|
---|
| 820 | /* initialize local vars */
|
---|
| 821 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask);
|
---|
| 822 | /* initialize counter struct */
|
---|
| 823 | memset(&counters, 0, sizeof(counters));
|
---|
| 824 | counters.expected_data_len = TCP_WND;
|
---|
| 825 | counters.expected_data = data_full_wnd;
|
---|
| 826 |
|
---|
| 827 | /* create and initialize the pcb */
|
---|
| 828 | pcb = test_tcp_new_counters_pcb(&counters);
|
---|
| 829 | EXPECT_RET(pcb != NULL);
|
---|
| 830 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
|
---|
| 831 | pcb->rcv_nxt = 0x8000;
|
---|
| 832 |
|
---|
| 833 | /* create segments */
|
---|
| 834 | p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
|
---|
| 835 | p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN);
|
---|
| 836 | k = 1;
|
---|
| 837 | p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK);
|
---|
| 838 | p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN);
|
---|
| 839 |
|
---|
| 840 | if(delay_packet & 1) {
|
---|
| 841 | /* drop normal data */
|
---|
| 842 | first_dropped = 1;
|
---|
| 843 | } else {
|
---|
| 844 | /* send normal data */
|
---|
| 845 | test_tcp_input(p, &netif);
|
---|
| 846 | exp_rx_calls++;
|
---|
| 847 | exp_rx_bytes += TCP_MSS;
|
---|
| 848 | }
|
---|
| 849 | /* check if counters are as expected */
|
---|
| 850 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 851 |
|
---|
| 852 | if(delay_packet & 2) {
|
---|
| 853 | /* drop FIN */
|
---|
| 854 | if(first_dropped > 2) {
|
---|
| 855 | first_dropped = 2;
|
---|
| 856 | }
|
---|
| 857 | } else {
|
---|
| 858 | /* send FIN */
|
---|
| 859 | test_tcp_input(p_normal_fin, &netif);
|
---|
| 860 | if (first_dropped < 2) {
|
---|
| 861 | /* already dropped packets, this one is ooseq */
|
---|
| 862 | exp_oos_pbufs++;
|
---|
| 863 | exp_oos_tcplen++;
|
---|
| 864 | } else {
|
---|
| 865 | /* inseq */
|
---|
| 866 | exp_close_calls++;
|
---|
| 867 | }
|
---|
| 868 | }
|
---|
| 869 | /* check if counters are as expected */
|
---|
| 870 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 871 |
|
---|
| 872 | if(delay_packet & 4) {
|
---|
| 873 | /* drop data-after-FIN */
|
---|
| 874 | if(first_dropped > 3) {
|
---|
| 875 | first_dropped = 3;
|
---|
| 876 | }
|
---|
| 877 | } else {
|
---|
| 878 | /* send data-after-FIN */
|
---|
| 879 | test_tcp_input(p_data_after_fin, &netif);
|
---|
| 880 | if (first_dropped < 3) {
|
---|
| 881 | /* already dropped packets, this one is ooseq */
|
---|
| 882 | if (delay_packet & 2) {
|
---|
| 883 | /* correct FIN was ooseq */
|
---|
| 884 | exp_oos_pbufs++;
|
---|
| 885 | exp_oos_tcplen += k;
|
---|
| 886 | }
|
---|
| 887 | } else {
|
---|
| 888 | /* inseq: no change */
|
---|
| 889 | }
|
---|
| 890 | }
|
---|
| 891 | /* check if counters are as expected */
|
---|
| 892 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 893 |
|
---|
| 894 | if(delay_packet & 8) {
|
---|
| 895 | /* drop 2nd-FIN */
|
---|
| 896 | if(first_dropped > 4) {
|
---|
| 897 | first_dropped = 4;
|
---|
| 898 | }
|
---|
| 899 | } else {
|
---|
| 900 | /* send 2nd-FIN */
|
---|
| 901 | test_tcp_input(p_2nd_fin_ooseq, &netif);
|
---|
| 902 | if (first_dropped < 3) {
|
---|
| 903 | /* already dropped packets, this one is ooseq */
|
---|
| 904 | if (delay_packet & 2) {
|
---|
| 905 | /* correct FIN was ooseq */
|
---|
| 906 | exp_oos_pbufs++;
|
---|
| 907 | exp_oos_tcplen++;
|
---|
| 908 | }
|
---|
| 909 | } else {
|
---|
| 910 | /* inseq: no change */
|
---|
| 911 | }
|
---|
| 912 | }
|
---|
| 913 | /* check if counters are as expected */
|
---|
| 914 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 915 |
|
---|
| 916 | if(delay_packet & 1) {
|
---|
| 917 | /* dropped normal data before */
|
---|
| 918 | test_tcp_input(p, &netif);
|
---|
| 919 | exp_rx_calls++;
|
---|
| 920 | exp_rx_bytes += TCP_MSS;
|
---|
| 921 | if((delay_packet & 2) == 0) {
|
---|
| 922 | /* normal FIN was NOT delayed */
|
---|
| 923 | exp_close_calls++;
|
---|
| 924 | exp_oos_pbufs = exp_oos_tcplen = 0;
|
---|
| 925 | }
|
---|
| 926 | }
|
---|
| 927 | /* check if counters are as expected */
|
---|
| 928 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 929 |
|
---|
| 930 | if(delay_packet & 2) {
|
---|
| 931 | /* dropped normal FIN before */
|
---|
| 932 | test_tcp_input(p_normal_fin, &netif);
|
---|
| 933 | exp_close_calls++;
|
---|
| 934 | exp_oos_pbufs = exp_oos_tcplen = 0;
|
---|
| 935 | }
|
---|
| 936 | /* check if counters are as expected */
|
---|
| 937 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 938 |
|
---|
| 939 | if(delay_packet & 4) {
|
---|
| 940 | /* dropped data-after-FIN before */
|
---|
| 941 | test_tcp_input(p_data_after_fin, &netif);
|
---|
| 942 | }
|
---|
| 943 | /* check if counters are as expected */
|
---|
| 944 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 945 |
|
---|
| 946 | if(delay_packet & 8) {
|
---|
| 947 | /* dropped 2nd-FIN before */
|
---|
| 948 | test_tcp_input(p_2nd_fin_ooseq, &netif);
|
---|
| 949 | }
|
---|
| 950 | /* check if counters are as expected */
|
---|
| 951 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
|
---|
| 952 |
|
---|
| 953 | /* check that ooseq data has been dumped */
|
---|
| 954 | EXPECT(pcb->ooseq == NULL);
|
---|
| 955 |
|
---|
| 956 | /* make sure the pcb is freed */
|
---|
| 957 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
|
---|
| 958 | tcp_abort(pcb);
|
---|
| 959 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
|
---|
| 960 | }
|
---|
| 961 |
|
---|
| 962 | /** create multiple segments and pass them to tcp_input with the first segment missing
|
---|
| 963 | * to simulate overruning the rxwin with ooseq queueing enabled */
|
---|
| 964 | #define FIN_TEST(name, num) \
|
---|
| 965 | START_TEST(name) \
|
---|
| 966 | { \
|
---|
| 967 | LWIP_UNUSED_ARG(_i); \
|
---|
| 968 | test_tcp_recv_ooseq_double_FINs(num); \
|
---|
| 969 | } \
|
---|
| 970 | END_TEST
|
---|
| 971 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0)
|
---|
| 972 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1)
|
---|
| 973 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2)
|
---|
| 974 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3)
|
---|
| 975 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4)
|
---|
| 976 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5)
|
---|
| 977 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6)
|
---|
| 978 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7)
|
---|
| 979 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8)
|
---|
| 980 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9)
|
---|
| 981 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10)
|
---|
| 982 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11)
|
---|
| 983 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12)
|
---|
| 984 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13)
|
---|
| 985 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14)
|
---|
| 986 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15)
|
---|
| 987 |
|
---|
| 988 |
|
---|
| 989 | /** Create the suite including all tests for this module */
|
---|
| 990 | Suite *
|
---|
| 991 | tcp_oos_suite(void)
|
---|
| 992 | {
|
---|
| 993 | testfunc tests[] = {
|
---|
| 994 | TESTFUNC(test_tcp_recv_ooseq_FIN_OOSEQ),
|
---|
| 995 | TESTFUNC(test_tcp_recv_ooseq_FIN_INSEQ),
|
---|
| 996 | TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin),
|
---|
| 997 | TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin_edge),
|
---|
| 998 | TESTFUNC(test_tcp_recv_ooseq_max_bytes),
|
---|
| 999 | TESTFUNC(test_tcp_recv_ooseq_max_pbufs),
|
---|
| 1000 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_0),
|
---|
| 1001 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_1),
|
---|
| 1002 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_2),
|
---|
| 1003 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_3),
|
---|
| 1004 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_4),
|
---|
| 1005 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_5),
|
---|
| 1006 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_6),
|
---|
| 1007 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_7),
|
---|
| 1008 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_8),
|
---|
| 1009 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_9),
|
---|
| 1010 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_10),
|
---|
| 1011 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_11),
|
---|
| 1012 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_12),
|
---|
| 1013 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_13),
|
---|
| 1014 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_14),
|
---|
| 1015 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_15)
|
---|
| 1016 | };
|
---|
| 1017 | return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(testfunc), tcp_oos_setup, tcp_oos_teardown);
|
---|
| 1018 | }
|
---|