suricata
stream-tcp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "../suricata-common.h"
19 #include "../stream-tcp-private.h"
20 #include "../stream-tcp.h"
21 #include "../stream-tcp-reassemble.h"
22 #include "../stream-tcp-inline.h"
23 #include "../stream-tcp-list.h"
24 #include "../stream-tcp-util.h"
25 #include "../util-streaming-buffer.h"
26 #include "../util-print.h"
27 #include "../util-unittest.h"
28 
29 #define SET_ISN(stream, setseq) \
30  (stream)->isn = (setseq); \
31  (stream)->base_seq = (setseq) + 1
32 
33 /**
34  * \test Test the allocation of TCP session for a given packet from the
35  * ssn_pool.
36  *
37  * \retval On success it returns 1 and on failure 0.
38  */
39 
40 static int StreamTcpTest01(void)
41 {
42  StreamTcpThread stt;
44  FAIL_IF_NULL(p);
45  Flow f;
46  memset(&f, 0, sizeof(Flow));
47  FLOW_INITIALIZE(&f);
48  p->flow = &f;
49  StreamTcpUTInit(&stt.ra_ctx);
50  TcpSession *ssn = StreamTcpNewSession(NULL, &stt, p, 0);
51  FAIL_IF_NULL(ssn);
52  f.protoctx = ssn;
54  FAIL_IF_NOT(ssn->state == 0);
56  SCFree(p);
57  FLOW_DESTROY(&f);
59  PASS;
60 }
61 
62 /**
63  * \test Test the deallocation of TCP session for a given packet and return
64  * the memory back to ssn_pool and corresponding segments to segment
65  * pool.
66  *
67  * \retval On success it returns 1 and on failure 0.
68  */
69 
70 static int StreamTcpTest02(void)
71 {
73  FAIL_IF(unlikely(p == NULL));
74  Flow f;
75  ThreadVars tv;
76  StreamTcpThread stt;
77  uint8_t payload[4];
78  TCPHdr tcph;
80  memset(&pq, 0, sizeof(pq));
81  memset(&f, 0, sizeof(Flow));
82  memset(&tv, 0, sizeof(ThreadVars));
83  memset(&stt, 0, sizeof(StreamTcpThread));
84  memset(&tcph, 0, sizeof(TCPHdr));
85 
86  FLOW_INITIALIZE(&f);
87  p->flow = &f;
88  tcph.th_win = htons(5480);
89  tcph.th_flags = TH_SYN;
90  p->tcph = &tcph;
92 
93  StreamTcpUTInit(&stt.ra_ctx);
94 
95  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
96 
97  p->tcph->th_ack = htonl(1);
98  p->tcph->th_flags = TH_SYN | TH_ACK;
100 
101  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
102 
103  p->tcph->th_ack = htonl(1);
104  p->tcph->th_seq = htonl(1);
105  p->tcph->th_flags = TH_ACK;
107 
108  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
109 
110  p->tcph->th_ack = htonl(1);
111  p->tcph->th_seq = htonl(2);
112  p->tcph->th_flags = TH_PUSH | TH_ACK;
114 
115  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
116  p->payload = payload;
117  p->payload_len = 3;
118 
119  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
120 
122  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
123 
124  p->tcph->th_ack = htonl(1);
125  p->tcph->th_seq = htonl(6);
126  p->tcph->th_flags = TH_PUSH | TH_ACK;
128 
129  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
130  p->payload = payload;
131  p->payload_len = 3;
132 
133  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
134 
136  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
137 
139  // StreamTcpUTClearSession(p->flow->protoctx);
140 
141  SCFree(p);
142  FLOW_DESTROY(&f);
144  PASS;
145 }
146 
147 /**
148  * \test Test the setting up a TCP session when we missed the initial
149  * SYN packet of the session. The session is setup only if midstream
150  * sessions are allowed to setup.
151  *
152  * \retval On success it returns 1 and on failure 0.
153  */
154 
155 static int StreamTcpTest03(void)
156 {
157  Packet *p = PacketGetFromAlloc();
158  FAIL_IF_NULL(p);
159  Flow f;
160  ThreadVars tv;
161  StreamTcpThread stt;
162  TCPHdr tcph;
164  memset(&pq, 0, sizeof(pq));
165  memset(&f, 0, sizeof(Flow));
166  memset(&tv, 0, sizeof(ThreadVars));
167  memset(&stt, 0, sizeof(StreamTcpThread));
168  memset(&tcph, 0, sizeof(TCPHdr));
169  FLOW_INITIALIZE(&f);
170  p->flow = &f;
171 
172  StreamTcpUTInit(&stt.ra_ctx);
173 
174  tcph.th_win = htons(5480);
175  tcph.th_seq = htonl(10);
176  tcph.th_ack = htonl(20);
177  tcph.th_flags = TH_SYN | TH_ACK;
178  p->tcph = &tcph;
179  int ret = 0;
180 
181  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
182  goto end;
183 
184  p->tcph->th_seq = htonl(20);
185  p->tcph->th_ack = htonl(11);
186  p->tcph->th_flags = TH_ACK;
188 
189  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
190  goto end;
191 
192  p->tcph->th_seq = htonl(19);
193  p->tcph->th_ack = htonl(11);
194  p->tcph->th_flags = TH_ACK | TH_PUSH;
196 
197  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
198  goto end;
199 
200  if (!stream_config.midstream) {
201  ret = 1;
202  goto end;
203  }
204  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
205  goto end;
206 
207  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 20 &&
208  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11)
209  goto end;
210 
212 
213  ret = 1;
214 end:
215  SCFree(p);
216  FLOW_DESTROY(&f);
218  return ret;
219 }
220 
221 /**
222  * \test Test the setting up a TCP session when we missed the initial
223  * SYN/ACK packet of the session. The session is setup only if
224  * midstream sessions are allowed to setup.
225  *
226  * \retval On success it returns 1 and on failure 0.
227  */
228 
229 static int StreamTcpTest04(void)
230 {
231  Packet *p = PacketGetFromAlloc();
232  FAIL_IF_NULL(p);
233  Flow f;
234  ThreadVars tv;
235  StreamTcpThread stt;
236  TCPHdr tcph;
238  memset(&pq, 0, sizeof(pq));
239  memset(&f, 0, sizeof(Flow));
240  memset(&tv, 0, sizeof(ThreadVars));
241  memset(&stt, 0, sizeof(StreamTcpThread));
242  memset(&tcph, 0, sizeof(TCPHdr));
243  FLOW_INITIALIZE(&f);
244  p->flow = &f;
245 
246  StreamTcpUTInit(&stt.ra_ctx);
247 
248  tcph.th_win = htons(5480);
249  tcph.th_seq = htonl(10);
250  tcph.th_ack = htonl(20);
251  tcph.th_flags = TH_ACK;
252  p->tcph = &tcph;
253 
254  int ret = 0;
255 
256  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
257  goto end;
258 
259  p->tcph->th_seq = htonl(9);
260  p->tcph->th_ack = htonl(19);
261  p->tcph->th_flags = TH_ACK | TH_PUSH;
263 
264  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
265  goto end;
266 
267  if (!stream_config.midstream) {
268  ret = 1;
269  goto end;
270  }
271  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
272  goto end;
273 
274  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 10 &&
275  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 20)
276  goto end;
277 
279 
280  ret = 1;
281 end:
282  SCFree(p);
283  FLOW_DESTROY(&f);
285  return ret;
286 }
287 
288 /**
289  * \test Test the setting up a TCP session when we missed the initial
290  * 3WHS packet of the session. The session is setup only if
291  * midstream sessions are allowed to setup.
292  *
293  * \retval On success it returns 1 and on failure 0.
294  */
295 
296 static int StreamTcpTest05(void)
297 {
298  Packet *p = PacketGetFromAlloc();
299  FAIL_IF_NULL(p);
300  Flow f;
301  ThreadVars tv;
302  StreamTcpThread stt;
303  TCPHdr tcph;
304  uint8_t payload[4];
306  memset(&pq, 0, sizeof(PacketQueueNoLock));
307  memset(&f, 0, sizeof(Flow));
308  memset(&tv, 0, sizeof(ThreadVars));
309  memset(&stt, 0, sizeof(StreamTcpThread));
310  memset(&tcph, 0, sizeof(TCPHdr));
311  FLOW_INITIALIZE(&f);
312  p->flow = &f;
313  int ret = 0;
314 
315  StreamTcpUTInit(&stt.ra_ctx);
316  tcph.th_win = htons(5480);
317  tcph.th_seq = htonl(10);
318  tcph.th_ack = htonl(20);
319  tcph.th_flags = TH_ACK | TH_PUSH;
320  p->tcph = &tcph;
321 
322  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
323  p->payload = payload;
324  p->payload_len = 3;
325 
326  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
327  goto end;
328 
329  p->tcph->th_seq = htonl(20);
330  p->tcph->th_ack = htonl(13);
331  p->tcph->th_flags = TH_ACK | TH_PUSH;
333 
334  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
335  p->payload = payload;
336  p->payload_len = 3;
337 
338  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
339  goto end;
340 
341  p->tcph->th_seq = htonl(13);
342  p->tcph->th_ack = htonl(23);
343  p->tcph->th_flags = TH_ACK | TH_PUSH;
345 
346  StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/
347  p->payload = payload;
348  p->payload_len = 3;
349 
350  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
351  goto end;
352 
353  p->tcph->th_seq = htonl(19);
354  p->tcph->th_ack = htonl(16);
355  p->tcph->th_flags = TH_ACK | TH_PUSH;
357 
358  StreamTcpCreateTestPacket(payload, 0x44, 3, 4); /*DDD*/
359  p->payload = payload;
360  p->payload_len = 3;
361 
362  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
363  goto end;
364 
365  if (!stream_config.midstream) {
366  ret = 1;
367  goto end;
368  }
369  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
370  goto end;
371 
372  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 16 &&
373  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23)
374  goto end;
375 
377 
378  ret = 1;
379 end:
380  SCFree(p);
381  FLOW_DESTROY(&f);
383  return ret;
384 }
385 
386 /**
387  * \test Test the setting up a TCP session when we have seen only the
388  * FIN, RST packets packet of the session. The session is setup only if
389  * midstream sessions are allowed to setup.
390  *
391  * \retval On success it returns 1 and on failure 0.
392  */
393 
394 static int StreamTcpTest06(void)
395 {
396  Packet *p = PacketGetFromAlloc();
397  FAIL_IF_NULL(p);
398  Flow f;
399  TcpSession ssn;
400  ThreadVars tv;
401  StreamTcpThread stt;
402  TCPHdr tcph;
404  memset(&pq, 0, sizeof(PacketQueueNoLock));
405  memset(&f, 0, sizeof(Flow));
406  memset(&ssn, 0, sizeof(TcpSession));
407  memset(&tv, 0, sizeof(ThreadVars));
408  memset(&stt, 0, sizeof(StreamTcpThread));
409  memset(&tcph, 0, sizeof(TCPHdr));
410  FLOW_INITIALIZE(&f);
411  p->flow = &f;
412  int ret = 0;
413 
414  StreamTcpUTInit(&stt.ra_ctx);
415 
416  tcph.th_flags = TH_FIN;
417  p->tcph = &tcph;
418 
419  /* StreamTcpPacket returns -1 on unsolicited FIN */
420  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
421  printf("StreamTcpPacket failed: ");
422  goto end;
423  }
424 
425  if (((TcpSession *)(p->flow->protoctx)) != NULL) {
426  printf("we have a ssn while we shouldn't: ");
427  goto end;
428  }
429 
430  p->tcph->th_flags = TH_RST;
431  /* StreamTcpPacket returns -1 on unsolicited RST */
432  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
433  printf("StreamTcpPacket failed (2): ");
434  goto end;
435  }
436 
437  if (((TcpSession *)(p->flow->protoctx)) != NULL) {
438  printf("we have a ssn while we shouldn't (2): ");
439  goto end;
440  }
441 
442  ret = 1;
443 end:
444  SCFree(p);
445  FLOW_DESTROY(&f);
447  return ret;
448 }
449 
450 /**
451  * \test Test the working on PAWS. The packet will be dropped by stream, as
452  * its timestamp is old, although the segment is in the window.
453  */
454 
455 static int StreamTcpTest07(void)
456 {
457  Packet *p = PacketGetFromAlloc();
458  FAIL_IF(unlikely(p == NULL));
459  Flow f;
460  ThreadVars tv;
461  StreamTcpThread stt;
462  TCPHdr tcph;
463  uint8_t payload[1] = { 0x42 };
465 
466  memset(&pq, 0, sizeof(PacketQueueNoLock));
467  memset(&f, 0, sizeof(Flow));
468  memset(&tv, 0, sizeof(ThreadVars));
469  memset(&stt, 0, sizeof(StreamTcpThread));
470  memset(&tcph, 0, sizeof(TCPHdr));
471 
472  FLOW_INITIALIZE(&f);
473  p->flow = &f;
474 
475  StreamTcpUTInit(&stt.ra_ctx);
476  stream_config.midstream = true;
477 
478  tcph.th_win = htons(5480);
479  tcph.th_seq = htonl(10);
480  tcph.th_ack = htonl(20);
481  tcph.th_flags = TH_ACK | TH_PUSH;
482  p->tcph = &tcph;
483 
484  p->tcpvars.ts_set = true;
485  p->tcpvars.ts_val = 10;
486  p->tcpvars.ts_ecr = 11;
487 
488  p->payload = payload;
489  p->payload_len = 1;
490 
491  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
492 
493  p->tcph->th_seq = htonl(11);
494  p->tcph->th_ack = htonl(23);
495  p->tcph->th_flags = TH_ACK | TH_PUSH;
497 
498  p->tcpvars.ts_val = 2;
499 
500  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) != -1);
501 
502  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 11);
503 
505  SCFree(p);
506  FLOW_DESTROY(&f);
508  PASS;
509 }
510 
511 /**
512  * \test Test the working on PAWS. The packet will be accepted by engine as
513  * the timestamp is valid and it is in window.
514  */
515 
516 static int StreamTcpTest08(void)
517 {
518  Packet *p = PacketGetFromAlloc();
519  FAIL_IF(unlikely(p == NULL));
520  Flow f;
521  ThreadVars tv;
522  StreamTcpThread stt;
523  TCPHdr tcph;
524  uint8_t payload[1] = { 0x42 };
525 
527  memset(&pq, 0, sizeof(PacketQueueNoLock));
528  memset(&f, 0, sizeof(Flow));
529  memset(&tv, 0, sizeof(ThreadVars));
530  memset(&stt, 0, sizeof(StreamTcpThread));
531  memset(&tcph, 0, sizeof(TCPHdr));
532 
533  FLOW_INITIALIZE(&f);
534  p->flow = &f;
535 
536  StreamTcpUTInit(&stt.ra_ctx);
537  stream_config.midstream = true;
538 
539  tcph.th_win = htons(5480);
540  tcph.th_seq = htonl(10);
541  tcph.th_ack = htonl(20);
542  tcph.th_flags = TH_ACK | TH_PUSH;
543  p->tcph = &tcph;
544 
545  p->tcpvars.ts_set = true;
546  p->tcpvars.ts_val = 10;
547  p->tcpvars.ts_ecr = 11;
548 
549  p->payload = payload;
550  p->payload_len = 1;
551 
552  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
553 
554  p->tcph->th_seq = htonl(11);
555  p->tcph->th_ack = htonl(20);
556  p->tcph->th_flags = TH_ACK | TH_PUSH;
558 
559  p->tcpvars.ts_val = 12;
560 
561  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
562 
563  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 12);
564 
566 
567  SCFree(p);
568  FLOW_DESTROY(&f);
570  PASS;
571 }
572 
573 /**
574  * \test Test the working of No stream reassembly flag. The stream will not
575  * reassemble the segment if the flag is set.
576  */
577 
578 static int StreamTcpTest09(void)
579 {
580  Packet *p = PacketGetFromAlloc();
581  FAIL_IF(unlikely(p == NULL));
582  Flow f;
583  ThreadVars tv;
584  StreamTcpThread stt;
585  TCPHdr tcph;
586  uint8_t payload[1] = { 0x42 };
587 
589  memset(&pq, 0, sizeof(PacketQueueNoLock));
590  memset(&f, 0, sizeof(Flow));
591  memset(&tv, 0, sizeof(ThreadVars));
592  memset(&stt, 0, sizeof(StreamTcpThread));
593  memset(&tcph, 0, sizeof(TCPHdr));
594 
595  FLOW_INITIALIZE(&f);
596  p->flow = &f;
597 
598  StreamTcpUTInit(&stt.ra_ctx);
599  stream_config.midstream = true;
600 
601  tcph.th_win = htons(5480);
602  tcph.th_seq = htonl(10);
603  tcph.th_ack = htonl(20);
604  tcph.th_flags = TH_ACK | TH_PUSH;
605  p->tcph = &tcph;
606 
607  p->payload = payload;
608  p->payload_len = 1;
609 
610  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
611 
612  p->tcph->th_seq = htonl(12);
613  p->tcph->th_ack = htonl(23);
614  p->tcph->th_flags = TH_ACK | TH_PUSH;
616 
617  FAIL_IF(p->flow->protoctx == NULL);
618 
620 
621  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
622 
623  p->tcph->th_seq = htonl(11);
624  p->tcph->th_ack = htonl(23);
625  p->tcph->th_flags = TH_ACK | TH_PUSH;
627 
628  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
629 
630  TcpSession *ssn = p->flow->protoctx;
631  FAIL_IF_NULL(ssn);
632  TcpSegment *seg = RB_MIN(TCPSEG, &ssn->client.seg_tree);
633  FAIL_IF_NULL(seg);
634  FAIL_IF(TCPSEG_RB_NEXT(seg) != NULL);
635 
637  SCFree(p);
638  FLOW_DESTROY(&f);
640  PASS;
641 }
642 
643 /**
644  * \test Test the setting up a TCP session when we are seeing asynchronous
645  * stream, while we see all the packets in that stream from start.
646  */
647 
648 static int StreamTcpTest10(void)
649 {
650  Packet *p = PacketGetFromAlloc();
651  FAIL_IF(unlikely(p == NULL));
652  Flow f;
653  ThreadVars tv;
654  StreamTcpThread stt;
655  TCPHdr tcph;
656  uint8_t payload[4];
658  memset(&pq, 0, sizeof(PacketQueueNoLock));
659  memset(&f, 0, sizeof(Flow));
660  memset(&tv, 0, sizeof(ThreadVars));
661  memset(&stt, 0, sizeof(StreamTcpThread));
662  memset(&tcph, 0, sizeof(TCPHdr));
663  FLOW_INITIALIZE(&f);
664  p->flow = &f;
665 
666  StreamTcpUTInit(&stt.ra_ctx);
668 
669  tcph.th_win = htons(5480);
670  tcph.th_seq = htonl(10);
671  tcph.th_ack = 0;
672  tcph.th_flags = TH_SYN;
673  p->tcph = &tcph;
674 
675  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
676 
677  p->tcph->th_seq = htonl(11);
678  p->tcph->th_ack = htonl(11);
679  p->tcph->th_flags = TH_ACK;
681 
682  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
683 
684  p->tcph->th_seq = htonl(11);
685  p->tcph->th_ack = htonl(11);
686  p->tcph->th_flags = TH_ACK | TH_PUSH;
688 
689  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
690  p->payload = payload;
691  p->payload_len = 3;
692 
693  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
694 
695  p->tcph->th_seq = htonl(6);
696  p->tcph->th_ack = htonl(11);
697  p->tcph->th_flags = TH_ACK | TH_PUSH;
699 
700  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
701  p->payload = payload;
702  p->payload_len = 3;
703 
704  /* spurious retransmission */
705  FAIL_IF_NOT(StreamTcpPacket(&tv, p, &stt, &pq) == 0);
706 
707  FAIL_IF(((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED);
708 
709  FAIL_IF(!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC));
710 
711  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
712  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11);
713 
715 
716  SCFree(p);
717  FLOW_DESTROY(&f);
719  PASS;
720 }
721 
722 /**
723  * \test Test the setting up a TCP session when we are seeing asynchronous
724  * stream, while we missed the SYN packet of that stream.
725  */
726 
727 static int StreamTcpTest11(void)
728 {
729  Packet *p = PacketGetFromAlloc();
730  FAIL_IF(unlikely(p == NULL));
731  Flow f;
732  ThreadVars tv;
733  StreamTcpThread stt;
734  TCPHdr tcph;
735  uint8_t payload[4];
737  memset(&pq, 0, sizeof(PacketQueueNoLock));
738  memset(&f, 0, sizeof(Flow));
739  memset(&tv, 0, sizeof(ThreadVars));
740  memset(&stt, 0, sizeof(StreamTcpThread));
741  memset(&tcph, 0, sizeof(TCPHdr));
742  FLOW_INITIALIZE(&f);
743  p->flow = &f;
744 
745  StreamTcpUTInit(&stt.ra_ctx);
747 
748  tcph.th_win = htons(5480);
749  tcph.th_seq = htonl(10);
750  tcph.th_ack = htonl(1);
751  tcph.th_flags = TH_SYN | TH_ACK;
752  p->tcph = &tcph;
753 
754  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
755 
756  p->tcph->th_seq = htonl(11);
757  p->tcph->th_ack = htonl(1);
758  p->tcph->th_flags = TH_ACK;
760 
761  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
762 
763  p->tcph->th_seq = htonl(11);
764  p->tcph->th_ack = htonl(1);
765  p->tcph->th_flags = TH_ACK | TH_PUSH;
767 
768  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
769  p->payload = payload;
770  p->payload_len = 3;
771 
772  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
773 
774  p->tcph->th_seq = htonl(2);
775  p->tcph->th_ack = htonl(1);
776  p->tcph->th_flags = TH_ACK | TH_PUSH;
778 
779  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
780  p->payload = payload;
781  p->payload_len = 3;
782 
783  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
784 
785  TcpSession *ssn = p->flow->protoctx;
786  FAIL_IF((ssn->flags & STREAMTCP_FLAG_ASYNC) == 0);
787  FAIL_IF(ssn->state != TCP_ESTABLISHED);
788 
789  FAIL_IF(ssn->server.last_ack != 11);
790  FAIL_IF(ssn->client.next_seq != 14);
791 
793  SCFree(p);
794  FLOW_DESTROY(&f);
796  PASS;
797 }
798 
799 /**
800  * \test Test the setting up a TCP session when we are seeing asynchronous
801  * stream, while we missed the SYN and SYN/ACK packets in that stream.
802  *
803  * \retval On success it returns 1 and on failure 0.
804  */
805 
806 static int StreamTcpTest12(void)
807 {
808  Packet *p = PacketGetFromAlloc();
809  FAIL_IF_NULL(p);
810  Flow f;
811  ThreadVars tv;
812  StreamTcpThread stt;
813  TCPHdr tcph;
814  uint8_t payload[4];
816  memset(&pq, 0, sizeof(PacketQueueNoLock));
817  memset(&f, 0, sizeof(Flow));
818  memset(&tv, 0, sizeof(ThreadVars));
819  memset(&stt, 0, sizeof(StreamTcpThread));
820  memset(&tcph, 0, sizeof(TCPHdr));
821  FLOW_INITIALIZE(&f);
822  p->flow = &f;
823 
824  StreamTcpUTInit(&stt.ra_ctx);
825 
826  tcph.th_win = htons(5480);
827  tcph.th_seq = htonl(10);
828  tcph.th_ack = htonl(11);
829  tcph.th_flags = TH_ACK;
830  p->tcph = &tcph;
831  int ret = 0;
832 
833  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
834  goto end;
835 
836  p->tcph->th_seq = htonl(10);
837  p->tcph->th_ack = htonl(11);
838  p->tcph->th_flags = TH_ACK | TH_PUSH;
840 
841  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
842  p->payload = payload;
843  p->payload_len = 3;
844 
845  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
846  goto end;
847 
848  p->tcph->th_seq = htonl(6);
849  p->tcph->th_ack = htonl(11);
850  p->tcph->th_flags = TH_ACK | TH_PUSH;
852 
853  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
854  p->payload = payload;
855  p->payload_len = 3;
856 
857  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
858  goto end;
859 
861  ret = 1;
862  goto end;
863  }
864 
865  if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
866  printf("failed in setting asynchronous session\n");
867  goto end;
868  }
869 
870  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
871  printf("failed in setting state\n");
872  goto end;
873  }
874 
875  if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
876  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) {
877  printf("failed in seq %" PRIu32 " match\n",
878  ((TcpSession *)(p->flow->protoctx))->client.last_ack);
879  goto end;
880  }
881 
883 
884  ret = 1;
885 end:
886  SCFree(p);
887  FLOW_DESTROY(&f);
889  return ret;
890 }
891 
892 /**
893  * \test Test the setting up a TCP session when we are seeing asynchronous
894  * stream, while we missed the SYN and SYN/ACK packets in that stream.
895  * Later, we start to receive the packet from other end stream too.
896  *
897  * \retval On success it returns 1 and on failure 0.
898  */
899 
900 static int StreamTcpTest13(void)
901 {
902  Packet *p = PacketGetFromAlloc();
903  FAIL_IF_NULL(p);
904  Flow f;
905  ThreadVars tv;
906  StreamTcpThread stt;
907  TCPHdr tcph;
908  uint8_t payload[4];
910  memset(&pq, 0, sizeof(PacketQueueNoLock));
911  memset(&f, 0, sizeof(Flow));
912  memset(&tv, 0, sizeof(ThreadVars));
913  memset(&stt, 0, sizeof(StreamTcpThread));
914  memset(&tcph, 0, sizeof(TCPHdr));
915  FLOW_INITIALIZE(&f);
916  p->flow = &f;
917 
918  StreamTcpUTInit(&stt.ra_ctx);
919 
920  tcph.th_win = htons(5480);
921  tcph.th_seq = htonl(10);
922  tcph.th_ack = htonl(11);
923  tcph.th_flags = TH_ACK;
924  p->tcph = &tcph;
925  int ret = 0;
926 
927  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
928  goto end;
929 
930  p->tcph->th_seq = htonl(10);
931  p->tcph->th_ack = htonl(11);
932  p->tcph->th_flags = TH_ACK | TH_PUSH;
934 
935  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
936  p->payload = payload;
937  p->payload_len = 3;
938 
939  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
940  goto end;
941 
942  p->tcph->th_seq = htonl(6);
943  p->tcph->th_ack = htonl(11);
944  p->tcph->th_flags = TH_ACK | TH_PUSH;
946 
947  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
948  p->payload = payload;
949  p->payload_len = 3;
950 
951  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
952  goto end;
953 
955  ret = 1;
956  goto end;
957  }
958 
959  if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
960  printf("failed in setting asynchronous session\n");
961  goto end;
962  }
963 
964  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
965  printf("failed in setting state\n");
966  goto end;
967  }
968 
969  p->tcph->th_seq = htonl(11);
970  p->tcph->th_ack = htonl(9);
971  p->tcph->th_flags = TH_ACK | TH_PUSH;
973 
974  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
975  p->payload = payload;
976  p->payload_len = 3;
977 
978  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
979  goto end;
980 
981  if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 9 &&
982  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 14) {
983  printf("failed in seq %" PRIu32 " match\n",
984  ((TcpSession *)(p->flow->protoctx))->client.last_ack);
985  goto end;
986  }
987 
989 
990  ret = 1;
991 end:
992  SCFree(p);
993  FLOW_DESTROY(&f);
995  return ret;
996 }
997 
998 /* Dummy conf string to setup the OS policy for unit testing */
999 static const char *dummy_conf_string = "%YAML 1.1\n"
1000  "---\n"
1001  "\n"
1002  "default-log-dir: /var/log/eidps\n"
1003  "\n"
1004  "logging:\n"
1005  "\n"
1006  " default-log-level: debug\n"
1007  "\n"
1008  " default-format: \"<%t> - <%l>\"\n"
1009  "\n"
1010  " default-startup-message: Your IDS has started.\n"
1011  "\n"
1012  " default-output-filter:\n"
1013  "\n"
1014  "host-os-policy:\n"
1015  "\n"
1016  " windows: 192.168.0.1\n"
1017  "\n"
1018  " linux: 192.168.0.2\n"
1019  "\n";
1020 /* Dummy conf string to setup the OS policy for unit testing */
1021 static const char *dummy_conf_string1 = "%YAML 1.1\n"
1022  "---\n"
1023  "\n"
1024  "default-log-dir: /var/log/eidps\n"
1025  "\n"
1026  "logging:\n"
1027  "\n"
1028  " default-log-level: debug\n"
1029  "\n"
1030  " default-format: \"<%t> - <%l>\"\n"
1031  "\n"
1032  " default-startup-message: Your IDS has started.\n"
1033  "\n"
1034  " default-output-filter:\n"
1035  "\n"
1036  "host-os-policy:\n"
1037  "\n"
1038  " windows: 192.168.0.0/24,"
1039  "192.168.1.1\n"
1040  "\n"
1041  " linux: 192.168.1.0/24,"
1042  "192.168.0.1\n"
1043  "\n";
1044 
1045 /**
1046  * \brief Function to parse the dummy conf string and get the value of IP
1047  * address for the corresponding OS policy type.
1048  *
1049  * \param conf_val_name Name of the OS policy type
1050  * \retval returns IP address as string on success and NULL on failure
1051  */
1052 static const char *StreamTcpParseOSPolicy(char *conf_var_name)
1053 {
1054  SCEnter();
1055  char conf_var_type_name[15] = "host-os-policy";
1056  char *conf_var_full_name = NULL;
1057  const char *conf_var_value = NULL;
1058 
1059  if (conf_var_name == NULL)
1060  goto end;
1061 
1062  /* the + 2 is for the '.' and the string termination character '\0' */
1063  conf_var_full_name = (char *)SCMalloc(strlen(conf_var_type_name) + strlen(conf_var_name) + 2);
1064  if (conf_var_full_name == NULL)
1065  goto end;
1066 
1067  if (snprintf(conf_var_full_name, strlen(conf_var_type_name) + strlen(conf_var_name) + 2,
1068  "%s.%s", conf_var_type_name, conf_var_name) < 0) {
1069  SCLogError("Error in making the conf full name");
1070  goto end;
1071  }
1072 
1073  if (ConfGet(conf_var_full_name, &conf_var_value) != 1) {
1074  SCLogError("Error in getting conf value for conf name %s", conf_var_full_name);
1075  goto end;
1076  }
1077 
1078  SCLogDebug("Value obtained from the yaml conf file, for the var "
1079  "\"%s\" is \"%s\"",
1080  conf_var_name, conf_var_value);
1081 
1082 end:
1083  if (conf_var_full_name != NULL)
1084  SCFree(conf_var_full_name);
1085  SCReturnCharPtr(conf_var_value);
1086 }
1087 /**
1088  * \test Test the setting up a OS policy. Te OS policy values are defined in
1089  * the config string "dummy_conf_string"
1090  *
1091  * \retval On success it returns 1 and on failure 0
1092  */
1093 
1094 static int StreamTcpTest14(void)
1095 {
1096  Packet *p = PacketGetFromAlloc();
1097  FAIL_IF_NULL(p);
1098  Flow f;
1099  ThreadVars tv;
1100  StreamTcpThread stt;
1101  TCPHdr tcph;
1102  uint8_t payload[4];
1103  struct in_addr addr;
1104  IPV4Hdr ipv4h;
1105  char os_policy_name[10] = "windows";
1106  const char *ip_addr;
1107  PacketQueueNoLock pq;
1108  memset(&pq, 0, sizeof(PacketQueueNoLock));
1109 
1110  memset(&f, 0, sizeof(Flow));
1111  memset(&tv, 0, sizeof(ThreadVars));
1112  memset(&stt, 0, sizeof(StreamTcpThread));
1113  memset(&tcph, 0, sizeof(TCPHdr));
1114  memset(&addr, 0, sizeof(addr));
1115  memset(&ipv4h, 0, sizeof(ipv4h));
1116  FLOW_INITIALIZE(&f);
1117  p->flow = &f;
1118  int ret = 0;
1119 
1120  StreamTcpUTInit(&stt.ra_ctx);
1121 
1122  /* Load the config string into parser */
1124  ConfInit();
1125  ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
1126 
1127  /* Get the IP address as string and add it to Host info tree for lookups */
1128  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1129  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1130  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1131  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1132  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1133  addr.s_addr = inet_addr("192.168.0.1");
1134  tcph.th_win = htons(5480);
1135  tcph.th_seq = htonl(10);
1136  tcph.th_ack = htonl(20);
1137  tcph.th_flags = TH_ACK | TH_PUSH;
1138  p->tcph = &tcph;
1139  p->dst.family = AF_INET;
1140  p->dst.address.address_un_data32[0] = addr.s_addr;
1141  p->ip4h = &ipv4h;
1142 
1143  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1144  p->payload = payload;
1145  p->payload_len = 3;
1146 
1147  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1148  goto end;
1149 
1150  p->tcph->th_seq = htonl(20);
1151  p->tcph->th_ack = htonl(13);
1152  p->tcph->th_flags = TH_ACK | TH_PUSH;
1154 
1155  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1156  p->payload = payload;
1157  p->payload_len = 3;
1158 
1159  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1160  goto end;
1161 
1162  p->tcph->th_seq = htonl(15);
1163  p->tcph->th_ack = htonl(23);
1164  p->tcph->th_flags = TH_ACK | TH_PUSH;
1166 
1167  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1168  p->payload = payload;
1169  p->payload_len = 3;
1170 
1171  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1172  goto end;
1173 
1174  p->tcph->th_seq = htonl(14);
1175  p->tcph->th_ack = htonl(23);
1176  p->tcph->th_flags = TH_ACK | TH_PUSH;
1178 
1179  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1180  p->payload = payload;
1181  p->payload_len = 3;
1182 
1183  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1184  goto end;
1185 
1186  addr.s_addr = inet_addr("192.168.0.2");
1187  p->tcph->th_seq = htonl(25);
1188  p->tcph->th_ack = htonl(13);
1189  p->tcph->th_flags = TH_ACK | TH_PUSH;
1191  p->dst.address.address_un_data32[0] = addr.s_addr;
1192 
1193  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1194  p->payload = payload;
1195  p->payload_len = 3;
1196 
1197  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1198  goto end;
1199 
1200  p->tcph->th_seq = htonl(24);
1201  p->tcph->th_ack = htonl(13);
1202  p->tcph->th_flags = TH_ACK | TH_PUSH;
1204 
1205  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1206  p->payload = payload;
1207  p->payload_len = 3;
1208 
1209  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1210  goto end;
1211 
1212  if (!stream_config.midstream) {
1213  ret = 1;
1214  goto end;
1215  }
1216  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1217  goto end;
1218 
1219  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1220  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1221  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1222  " server.next_seq %" PRIu32 "\n",
1223  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1224  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1225  goto end;
1226  }
1227 
1228  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1229  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1230  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1231  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1232  " should be %" PRIu8 "\n",
1233  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1234  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1235  goto end;
1236  }
1238 
1239  ret = 1;
1240 end:
1241  ConfDeInit();
1243  SCFree(p);
1244  FLOW_DESTROY(&f);
1246  return ret;
1247 }
1248 
1249 /**
1250  * \test Test the setting up a TCP session using the 4WHS:
1251  * SYN, SYN, SYN/ACK, ACK
1252  *
1253  * \retval On success it returns 1 and on failure 0.
1254  */
1255 
1256 static int StreamTcp4WHSTest01(void)
1257 {
1258  int ret = 0;
1259  Packet *p = PacketGetFromAlloc();
1260  FAIL_IF_NULL(p);
1261  Flow f;
1262  ThreadVars tv;
1263  StreamTcpThread stt;
1264  TCPHdr tcph;
1265  PacketQueueNoLock pq;
1266  memset(&pq, 0, sizeof(PacketQueueNoLock));
1267  memset(&f, 0, sizeof(Flow));
1268  memset(&tv, 0, sizeof(ThreadVars));
1269  memset(&stt, 0, sizeof(StreamTcpThread));
1270  memset(&tcph, 0, sizeof(TCPHdr));
1271  FLOW_INITIALIZE(&f);
1272  p->flow = &f;
1273 
1274  StreamTcpUTInit(&stt.ra_ctx);
1275 
1276  tcph.th_win = htons(5480);
1277  tcph.th_seq = htonl(10);
1278  tcph.th_ack = 0;
1279  tcph.th_flags = TH_SYN;
1280  p->tcph = &tcph;
1281 
1282  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1283  goto end;
1284 
1285  p->tcph->th_seq = htonl(20);
1286  p->tcph->th_ack = 0;
1287  p->tcph->th_flags = TH_SYN;
1289 
1290  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1291  goto end;
1292 
1293  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1294  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1295  goto end;
1296  }
1297 
1298  p->tcph->th_seq = htonl(10);
1299  p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1300  p->tcph->th_flags = TH_SYN | TH_ACK;
1302 
1303  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1304  goto end;
1305 
1306  p->tcph->th_seq = htonl(21);
1307  p->tcph->th_ack = htonl(10);
1308  p->tcph->th_flags = TH_ACK;
1310 
1311  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1312  goto end;
1313 
1314  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1315  printf("state is not ESTABLISHED: ");
1316  goto end;
1317  }
1318 
1319  ret = 1;
1320 end:
1322  SCFree(p);
1323  FLOW_DESTROY(&f);
1325  return ret;
1326 }
1327 
1328 /**
1329  * \test set up a TCP session using the 4WHS:
1330  * SYN, SYN, SYN/ACK, ACK, but the SYN/ACK does
1331  * not have the right SEQ
1332  *
1333  * \retval On success it returns 1 and on failure 0.
1334  */
1335 
1336 static int StreamTcp4WHSTest02(void)
1337 {
1338  int ret = 0;
1339  Packet *p = PacketGetFromAlloc();
1340  FAIL_IF_NULL(p);
1341  Flow f;
1342  ThreadVars tv;
1343  StreamTcpThread stt;
1344  TCPHdr tcph;
1345  PacketQueueNoLock pq;
1346  memset(&pq, 0, sizeof(PacketQueueNoLock));
1347  memset(&f, 0, sizeof(Flow));
1348  memset(&tv, 0, sizeof(ThreadVars));
1349  memset(&stt, 0, sizeof(StreamTcpThread));
1350  memset(&tcph, 0, sizeof(TCPHdr));
1351  FLOW_INITIALIZE(&f);
1352  p->flow = &f;
1353 
1354  StreamTcpUTInit(&stt.ra_ctx);
1355 
1356  tcph.th_win = htons(5480);
1357  tcph.th_seq = htonl(10);
1358  tcph.th_ack = 0;
1359  tcph.th_flags = TH_SYN;
1360  p->tcph = &tcph;
1361 
1362  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1363  goto end;
1364 
1365  p->tcph->th_seq = htonl(20);
1366  p->tcph->th_ack = 0;
1367  p->tcph->th_flags = TH_SYN;
1369 
1370  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1371  goto end;
1372 
1373  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1374  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1375  goto end;
1376  }
1377 
1378  p->tcph->th_seq = htonl(30);
1379  p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1380  p->tcph->th_flags = TH_SYN | TH_ACK;
1382 
1383  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
1384  printf("SYN/ACK pkt not rejected but it should have: ");
1385  goto end;
1386  }
1387 
1388  ret = 1;
1389 end:
1391  SCFree(p);
1392  FLOW_DESTROY(&f);
1394  return ret;
1395 }
1396 
1397 /**
1398  * \test set up a TCP session using the 4WHS:
1399  * SYN, SYN, SYN/ACK, ACK: however the SYN/ACK and ACK
1400  * are part of a normal 3WHS
1401  *
1402  * \retval On success it returns 1 and on failure 0.
1403  */
1404 
1405 static int StreamTcp4WHSTest03(void)
1406 {
1407  int ret = 0;
1408  Packet *p = PacketGetFromAlloc();
1409  FAIL_IF(unlikely(p == NULL));
1410  Flow f;
1411  ThreadVars tv;
1412  StreamTcpThread stt;
1413  TCPHdr tcph;
1414  PacketQueueNoLock pq;
1415  memset(&pq, 0, sizeof(PacketQueueNoLock));
1416  memset(&f, 0, sizeof(Flow));
1417  memset(&tv, 0, sizeof(ThreadVars));
1418  memset(&stt, 0, sizeof(StreamTcpThread));
1419  memset(&tcph, 0, sizeof(TCPHdr));
1420  FLOW_INITIALIZE(&f);
1421  p->flow = &f;
1422 
1423  StreamTcpUTInit(&stt.ra_ctx);
1424 
1425  tcph.th_win = htons(5480);
1426  tcph.th_seq = htonl(10);
1427  tcph.th_ack = 0;
1428  tcph.th_flags = TH_SYN;
1429  p->tcph = &tcph;
1430 
1431  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1432  goto end;
1433 
1434  p->tcph->th_seq = htonl(20);
1435  p->tcph->th_ack = 0;
1436  p->tcph->th_flags = TH_SYN;
1438 
1439  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1440  goto end;
1441 
1442  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1443  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1444  goto end;
1445  }
1446 
1447  p->tcph->th_seq = htonl(30);
1448  p->tcph->th_ack = htonl(11);
1449  p->tcph->th_flags = TH_SYN | TH_ACK;
1451 
1452  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1453  goto end;
1454 
1455  p->tcph->th_seq = htonl(11);
1456  p->tcph->th_ack = htonl(31);
1457  p->tcph->th_flags = TH_ACK;
1459 
1460  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1461  goto end;
1462 
1463  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1464  printf("state is not ESTABLISHED: ");
1465  goto end;
1466  }
1467 
1468  ret = 1;
1469 end:
1471  SCFree(p);
1472  FLOW_DESTROY(&f);
1474  return ret;
1475 }
1476 
1477 /**
1478  * \test Test the setting up a OS policy. Te OS policy values are defined in
1479  * the config string "dummy_conf_string1"
1480  *
1481  * \retval On success it returns 1 and on failure 0
1482  */
1483 
1484 static int StreamTcpTest15(void)
1485 {
1486  Packet *p = PacketGetFromAlloc();
1487  FAIL_IF_NULL(p);
1488  Flow f;
1489  ThreadVars tv;
1490  StreamTcpThread stt;
1491  TCPHdr tcph;
1492  uint8_t payload[4];
1493  struct in_addr addr;
1494  IPV4Hdr ipv4h;
1495  char os_policy_name[10] = "windows";
1496  const char *ip_addr;
1497  PacketQueueNoLock pq;
1498  memset(&pq, 0, sizeof(PacketQueueNoLock));
1499 
1500  memset(&f, 0, sizeof(Flow));
1501  memset(&tv, 0, sizeof(ThreadVars));
1502  memset(&stt, 0, sizeof(StreamTcpThread));
1503  memset(&tcph, 0, sizeof(TCPHdr));
1504  memset(&addr, 0, sizeof(addr));
1505  memset(&ipv4h, 0, sizeof(ipv4h));
1506  FLOW_INITIALIZE(&f);
1507  p->flow = &f;
1508  int ret = 0;
1509 
1510  StreamTcpUTInit(&stt.ra_ctx);
1511 
1512  /* Load the config string into parser */
1514  ConfInit();
1515  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1516 
1517  /* Get the IP address as string and add it to Host info tree for lookups */
1518  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1519  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1520  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1521  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1522  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1523  addr.s_addr = inet_addr("192.168.0.20");
1524  tcph.th_win = htons(5480);
1525  tcph.th_seq = htonl(10);
1526  tcph.th_ack = htonl(20);
1527  tcph.th_flags = TH_ACK | TH_PUSH;
1528  p->tcph = &tcph;
1529  p->dst.family = AF_INET;
1530  p->dst.address.address_un_data32[0] = addr.s_addr;
1531  p->ip4h = &ipv4h;
1532 
1533  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1534  p->payload = payload;
1535  p->payload_len = 3;
1536 
1537  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1538  goto end;
1539 
1540  p->tcph->th_seq = htonl(20);
1541  p->tcph->th_ack = htonl(13);
1542  p->tcph->th_flags = TH_ACK | TH_PUSH;
1544 
1545  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1546  p->payload = payload;
1547  p->payload_len = 3;
1548 
1549  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1550  goto end;
1551 
1552  p->tcph->th_seq = htonl(15);
1553  p->tcph->th_ack = htonl(23);
1554  p->tcph->th_flags = TH_ACK | TH_PUSH;
1556 
1557  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1558  p->payload = payload;
1559  p->payload_len = 3;
1560 
1561  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1562  goto end;
1563 
1564  p->tcph->th_seq = htonl(14);
1565  p->tcph->th_ack = htonl(23);
1566  p->tcph->th_flags = TH_ACK | TH_PUSH;
1568 
1569  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1570  p->payload = payload;
1571  p->payload_len = 3;
1572 
1573  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1574  goto end;
1575 
1576  addr.s_addr = inet_addr("192.168.1.20");
1577  p->tcph->th_seq = htonl(25);
1578  p->tcph->th_ack = htonl(13);
1579  p->tcph->th_flags = TH_ACK | TH_PUSH;
1581  p->dst.address.address_un_data32[0] = addr.s_addr;
1582 
1583  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1584  p->payload = payload;
1585  p->payload_len = 3;
1586 
1587  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1588  goto end;
1589 
1590  p->tcph->th_seq = htonl(24);
1591  p->tcph->th_ack = htonl(13);
1592  p->tcph->th_flags = TH_ACK | TH_PUSH;
1594 
1595  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1596  p->payload = payload;
1597  p->payload_len = 3;
1598 
1599  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1600  goto end;
1601 
1602  if (!stream_config.midstream) {
1603  ret = 1;
1604  goto end;
1605  }
1606  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1607  goto end;
1608 
1609  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1610  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1611  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1612  " server.next_seq %" PRIu32 "\n",
1613  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1614  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1615  goto end;
1616  }
1617 
1618  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1619  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1620  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1621  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1622  " should be %" PRIu8 "\n",
1623  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1624  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1625  goto end;
1626  }
1628 
1629  ret = 1;
1630 end:
1631  ConfDeInit();
1633  SCFree(p);
1634  FLOW_DESTROY(&f);
1636  return ret;
1637 }
1638 
1639 /**
1640  * \test Test the setting up a OS policy. Te OS policy values are defined in
1641  * the config string "dummy_conf_string1"
1642  *
1643  * \retval On success it returns 1 and on failure 0
1644  */
1645 
1646 static int StreamTcpTest16(void)
1647 {
1648  Packet *p = PacketGetFromAlloc();
1649  FAIL_IF_NULL(p);
1650  Flow f;
1651  ThreadVars tv;
1652  StreamTcpThread stt;
1653  TCPHdr tcph;
1654  uint8_t payload[4];
1655  struct in_addr addr;
1656  IPV4Hdr ipv4h;
1657  char os_policy_name[10] = "windows";
1658  const char *ip_addr;
1659  PacketQueueNoLock pq;
1660  memset(&pq, 0, sizeof(PacketQueueNoLock));
1661 
1662  memset(&f, 0, sizeof(Flow));
1663  memset(&tv, 0, sizeof(ThreadVars));
1664  memset(&stt, 0, sizeof(StreamTcpThread));
1665  memset(&tcph, 0, sizeof(TCPHdr));
1666  memset(&addr, 0, sizeof(addr));
1667  memset(&ipv4h, 0, sizeof(ipv4h));
1668  FLOW_INITIALIZE(&f);
1669  p->flow = &f;
1670  int ret = 0;
1671 
1672  StreamTcpUTInit(&stt.ra_ctx);
1673 
1674  /* Load the config string into parser */
1676  ConfInit();
1677  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1678 
1679  /* Get the IP address as string and add it to Host info tree for lookups */
1680  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1681  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1682  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1683  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1684  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1685  addr.s_addr = inet_addr("192.168.0.1");
1686  tcph.th_win = htons(5480);
1687  tcph.th_seq = htonl(10);
1688  tcph.th_ack = htonl(20);
1689  tcph.th_flags = TH_ACK | TH_PUSH;
1690  p->tcph = &tcph;
1691  p->dst.family = AF_INET;
1692  p->dst.address.address_un_data32[0] = addr.s_addr;
1693  p->ip4h = &ipv4h;
1694 
1695  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1696  p->payload = payload;
1697  p->payload_len = 3;
1698 
1699  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1700  goto end;
1701 
1702  p->tcph->th_seq = htonl(20);
1703  p->tcph->th_ack = htonl(13);
1704  p->tcph->th_flags = TH_ACK | TH_PUSH;
1706 
1707  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1708  p->payload = payload;
1709  p->payload_len = 3;
1710 
1711  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1712  goto end;
1713 
1714  p->tcph->th_seq = htonl(15);
1715  p->tcph->th_ack = htonl(23);
1716  p->tcph->th_flags = TH_ACK | TH_PUSH;
1718 
1719  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1720  p->payload = payload;
1721  p->payload_len = 3;
1722 
1723  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1724  goto end;
1725 
1726  p->tcph->th_seq = htonl(14);
1727  p->tcph->th_ack = htonl(23);
1728  p->tcph->th_flags = TH_ACK | TH_PUSH;
1730 
1731  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1732  p->payload = payload;
1733  p->payload_len = 3;
1734 
1735  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1736  goto end;
1737 
1738  addr.s_addr = inet_addr("192.168.1.1");
1739  p->tcph->th_seq = htonl(25);
1740  p->tcph->th_ack = htonl(13);
1741  p->tcph->th_flags = TH_ACK | TH_PUSH;
1743  p->dst.address.address_un_data32[0] = addr.s_addr;
1744 
1745  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1746  p->payload = payload;
1747  p->payload_len = 3;
1748 
1749  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1750  goto end;
1751 
1752  p->tcph->th_seq = htonl(24);
1753  p->tcph->th_ack = htonl(13);
1754  p->tcph->th_flags = TH_ACK | TH_PUSH;
1756 
1757  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1758  p->payload = payload;
1759  p->payload_len = 3;
1760 
1761  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1762  goto end;
1763 
1764  if (!stream_config.midstream) {
1765  ret = 1;
1766  goto end;
1767  }
1768  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1769  goto end;
1770 
1771  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1772  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1773  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1774  " server.next_seq %" PRIu32 "\n",
1775  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1776  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1777  goto end;
1778  }
1779 
1780  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1781  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_WINDOWS) {
1782  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1783  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1784  " should be %" PRIu8 "\n",
1785  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1786  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_WINDOWS);
1787  goto end;
1788  }
1790 
1791  ret = 1;
1792 end:
1793  ConfDeInit();
1795  SCFree(p);
1796  FLOW_DESTROY(&f);
1798  return ret;
1799 }
1800 
1801 /**
1802  * \test Test the setting up a OS policy. Te OS policy values are defined in
1803  * the config string "dummy_conf_string1". To check the setting of
1804  * Default os policy
1805  *
1806  * \retval On success it returns 1 and on failure 0
1807  */
1808 
1809 static int StreamTcpTest17(void)
1810 {
1811  Packet *p = PacketGetFromAlloc();
1812  FAIL_IF_NULL(p);
1813  Flow f;
1814  ThreadVars tv;
1815  StreamTcpThread stt;
1816  TCPHdr tcph;
1817  uint8_t payload[4];
1818  struct in_addr addr;
1819  IPV4Hdr ipv4h;
1820  char os_policy_name[10] = "windows";
1821  const char *ip_addr;
1822  PacketQueueNoLock pq;
1823  memset(&pq, 0, sizeof(PacketQueueNoLock));
1824 
1825  memset(&f, 0, sizeof(Flow));
1826  memset(&tv, 0, sizeof(ThreadVars));
1827  memset(&stt, 0, sizeof(StreamTcpThread));
1828  memset(&tcph, 0, sizeof(TCPHdr));
1829  memset(&addr, 0, sizeof(addr));
1830  memset(&ipv4h, 0, sizeof(ipv4h));
1831  FLOW_INITIALIZE(&f);
1832  p->flow = &f;
1833  int ret = 0;
1834 
1835  StreamTcpUTInit(&stt.ra_ctx);
1836 
1837  /* Load the config string into parser */
1839  ConfInit();
1840  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1841 
1842  /* Get the IP address as string and add it to Host info tree for lookups */
1843  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1844  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1845  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1846  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1847  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1848  addr.s_addr = inet_addr("192.168.0.1");
1849  tcph.th_win = htons(5480);
1850  tcph.th_seq = htonl(10);
1851  tcph.th_ack = htonl(20);
1852  tcph.th_flags = TH_ACK | TH_PUSH;
1853  p->tcph = &tcph;
1854  p->dst.family = AF_INET;
1855  p->dst.address.address_un_data32[0] = addr.s_addr;
1856  p->ip4h = &ipv4h;
1857 
1858  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1859  p->payload = payload;
1860  p->payload_len = 3;
1861 
1862  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1863  goto end;
1864 
1865  p->tcph->th_seq = htonl(20);
1866  p->tcph->th_ack = htonl(13);
1867  p->tcph->th_flags = TH_ACK | TH_PUSH;
1869 
1870  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1871  p->payload = payload;
1872  p->payload_len = 3;
1873 
1874  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1875  goto end;
1876 
1877  p->tcph->th_seq = htonl(15);
1878  p->tcph->th_ack = htonl(23);
1879  p->tcph->th_flags = TH_ACK | TH_PUSH;
1881 
1882  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1883  p->payload = payload;
1884  p->payload_len = 3;
1885 
1886  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1887  goto end;
1888 
1889  p->tcph->th_seq = htonl(14);
1890  p->tcph->th_ack = htonl(23);
1891  p->tcph->th_flags = TH_ACK | TH_PUSH;
1893 
1894  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1895  p->payload = payload;
1896  p->payload_len = 3;
1897 
1898  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1899  goto end;
1900 
1901  addr.s_addr = inet_addr("10.1.1.1");
1902  p->tcph->th_seq = htonl(25);
1903  p->tcph->th_ack = htonl(13);
1904  p->tcph->th_flags = TH_ACK | TH_PUSH;
1906  p->dst.address.address_un_data32[0] = addr.s_addr;
1907 
1908  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1909  p->payload = payload;
1910  p->payload_len = 3;
1911 
1912  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1913  goto end;
1914 
1915  p->tcph->th_seq = htonl(24);
1916  p->tcph->th_ack = htonl(13);
1917  p->tcph->th_flags = TH_ACK | TH_PUSH;
1919 
1920  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1921  p->payload = payload;
1922  p->payload_len = 3;
1923 
1924  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1925  goto end;
1926 
1927  if (!stream_config.midstream) {
1928  ret = 1;
1929  goto end;
1930  }
1931  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1932  goto end;
1933 
1934  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1935  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1936  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1937  " server.next_seq %" PRIu32 "\n",
1938  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1939  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1940  goto end;
1941  }
1942 
1943  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1944  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_DEFAULT) {
1945  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1946  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1947  " should be %" PRIu8 "\n",
1948  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1949  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_DEFAULT);
1950  goto end;
1951  }
1953 
1954  ret = 1;
1955 end:
1956  ConfDeInit();
1958  SCFree(p);
1959  FLOW_DESTROY(&f);
1961  return ret;
1962 }
1963 
1964 /** \test Test the various OS policies based on different IP addresses from
1965  configuration defined in 'dummy_conf_string1' */
1966 static int StreamTcpTest18(void)
1967 {
1968  StreamTcpThread stt;
1969  struct in_addr addr;
1970  char os_policy_name[10] = "windows";
1971  const char *ip_addr;
1972  TcpStream stream;
1973  Packet *p = PacketGetFromAlloc();
1974  FAIL_IF_NULL(p);
1975  IPV4Hdr ipv4h;
1976  int ret = 0;
1977 
1978  memset(&addr, 0, sizeof(addr));
1979  memset(&stream, 0, sizeof(stream));
1980  memset(&ipv4h, 0, sizeof(ipv4h));
1981 
1982  StreamTcpUTInit(&stt.ra_ctx);
1984 
1985  /* Load the config string into parser */
1987  ConfInit();
1988  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1989 
1990  /* Get the IP address as string and add it to Host info tree for lookups */
1991  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1992  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1993 
1994  p->dst.family = AF_INET;
1995  p->ip4h = &ipv4h;
1996  addr.s_addr = inet_addr("192.168.1.1");
1997  p->dst.address.address_un_data32[0] = addr.s_addr;
1998  StreamTcpSetOSPolicy(&stream, p);
1999 
2000  if (stream.os_policy != OS_POLICY_WINDOWS)
2001  goto end;
2002 
2003  ret = 1;
2004 end:
2005  ConfDeInit();
2007  SCFree(p);
2009  return ret;
2010 }
2011 /** \test Test the various OS policies based on different IP addresses from
2012  configuration defined in 'dummy_conf_string1' */
2013 static int StreamTcpTest19(void)
2014 {
2015  StreamTcpThread stt;
2016  struct in_addr addr;
2017  char os_policy_name[10] = "windows";
2018  const char *ip_addr;
2019  TcpStream stream;
2020  Packet *p = PacketGetFromAlloc();
2021  FAIL_IF_NULL(p);
2022  IPV4Hdr ipv4h;
2023  int ret = 0;
2024 
2025  memset(&addr, 0, sizeof(addr));
2026  memset(&stream, 0, sizeof(stream));
2027  memset(&ipv4h, 0, sizeof(ipv4h));
2028 
2029  StreamTcpUTInit(&stt.ra_ctx);
2031 
2032  /* Load the config string into parser */
2034  ConfInit();
2035  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2036 
2037  /* Get the IP address as string and add it to Host info tree for lookups */
2038  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2039  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2040 
2041  p->dst.family = AF_INET;
2042  p->ip4h = &ipv4h;
2043  addr.s_addr = inet_addr("192.168.0.30");
2044  p->dst.address.address_un_data32[0] = addr.s_addr;
2045  StreamTcpSetOSPolicy(&stream, p);
2046 
2047  if (stream.os_policy != OS_POLICY_WINDOWS) {
2048  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 ": ",
2049  (uint8_t)OS_POLICY_WINDOWS, stream.os_policy);
2050  goto end;
2051  }
2052 
2053  ret = 1;
2054 end:
2055  ConfDeInit();
2057  SCFree(p);
2059  return ret;
2060 }
2061 /** \test Test the various OS policies based on different IP addresses from
2062  configuration defined in 'dummy_conf_string1' */
2063 static int StreamTcpTest20(void)
2064 {
2065  StreamTcpThread stt;
2066  struct in_addr addr;
2067  char os_policy_name[10] = "linux";
2068  const char *ip_addr;
2069  TcpStream stream;
2070  Packet *p = PacketGetFromAlloc();
2071  FAIL_IF_NULL(p);
2072  IPV4Hdr ipv4h;
2073  int ret = 0;
2074 
2075  memset(&addr, 0, sizeof(addr));
2076  memset(&stream, 0, sizeof(stream));
2077  memset(&ipv4h, 0, sizeof(ipv4h));
2078 
2079  StreamTcpUTInit(&stt.ra_ctx);
2081 
2082  /* Load the config string into parser */
2084  ConfInit();
2085  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2086 
2087  /* Get the IP address as string and add it to Host info tree for lookups */
2088  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2089  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2090 
2091  p->dst.family = AF_INET;
2092  p->ip4h = &ipv4h;
2093  addr.s_addr = inet_addr("192.168.0.1");
2094  p->dst.address.address_un_data32[0] = addr.s_addr;
2095  StreamTcpSetOSPolicy(&stream, p);
2096 
2097  if (stream.os_policy != OS_POLICY_LINUX) {
2098  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2099  stream.os_policy);
2100  goto end;
2101  }
2102 
2103  ret = 1;
2104 end:
2105  ConfDeInit();
2107  SCFree(p);
2109  return ret;
2110 }
2111 /** \test Test the various OS policies based on different IP addresses from
2112  configuration defined in 'dummy_conf_string1' */
2113 static int StreamTcpTest21(void)
2114 {
2115  StreamTcpThread stt;
2116  struct in_addr addr;
2117  char os_policy_name[10] = "linux";
2118  const char *ip_addr;
2119  TcpStream stream;
2120  Packet *p = PacketGetFromAlloc();
2121  FAIL_IF_NULL(p);
2122  IPV4Hdr ipv4h;
2123  int ret = 0;
2124 
2125  memset(&addr, 0, sizeof(addr));
2126  memset(&stream, 0, sizeof(stream));
2127  memset(&ipv4h, 0, sizeof(ipv4h));
2128 
2129  StreamTcpUTInit(&stt.ra_ctx);
2131 
2132  /* Load the config string into parser */
2134  ConfInit();
2135  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2136 
2137  /* Get the IP address as string and add it to Host info tree for lookups */
2138  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2139  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2140 
2141  p->dst.family = AF_INET;
2142  p->ip4h = &ipv4h;
2143  addr.s_addr = inet_addr("192.168.1.30");
2144  p->dst.address.address_un_data32[0] = addr.s_addr;
2145  StreamTcpSetOSPolicy(&stream, p);
2146 
2147  if (stream.os_policy != OS_POLICY_LINUX) {
2148  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2149  stream.os_policy);
2150  goto end;
2151  }
2152 
2153  ret = 1;
2154 end:
2155  ConfDeInit();
2157  SCFree(p);
2159  return ret;
2160 }
2161 /** \test Test the various OS policies based on different IP addresses from
2162  configuration defined in 'dummy_conf_string1' */
2163 static int StreamTcpTest22(void)
2164 {
2165  StreamTcpThread stt;
2166  struct in_addr addr;
2167  char os_policy_name[10] = "windows";
2168  const char *ip_addr;
2169  TcpStream stream;
2170  Packet *p = PacketGetFromAlloc();
2171  FAIL_IF_NULL(p);
2172  IPV4Hdr ipv4h;
2173  int ret = 0;
2174 
2175  memset(&addr, 0, sizeof(addr));
2176  memset(&stream, 0, sizeof(stream));
2177  memset(&ipv4h, 0, sizeof(ipv4h));
2178 
2179  StreamTcpUTInit(&stt.ra_ctx);
2181 
2182  /* Load the config string into parser */
2184  ConfInit();
2185  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2186 
2187  /* Get the IP address as string and add it to Host info tree for lookups */
2188  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2189  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2190 
2191  p->dst.family = AF_INET;
2192  p->ip4h = &ipv4h;
2193  addr.s_addr = inet_addr("123.231.2.1");
2194  p->dst.address.address_un_data32[0] = addr.s_addr;
2195  StreamTcpSetOSPolicy(&stream, p);
2196 
2197  if (stream.os_policy != OS_POLICY_DEFAULT) {
2198  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n",
2199  (uint8_t)OS_POLICY_DEFAULT, stream.os_policy);
2200  goto end;
2201  }
2202 
2203  ret = 1;
2204 end:
2205  ConfDeInit();
2207  SCFree(p);
2209  return ret;
2210 }
2211 
2212 /** \test Test the stream mem leaks conditions. */
2213 static int StreamTcpTest23(void)
2214 {
2215  StreamTcpThread stt;
2216  TcpSession ssn;
2217  Flow f;
2218  TCPHdr tcph;
2219  uint8_t packet[1460] = "";
2220  ThreadVars tv;
2221 
2222  Packet *p = PacketGetFromAlloc();
2223  FAIL_IF(p == NULL);
2224 
2225  memset(&f, 0, sizeof(Flow));
2226  memset(&tcph, 0, sizeof(TCPHdr));
2227  memset(&tv, 0, sizeof(ThreadVars));
2228 
2229  StreamTcpUTInit(&stt.ra_ctx);
2231  FLOW_INITIALIZE(&f);
2233  f.protoctx = &ssn;
2234  p->src.family = AF_INET;
2235  p->dst.family = AF_INET;
2236  p->proto = IPPROTO_TCP;
2237  p->flow = &f;
2238  tcph.th_win = 5480;
2239  tcph.th_flags = TH_PUSH | TH_ACK;
2240  p->tcph = &tcph;
2242  p->payload = packet;
2243  SET_ISN(&ssn.client, 3184324452UL);
2244 
2245  p->tcph->th_seq = htonl(3184324453UL);
2246  p->tcph->th_ack = htonl(3373419609UL);
2247  p->payload_len = 2;
2248 
2249  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2250 
2251  p->tcph->th_seq = htonl(3184324455UL);
2252  p->tcph->th_ack = htonl(3373419621UL);
2253  p->payload_len = 2;
2254 
2255  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2256 
2257  p->tcph->th_seq = htonl(3184324453UL);
2258  p->tcph->th_ack = htonl(3373419621UL);
2259  p->payload_len = 6;
2260 
2261  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2262 
2263  TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2264  FAIL_IF_NULL(seg);
2265  FAIL_IF(TCP_SEG_LEN(seg) != 2);
2266 
2268  SCFree(p);
2269  FLOW_DESTROY(&f);
2271  FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2272  PASS;
2273 }
2274 
2275 /** \test Test the stream mem leaks conditions. */
2276 static int StreamTcpTest24(void)
2277 {
2278  StreamTcpThread stt;
2279  TcpSession ssn;
2280  Packet *p = PacketGetFromAlloc();
2281  FAIL_IF(p == NULL);
2282  Flow f;
2283  TCPHdr tcph;
2284  uint8_t packet[1460] = "";
2285  ThreadVars tv;
2286  memset(&tv, 0, sizeof(ThreadVars));
2287 
2288  StreamTcpUTInit(&stt.ra_ctx);
2290 
2291  memset(&f, 0, sizeof(Flow));
2292  memset(&tcph, 0, sizeof(TCPHdr));
2293  FLOW_INITIALIZE(&f);
2295  f.protoctx = &ssn;
2296  p->src.family = AF_INET;
2297  p->dst.family = AF_INET;
2298  p->proto = IPPROTO_TCP;
2299  p->flow = &f;
2300  tcph.th_win = 5480;
2301  tcph.th_flags = TH_PUSH | TH_ACK;
2302  p->tcph = &tcph;
2304  p->payload = packet;
2305  // ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL;
2306  SET_ISN(&ssn.client, 3184324453UL);
2307 
2308  p->tcph->th_seq = htonl(3184324455UL);
2309  p->tcph->th_ack = htonl(3373419621UL);
2310  p->payload_len = 4;
2311 
2312  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2313 
2314  p->tcph->th_seq = htonl(3184324459UL);
2315  p->tcph->th_ack = htonl(3373419633UL);
2316  p->payload_len = 2;
2317 
2318  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2319 
2320  p->tcph->th_seq = htonl(3184324459UL);
2321  p->tcph->th_ack = htonl(3373419657UL);
2322  p->payload_len = 4;
2323 
2324  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p) == -1);
2325 
2326  TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2327  FAIL_IF_NULL(seg);
2328  FAIL_IF(TCP_SEG_LEN(seg) != 4);
2329 
2331  SCFree(p);
2332  FLOW_DESTROY(&f);
2334  FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2335  PASS;
2336 }
2337 
2338 /**
2339  * \test Test the initialization of tcp streams with congestion flags
2340  *
2341  * \retval On success it returns 1 and on failure 0.
2342  */
2343 static int StreamTcpTest25(void)
2344 {
2345  Packet *p = PacketGetFromAlloc();
2346  FAIL_IF_NULL(p);
2347  Flow f;
2348  ThreadVars tv;
2349  StreamTcpThread stt;
2350  uint8_t payload[4];
2351  TCPHdr tcph;
2352  int ret = 0;
2353  PacketQueueNoLock pq;
2354  memset(&pq, 0, sizeof(PacketQueueNoLock));
2355 
2356  memset(&f, 0, sizeof(Flow));
2357  memset(&tv, 0, sizeof(ThreadVars));
2358  memset(&stt, 0, sizeof(StreamTcpThread));
2359  memset(&tcph, 0, sizeof(TCPHdr));
2360 
2361  FLOW_INITIALIZE(&f);
2362  p->flow = &f;
2363  tcph.th_win = htons(5480);
2364  tcph.th_flags = TH_SYN | TH_CWR;
2365  p->tcph = &tcph;
2367  StreamTcpUTInit(&stt.ra_ctx);
2368 
2369  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2370  goto end;
2371 
2372  p->tcph->th_ack = htonl(1);
2373  p->tcph->th_flags = TH_SYN | TH_ACK;
2375 
2376  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2377  goto end;
2378 
2379  p->tcph->th_ack = htonl(1);
2380  p->tcph->th_seq = htonl(1);
2381  p->tcph->th_flags = TH_ACK;
2383 
2384  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2385  goto end;
2386 
2387  p->tcph->th_ack = htonl(1);
2388  p->tcph->th_seq = htonl(2);
2389  p->tcph->th_flags = TH_PUSH | TH_ACK;
2391 
2392  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2393  p->payload = payload;
2394  p->payload_len = 3;
2395 
2396  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2397  goto end;
2398 
2400  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2401  goto end;
2402 
2403  p->tcph->th_ack = htonl(1);
2404  p->tcph->th_seq = htonl(6);
2405  p->tcph->th_flags = TH_PUSH | TH_ACK;
2407 
2408  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2409  p->payload = payload;
2410  p->payload_len = 3;
2411 
2412  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2413  goto end;
2414 
2416  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2417  goto end;
2418 
2420 
2421  ret = 1;
2422 end:
2423  SCFree(p);
2424  FLOW_DESTROY(&f);
2426  return ret;
2427 }
2428 
2429 /**
2430  * \test Test the initialization of tcp streams with congestion flags
2431  *
2432  * \retval On success it returns 1 and on failure 0.
2433  */
2434 static int StreamTcpTest26(void)
2435 {
2436  Packet *p = PacketGetFromAlloc();
2437  FAIL_IF_NULL(p);
2438  Flow f;
2439  ThreadVars tv;
2440  StreamTcpThread stt;
2441  uint8_t payload[4];
2442  TCPHdr tcph;
2443  int ret = 0;
2444  PacketQueueNoLock pq;
2445  memset(&pq, 0, sizeof(PacketQueueNoLock));
2446 
2447  memset(&f, 0, sizeof(Flow));
2448  memset(&tv, 0, sizeof(ThreadVars));
2449  memset(&stt, 0, sizeof(StreamTcpThread));
2450  memset(&tcph, 0, sizeof(TCPHdr));
2451 
2452  FLOW_INITIALIZE(&f);
2453  p->flow = &f;
2454  tcph.th_win = htons(5480);
2455  tcph.th_flags = TH_SYN | TH_ECN;
2456  p->tcph = &tcph;
2458 
2459  StreamTcpUTInit(&stt.ra_ctx);
2460 
2461  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2462  goto end;
2463 
2464  p->tcph->th_ack = htonl(1);
2465  p->tcph->th_flags = TH_SYN | TH_ACK;
2467 
2468  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2469  goto end;
2470 
2471  p->tcph->th_ack = htonl(1);
2472  p->tcph->th_seq = htonl(1);
2473  p->tcph->th_flags = TH_ACK;
2475 
2476  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2477  goto end;
2478 
2479  p->tcph->th_ack = htonl(1);
2480  p->tcph->th_seq = htonl(2);
2481  p->tcph->th_flags = TH_PUSH | TH_ACK;
2483 
2484  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2485  p->payload = payload;
2486  p->payload_len = 3;
2487 
2488  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2489  goto end;
2490 
2492  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2493  goto end;
2494 
2495  p->tcph->th_ack = htonl(1);
2496  p->tcph->th_seq = htonl(6);
2497  p->tcph->th_flags = TH_PUSH | TH_ACK;
2499 
2500  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2501  p->payload = payload;
2502  p->payload_len = 3;
2503 
2504  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2505  goto end;
2506 
2508  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2509  goto end;
2510 
2512 
2513  ret = 1;
2514 end:
2515  SCFree(p);
2516  FLOW_DESTROY(&f);
2518  return ret;
2519 }
2520 
2521 /**
2522  * \test Test the initialization of tcp streams with congestion flags
2523  *
2524  * \retval On success it returns 1 and on failure 0.
2525  */
2526 static int StreamTcpTest27(void)
2527 {
2528  Packet *p = PacketGetFromAlloc();
2529  FAIL_IF_NULL(p);
2530  Flow f;
2531  ThreadVars tv;
2532  StreamTcpThread stt;
2533  uint8_t payload[4];
2534  TCPHdr tcph;
2535  int ret = 0;
2536  PacketQueueNoLock pq;
2537  memset(&pq, 0, sizeof(PacketQueueNoLock));
2538 
2539  memset(&f, 0, sizeof(Flow));
2540  memset(&tv, 0, sizeof(ThreadVars));
2541  memset(&stt, 0, sizeof(StreamTcpThread));
2542  memset(&tcph, 0, sizeof(TCPHdr));
2543 
2544  FLOW_INITIALIZE(&f);
2545  p->flow = &f;
2546  tcph.th_win = htons(5480);
2547  tcph.th_flags = TH_SYN | TH_CWR | TH_ECN;
2548  p->tcph = &tcph;
2550 
2551  StreamTcpUTInit(&stt.ra_ctx);
2552 
2553  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2554  goto end;
2555 
2556  p->tcph->th_ack = htonl(1);
2557  p->tcph->th_flags = TH_SYN | TH_ACK;
2559 
2560  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2561  goto end;
2562 
2563  p->tcph->th_ack = htonl(1);
2564  p->tcph->th_seq = htonl(1);
2565  p->tcph->th_flags = TH_ACK;
2567 
2568  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2569  goto end;
2570 
2571  p->tcph->th_ack = htonl(1);
2572  p->tcph->th_seq = htonl(2);
2573  p->tcph->th_flags = TH_PUSH | TH_ACK;
2575 
2576  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2577  p->payload = payload;
2578  p->payload_len = 3;
2579 
2580  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2581  goto end;
2582 
2584  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2585  goto end;
2586 
2587  p->tcph->th_ack = htonl(1);
2588  p->tcph->th_seq = htonl(6);
2589  p->tcph->th_flags = TH_PUSH | TH_ACK;
2591 
2592  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2593  p->payload = payload;
2594  p->payload_len = 3;
2595 
2596  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2597  goto end;
2598 
2600  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2601  goto end;
2602 
2604 
2605  ret = 1;
2606 end:
2607  SCFree(p);
2608  FLOW_DESTROY(&f);
2610  return ret;
2611 }
2612 
2613 /** \test Test the memcap incrementing/decrementing and memcap check */
2614 static int StreamTcpTest28(void)
2615 {
2616  StreamTcpThread stt;
2617  StreamTcpUTInit(&stt.ra_ctx);
2618 
2619  uint32_t memuse = SC_ATOMIC_GET(st_memuse);
2620 
2621  StreamTcpIncrMemuse(500);
2622  FAIL_IF(SC_ATOMIC_GET(st_memuse) != (memuse + 500));
2623 
2624  StreamTcpDecrMemuse(500);
2625  FAIL_IF(SC_ATOMIC_GET(st_memuse) != memuse);
2626 
2627  FAIL_IF(StreamTcpCheckMemcap(500) != 1);
2628 
2629  FAIL_IF(StreamTcpCheckMemcap((memuse + SC_ATOMIC_GET(stream_config.memcap))) != 0);
2630 
2632 
2633  FAIL_IF(SC_ATOMIC_GET(st_memuse) != 0);
2634  PASS;
2635 }
2636 
2637 /**
2638  * \test Test the processing of out of order FIN packets in tcp session.
2639  *
2640  * \retval On success it returns 1 and on failure 0.
2641  */
2642 static int StreamTcpTest37(void)
2643 {
2644  Packet *p = PacketGetFromAlloc();
2645  FAIL_IF_NULL(p);
2646  Flow f;
2647  ThreadVars tv;
2648  StreamTcpThread stt;
2649  uint8_t payload[4];
2650  TCPHdr tcph;
2651  int ret = 0;
2652  PacketQueueNoLock pq;
2653  memset(&pq, 0, sizeof(PacketQueueNoLock));
2654 
2655  memset(&f, 0, sizeof(Flow));
2656  memset(&tv, 0, sizeof(ThreadVars));
2657  memset(&stt, 0, sizeof(StreamTcpThread));
2658  memset(&tcph, 0, sizeof(TCPHdr));
2659 
2660  FLOW_INITIALIZE(&f);
2661 
2662  p->flow = &f;
2663  tcph.th_win = htons(5480);
2664  tcph.th_flags = TH_SYN;
2665  p->tcph = &tcph;
2667 
2668  StreamTcpUTInit(&stt.ra_ctx);
2669 
2670  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2671  printf("failed in processing packet\n");
2672  goto end;
2673  }
2674 
2675  p->tcph->th_ack = htonl(1);
2676  p->tcph->th_flags = TH_SYN | TH_ACK;
2678 
2679  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2680  printf("failed in processing packet\n");
2681  goto end;
2682  }
2683 
2684  p->tcph->th_ack = htonl(1);
2685  p->tcph->th_seq = htonl(1);
2686  p->tcph->th_flags = TH_ACK;
2688 
2689  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2690  printf("failed in processing packet\n");
2691  goto end;
2692  }
2693 
2694  if (((TcpSession *)p->flow->protoctx)->state != TCP_ESTABLISHED) {
2695  printf("the TCP state should be TCP_ESTABLISHED\n");
2696  goto end;
2697  }
2698 
2699  p->tcph->th_ack = htonl(2);
2700  p->tcph->th_seq = htonl(4);
2701  p->tcph->th_flags = TH_ACK | TH_FIN;
2703 
2704  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2705  printf("failed in processing packet\n");
2706  goto end;
2707  }
2708 
2709  if (((TcpSession *)p->flow->protoctx)->state != TCP_CLOSE_WAIT) {
2710  printf("the TCP state should be TCP_CLOSE_WAIT\n");
2711  goto end;
2712  }
2713 
2714  p->tcph->th_ack = htonl(1);
2715  p->tcph->th_seq = htonl(1);
2716  p->tcph->th_flags = TH_PUSH | TH_ACK;
2718 
2719  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2720  p->payload = payload;
2721  p->payload_len = 3;
2722 
2723  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2724  printf("failed in processing packet\n");
2725  goto end;
2726  }
2727 
2728  p->tcph->th_ack = htonl(4);
2729  p->tcph->th_seq = htonl(2);
2730  p->tcph->th_flags = TH_ACK;
2731  p->payload_len = 0;
2733 
2734  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
2735  printf("failed in processing packet\n");
2736  goto end;
2737  }
2738 
2739  TcpStream *stream = &(((TcpSession *)p->flow->protoctx)->client);
2740  FAIL_IF(STREAM_RAW_PROGRESS(stream) != 0); // no detect no progress update
2741 
2743 
2744  ret = 1;
2745 end:
2746  SCFree(p);
2747  FLOW_DESTROY(&f);
2749  return ret;
2750 }
2751 
2752 /**
2753  * \test Test the validation of the ACK number before setting up the
2754  * stream.last_ack.
2755  *
2756  * \retval On success it returns 1 and on failure 0.
2757  */
2758 
2759 static int StreamTcpTest38(void)
2760 {
2761  int ret = 0;
2762  Flow f;
2763  ThreadVars tv;
2764  StreamTcpThread stt;
2765  uint8_t payload[128];
2766  TCPHdr tcph;
2767  PacketQueueNoLock pq;
2768 
2769  memset(&f, 0, sizeof(Flow));
2770  memset(&tv, 0, sizeof(ThreadVars));
2771  memset(&stt, 0, sizeof(StreamTcpThread));
2772  memset(&tcph, 0, sizeof(TCPHdr));
2773  memset(&pq, 0, sizeof(PacketQueueNoLock));
2774 
2775  Packet *p = PacketGetFromAlloc();
2776  FAIL_IF_NULL(p);
2777 
2778  FLOW_INITIALIZE(&f);
2779  p->flow = &f;
2780  tcph.th_win = htons(5480);
2781  tcph.th_flags = TH_SYN;
2782  p->tcph = &tcph;
2784 
2785  StreamTcpUTInit(&stt.ra_ctx);
2786  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2787  printf("failed in processing packet in StreamTcpPacket\n");
2788  goto end;
2789  }
2790 
2791  p->tcph->th_ack = htonl(1);
2792  p->tcph->th_flags = TH_SYN | TH_ACK;
2794 
2795  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2796  printf("failed in processing packet in StreamTcpPacket\n");
2797  goto end;
2798  }
2799 
2800  p->tcph->th_ack = htonl(1);
2801  p->tcph->th_seq = htonl(1);
2802  p->tcph->th_flags = TH_ACK;
2804 
2805  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2806  printf("failed in processing packet in StreamTcpPacket\n");
2807  goto end;
2808  }
2809 
2810  p->tcph->th_ack = htonl(29847);
2811  p->tcph->th_seq = htonl(2);
2812  p->tcph->th_flags = TH_PUSH | TH_ACK;
2814 
2815  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2816  p->payload = payload;
2817  p->payload_len = 3;
2818 
2819  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2820  printf("failed in processing packet in StreamTcpPacket\n");
2821  goto end;
2822  }
2823 
2824  /* last_ack value should be 1 as the previous sent ACK value is out of
2825  window */
2826  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 1) {
2827  printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
2828  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2829  goto end;
2830  }
2831 
2832  p->tcph->th_ack = htonl(1);
2833  p->tcph->th_seq = htonl(1);
2834  p->tcph->th_flags = TH_PUSH | TH_ACK;
2836 
2837  StreamTcpCreateTestPacket(payload, 0x41, 127, 128); /*AAA*/
2838  p->payload = payload;
2839  p->payload_len = 127;
2840 
2841  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2842  printf("failed in processing packet in StreamTcpPacket\n");
2843  goto end;
2844  }
2845 
2846  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 128) {
2847  printf("the server.next_seq should be 128, but it is %" PRIu32 "\n",
2848  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
2849  goto end;
2850  }
2851 
2852  p->tcph->th_ack = htonl(256); // in window, but beyond next_seq
2853  p->tcph->th_seq = htonl(5);
2854  p->tcph->th_flags = TH_PUSH | TH_ACK;
2856 
2857  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2858  p->payload = payload;
2859  p->payload_len = 3;
2860 
2861  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2862  printf("failed in processing packet in StreamTcpPacket\n");
2863  goto end;
2864  }
2865 
2866  /* last_ack value should be 256, as the previous sent ACK value
2867  is inside window */
2868  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
2869  printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
2870  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2871  goto end;
2872  }
2873 
2874  p->tcph->th_ack = htonl(128);
2875  p->tcph->th_seq = htonl(8);
2876  p->tcph->th_flags = TH_PUSH | TH_ACK;
2878 
2879  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2880  p->payload = payload;
2881  p->payload_len = 3;
2882 
2883  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2884  printf("failed in processing packet in StreamTcpPacket\n");
2885  goto end;
2886  }
2887 
2888  /* last_ack value should be 256 as the previous sent ACK value is inside
2889  window */
2890  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
2891  printf("the server.last_ack should be 256, but it is %" PRIu32 "\n",
2892  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
2893  goto end;
2894  }
2895 
2896  ret = 1;
2897 
2898 end:
2900  SCFree(p);
2901  FLOW_DESTROY(&f);
2903  return ret;
2904 }
2905 
2906 /**
2907  * \test Test the validation of the ACK number before setting up the
2908  * stream.last_ack and update the next_seq after loosing the .
2909  *
2910  * \retval On success it returns 1 and on failure 0.
2911  */
2912 
2913 static int StreamTcpTest39(void)
2914 {
2915  Flow f;
2916  ThreadVars tv;
2917  StreamTcpThread stt;
2918  uint8_t payload[4];
2919  TCPHdr tcph;
2920  PacketQueueNoLock pq;
2921 
2922  memset(&f, 0, sizeof(Flow));
2923  memset(&tv, 0, sizeof(ThreadVars));
2924  memset(&stt, 0, sizeof(StreamTcpThread));
2925  memset(&tcph, 0, sizeof(TCPHdr));
2926  memset(&pq, 0, sizeof(PacketQueueNoLock));
2927 
2928  Packet *p = PacketGetFromAlloc();
2929  FAIL_IF_NULL(p);
2930 
2931  FLOW_INITIALIZE(&f);
2932  p->flow = &f;
2933  tcph.th_win = htons(5480);
2934  tcph.th_flags = TH_SYN;
2935  p->tcph = &tcph;
2937  int ret = 0;
2938 
2939  StreamTcpUTInit(&stt.ra_ctx);
2940 
2941  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2942  printf("failed in processing packet in StreamTcpPacket\n");
2943  goto end;
2944  }
2945 
2946  p->tcph->th_ack = htonl(1);
2947  p->tcph->th_flags = TH_SYN | TH_ACK;
2949 
2950  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2951  printf("failed in processing packet in StreamTcpPacket\n");
2952  goto end;
2953  }
2954 
2955  p->tcph->th_ack = htonl(1);
2956  p->tcph->th_seq = htonl(1);
2957  p->tcph->th_flags = TH_ACK;
2959 
2960  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2961  printf("failed in processing packet in StreamTcpPacket\n");
2962  goto end;
2963  }
2964 
2965  p->tcph->th_ack = htonl(1);
2966  p->tcph->th_seq = htonl(1);
2967  p->tcph->th_flags = TH_PUSH | TH_ACK;
2969 
2970  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2971  p->payload = payload;
2972  p->payload_len = 3;
2973 
2974  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2975  printf("failed in processing packet in StreamTcpPacket\n");
2976  goto end;
2977  }
2978 
2979  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 4) {
2980  printf("the server.next_seq should be 4, but it is %" PRIu32 "\n",
2981  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
2982  goto end;
2983  }
2984 
2985  p->tcph->th_ack = htonl(4);
2986  p->tcph->th_seq = htonl(2);
2987  p->tcph->th_flags = TH_PUSH | TH_ACK;
2989 
2990  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2991  p->payload = payload;
2992  p->payload_len = 3;
2993 
2994  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
2995  printf("failed in processing packet in StreamTcpPacket\n");
2996  goto end;
2997  }
2998 
2999  /* last_ack value should be 4 as the previous sent ACK value is inside
3000  window */
3001  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 4) {
3002  printf("the server.last_ack should be 4, but it is %" PRIu32 "\n",
3003  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3004  goto end;
3005  }
3006 
3007  p->tcph->th_seq = htonl(4);
3008  p->tcph->th_ack = htonl(5);
3009  p->tcph->th_flags = TH_PUSH | TH_ACK;
3011 
3012  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3013  p->payload = payload;
3014  p->payload_len = 3;
3015 
3016  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3017  printf("failed in processing packet in StreamTcpPacket\n");
3018  goto end;
3019  }
3020 
3021  /* next_seq value should be 2987 as the previous sent ACK value is inside
3022  window */
3023  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 7) {
3024  printf("the server.next_seq should be 7, but it is %" PRIu32 "\n",
3025  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
3026  goto end;
3027  }
3028 
3029  ret = 1;
3030 
3031 end:
3033  SCFree(p);
3034  FLOW_DESTROY(&f);
3036  return ret;
3037 }
3038 
3039 /** \test multiple different SYN/ACK, pick first */
3040 static int StreamTcpTest42(void)
3041 {
3042  int ret = 0;
3043  Flow f;
3044  ThreadVars tv;
3045  StreamTcpThread stt;
3046  TCPHdr tcph;
3047  PacketQueueNoLock pq;
3048  Packet *p = PacketGetFromAlloc();
3049  FAIL_IF_NULL(p);
3050  TcpSession *ssn;
3051 
3052  memset(&pq, 0, sizeof(PacketQueueNoLock));
3053  memset(&f, 0, sizeof(Flow));
3054  memset(&tv, 0, sizeof(ThreadVars));
3055  memset(&stt, 0, sizeof(StreamTcpThread));
3056  memset(&tcph, 0, sizeof(TCPHdr));
3057 
3058  StreamTcpUTInit(&stt.ra_ctx);
3059 
3060  FLOW_INITIALIZE(&f);
3061  p->tcph = &tcph;
3062  tcph.th_win = htons(5480);
3063  p->flow = &f;
3064 
3065  /* SYN pkt */
3066  tcph.th_flags = TH_SYN;
3067  tcph.th_seq = htonl(100);
3069 
3070  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3071  goto end;
3072 
3073  /* SYN/ACK */
3074  p->tcph->th_seq = htonl(500);
3075  p->tcph->th_ack = htonl(101);
3076  p->tcph->th_flags = TH_SYN | TH_ACK;
3078 
3079  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3080  goto end;
3081 
3082  /* SYN/ACK */
3083  p->tcph->th_seq = htonl(1000);
3084  p->tcph->th_ack = htonl(101);
3085  p->tcph->th_flags = TH_SYN | TH_ACK;
3087 
3088  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3089  goto end;
3090 
3091  /* ACK */
3092  p->tcph->th_ack = htonl(501);
3093  p->tcph->th_seq = htonl(101);
3094  p->tcph->th_flags = TH_ACK;
3096 
3097  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3098  goto end;
3099 
3100  ssn = p->flow->protoctx;
3101 
3102  if (ssn->state != TCP_ESTABLISHED) {
3103  printf("state not TCP_ESTABLISHED: ");
3104  goto end;
3105  }
3106 
3107  if (ssn->server.isn != 500) {
3108  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 500);
3109  goto end;
3110  }
3111  if (ssn->client.isn != 100) {
3112  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3113  goto end;
3114  }
3115 
3117 
3118  ret = 1;
3119 end:
3120  SCFree(p);
3121  FLOW_DESTROY(&f);
3123  return ret;
3124 }
3125 
3126 /** \test multiple different SYN/ACK, pick second */
3127 static int StreamTcpTest43(void)
3128 {
3129  int ret = 0;
3130  Flow f;
3131  ThreadVars tv;
3132  StreamTcpThread stt;
3133  TCPHdr tcph;
3134  PacketQueueNoLock pq;
3135  Packet *p = PacketGetFromAlloc();
3136  FAIL_IF_NULL(p);
3137  TcpSession *ssn;
3138 
3139  memset(&pq, 0, sizeof(PacketQueueNoLock));
3140  memset(&f, 0, sizeof(Flow));
3141  memset(&tv, 0, sizeof(ThreadVars));
3142  memset(&stt, 0, sizeof(StreamTcpThread));
3143  memset(&tcph, 0, sizeof(TCPHdr));
3144 
3145  StreamTcpUTInit(&stt.ra_ctx);
3146 
3147  FLOW_INITIALIZE(&f);
3148  p->tcph = &tcph;
3149  tcph.th_win = htons(5480);
3150  p->flow = &f;
3151 
3152  /* SYN pkt */
3153  tcph.th_flags = TH_SYN;
3154  tcph.th_seq = htonl(100);
3156 
3157  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3158  goto end;
3159 
3160  /* SYN/ACK */
3161  p->tcph->th_seq = htonl(500);
3162  p->tcph->th_ack = htonl(101);
3163  p->tcph->th_flags = TH_SYN | TH_ACK;
3165 
3166  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3167  goto end;
3168 
3169  /* SYN/ACK */
3170  p->tcph->th_seq = htonl(1000);
3171  p->tcph->th_ack = htonl(101);
3172  p->tcph->th_flags = TH_SYN | TH_ACK;
3174 
3175  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3176  goto end;
3177 
3178  /* ACK */
3179  p->tcph->th_ack = htonl(1001);
3180  p->tcph->th_seq = htonl(101);
3181  p->tcph->th_flags = TH_ACK;
3183 
3184  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3185  goto end;
3186 
3187  ssn = p->flow->protoctx;
3188 
3189  if (ssn->state != TCP_ESTABLISHED) {
3190  printf("state not TCP_ESTABLISHED: ");
3191  goto end;
3192  }
3193 
3194  if (ssn->server.isn != 1000) {
3195  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
3196  goto end;
3197  }
3198  if (ssn->client.isn != 100) {
3199  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3200  goto end;
3201  }
3202 
3204 
3205  ret = 1;
3206 end:
3207  SCFree(p);
3208  FLOW_DESTROY(&f);
3210  return ret;
3211 }
3212 
3213 /** \test multiple different SYN/ACK, pick neither */
3214 static int StreamTcpTest44(void)
3215 {
3216  int ret = 0;
3217  Flow f;
3218  ThreadVars tv;
3219  StreamTcpThread stt;
3220  TCPHdr tcph;
3221  PacketQueueNoLock pq;
3222  Packet *p = PacketGetFromAlloc();
3223  FAIL_IF_NULL(p);
3224  TcpSession *ssn;
3225 
3226  memset(&pq, 0, sizeof(PacketQueueNoLock));
3227  memset(&f, 0, sizeof(Flow));
3228  memset(&tv, 0, sizeof(ThreadVars));
3229  memset(&stt, 0, sizeof(StreamTcpThread));
3230  memset(&tcph, 0, sizeof(TCPHdr));
3231 
3232  StreamTcpUTInit(&stt.ra_ctx);
3233 
3234  FLOW_INITIALIZE(&f);
3235  p->tcph = &tcph;
3236  tcph.th_win = htons(5480);
3237  p->flow = &f;
3238 
3239  /* SYN pkt */
3240  tcph.th_flags = TH_SYN;
3241  tcph.th_seq = htonl(100);
3243 
3244  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3245  goto end;
3246 
3247  /* SYN/ACK */
3248  p->tcph->th_seq = htonl(500);
3249  p->tcph->th_ack = htonl(101);
3250  p->tcph->th_flags = TH_SYN | TH_ACK;
3252 
3253  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3254  goto end;
3255 
3256  /* SYN/ACK */
3257  p->tcph->th_seq = htonl(1000);
3258  p->tcph->th_ack = htonl(101);
3259  p->tcph->th_flags = TH_SYN | TH_ACK;
3261 
3262  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3263  goto end;
3264 
3265  /* ACK */
3266  p->tcph->th_ack = htonl(3001);
3267  p->tcph->th_seq = htonl(101);
3268  p->tcph->th_flags = TH_ACK;
3270 
3271  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
3272  goto end;
3273 
3274  ssn = p->flow->protoctx;
3275 
3276  if (ssn->state != TCP_SYN_RECV) {
3277  SCLogDebug("state not TCP_SYN_RECV");
3278  goto end;
3279  }
3280 
3281  if (ssn->client.isn != 100) {
3282  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3283  goto end;
3284  }
3285 
3287 
3288  ret = 1;
3289 end:
3290  SCFree(p);
3291  FLOW_DESTROY(&f);
3293  return ret;
3294 }
3295 
3296 /** \test multiple different SYN/ACK, over the limit */
3297 static int StreamTcpTest45(void)
3298 {
3299  int ret = 0;
3300  Flow f;
3301  ThreadVars tv;
3302  StreamTcpThread stt;
3303  TCPHdr tcph;
3304  PacketQueueNoLock pq;
3305  Packet *p = PacketGetFromAlloc();
3306  FAIL_IF_NULL(p);
3307  TcpSession *ssn;
3308 
3309  memset(&pq, 0, sizeof(PacketQueueNoLock));
3310  memset(&f, 0, sizeof(Flow));
3311  memset(&tv, 0, sizeof(ThreadVars));
3312  memset(&stt, 0, sizeof(StreamTcpThread));
3313  memset(&tcph, 0, sizeof(TCPHdr));
3314 
3315  StreamTcpUTInit(&stt.ra_ctx);
3317 
3318  FLOW_INITIALIZE(&f);
3319  p->tcph = &tcph;
3320  tcph.th_win = htons(5480);
3321  p->flow = &f;
3322 
3323  /* SYN pkt */
3324  tcph.th_flags = TH_SYN;
3325  tcph.th_seq = htonl(100);
3327 
3328  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3329  goto end;
3330 
3331  /* SYN/ACK */
3332  p->tcph->th_seq = htonl(500);
3333  p->tcph->th_ack = htonl(101);
3334  p->tcph->th_flags = TH_SYN | TH_ACK;
3336 
3337  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3338  goto end;
3339 
3340  /* SYN/ACK */
3341  p->tcph->th_seq = htonl(1000);
3342  p->tcph->th_ack = htonl(101);
3343  p->tcph->th_flags = TH_SYN | TH_ACK;
3345 
3346  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3347  goto end;
3348 
3349  /* SYN/ACK */
3350  p->tcph->th_seq = htonl(2000);
3351  p->tcph->th_ack = htonl(101);
3352  p->tcph->th_flags = TH_SYN | TH_ACK;
3354 
3355  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3356  goto end;
3357 
3358  /* SYN/ACK */
3359  p->tcph->th_seq = htonl(3000);
3360  p->tcph->th_ack = htonl(101);
3361  p->tcph->th_flags = TH_SYN | TH_ACK;
3363 
3364  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
3365  goto end;
3366 
3367  /* ACK */
3368  p->tcph->th_ack = htonl(1001);
3369  p->tcph->th_seq = htonl(101);
3370  p->tcph->th_flags = TH_ACK;
3372 
3373  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3374  goto end;
3375 
3376  ssn = p->flow->protoctx;
3377 
3378  if (ssn->state != TCP_ESTABLISHED) {
3379  printf("state not TCP_ESTABLISHED: ");
3380  goto end;
3381  }
3382 
3383  if (ssn->server.isn != 1000) {
3384  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
3385  goto end;
3386  }
3387  if (ssn->client.isn != 100) {
3388  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3389  goto end;
3390  }
3391 
3393 
3394  ret = 1;
3395 end:
3396  SCFree(p);
3398  return ret;
3399 }
3400 
3402 {
3403  UtRegisterTest("StreamTcpTest01 -- TCP session allocation", StreamTcpTest01);
3404  UtRegisterTest("StreamTcpTest02 -- TCP session deallocation", StreamTcpTest02);
3405  UtRegisterTest("StreamTcpTest03 -- SYN missed MidStream session", StreamTcpTest03);
3406  UtRegisterTest("StreamTcpTest04 -- SYN/ACK missed MidStream session", StreamTcpTest04);
3407  UtRegisterTest("StreamTcpTest05 -- 3WHS missed MidStream session", StreamTcpTest05);
3408  UtRegisterTest("StreamTcpTest06 -- FIN, RST message MidStream session", StreamTcpTest06);
3409  UtRegisterTest("StreamTcpTest07 -- PAWS invalid timestamp", StreamTcpTest07);
3410  UtRegisterTest("StreamTcpTest08 -- PAWS valid timestamp", StreamTcpTest08);
3411  UtRegisterTest("StreamTcpTest09 -- No Client Reassembly", StreamTcpTest09);
3412  UtRegisterTest("StreamTcpTest10 -- No missed packet Async stream", StreamTcpTest10);
3413  UtRegisterTest("StreamTcpTest11 -- SYN missed Async stream", StreamTcpTest11);
3414  UtRegisterTest("StreamTcpTest12 -- SYN/ACK missed Async stream", StreamTcpTest12);
3415  UtRegisterTest("StreamTcpTest13 -- opposite stream packets for Async "
3416  "stream",
3417  StreamTcpTest13);
3418  UtRegisterTest("StreamTcp4WHSTest01", StreamTcp4WHSTest01);
3419  UtRegisterTest("StreamTcp4WHSTest02", StreamTcp4WHSTest02);
3420  UtRegisterTest("StreamTcp4WHSTest03", StreamTcp4WHSTest03);
3421  UtRegisterTest("StreamTcpTest14 -- setup OS policy", StreamTcpTest14);
3422  UtRegisterTest("StreamTcpTest15 -- setup OS policy", StreamTcpTest15);
3423  UtRegisterTest("StreamTcpTest16 -- setup OS policy", StreamTcpTest16);
3424  UtRegisterTest("StreamTcpTest17 -- setup OS policy", StreamTcpTest17);
3425  UtRegisterTest("StreamTcpTest18 -- setup OS policy", StreamTcpTest18);
3426  UtRegisterTest("StreamTcpTest19 -- setup OS policy", StreamTcpTest19);
3427  UtRegisterTest("StreamTcpTest20 -- setup OS policy", StreamTcpTest20);
3428  UtRegisterTest("StreamTcpTest21 -- setup OS policy", StreamTcpTest21);
3429  UtRegisterTest("StreamTcpTest22 -- setup OS policy", StreamTcpTest22);
3430  UtRegisterTest("StreamTcpTest23 -- stream memory leaks", StreamTcpTest23);
3431  UtRegisterTest("StreamTcpTest24 -- stream memory leaks", StreamTcpTest24);
3432  UtRegisterTest("StreamTcpTest25 -- test ecn/cwr sessions", StreamTcpTest25);
3433  UtRegisterTest("StreamTcpTest26 -- test ecn/cwr sessions", StreamTcpTest26);
3434  UtRegisterTest("StreamTcpTest27 -- test ecn/cwr sessions", StreamTcpTest27);
3435  UtRegisterTest("StreamTcpTest28 -- Memcap Test", StreamTcpTest28);
3436 
3437 #if 0 /* VJ 2010/09/01 disabled since they blow up on Fedora and Fedora is \
3438  * right about blowing up. The checksum functions are not used properly \
3439  * in the tests. */
3440  UtRegisterTest("StreamTcpTest29 -- Badchecksum Reset Test", StreamTcpTest29, 1);
3441  UtRegisterTest("StreamTcpTest30 -- Badchecksum Overlap Test", StreamTcpTest30, 1);
3442  UtRegisterTest("StreamTcpTest31 -- MultipleSyns Test", StreamTcpTest31, 1);
3443  UtRegisterTest("StreamTcpTest32 -- Bogus CWR Test", StreamTcpTest32, 1);
3444  UtRegisterTest("StreamTcpTest33 -- RST-SYN Again Test", StreamTcpTest33, 1);
3445  UtRegisterTest("StreamTcpTest34 -- SYN-PUSH Test", StreamTcpTest34, 1);
3446  UtRegisterTest("StreamTcpTest35 -- SYN-URG Test", StreamTcpTest35, 1);
3447  UtRegisterTest("StreamTcpTest36 -- PUSH-URG Test", StreamTcpTest36, 1);
3448 #endif
3449  UtRegisterTest("StreamTcpTest37 -- Out of order FIN Test", StreamTcpTest37);
3450 
3451  UtRegisterTest("StreamTcpTest38 -- validate ACK", StreamTcpTest38);
3452  UtRegisterTest("StreamTcpTest39 -- update next_seq", StreamTcpTest39);
3453 
3454  UtRegisterTest("StreamTcpTest42 -- SYN/ACK queue", StreamTcpTest42);
3455  UtRegisterTest("StreamTcpTest43 -- SYN/ACK queue", StreamTcpTest43);
3456  UtRegisterTest("StreamTcpTest44 -- SYN/ACK queue", StreamTcpTest44);
3457  UtRegisterTest("StreamTcpTest45 -- SYN/ACK queue", StreamTcpTest45);
3458 
3459  /* set up the reassembly tests as well */
3461 
3463 }
StreamTcpIncrMemuse
void StreamTcpIncrMemuse(uint64_t size)
Definition: stream-tcp.c:228
TCP_SYN_RECV
@ TCP_SYN_RECV
Definition: stream-tcp-private.h:154
Packet_::proto
uint8_t proto
Definition: decode.h:459
TcpStream_
Definition: stream-tcp-private.h:106
StreamTcpSessionPktFree
void StreamTcpSessionPktFree(Packet *p)
Function to return the stream segments back to the pool.
Definition: stream-tcp.c:382
StreamTcpUTDeinit
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
Definition: stream-tcp-util.c:51
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
TcpStream_::isn
uint32_t isn
Definition: stream-tcp-private.h:113
TCPVars_::ts_set
bool ts_set
Definition: decode-tcp.h:159
SCReturnCharPtr
#define SCReturnCharPtr(x)
Definition: util-debug.h:283
TCP_SEG_LEN
#define TCP_SEG_LEN(seg)
Definition: stream-tcp-private.h:94
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
TcpStream_::seg_tree
struct TCPSEG seg_tree
Definition: stream-tcp-private.h:136
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
StreamTcpThread_
Definition: stream-tcp.h:80
StreamTcpSetSessionNoReassemblyFlag
void StreamTcpSetSessionNoReassemblyFlag(TcpSession *ssn, char direction)
disable reassembly
Definition: stream-tcp.c:6625
Packet_::payload
uint8_t * payload
Definition: decode.h:586
TcpStreamCnf_::async_oneside
bool async_oneside
Definition: stream-tcp.h:61
StreamTcpSetOSPolicy
void StreamTcpSetOSPolicy(TcpStream *, Packet *)
Function to set the OS policy for the given stream based on the destination of the received packet.
Definition: stream-tcp.c:941
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
TcpStream_::os_policy
uint8_t os_policy
Definition: stream-tcp-private.h:110
Flow_
Flow data structure.
Definition: flow.h:351
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
TCPHdr_::th_win
uint16_t th_win
Definition: decode-tcp.h:149
StreamTcpSackRegisterTests
void StreamTcpSackRegisterTests(void)
Definition: stream-tcp-sack.c:908
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:223
RB_MIN
#define RB_MIN(name, x)
Definition: tree.h:778
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:155
Address_::address_un_data32
uint32_t address_un_data32[4]
Definition: decode.h:119
Packet_::tcpvars
TCPVars tcpvars
Definition: decode.h:559
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:468
Flow_::protoctx
void * protoctx
Definition: flow.h:441
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:587
PacketQueueNoLock_
simple fifo queue for packets
Definition: packet-queue.h:34
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TCPHdr_::th_ack
uint32_t th_ack
Definition: decode-tcp.h:146
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:292
TcpStream_::last_ack
uint32_t last_ack
Definition: stream-tcp-private.h:115
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:475
StreamTcpUTInit
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
Definition: stream-tcp-util.c:44
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
TCP_CLOSE_WAIT
@ TCP_CLOSE_WAIT
Definition: stream-tcp-private.h:160
TCPHdr_::th_flags
uint8_t th_flags
Definition: decode-tcp.h:148
TCPVars_::ts_ecr
uint32_t ts_ecr
Definition: decode-tcp.h:161
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
StreamTcpCheckMemcap
int StreamTcpCheckMemcap(uint64_t size)
Check if alloc'ing "size" would mean we're over memcap.
Definition: stream-tcp.c:268
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
STREAMTCP_FLAG_ASYNC
#define STREAMTCP_FLAG_ASYNC
Definition: stream-tcp-private.h:182
TCPHdr_::th_seq
uint32_t th_seq
Definition: decode-tcp.h:145
RB_MAX
#define RB_MAX(name, x)
Definition: tree.h:779
OS_POLICY_BSD
@ OS_POLICY_BSD
Definition: stream-tcp-reassemble.h:37
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5469
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:522
StreamTcpCreateTestPacket
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t)
The Function to create the packet with given payload, which is used to test the reassembly of the eng...
Definition: stream-tcp-reassemble.c:2159
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
Address_::address
union Address_::@30 address
StreamTcpSessionClear
void StreamTcpSessionClear(void *ssnptr)
Function to return the stream back to the pool. It returns the segments in the stream to the segment ...
Definition: stream-tcp.c:353
TcpStreamCnf_::max_synack_queued
uint8_t max_synack_queued
Definition: stream-tcp.h:56
TcpSegment
Definition: stream-tcp-private.h:72
Packet_
Definition: decode.h:437
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:545
TH_ECN
#define TH_ECN
Definition: decode-tcp.h:41
ConfCreateContextBackup
void ConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:670
SCHInfoAddHostOSInfo
int SCHInfoAddHostOSInfo(const char *host_os, const char *host_os_ip_range, int is_ipv4)
Used to add the host-os-info data obtained from the conf.
Definition: util-host-os-info.c:122
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:224
SCHInfoCleanResources
void SCHInfoCleanResources(void)
Definition: util-host-os-info.c:320
IPV4Hdr_
Definition: decode-ipv4.h:72
StreamTcpUTClearSession
void StreamTcpUTClearSession(TcpSession *ssn)
Definition: stream-tcp-util.c:71
TCPVars_::ts_val
uint32_t ts_val
Definition: decode-tcp.h:160
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
Packet_::flow
struct Flow_ * flow
Definition: decode.h:476
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:567
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:682
StreamTcpRegisterTests
void StreamTcpRegisterTests(void)
Definition: stream-tcp.c:3401
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:295
StreamTcpReassembleHandleSegment
int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
Definition: stream-tcp-reassemble.c:1956
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
OS_POLICY_WINDOWS
@ OS_POLICY_WINDOWS
Definition: stream-tcp-reassemble.h:47
TcpStreamCnf_::midstream
bool midstream
Definition: stream-tcp.h:60
TcpStream_::next_seq
uint32_t next_seq
Definition: stream-tcp-private.h:114
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:229
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
ConfInit
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:120
StreamTcpUTSetupSession
void StreamTcpUTSetupSession(TcpSession *ssn)
Definition: stream-tcp-util.c:62
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:294
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
OS_POLICY_LINUX
@ OS_POLICY_LINUX
Definition: stream-tcp-reassemble.h:40
TH_CWR
#define TH_CWR
Definition: decode-tcp.h:43
StreamTcpThread_::ra_ctx
TcpReassemblyThreadCtx * ra_ctx
Definition: stream-tcp.h:107
SET_ISN
#define SET_ISN(stream, setseq)
Definition: stream-tcp.c:29
Address_::family
char family
Definition: decode.h:117
Packet_::dst
Address dst
Definition: decode.h:442
ConfDeInit
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:693
StreamTcpReassembleRegisterTests
void StreamTcpReassembleRegisterTests(void)
The Function Register the Unit tests to test the reassembly engine for various OS policies.
Definition: stream-tcp-reassemble.c:3855
OS_POLICY_DEFAULT
#define OS_POLICY_DEFAULT
Definition: stream-tcp-reassemble.h:88
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
STREAMTCP_FLAG_4WHS
#define STREAMTCP_FLAG_4WHS
Definition: stream-tcp-private.h:185
TcpSession_
Definition: stream-tcp-private.h:283
StreamTcpDecrMemuse
void StreamTcpDecrMemuse(uint64_t size)
Definition: stream-tcp.c:235
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
TCPHdr_
Definition: decode-tcp.h:142
Packet_::src
Address src
Definition: decode.h:441
STREAM_RAW_PROGRESS
#define STREAM_RAW_PROGRESS(stream)
Definition: stream-tcp-private.h:146