1 #include "test_tcp_oos.h"
4 #include "lwip/stats.h"
5 #include "tcp_helper.h"
7 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
8 #error "This tests needs TCP- and MEMP-statistics enabled"
11 #error "This tests needs TCP_QUEUE_OOSEQ enabled"
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
19 #if CHECK_SEGMENTS_ON_OOSEQ
20 #define EXPECT_OOSEQ(x) EXPECT(x)
22 #define EXPECT_OOSEQ(x)
25 /* helper functions */
27 /** Get the numbers of segments on the ooseq list */
28 static int tcp_oos_count(struct tcp_pcb
* pcb
)
31 struct tcp_seg
* seg
= pcb
->ooseq
;
39 /** Get the seqno of a segment (by index) on the ooseq list
41 * @param pcb the pcb to check for ooseq segments
42 * @param seg_index index of the segment on the ooseq list
43 * @return seqno of the segment
46 tcp_oos_seg_seqno(struct tcp_pcb
* pcb
, int seg_index
)
49 struct tcp_seg
* seg
= pcb
->ooseq
;
51 /* then check the actual segment */
53 if(num
== seg_index
) {
54 return seg
->tcphdr
->seqno
;
63 /** Get the tcplen of a segment (by index) on the ooseq list
65 * @param pcb the pcb to check for ooseq segments
66 * @param seg_index index of the segment on the ooseq list
67 * @return tcplen of the segment
70 tcp_oos_seg_tcplen(struct tcp_pcb
* pcb
, int seg_index
)
73 struct tcp_seg
* seg
= pcb
->ooseq
;
75 /* then check the actual segment */
77 if(num
== seg_index
) {
78 return TCP_TCPLEN(seg
);
87 /* Setup/teardown functions */
96 tcp_oos_teardown(void)
105 /** create multiple segments and pass them to tcp_input in a wrong
106 * order to see if ooseq-caching works correctly
107 * FIN is received in out-of-sequence segments only */
108 START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ
)
110 struct test_tcp_counters counters
;
112 struct pbuf
*p_8_9
, *p_4_8
, *p_4_10
, *p_2_14
, *p_fin
, *pinseq
;
118 struct ip_addr remote_ip
, local_ip
;
120 u16_t remote_port
= 0x100, local_port
= 0x101;
124 /* initialize local vars */
125 memset(&netif
, 0, sizeof(netif
));
126 IP4_ADDR(&local_ip
, 192, 168, 1, 1);
127 IP4_ADDR(&remote_ip
, 192, 168, 1, 2);
128 data_len
= sizeof(data
);
129 /* initialize counter struct */
130 memset(&counters
, 0, sizeof(counters
));
131 counters
.expected_data_len
= data_len
;
132 counters
.expected_data
= data
;
134 /* create and initialize the pcb */
135 pcb
= test_tcp_new_counters_pcb(&counters
);
136 EXPECT_RET(pcb
!= NULL
);
137 tcp_set_state(pcb
, ESTABLISHED
, &local_ip
, &remote_ip
, local_port
, remote_port
);
139 /* create segments */
140 /* pinseq is sent as last segment! */
141 pinseq
= tcp_create_rx_segment(pcb
, &data
[0], 4, 0, 0, TCP_ACK
);
142 /* p1: 8 bytes before FIN */
144 p_8_9
= tcp_create_rx_segment(pcb
, &data
[8], 8, 8, 0, TCP_ACK
|TCP_FIN
);
145 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
147 p_4_8
= tcp_create_rx_segment(pcb
, &data
[4], 8, 4, 0, TCP_ACK
);
148 /* p3: same as p2 but 2 bytes longer */
150 p_4_10
= tcp_create_rx_segment(pcb
, &data
[4], 10, 4, 0, TCP_ACK
);
151 /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
153 p_2_14
= tcp_create_rx_segment(pcb
, &data
[2], 14, 2, 0, TCP_ACK
);
155 p_fin
= tcp_create_rx_segment(pcb
, NULL
, 0,16, 0, TCP_ACK
|TCP_FIN
);
156 EXPECT(pinseq
!= NULL
);
157 EXPECT(p_8_9
!= NULL
);
158 EXPECT(p_4_8
!= NULL
);
159 EXPECT(p_4_10
!= NULL
);
160 EXPECT(p_2_14
!= NULL
);
161 EXPECT(p_fin
!= NULL
);
162 if ((pinseq
!= NULL
) && (p_8_9
!= NULL
) && (p_4_8
!= NULL
) && (p_4_10
!= NULL
) && (p_2_14
!= NULL
) && (p_fin
!= NULL
)) {
163 /* pass the segment to tcp_input */
164 tcp_input(p_8_9
, &netif
);
165 /* check if counters are as expected */
166 EXPECT(counters
.close_calls
== 0);
167 EXPECT(counters
.recv_calls
== 0);
168 EXPECT(counters
.recved_bytes
== 0);
169 EXPECT(counters
.err_calls
== 0);
170 /* check ooseq queue */
171 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 1);
172 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 8);
173 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 9); /* includes FIN */
175 /* pass the segment to tcp_input */
176 tcp_input(p_4_8
, &netif
);
177 /* check if counters are as expected */
178 EXPECT(counters
.close_calls
== 0);
179 EXPECT(counters
.recv_calls
== 0);
180 EXPECT(counters
.recved_bytes
== 0);
181 EXPECT(counters
.err_calls
== 0);
182 /* check ooseq queue */
183 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
184 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 4);
185 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 4);
186 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 8);
187 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 9); /* includes FIN */
189 /* pass the segment to tcp_input */
190 tcp_input(p_4_10
, &netif
);
191 /* check if counters are as expected */
192 EXPECT(counters
.close_calls
== 0);
193 EXPECT(counters
.recv_calls
== 0);
194 EXPECT(counters
.recved_bytes
== 0);
195 EXPECT(counters
.err_calls
== 0);
196 /* ooseq queue: unchanged */
197 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
198 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 4);
199 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 4);
200 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 8);
201 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 9); /* includes FIN */
203 /* pass the segment to tcp_input */
204 tcp_input(p_2_14
, &netif
);
205 /* check if counters are as expected */
206 EXPECT(counters
.close_calls
== 0);
207 EXPECT(counters
.recv_calls
== 0);
208 EXPECT(counters
.recved_bytes
== 0);
209 EXPECT(counters
.err_calls
== 0);
210 /* check ooseq queue */
211 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
212 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 2);
213 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 6);
214 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 8);
215 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 9); /* includes FIN */
217 /* pass the segment to tcp_input */
218 tcp_input(p_fin
, &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 /* ooseq queue: unchanged */
225 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
226 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 2);
227 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 6);
228 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 8);
229 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 9); /* includes FIN */
231 /* pass the segment to tcp_input */
232 tcp_input(pinseq
, &netif
);
233 /* check if counters are as expected */
234 EXPECT(counters
.close_calls
== 1);
235 EXPECT(counters
.recv_calls
== 1);
236 EXPECT(counters
.recved_bytes
== data_len
);
237 EXPECT(counters
.err_calls
== 0);
238 EXPECT(pcb
->ooseq
== NULL
);
241 /* make sure the pcb is freed */
242 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
244 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
249 /** create multiple segments and pass them to tcp_input in a wrong
250 * order to see if ooseq-caching works correctly
251 * FIN is received IN-SEQUENCE at the end */
252 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ
)
254 struct test_tcp_counters counters
;
256 struct pbuf
*p_1_2
, *p_4_8
, *p_3_11
, *p_2_12
, *p_15_1
, *p_15_1a
, *pinseq
, *pinseqFIN
;
262 struct ip_addr remote_ip
, local_ip
;
264 u16_t remote_port
= 0x100, local_port
= 0x101;
268 /* initialize local vars */
269 memset(&netif
, 0, sizeof(netif
));
270 IP4_ADDR(&local_ip
, 192, 168, 1, 1);
271 IP4_ADDR(&remote_ip
, 192, 168, 1, 2);
272 data_len
= sizeof(data
);
273 /* initialize counter struct */
274 memset(&counters
, 0, sizeof(counters
));
275 counters
.expected_data_len
= data_len
;
276 counters
.expected_data
= data
;
278 /* create and initialize the pcb */
279 pcb
= test_tcp_new_counters_pcb(&counters
);
280 EXPECT_RET(pcb
!= NULL
);
281 tcp_set_state(pcb
, ESTABLISHED
, &local_ip
, &remote_ip
, local_port
, remote_port
);
283 /* create segments */
284 /* p1: 7 bytes - 2 before FIN */
286 p_1_2
= tcp_create_rx_segment(pcb
, &data
[1], 2, 1, 0, TCP_ACK
);
287 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
289 p_4_8
= tcp_create_rx_segment(pcb
, &data
[4], 8, 4, 0, TCP_ACK
);
290 /* p3: same as p2 but 2 bytes longer and one byte more at the front */
292 p_3_11
= tcp_create_rx_segment(pcb
, &data
[3], 11, 3, 0, TCP_ACK
);
293 /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
295 p_2_12
= tcp_create_rx_segment(pcb
, &data
[2], 12, 2, 0, TCP_ACK
);
296 /* pinseq is the first segment that is held back to create ooseq! */
298 pinseq
= tcp_create_rx_segment(pcb
, &data
[0], 4, 0, 0, TCP_ACK
);
299 /* p5: last byte before FIN */
301 p_15_1
= tcp_create_rx_segment(pcb
, &data
[15], 1, 15, 0, TCP_ACK
);
302 /* p6: same as p5, should be ignored */
303 p_15_1a
= tcp_create_rx_segment(pcb
, &data
[15], 1, 15, 0, TCP_ACK
);
304 /* pinseqFIN: last 2 bytes plus FIN */
305 /* only segment containing seqno 14 and FIN */
306 pinseqFIN
= tcp_create_rx_segment(pcb
, &data
[14], 2, 14, 0, TCP_ACK
|TCP_FIN
);
307 EXPECT(pinseq
!= NULL
);
308 EXPECT(p_1_2
!= NULL
);
309 EXPECT(p_4_8
!= NULL
);
310 EXPECT(p_3_11
!= NULL
);
311 EXPECT(p_2_12
!= NULL
);
312 EXPECT(p_15_1
!= NULL
);
313 EXPECT(p_15_1a
!= NULL
);
314 EXPECT(pinseqFIN
!= NULL
);
315 if ((pinseq
!= NULL
) && (p_1_2
!= NULL
) && (p_4_8
!= NULL
) && (p_3_11
!= NULL
) && (p_2_12
!= NULL
)
316 && (p_15_1
!= NULL
) && (p_15_1a
!= NULL
) && (pinseqFIN
!= NULL
)) {
317 /* pass the segment to tcp_input */
318 tcp_input(p_1_2
, &netif
);
319 /* check if counters are as expected */
320 EXPECT(counters
.close_calls
== 0);
321 EXPECT(counters
.recv_calls
== 0);
322 EXPECT(counters
.recved_bytes
== 0);
323 EXPECT(counters
.err_calls
== 0);
324 /* check ooseq queue */
325 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 1);
326 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 1);
327 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 2);
329 /* pass the segment to tcp_input */
330 tcp_input(p_4_8
, &netif
);
331 /* check if counters are as expected */
332 EXPECT(counters
.close_calls
== 0);
333 EXPECT(counters
.recv_calls
== 0);
334 EXPECT(counters
.recved_bytes
== 0);
335 EXPECT(counters
.err_calls
== 0);
336 /* check ooseq queue */
337 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
338 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 1);
339 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 2);
340 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 4);
341 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 8);
343 /* pass the segment to tcp_input */
344 tcp_input(p_3_11
, &netif
);
345 /* check if counters are as expected */
346 EXPECT(counters
.close_calls
== 0);
347 EXPECT(counters
.recv_calls
== 0);
348 EXPECT(counters
.recved_bytes
== 0);
349 EXPECT(counters
.err_calls
== 0);
350 /* check ooseq queue */
351 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 2);
352 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 1);
353 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 2);
354 /* p_3_11 has removed p_4_8 from ooseq */
355 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 3);
356 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 11);
358 /* pass the segment to tcp_input */
359 tcp_input(p_2_12
, &netif
);
360 /* check if counters are as expected */
361 EXPECT(counters
.close_calls
== 0);
362 EXPECT(counters
.recv_calls
== 0);
363 EXPECT(counters
.recved_bytes
== 0);
364 EXPECT(counters
.err_calls
== 0);
365 /* check ooseq queue */
366 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 3);
367 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 1);
368 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 1);
369 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 1) == 2);
370 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 1) == 1);
371 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 2) == 3);
372 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 2) == 11);
374 /* pass the segment to tcp_input */
375 tcp_input(pinseq
, &netif
);
376 /* check if counters are as expected */
377 EXPECT(counters
.close_calls
== 0);
378 EXPECT(counters
.recv_calls
== 1);
379 EXPECT(counters
.recved_bytes
== 14);
380 EXPECT(counters
.err_calls
== 0);
381 EXPECT(pcb
->ooseq
== NULL
);
383 /* pass the segment to tcp_input */
384 tcp_input(p_15_1
, &netif
);
385 /* check if counters are as expected */
386 EXPECT(counters
.close_calls
== 0);
387 EXPECT(counters
.recv_calls
== 1);
388 EXPECT(counters
.recved_bytes
== 14);
389 EXPECT(counters
.err_calls
== 0);
390 /* check ooseq queue */
391 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 1);
392 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 15);
393 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 1);
395 /* pass the segment to tcp_input */
396 tcp_input(p_15_1a
, &netif
);
397 /* check if counters are as expected */
398 EXPECT(counters
.close_calls
== 0);
399 EXPECT(counters
.recv_calls
== 1);
400 EXPECT(counters
.recved_bytes
== 14);
401 EXPECT(counters
.err_calls
== 0);
402 /* check ooseq queue: unchanged */
403 EXPECT_OOSEQ(tcp_oos_count(pcb
) == 1);
404 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb
, 0) == 15);
405 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb
, 0) == 1);
407 /* pass the segment to tcp_input */
408 tcp_input(pinseqFIN
, &netif
);
409 /* check if counters are as expected */
410 EXPECT(counters
.close_calls
== 1);
411 EXPECT(counters
.recv_calls
== 2);
412 EXPECT(counters
.recved_bytes
== data_len
);
413 EXPECT(counters
.err_calls
== 0);
414 EXPECT(pcb
->ooseq
== NULL
);
417 /* make sure the pcb is freed */
418 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
420 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
424 /** Create the suite including all tests for this module */
429 test_tcp_recv_ooseq_FIN_OOSEQ
,
430 test_tcp_recv_ooseq_FIN_INSEQ
,
432 return create_suite("TCP_OOS", tests
, sizeof(tests
)/sizeof(TFun
), tcp_oos_setup
, tcp_oos_teardown
);