[TCPIP]
[reactos.git] / reactos / lib / drivers / lwip / test / unit / tcp / test_tcp_oos.c
1 #include "test_tcp_oos.h"
2
3 #include "lwip/tcp.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 /** Get the seqno of a segment (by index) on the ooseq list
40 *
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
44 */
45 static u32_t
46 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
47 {
48 int num = 0;
49 struct tcp_seg* seg = pcb->ooseq;
50
51 /* then check the actual segment */
52 while(seg != NULL) {
53 if(num == seg_index) {
54 return seg->tcphdr->seqno;
55 }
56 num++;
57 seg = seg->next;
58 }
59 fail();
60 return 0;
61 }
62
63 /** Get the tcplen of a segment (by index) on the ooseq list
64 *
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
68 */
69 static int
70 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
71 {
72 int num = 0;
73 struct tcp_seg* seg = pcb->ooseq;
74
75 /* then check the actual segment */
76 while(seg != NULL) {
77 if(num == seg_index) {
78 return TCP_TCPLEN(seg);
79 }
80 num++;
81 seg = seg->next;
82 }
83 fail();
84 return -1;
85 }
86
87 /* Setup/teardown functions */
88
89 static void
90 tcp_oos_setup(void)
91 {
92 tcp_remove_all();
93 }
94
95 static void
96 tcp_oos_teardown(void)
97 {
98 tcp_remove_all();
99 }
100
101
102
103 /* Test functions */
104
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)
109 {
110 struct test_tcp_counters counters;
111 struct tcp_pcb* pcb;
112 struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
113 char data[] = {
114 1, 2, 3, 4,
115 5, 6, 7, 8,
116 9, 10, 11, 12,
117 13, 14, 15, 16};
118 struct ip_addr remote_ip, local_ip;
119 u16_t data_len;
120 u16_t remote_port = 0x100, local_port = 0x101;
121 struct netif netif;
122 LWIP_UNUSED_ARG(_i);
123
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;
133
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);
138
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 */
143 /* seqno: 8..16 */
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) */
146 /* seqno: 4..11 */
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 */
149 /* seqno: 4..13 */
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 */
152 /* seqno: 2..15 */
153 p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
154 /* FIN, seqno 16 */
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 */
174
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 */
188
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 */
202
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 */
216
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 */
230
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);
239 }
240
241 /* make sure the pcb is freed */
242 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
243 tcp_abort(pcb);
244 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
245 }
246 END_TEST
247
248
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)
253 {
254 struct test_tcp_counters counters;
255 struct tcp_pcb* pcb;
256 struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
257 char data[] = {
258 1, 2, 3, 4,
259 5, 6, 7, 8,
260 9, 10, 11, 12,
261 13, 14, 15, 16};
262 struct ip_addr remote_ip, local_ip;
263 u16_t data_len;
264 u16_t remote_port = 0x100, local_port = 0x101;
265 struct netif netif;
266 LWIP_UNUSED_ARG(_i);
267
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;
277
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);
282
283 /* create segments */
284 /* p1: 7 bytes - 2 before FIN */
285 /* seqno: 1..2 */
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) */
288 /* seqno: 4..11 */
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 */
291 /* seqno: 3..13 */
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 */
294 /* seqno: 2..13 */
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! */
297 /* seqno: 0..3 */
298 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
299 /* p5: last byte before FIN */
300 /* seqno: 15 */
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);
328
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);
342
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);
357
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);
373
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);
382
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);
394
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);
406
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);
415 }
416
417 /* make sure the pcb is freed */
418 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
419 tcp_abort(pcb);
420 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
421 }
422 END_TEST
423
424 /** Create the suite including all tests for this module */
425 Suite *
426 tcp_oos_suite(void)
427 {
428 TFun tests[] = {
429 test_tcp_recv_ooseq_FIN_OOSEQ,
430 test_tcp_recv_ooseq_FIN_INSEQ,
431 };
432 return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
433 }