1 #include "test_tcp_oos.h"
3 #include "lwip/tcp_impl.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 ip_addr_t 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) == 1);
212 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
213 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
215 /* pass the segment to tcp_input */
216 tcp_input(p_fin, &netif);
217 /* check if counters are as expected */
218 EXPECT(counters.close_calls == 0);
219 EXPECT(counters.recv_calls == 0);
220 EXPECT(counters.recved_bytes == 0);
221 EXPECT(counters.err_calls == 0);
222 /* ooseq queue: unchanged */
223 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
224 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
225 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
227 /* pass the segment to tcp_input */
228 tcp_input(pinseq, &netif);
229 /* check if counters are as expected */
230 EXPECT(counters.close_calls == 1);
231 EXPECT(counters.recv_calls == 1);
232 EXPECT(counters.recved_bytes == data_len);
233 EXPECT(counters.err_calls == 0);
234 EXPECT(pcb->ooseq == NULL);
237 /* make sure the pcb is freed */
238 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
240 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
245 /** create multiple segments and pass them to tcp_input in a wrong
246 * order to see if ooseq-caching works correctly
247 * FIN is received IN-SEQUENCE at the end */
248 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
250 struct test_tcp_counters counters;
252 struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
258 ip_addr_t remote_ip, local_ip;
260 u16_t remote_port = 0x100, local_port = 0x101;
264 /* initialize local vars */
265 memset(&netif, 0, sizeof(netif));
266 IP4_ADDR(&local_ip, 192, 168, 1, 1);
267 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
268 data_len = sizeof(data);
269 /* initialize counter struct */
270 memset(&counters, 0, sizeof(counters));
271 counters.expected_data_len = data_len;
272 counters.expected_data = data;
274 /* create and initialize the pcb */
275 pcb = test_tcp_new_counters_pcb(&counters);
276 EXPECT_RET(pcb != NULL);
277 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
279 /* create segments */
280 /* p1: 7 bytes - 2 before FIN */
282 p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
283 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
285 p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
286 /* p3: same as p2 but 2 bytes longer and one byte more at the front */
288 p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
289 /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
291 p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
292 /* pinseq is the first segment that is held back to create ooseq! */
294 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
295 /* p5: last byte before FIN */
297 p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
298 /* p6: same as p5, should be ignored */
299 p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
300 /* pinseqFIN: last 2 bytes plus FIN */
301 /* only segment containing seqno 14 and FIN */
302 pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
303 EXPECT(pinseq != NULL);
304 EXPECT(p_1_2 != NULL);
305 EXPECT(p_4_8 != NULL);
306 EXPECT(p_3_11 != NULL);
307 EXPECT(p_2_12 != NULL);
308 EXPECT(p_15_1 != NULL);
309 EXPECT(p_15_1a != NULL);
310 EXPECT(pinseqFIN != NULL);
311 if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
312 && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
313 /* pass the segment to tcp_input */
314 tcp_input(p_1_2, &netif);
315 /* check if counters are as expected */
316 EXPECT(counters.close_calls == 0);
317 EXPECT(counters.recv_calls == 0);
318 EXPECT(counters.recved_bytes == 0);
319 EXPECT(counters.err_calls == 0);
320 /* check ooseq queue */
321 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
322 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
323 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
325 /* pass the segment to tcp_input */
326 tcp_input(p_4_8, &netif);
327 /* check if counters are as expected */
328 EXPECT(counters.close_calls == 0);
329 EXPECT(counters.recv_calls == 0);
330 EXPECT(counters.recved_bytes == 0);
331 EXPECT(counters.err_calls == 0);
332 /* check ooseq queue */
333 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
334 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
335 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
336 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
337 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
339 /* pass the segment to tcp_input */
340 tcp_input(p_3_11, &netif);
341 /* check if counters are as expected */
342 EXPECT(counters.close_calls == 0);
343 EXPECT(counters.recv_calls == 0);
344 EXPECT(counters.recved_bytes == 0);
345 EXPECT(counters.err_calls == 0);
346 /* check ooseq queue */
347 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
348 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
349 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
350 /* p_3_11 has removed p_4_8 from ooseq */
351 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
352 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
354 /* pass the segment to tcp_input */
355 tcp_input(p_2_12, &netif);
356 /* check if counters are as expected */
357 EXPECT(counters.close_calls == 0);
358 EXPECT(counters.recv_calls == 0);
359 EXPECT(counters.recved_bytes == 0);
360 EXPECT(counters.err_calls == 0);
361 /* check ooseq queue */
362 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
363 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
364 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
365 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
366 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
368 /* pass the segment to tcp_input */
369 tcp_input(pinseq, &netif);
370 /* check if counters are as expected */
371 EXPECT(counters.close_calls == 0);
372 EXPECT(counters.recv_calls == 1);
373 EXPECT(counters.recved_bytes == 14);
374 EXPECT(counters.err_calls == 0);
375 EXPECT(pcb->ooseq == NULL);
377 /* pass the segment to tcp_input */
378 tcp_input(p_15_1, &netif);
379 /* check if counters are as expected */
380 EXPECT(counters.close_calls == 0);
381 EXPECT(counters.recv_calls == 1);
382 EXPECT(counters.recved_bytes == 14);
383 EXPECT(counters.err_calls == 0);
384 /* check ooseq queue */
385 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
386 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
387 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
389 /* pass the segment to tcp_input */
390 tcp_input(p_15_1a, &netif);
391 /* check if counters are as expected */
392 EXPECT(counters.close_calls == 0);
393 EXPECT(counters.recv_calls == 1);
394 EXPECT(counters.recved_bytes == 14);
395 EXPECT(counters.err_calls == 0);
396 /* check ooseq queue: unchanged */
397 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
398 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
399 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
401 /* pass the segment to tcp_input */
402 tcp_input(pinseqFIN, &netif);
403 /* check if counters are as expected */
404 EXPECT(counters.close_calls == 1);
405 EXPECT(counters.recv_calls == 2);
406 EXPECT(counters.recved_bytes == data_len);
407 EXPECT(counters.err_calls == 0);
408 EXPECT(pcb->ooseq == NULL);
411 /* make sure the pcb is freed */
412 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
414 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
418 /** Create the suite including all tests for this module */
423 test_tcp_recv_ooseq_FIN_OOSEQ,
424 test_tcp_recv_ooseq_FIN_INSEQ,
426 return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);