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 | }
|
---|