source: mainline/uspace/srv/net/tcp/test/seq_no.c@ 3f932a7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3f932a7e was 3f932a7e, checked in by Jiri Svoboda <jiri@…>, 7 years ago

PCUT_INIT declaration also needs a terminating semicolon.

  • Property mode set to 100644
File size: 13.5 KB
RevLine 
[e73dbc1]1/*
2 * Copyright (c) 2017 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <errno.h>
30#include <inet/endpoint.h>
31#include <pcut/pcut.h>
32
33#include "../conn.h"
34#include "../segment.h"
35#include "../seq_no.h"
36
[3f932a7e]37PCUT_INIT;
[e73dbc1]38
39PCUT_TEST_SUITE(seq_no);
40
41/** Test seq_no_ack_acceptable() */
42PCUT_TEST(ack_acceptable)
43{
44 tcp_conn_t *conn;
45 inet_ep2_t epp;
46
47 inet_ep2_init(&epp);
48 conn = tcp_conn_new(&epp);
49 PCUT_ASSERT_NOT_NULL(conn);
50
51 /* ACK is acceptable iff SND.UNA < SEG.ACK <= SND.NXT */
52
53 conn->snd_una = 10;
54 conn->snd_nxt = 30;
55
56 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 9));
57 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 10));
58 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 11));
59 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 29));
60 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 30));
61 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 31));
62
63 /* We also test whether seq_no_lt_le() wraps around properly */
64
65 conn->snd_una = 30;
66 conn->snd_nxt = 10;
67
68 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 29));
69 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 30));
70 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 31));
71 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 9));
72 PCUT_ASSERT_TRUE(seq_no_ack_acceptable(conn, 10));
73 PCUT_ASSERT_FALSE(seq_no_ack_acceptable(conn, 11));
74
75 tcp_conn_delete(conn);
76}
77
78/** Test seq_no_ack_duplicate() */
79PCUT_TEST(ack_duplicate)
80{
81 tcp_conn_t *conn;
82 inet_ep2_t epp;
83
84 inet_ep2_init(&epp);
85 conn = tcp_conn_new(&epp);
86 PCUT_ASSERT_NOT_NULL(conn);
87
88 /* ACK is duplicate iff SEG.ACK <= SND.UNA */
89
90 conn->snd_una = 10;
91
92 PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, 9));
93 PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, 10));
94 PCUT_ASSERT_FALSE(seq_no_ack_duplicate(conn, 11));
95
96 conn->snd_una = (uint32_t) -10;
97
98 PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, (uint32_t) -11));
99 PCUT_ASSERT_TRUE(seq_no_ack_duplicate(conn, (uint32_t) -10));
100 PCUT_ASSERT_FALSE(seq_no_ack_duplicate(conn, (uint32_t) -9));
101
102 tcp_conn_delete(conn);
103}
104
105/** Test seq_no_in_rcv_wnd() */
106PCUT_TEST(in_rcv_wnd)
107{
108 tcp_conn_t *conn;
109 inet_ep2_t epp;
110
111 inet_ep2_init(&epp);
112 conn = tcp_conn_new(&epp);
113 PCUT_ASSERT_NOT_NULL(conn);
114
115 /* In receive window iff RCV.WND <= SEG.SEQ <= SND.UNA */
116
117 conn->rcv_nxt = 10;
118 conn->rcv_wnd = 20;
119
120 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 9));
121 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 10));
122 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 11));
123 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 29));
124 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 30));
125 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 31));
126
127 /* We also test whether seq_no_le_lt() wraps around properly */
128
129 conn->rcv_nxt = 20;
130 conn->rcv_wnd = (uint32_t) -10;
131
132 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn,19));
133 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 20));
134 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 21));
135 PCUT_ASSERT_TRUE(seq_no_in_rcv_wnd(conn, 9));
136 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 10));
137 PCUT_ASSERT_FALSE(seq_no_in_rcv_wnd(conn, 11));
138
139 tcp_conn_delete(conn);
140}
141
142/** Test seq_no_new_wnd_update() */
143PCUT_TEST(new_wnd_update)
144{
145 tcp_conn_t *conn;
146 inet_ep2_t epp;
147 tcp_segment_t *seg;
148
149 inet_ep2_init(&epp);
150 conn = tcp_conn_new(&epp);
151 PCUT_ASSERT_NOT_NULL(conn);
152
153 /*
154 * Segment must be acceptable. Segment has new window update iff
155 * either SND.WL1 < SEG.SEQ or
156 * (SND.WL1 = SEG.SEQ and SND.WL2 <= SEG.ACK)
157 */
158
159 conn->rcv_nxt = 10;
160 conn->rcv_wnd = 20;
161 conn->snd_una = 30;
162 conn->snd_wnd = 40;
163 conn->snd_wl1 = 15;
164 conn->snd_wl2 = 60;
165
166 seg = tcp_segment_make_ctrl(CTL_ACK);
167 PCUT_ASSERT_NOT_NULL(seg);
168
169 seg->seq = 14;
170 seg->ack = 80;
171 PCUT_ASSERT_FALSE(seq_no_new_wnd_update(conn, seg));
172
173 seg->seq = 15;
174 seg->ack = 59;
175 PCUT_ASSERT_FALSE(seq_no_new_wnd_update(conn, seg));
176
177 seg->seq = 15;
178 seg->ack = 60;
179 PCUT_ASSERT_TRUE(seq_no_new_wnd_update(conn, seg));
180
181 seg->seq = 16;
182 seg->ack = 50;
183 PCUT_ASSERT_TRUE(seq_no_new_wnd_update(conn, seg));
184
185 tcp_segment_delete(seg);
186 tcp_conn_delete(conn);
187}
188
189/** Test seq_no_segment_acked() */
190PCUT_TEST(segment_acked)
191{
192 tcp_conn_t *conn;
193 inet_ep2_t epp;
194 tcp_segment_t *seg;
195 uint8_t *data;
196 size_t dsize;
197
198 inet_ep2_init(&epp);
199 conn = tcp_conn_new(&epp);
200 PCUT_ASSERT_NOT_NULL(conn);
201
202 dsize = 15;
203 data = calloc(dsize, 1);
204 PCUT_ASSERT_NOT_NULL(data);
205
206 seg = tcp_segment_make_data(0, data, dsize);
207 PCUT_ASSERT_NOT_NULL(seg);
208
209 /* Segment is acked iff SEG.SEQ + SEG.LEN <= SND.UNA */
210
211 seg->seq = 10;
212 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
213
214 PCUT_ASSERT_FALSE(seq_no_segment_acked(conn, seg, 24));
215 PCUT_ASSERT_TRUE(seq_no_segment_acked(conn, seg, 25));
216
217 tcp_segment_delete(seg);
218 tcp_conn_delete(conn);
219 free(data);
220}
221
222/** Test seq_no_syn_acked() */
223PCUT_TEST(syn_acked)
224{
225 tcp_conn_t *conn;
226 inet_ep2_t epp;
227
228 inet_ep2_init(&epp);
229 conn = tcp_conn_new(&epp);
230 PCUT_ASSERT_NOT_NULL(conn);
231
232 conn->iss = 1;
233 conn->snd_una = 1;
234 conn->snd_nxt = 2;
235
236 PCUT_ASSERT_FALSE(seq_no_syn_acked(conn));
237
238 conn->snd_una = 2;
239 PCUT_ASSERT_TRUE(seq_no_syn_acked(conn));
240
241 tcp_conn_delete(conn);
242}
243
[1ddbf81]244/** Test seq_no_segment_ready() */
245PCUT_TEST(segment_ready)
246{
247 tcp_conn_t *conn;
248 inet_ep2_t epp;
249 tcp_segment_t *seg;
250 uint8_t *data;
251 size_t dsize;
252
253 inet_ep2_init(&epp);
254 conn = tcp_conn_new(&epp);
255 PCUT_ASSERT_NOT_NULL(conn);
256
257 dsize = 15;
258 data = calloc(dsize, 1);
259 PCUT_ASSERT_NOT_NULL(data);
260
261 seg = tcp_segment_make_data(0, data, dsize);
262 PCUT_ASSERT_NOT_NULL(seg);
263
264 /* Segment must be acceptable. Ready iff intersects RCV.NXT */
265
266 conn->rcv_nxt = 30;
267 conn->rcv_wnd = 20;
268
269 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
270
271 seg->seq = 16;
272 PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
273
274 seg->seq = 17;
275 PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
276
277 seg->seq = 29;
278 PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
279
280 seg->seq = 30;
281 PCUT_ASSERT_TRUE(seq_no_segment_ready(conn, seg));
282
283 seg->seq = 31;
284 PCUT_ASSERT_FALSE(seq_no_segment_ready(conn, seg));
285
286 tcp_segment_delete(seg);
287 tcp_conn_delete(conn);
288 free(data);
289}
290
[e73dbc1]291/** Test seq_no_segment_acceptable() */
292PCUT_TEST(segment_acceptable)
293{
294 tcp_conn_t *conn;
295 inet_ep2_t epp;
296 tcp_segment_t *seg;
297 uint8_t *data;
298 size_t dsize;
299
300 inet_ep2_init(&epp);
301 conn = tcp_conn_new(&epp);
302 PCUT_ASSERT_NOT_NULL(conn);
303
304 dsize = 15;
305 data = calloc(dsize, 1);
306 PCUT_ASSERT_NOT_NULL(data);
307
308 seg = tcp_segment_make_data(0, data, dsize);
309 PCUT_ASSERT_NOT_NULL(seg);
310
311 /* Segment acceptable iff overlaps receive window */
312
313 /* Segment shorter than receive window */
314 conn->rcv_nxt = 30;
315 conn->rcv_wnd = 20;
316
317 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
318
319 seg->seq = 10;
320 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
321
322 seg->seq = 15;
323 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
324
325 seg->seq = 16;
326 PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
327
328 seg->seq = 49;
329 PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
330
331 seg->seq = 50;
332 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
333
334 /* Segment longer than receive window */
335 conn->rcv_nxt = 30;
336 conn->rcv_wnd = 10;
337
338 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
339
340 seg->seq = 10;
341 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
342
343 seg->seq = 15;
344 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
345
346 seg->seq = 16;
347 PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
348
349 seg->seq = 39;
350 PCUT_ASSERT_TRUE(seq_no_segment_acceptable(conn, seg));
351
352 seg->seq = 40;
353 PCUT_ASSERT_FALSE(seq_no_segment_acceptable(conn, seg));
354
355 tcp_segment_delete(seg);
356 tcp_conn_delete(conn);
357 free(data);
358}
359
360/** Test seq_no_seg_trim_calc() */
361PCUT_TEST(seg_trim_calc)
362{
363 tcp_conn_t *conn;
364 inet_ep2_t epp;
365 tcp_segment_t *seg;
366 uint8_t *data;
367 size_t dsize;
368 uint32_t ltrim, rtrim;
369
370 inet_ep2_init(&epp);
371 conn = tcp_conn_new(&epp);
372 PCUT_ASSERT_NOT_NULL(conn);
373
374 dsize = 15;
375 data = calloc(dsize, 1);
376 PCUT_ASSERT_NOT_NULL(data);
377
378 seg = tcp_segment_make_data(0, data, dsize);
379 PCUT_ASSERT_NOT_NULL(seg);
380
381 /* Segment must be acceptable, amount of trim needed */
382
383 /* Segment shorter than receive window */
384 conn->rcv_nxt = 30;
385 conn->rcv_wnd = 20;
386
387 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
388
389 seg->seq = 16;
390 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
391 PCUT_ASSERT_INT_EQUALS(14, ltrim);
392 PCUT_ASSERT_INT_EQUALS(0, rtrim);
393
394 seg->seq = 17;
395 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
396 PCUT_ASSERT_INT_EQUALS(13, ltrim);
397 PCUT_ASSERT_INT_EQUALS(0, rtrim);
398
399 seg->seq = 29;
400 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
401 PCUT_ASSERT_INT_EQUALS(1, ltrim);
402 PCUT_ASSERT_INT_EQUALS(0, rtrim);
403
404 seg->seq = 30;
405 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
406 PCUT_ASSERT_INT_EQUALS(0, ltrim);
407 PCUT_ASSERT_INT_EQUALS(0, rtrim);
408
409 seg->seq = 31;
410 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
411 PCUT_ASSERT_INT_EQUALS(0, ltrim);
412 PCUT_ASSERT_INT_EQUALS(0, rtrim);
413
414 seg->seq = 35;
415 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
416 PCUT_ASSERT_INT_EQUALS(0, ltrim);
417 PCUT_ASSERT_INT_EQUALS(0, rtrim);
418
419 seg->seq = 36;
420 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
421 PCUT_ASSERT_INT_EQUALS(0, ltrim);
422 PCUT_ASSERT_INT_EQUALS(1, rtrim);
423
424 seg->seq = 37;
425 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
426 PCUT_ASSERT_INT_EQUALS(0, ltrim);
427 PCUT_ASSERT_INT_EQUALS(2, rtrim);
428
429 seg->seq = 48;
430 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
431 PCUT_ASSERT_INT_EQUALS(0, ltrim);
432 PCUT_ASSERT_INT_EQUALS(13, rtrim);
433
434 seg->seq = 49;
435 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
436 PCUT_ASSERT_INT_EQUALS(0, ltrim);
437 PCUT_ASSERT_INT_EQUALS(14, rtrim);
438
439 /* Segment longer than receive window */
440 conn->rcv_nxt = 30;
441 conn->rcv_wnd = 10;
442
443 PCUT_ASSERT_INT_EQUALS(dsize, seg->len);
444
445 seg->seq = 16;
446 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
447 PCUT_ASSERT_INT_EQUALS(14, ltrim);
448 PCUT_ASSERT_INT_EQUALS(0, rtrim);
449
450 seg->seq = 17;
451 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
452 PCUT_ASSERT_INT_EQUALS(13, ltrim);
453 PCUT_ASSERT_INT_EQUALS(0, rtrim);
454
455 seg->seq = 24;
456 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
457 PCUT_ASSERT_INT_EQUALS(6, ltrim);
458 PCUT_ASSERT_INT_EQUALS(0, rtrim);
459
460 seg->seq = 25;
461 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
462 PCUT_ASSERT_INT_EQUALS(5, ltrim);
463 PCUT_ASSERT_INT_EQUALS(0, rtrim);
464
465 seg->seq = 26;
466 seq_no_seg_trim_calc(conn, seg, &ltrim, &rtrim);
467 PCUT_ASSERT_INT_EQUALS(4, ltrim);
468 PCUT_ASSERT_INT_EQUALS(1, rtrim);
469
470 tcp_segment_delete(seg);
471 tcp_conn_delete(conn);
472 free(data);
473}
474
475/** Test seq_no_seg_cmp() */
476PCUT_TEST(seg_cmp)
477{
478 tcp_conn_t *conn;
479 inet_ep2_t epp;
480 tcp_segment_t *seg1, *seg2;
481 uint8_t *data;
482 size_t dsize;
483
484 inet_ep2_init(&epp);
485 conn = tcp_conn_new(&epp);
486 PCUT_ASSERT_NOT_NULL(conn);
487
488 dsize = 15;
489 data = calloc(dsize, 1);
490 PCUT_ASSERT_NOT_NULL(data);
491
492 seg1 = tcp_segment_make_data(0, data, dsize);
493 PCUT_ASSERT_NOT_NULL(seg1);
494 seg2 = tcp_segment_make_data(0, data, dsize);
495 PCUT_ASSERT_NOT_NULL(seg2);
496
497 /* Both segments must be acceptable */
498
499 conn->rcv_nxt = 10;
500 conn->rcv_wnd = 20;
501
502 PCUT_ASSERT_INT_EQUALS(dsize, seg1->len);
503 PCUT_ASSERT_INT_EQUALS(dsize, seg2->len);
504
505 seg1->seq = 5;
506 seg2->seq = 6;
507 PCUT_ASSERT_INT_EQUALS(-1, seq_no_seg_cmp(conn, seg1, seg2));
508
509 seg1->seq = 6;
510 seg2->seq = 6;
511 PCUT_ASSERT_INT_EQUALS(0, seq_no_seg_cmp(conn, seg1, seg2));
512
513 seg1->seq = 6;
514 seg2->seq = 5;
515 PCUT_ASSERT_INT_EQUALS(1, seq_no_seg_cmp(conn, seg1, seg2));
516
517 tcp_segment_delete(seg1);
518 tcp_segment_delete(seg2);
519 tcp_conn_delete(conn);
520 free(data);
521}
522
523/** Test seq_no_control_len() */
524PCUT_TEST(control_len)
525{
526 PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(0));
527 PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_ACK));
528 PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_RST));
529 PCUT_ASSERT_INT_EQUALS(0, seq_no_control_len(CTL_ACK | CTL_RST));
530 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN));
531 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN));
532 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_ACK));
533 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_ACK));
534 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_RST));
535 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_RST));
536 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_SYN | CTL_ACK |
537 CTL_RST));
538 PCUT_ASSERT_INT_EQUALS(1, seq_no_control_len(CTL_FIN | CTL_ACK |
539 CTL_RST));
540 PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN));
541 PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
542 CTL_ACK));
543 PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
544 CTL_RST));
545 PCUT_ASSERT_INT_EQUALS(2, seq_no_control_len(CTL_SYN | CTL_FIN |
546 CTL_ACK | CTL_RST));
547}
548
549PCUT_EXPORT(seq_no);
Note: See TracBrowser for help on using the repository browser.