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  int ret = 0;
50 
51  StreamTcpUTInit(&stt.ra_ctx);
52 
53  TcpSession *ssn = StreamTcpNewSession(p, 0);
54  if (ssn == NULL) {
55  printf("Session can not be allocated: ");
56  goto end;
57  }
58  f.protoctx = ssn;
59 
60  if (f.alparser != NULL) {
61  printf("AppLayer field not set to NULL: ");
62  goto end;
63  }
64  if (ssn->state != 0) {
65  printf("TCP state field not set to 0: ");
66  goto end;
67  }
68 
70 
71  ret = 1;
72 end:
73  SCFree(p);
74  FLOW_DESTROY(&f);
76  return ret;
77 }
78 
79 /**
80  * \test Test the deallocation of TCP session for a given packet and return
81  * the memory back to ssn_pool and corresponding segments to segment
82  * pool.
83  *
84  * \retval On success it returns 1 and on failure 0.
85  */
86 
87 static int StreamTcpTest02(void)
88 {
90  FAIL_IF(unlikely(p == NULL));
91  Flow f;
92  ThreadVars tv;
93  StreamTcpThread stt;
94  uint8_t payload[4];
95  TCPHdr tcph;
97  memset(&pq, 0, sizeof(pq));
98  memset(&f, 0, sizeof(Flow));
99  memset(&tv, 0, sizeof(ThreadVars));
100  memset(&stt, 0, sizeof(StreamTcpThread));
101  memset(&tcph, 0, sizeof(TCPHdr));
102 
103  FLOW_INITIALIZE(&f);
104  p->flow = &f;
105  tcph.th_win = htons(5480);
106  tcph.th_flags = TH_SYN;
107  p->tcph = &tcph;
109 
110  StreamTcpUTInit(&stt.ra_ctx);
111 
112  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
113 
114  p->tcph->th_ack = htonl(1);
115  p->tcph->th_flags = TH_SYN | TH_ACK;
117 
118  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
119 
120  p->tcph->th_ack = htonl(1);
121  p->tcph->th_seq = htonl(1);
122  p->tcph->th_flags = TH_ACK;
124 
125  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
126 
127  p->tcph->th_ack = htonl(1);
128  p->tcph->th_seq = htonl(2);
129  p->tcph->th_flags = TH_PUSH | TH_ACK;
131 
132  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
133  p->payload = payload;
134  p->payload_len = 3;
135 
136  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
137 
139  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
140 
141  p->tcph->th_ack = htonl(1);
142  p->tcph->th_seq = htonl(6);
143  p->tcph->th_flags = TH_PUSH | TH_ACK;
145 
146  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
147  p->payload = payload;
148  p->payload_len = 3;
149 
150  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
151 
153  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
154 
156  // StreamTcpUTClearSession(p->flow->protoctx);
157 
158  SCFree(p);
159  FLOW_DESTROY(&f);
161  PASS;
162 }
163 
164 /**
165  * \test Test the setting up a TCP session when we missed the intial
166  * SYN packet of the session. The session is setup only if midstream
167  * sessions are allowed to setup.
168  *
169  * \retval On success it returns 1 and on failure 0.
170  */
171 
172 static int StreamTcpTest03(void)
173 {
174  Packet *p = PacketGetFromAlloc();
175  FAIL_IF_NULL(p);
176  Flow f;
177  ThreadVars tv;
178  StreamTcpThread stt;
179  TCPHdr tcph;
181  memset(&pq, 0, sizeof(pq));
182  memset(&f, 0, sizeof(Flow));
183  memset(&tv, 0, sizeof(ThreadVars));
184  memset(&stt, 0, sizeof(StreamTcpThread));
185  memset(&tcph, 0, sizeof(TCPHdr));
186  FLOW_INITIALIZE(&f);
187  p->flow = &f;
188 
189  StreamTcpUTInit(&stt.ra_ctx);
190 
191  tcph.th_win = htons(5480);
192  tcph.th_seq = htonl(10);
193  tcph.th_ack = htonl(20);
194  tcph.th_flags = TH_SYN | TH_ACK;
195  p->tcph = &tcph;
196  int ret = 0;
197 
198  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
199  goto end;
200 
201  p->tcph->th_seq = htonl(20);
202  p->tcph->th_ack = htonl(11);
203  p->tcph->th_flags = TH_ACK;
205 
206  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
207  goto end;
208 
209  p->tcph->th_seq = htonl(19);
210  p->tcph->th_ack = htonl(11);
211  p->tcph->th_flags = TH_ACK | TH_PUSH;
213 
214  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
215  goto end;
216 
217  if (!stream_config.midstream) {
218  ret = 1;
219  goto end;
220  }
221  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
222  goto end;
223 
224  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 20 &&
225  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11)
226  goto end;
227 
229 
230  ret = 1;
231 end:
232  SCFree(p);
233  FLOW_DESTROY(&f);
235  return ret;
236 }
237 
238 /**
239  * \test Test the setting up a TCP session when we missed the intial
240  * SYN/ACK packet of the session. The session is setup only if
241  * midstream sessions are allowed to setup.
242  *
243  * \retval On success it returns 1 and on failure 0.
244  */
245 
246 static int StreamTcpTest04(void)
247 {
248  Packet *p = PacketGetFromAlloc();
249  FAIL_IF_NULL(p);
250  Flow f;
251  ThreadVars tv;
252  StreamTcpThread stt;
253  TCPHdr tcph;
255  memset(&pq, 0, sizeof(pq));
256  memset(&f, 0, sizeof(Flow));
257  memset(&tv, 0, sizeof(ThreadVars));
258  memset(&stt, 0, sizeof(StreamTcpThread));
259  memset(&tcph, 0, sizeof(TCPHdr));
260  FLOW_INITIALIZE(&f);
261  p->flow = &f;
262 
263  StreamTcpUTInit(&stt.ra_ctx);
264 
265  tcph.th_win = htons(5480);
266  tcph.th_seq = htonl(10);
267  tcph.th_ack = htonl(20);
268  tcph.th_flags = TH_ACK;
269  p->tcph = &tcph;
270 
271  int ret = 0;
272 
273  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
274  goto end;
275 
276  p->tcph->th_seq = htonl(9);
277  p->tcph->th_ack = htonl(19);
278  p->tcph->th_flags = TH_ACK | TH_PUSH;
280 
281  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
282  goto end;
283 
284  if (!stream_config.midstream) {
285  ret = 1;
286  goto end;
287  }
288  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
289  goto end;
290 
291  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 10 &&
292  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 20)
293  goto end;
294 
296 
297  ret = 1;
298 end:
299  SCFree(p);
300  FLOW_DESTROY(&f);
302  return ret;
303 }
304 
305 /**
306  * \test Test the setting up a TCP session when we missed the intial
307  * 3WHS packet of the session. The session is setup only if
308  * midstream sessions are allowed to setup.
309  *
310  * \retval On success it returns 1 and on failure 0.
311  */
312 
313 static int StreamTcpTest05(void)
314 {
315  Packet *p = PacketGetFromAlloc();
316  FAIL_IF_NULL(p);
317  Flow f;
318  ThreadVars tv;
319  StreamTcpThread stt;
320  TCPHdr tcph;
321  uint8_t payload[4];
323  memset(&pq, 0, sizeof(PacketQueueNoLock));
324  memset(&f, 0, sizeof(Flow));
325  memset(&tv, 0, sizeof(ThreadVars));
326  memset(&stt, 0, sizeof(StreamTcpThread));
327  memset(&tcph, 0, sizeof(TCPHdr));
328  FLOW_INITIALIZE(&f);
329  p->flow = &f;
330  int ret = 0;
331 
332  StreamTcpUTInit(&stt.ra_ctx);
333  tcph.th_win = htons(5480);
334  tcph.th_seq = htonl(10);
335  tcph.th_ack = htonl(20);
336  tcph.th_flags = TH_ACK | TH_PUSH;
337  p->tcph = &tcph;
338 
339  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
340  p->payload = payload;
341  p->payload_len = 3;
342 
343  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
344  goto end;
345 
346  p->tcph->th_seq = htonl(20);
347  p->tcph->th_ack = htonl(13);
348  p->tcph->th_flags = TH_ACK | TH_PUSH;
350 
351  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
352  p->payload = payload;
353  p->payload_len = 3;
354 
355  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
356  goto end;
357 
358  p->tcph->th_seq = htonl(13);
359  p->tcph->th_ack = htonl(23);
360  p->tcph->th_flags = TH_ACK | TH_PUSH;
362 
363  StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/
364  p->payload = payload;
365  p->payload_len = 3;
366 
367  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
368  goto end;
369 
370  p->tcph->th_seq = htonl(19);
371  p->tcph->th_ack = htonl(16);
372  p->tcph->th_flags = TH_ACK | TH_PUSH;
374 
375  StreamTcpCreateTestPacket(payload, 0x44, 3, 4); /*DDD*/
376  p->payload = payload;
377  p->payload_len = 3;
378 
379  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
380  goto end;
381 
382  if (!stream_config.midstream) {
383  ret = 1;
384  goto end;
385  }
386  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
387  goto end;
388 
389  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 16 &&
390  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23)
391  goto end;
392 
394 
395  ret = 1;
396 end:
397  SCFree(p);
398  FLOW_DESTROY(&f);
400  return ret;
401 }
402 
403 /**
404  * \test Test the setting up a TCP session when we have seen only the
405  * FIN, RST packets packet of the session. The session is setup only if
406  * midstream sessions are allowed to setup.
407  *
408  * \retval On success it returns 1 and on failure 0.
409  */
410 
411 static int StreamTcpTest06(void)
412 {
413  Packet *p = PacketGetFromAlloc();
414  FAIL_IF_NULL(p);
415  Flow f;
416  TcpSession ssn;
417  ThreadVars tv;
418  StreamTcpThread stt;
419  TCPHdr tcph;
421  memset(&pq, 0, sizeof(PacketQueueNoLock));
422  memset(&f, 0, sizeof(Flow));
423  memset(&ssn, 0, sizeof(TcpSession));
424  memset(&tv, 0, sizeof(ThreadVars));
425  memset(&stt, 0, sizeof(StreamTcpThread));
426  memset(&tcph, 0, sizeof(TCPHdr));
427  FLOW_INITIALIZE(&f);
428  p->flow = &f;
429  int ret = 0;
430 
431  StreamTcpUTInit(&stt.ra_ctx);
432 
433  tcph.th_flags = TH_FIN;
434  p->tcph = &tcph;
435 
436  /* StreamTcpPacket returns -1 on unsolicited FIN */
437  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
438  printf("StreamTcpPacket failed: ");
439  goto end;
440  }
441 
442  if (((TcpSession *)(p->flow->protoctx)) != NULL) {
443  printf("we have a ssn while we shouldn't: ");
444  goto end;
445  }
446 
447  p->tcph->th_flags = TH_RST;
448  /* StreamTcpPacket returns -1 on unsolicited RST */
449  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
450  printf("StreamTcpPacket failed (2): ");
451  goto end;
452  }
453 
454  if (((TcpSession *)(p->flow->protoctx)) != NULL) {
455  printf("we have a ssn while we shouldn't (2): ");
456  goto end;
457  }
458 
459  ret = 1;
460 end:
461  SCFree(p);
462  FLOW_DESTROY(&f);
464  return ret;
465 }
466 
467 /**
468  * \test Test the working on PAWS. The packet will be dropped by stream, as
469  * its timestamp is old, although the segment is in the window.
470  */
471 
472 static int StreamTcpTest07(void)
473 {
474  Packet *p = PacketGetFromAlloc();
475  FAIL_IF(unlikely(p == NULL));
476  Flow f;
477  ThreadVars tv;
478  StreamTcpThread stt;
479  TCPHdr tcph;
480  uint8_t payload[1] = { 0x42 };
482 
483  memset(&pq, 0, sizeof(PacketQueueNoLock));
484  memset(&f, 0, sizeof(Flow));
485  memset(&tv, 0, sizeof(ThreadVars));
486  memset(&stt, 0, sizeof(StreamTcpThread));
487  memset(&tcph, 0, sizeof(TCPHdr));
488 
489  FLOW_INITIALIZE(&f);
490  p->flow = &f;
491 
492  StreamTcpUTInit(&stt.ra_ctx);
493  stream_config.midstream = true;
494 
495  tcph.th_win = htons(5480);
496  tcph.th_seq = htonl(10);
497  tcph.th_ack = htonl(20);
498  tcph.th_flags = TH_ACK | TH_PUSH;
499  p->tcph = &tcph;
500 
501  p->tcpvars.ts_set = true;
502  p->tcpvars.ts_val = 10;
503  p->tcpvars.ts_ecr = 11;
504 
505  p->payload = payload;
506  p->payload_len = 1;
507 
508  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
509 
510  p->tcph->th_seq = htonl(11);
511  p->tcph->th_ack = htonl(23);
512  p->tcph->th_flags = TH_ACK | TH_PUSH;
514 
515  p->tcpvars.ts_val = 2;
516 
517  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) != -1);
518 
519  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 11);
520 
522  SCFree(p);
523  FLOW_DESTROY(&f);
525  PASS;
526 }
527 
528 /**
529  * \test Test the working on PAWS. The packet will be accpeted by engine as
530  * the timestamp is valid and it is in window.
531  */
532 
533 static int StreamTcpTest08(void)
534 {
535  Packet *p = PacketGetFromAlloc();
536  FAIL_IF(unlikely(p == NULL));
537  Flow f;
538  ThreadVars tv;
539  StreamTcpThread stt;
540  TCPHdr tcph;
541  uint8_t payload[1] = { 0x42 };
542 
544  memset(&pq, 0, sizeof(PacketQueueNoLock));
545  memset(&f, 0, sizeof(Flow));
546  memset(&tv, 0, sizeof(ThreadVars));
547  memset(&stt, 0, sizeof(StreamTcpThread));
548  memset(&tcph, 0, sizeof(TCPHdr));
549 
550  FLOW_INITIALIZE(&f);
551  p->flow = &f;
552 
553  StreamTcpUTInit(&stt.ra_ctx);
554  stream_config.midstream = true;
555 
556  tcph.th_win = htons(5480);
557  tcph.th_seq = htonl(10);
558  tcph.th_ack = htonl(20);
559  tcph.th_flags = TH_ACK | TH_PUSH;
560  p->tcph = &tcph;
561 
562  p->tcpvars.ts_set = true;
563  p->tcpvars.ts_val = 10;
564  p->tcpvars.ts_ecr = 11;
565 
566  p->payload = payload;
567  p->payload_len = 1;
568 
569  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
570 
571  p->tcph->th_seq = htonl(11);
572  p->tcph->th_ack = htonl(20);
573  p->tcph->th_flags = TH_ACK | TH_PUSH;
575 
576  p->tcpvars.ts_val = 12;
577 
578  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
579 
580  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.next_seq != 12);
581 
583 
584  SCFree(p);
585  FLOW_DESTROY(&f);
587  PASS;
588 }
589 
590 /**
591  * \test Test the working of No stream reassembly flag. The stream will not
592  * reassemble the segment if the flag is set.
593  */
594 
595 static int StreamTcpTest09(void)
596 {
597  Packet *p = PacketGetFromAlloc();
598  FAIL_IF(unlikely(p == NULL));
599  Flow f;
600  ThreadVars tv;
601  StreamTcpThread stt;
602  TCPHdr tcph;
603  uint8_t payload[1] = { 0x42 };
604 
606  memset(&pq, 0, sizeof(PacketQueueNoLock));
607  memset(&f, 0, sizeof(Flow));
608  memset(&tv, 0, sizeof(ThreadVars));
609  memset(&stt, 0, sizeof(StreamTcpThread));
610  memset(&tcph, 0, sizeof(TCPHdr));
611 
612  FLOW_INITIALIZE(&f);
613  p->flow = &f;
614 
615  StreamTcpUTInit(&stt.ra_ctx);
616  stream_config.midstream = true;
617 
618  tcph.th_win = htons(5480);
619  tcph.th_seq = htonl(10);
620  tcph.th_ack = htonl(20);
621  tcph.th_flags = TH_ACK | TH_PUSH;
622  p->tcph = &tcph;
623 
624  p->payload = payload;
625  p->payload_len = 1;
626 
627  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
628 
629  p->tcph->th_seq = htonl(12);
630  p->tcph->th_ack = htonl(23);
631  p->tcph->th_flags = TH_ACK | TH_PUSH;
633 
634  FAIL_IF(p->flow->protoctx == NULL);
635 
637 
638  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
639 
640  p->tcph->th_seq = htonl(11);
641  p->tcph->th_ack = htonl(23);
642  p->tcph->th_flags = TH_ACK | TH_PUSH;
644 
645  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
646 
647  TcpSession *ssn = p->flow->protoctx;
648  FAIL_IF_NULL(ssn);
649  TcpSegment *seg = RB_MIN(TCPSEG, &ssn->client.seg_tree);
650  FAIL_IF_NULL(seg);
651  FAIL_IF(TCPSEG_RB_NEXT(seg) != NULL);
652 
654  SCFree(p);
655  FLOW_DESTROY(&f);
657  PASS;
658 }
659 
660 /**
661  * \test Test the setting up a TCP session when we are seeing asynchronous
662  * stream, while we see all the packets in that stream from start.
663  */
664 
665 static int StreamTcpTest10(void)
666 {
667  Packet *p = PacketGetFromAlloc();
668  FAIL_IF(unlikely(p == NULL));
669  Flow f;
670  ThreadVars tv;
671  StreamTcpThread stt;
672  TCPHdr tcph;
673  uint8_t payload[4];
675  memset(&pq, 0, sizeof(PacketQueueNoLock));
676  memset(&f, 0, sizeof(Flow));
677  memset(&tv, 0, sizeof(ThreadVars));
678  memset(&stt, 0, sizeof(StreamTcpThread));
679  memset(&tcph, 0, sizeof(TCPHdr));
680  FLOW_INITIALIZE(&f);
681  p->flow = &f;
682 
683  StreamTcpUTInit(&stt.ra_ctx);
685 
686  tcph.th_win = htons(5480);
687  tcph.th_seq = htonl(10);
688  tcph.th_ack = 0;
689  tcph.th_flags = TH_SYN;
690  p->tcph = &tcph;
691 
692  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
693 
694  p->tcph->th_seq = htonl(11);
695  p->tcph->th_ack = htonl(11);
696  p->tcph->th_flags = TH_ACK;
698 
699  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
700 
701  p->tcph->th_seq = htonl(11);
702  p->tcph->th_ack = htonl(11);
703  p->tcph->th_flags = TH_ACK | TH_PUSH;
705 
706  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
707  p->payload = payload;
708  p->payload_len = 3;
709 
710  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
711 
712  p->tcph->th_seq = htonl(6);
713  p->tcph->th_ack = htonl(11);
714  p->tcph->th_flags = TH_ACK | TH_PUSH;
716 
717  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
718  p->payload = payload;
719  p->payload_len = 3;
720 
721  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
722 
723  FAIL_IF(((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED);
724 
725  FAIL_IF(!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC));
726 
727  FAIL_IF(((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
728  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11);
729 
731 
732  SCFree(p);
733  FLOW_DESTROY(&f);
735  PASS;
736 }
737 
738 /**
739  * \test Test the setting up a TCP session when we are seeing asynchronous
740  * stream, while we missed the SYN packet of that stream.
741  */
742 
743 static int StreamTcpTest11(void)
744 {
745  Packet *p = PacketGetFromAlloc();
746  FAIL_IF(unlikely(p == NULL));
747  Flow f;
748  ThreadVars tv;
749  StreamTcpThread stt;
750  TCPHdr tcph;
751  uint8_t payload[4];
753  memset(&pq, 0, sizeof(PacketQueueNoLock));
754  memset(&f, 0, sizeof(Flow));
755  memset(&tv, 0, sizeof(ThreadVars));
756  memset(&stt, 0, sizeof(StreamTcpThread));
757  memset(&tcph, 0, sizeof(TCPHdr));
758  FLOW_INITIALIZE(&f);
759  p->flow = &f;
760 
761  StreamTcpUTInit(&stt.ra_ctx);
763 
764  tcph.th_win = htons(5480);
765  tcph.th_seq = htonl(10);
766  tcph.th_ack = htonl(1);
767  tcph.th_flags = TH_SYN | TH_ACK;
768  p->tcph = &tcph;
769 
770  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
771 
772  p->tcph->th_seq = htonl(11);
773  p->tcph->th_ack = htonl(1);
774  p->tcph->th_flags = TH_ACK;
776 
777  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
778 
779  p->tcph->th_seq = htonl(11);
780  p->tcph->th_ack = htonl(1);
781  p->tcph->th_flags = TH_ACK | TH_PUSH;
783 
784  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
785  p->payload = payload;
786  p->payload_len = 3;
787 
788  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
789 
790  p->tcph->th_seq = htonl(2);
791  p->tcph->th_ack = htonl(1);
792  p->tcph->th_flags = TH_ACK | TH_PUSH;
794 
795  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
796  p->payload = payload;
797  p->payload_len = 3;
798 
799  FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
800 
801  FAIL_IF(!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC));
802 
803  FAIL_IF(((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED);
804 
805  FAIL_IF(((TcpSession *)(p->flow->protoctx))->server.last_ack != 2 &&
806  ((TcpSession *)(p->flow->protoctx))->client.next_seq != 1);
807 
809  SCFree(p);
810  FLOW_DESTROY(&f);
812  PASS;
813 }
814 
815 /**
816  * \test Test the setting up a TCP session when we are seeing asynchronous
817  * stream, while we missed the SYN and SYN/ACK packets in that stream.
818  *
819  * \retval On success it returns 1 and on failure 0.
820  */
821 
822 static int StreamTcpTest12(void)
823 {
824  Packet *p = PacketGetFromAlloc();
825  FAIL_IF_NULL(p);
826  Flow f;
827  ThreadVars tv;
828  StreamTcpThread stt;
829  TCPHdr tcph;
830  uint8_t payload[4];
832  memset(&pq, 0, sizeof(PacketQueueNoLock));
833  memset(&f, 0, sizeof(Flow));
834  memset(&tv, 0, sizeof(ThreadVars));
835  memset(&stt, 0, sizeof(StreamTcpThread));
836  memset(&tcph, 0, sizeof(TCPHdr));
837  FLOW_INITIALIZE(&f);
838  p->flow = &f;
839 
840  StreamTcpUTInit(&stt.ra_ctx);
841 
842  tcph.th_win = htons(5480);
843  tcph.th_seq = htonl(10);
844  tcph.th_ack = htonl(11);
845  tcph.th_flags = TH_ACK;
846  p->tcph = &tcph;
847  int ret = 0;
848 
849  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
850  goto end;
851 
852  p->tcph->th_seq = htonl(10);
853  p->tcph->th_ack = htonl(11);
854  p->tcph->th_flags = TH_ACK | TH_PUSH;
856 
857  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
858  p->payload = payload;
859  p->payload_len = 3;
860 
861  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
862  goto end;
863 
864  p->tcph->th_seq = htonl(6);
865  p->tcph->th_ack = htonl(11);
866  p->tcph->th_flags = TH_ACK | TH_PUSH;
868 
869  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
870  p->payload = payload;
871  p->payload_len = 3;
872 
873  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
874  goto end;
875 
877  ret = 1;
878  goto end;
879  }
880 
881  if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
882  printf("failed in setting asynchronous session\n");
883  goto end;
884  }
885 
886  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
887  printf("failed in setting state\n");
888  goto end;
889  }
890 
891  if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 &&
892  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) {
893  printf("failed in seq %" PRIu32 " match\n",
894  ((TcpSession *)(p->flow->protoctx))->client.last_ack);
895  goto end;
896  }
897 
899 
900  ret = 1;
901 end:
902  SCFree(p);
903  FLOW_DESTROY(&f);
905  return ret;
906 }
907 
908 /**
909  * \test Test the setting up a TCP session when we are seeing asynchronous
910  * stream, while we missed the SYN and SYN/ACK packets in that stream.
911  * Later, we start to receive the packet from other end stream too.
912  *
913  * \retval On success it returns 1 and on failure 0.
914  */
915 
916 static int StreamTcpTest13(void)
917 {
918  Packet *p = PacketGetFromAlloc();
919  FAIL_IF_NULL(p);
920  Flow f;
921  ThreadVars tv;
922  StreamTcpThread stt;
923  TCPHdr tcph;
924  uint8_t payload[4];
926  memset(&pq, 0, sizeof(PacketQueueNoLock));
927  memset(&f, 0, sizeof(Flow));
928  memset(&tv, 0, sizeof(ThreadVars));
929  memset(&stt, 0, sizeof(StreamTcpThread));
930  memset(&tcph, 0, sizeof(TCPHdr));
931  FLOW_INITIALIZE(&f);
932  p->flow = &f;
933 
934  StreamTcpUTInit(&stt.ra_ctx);
935 
936  tcph.th_win = htons(5480);
937  tcph.th_seq = htonl(10);
938  tcph.th_ack = htonl(11);
939  tcph.th_flags = TH_ACK;
940  p->tcph = &tcph;
941  int ret = 0;
942 
943  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
944  goto end;
945 
946  p->tcph->th_seq = htonl(10);
947  p->tcph->th_ack = htonl(11);
948  p->tcph->th_flags = TH_ACK | TH_PUSH;
950 
951  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
952  p->payload = payload;
953  p->payload_len = 3;
954 
955  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
956  goto end;
957 
958  p->tcph->th_seq = htonl(6);
959  p->tcph->th_ack = htonl(11);
960  p->tcph->th_flags = TH_ACK | TH_PUSH;
962 
963  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
964  p->payload = payload;
965  p->payload_len = 3;
966 
967  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
968  goto end;
969 
971  ret = 1;
972  goto end;
973  }
974 
975  if (!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) {
976  printf("failed in setting asynchronous session\n");
977  goto end;
978  }
979 
980  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
981  printf("failed in setting state\n");
982  goto end;
983  }
984 
985  p->tcph->th_seq = htonl(11);
986  p->tcph->th_ack = htonl(9);
987  p->tcph->th_flags = TH_ACK | TH_PUSH;
989 
990  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
991  p->payload = payload;
992  p->payload_len = 3;
993 
994  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
995  goto end;
996 
997  if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 9 &&
998  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 14) {
999  printf("failed in seq %" PRIu32 " match\n",
1000  ((TcpSession *)(p->flow->protoctx))->client.last_ack);
1001  goto end;
1002  }
1003 
1005 
1006  ret = 1;
1007 end:
1008  SCFree(p);
1009  FLOW_DESTROY(&f);
1011  return ret;
1012 }
1013 
1014 /* Dummy conf string to setup the OS policy for unit testing */
1015 static const char *dummy_conf_string = "%YAML 1.1\n"
1016  "---\n"
1017  "\n"
1018  "default-log-dir: /var/log/eidps\n"
1019  "\n"
1020  "logging:\n"
1021  "\n"
1022  " default-log-level: debug\n"
1023  "\n"
1024  " default-format: \"<%t> - <%l>\"\n"
1025  "\n"
1026  " default-startup-message: Your IDS has started.\n"
1027  "\n"
1028  " default-output-filter:\n"
1029  "\n"
1030  "host-os-policy:\n"
1031  "\n"
1032  " windows: 192.168.0.1\n"
1033  "\n"
1034  " linux: 192.168.0.2\n"
1035  "\n";
1036 /* Dummy conf string to setup the OS policy for unit testing */
1037 static const char *dummy_conf_string1 = "%YAML 1.1\n"
1038  "---\n"
1039  "\n"
1040  "default-log-dir: /var/log/eidps\n"
1041  "\n"
1042  "logging:\n"
1043  "\n"
1044  " default-log-level: debug\n"
1045  "\n"
1046  " default-format: \"<%t> - <%l>\"\n"
1047  "\n"
1048  " default-startup-message: Your IDS has started.\n"
1049  "\n"
1050  " default-output-filter:\n"
1051  "\n"
1052  "host-os-policy:\n"
1053  "\n"
1054  " windows: 192.168.0.0/24,"
1055  "192.168.1.1\n"
1056  "\n"
1057  " linux: 192.168.1.0/24,"
1058  "192.168.0.1\n"
1059  "\n";
1060 
1061 /**
1062  * \brief Function to parse the dummy conf string and get the value of IP
1063  * address for the corresponding OS policy type.
1064  *
1065  * \param conf_val_name Name of the OS policy type
1066  * \retval returns IP address as string on success and NULL on failure
1067  */
1068 static const char *StreamTcpParseOSPolicy(char *conf_var_name)
1069 {
1070  SCEnter();
1071  char conf_var_type_name[15] = "host-os-policy";
1072  char *conf_var_full_name = NULL;
1073  const char *conf_var_value = NULL;
1074 
1075  if (conf_var_name == NULL)
1076  goto end;
1077 
1078  /* the + 2 is for the '.' and the string termination character '\0' */
1079  conf_var_full_name = (char *)SCMalloc(strlen(conf_var_type_name) + strlen(conf_var_name) + 2);
1080  if (conf_var_full_name == NULL)
1081  goto end;
1082 
1083  if (snprintf(conf_var_full_name, strlen(conf_var_type_name) + strlen(conf_var_name) + 2,
1084  "%s.%s", conf_var_type_name, conf_var_name) < 0) {
1085  SCLogError(SC_ERR_INVALID_VALUE, "Error in making the conf full name");
1086  goto end;
1087  }
1088 
1089  if (ConfGet(conf_var_full_name, &conf_var_value) != 1) {
1090  SCLogError(SC_ERR_UNKNOWN_VALUE, "Error in getting conf value for conf name %s",
1091  conf_var_full_name);
1092  goto end;
1093  }
1094 
1095  SCLogDebug("Value obtained from the yaml conf file, for the var "
1096  "\"%s\" is \"%s\"",
1097  conf_var_name, conf_var_value);
1098 
1099 end:
1100  if (conf_var_full_name != NULL)
1101  SCFree(conf_var_full_name);
1102  SCReturnCharPtr(conf_var_value);
1103 }
1104 /**
1105  * \test Test the setting up a OS policy. Te OS policy values are defined in
1106  * the config string "dummy_conf_string"
1107  *
1108  * \retval On success it returns 1 and on failure 0
1109  */
1110 
1111 static int StreamTcpTest14(void)
1112 {
1113  Packet *p = PacketGetFromAlloc();
1114  FAIL_IF_NULL(p);
1115  Flow f;
1116  ThreadVars tv;
1117  StreamTcpThread stt;
1118  TCPHdr tcph;
1119  uint8_t payload[4];
1120  struct in_addr addr;
1121  IPV4Hdr ipv4h;
1122  char os_policy_name[10] = "windows";
1123  const char *ip_addr;
1124  PacketQueueNoLock pq;
1125  memset(&pq, 0, sizeof(PacketQueueNoLock));
1126 
1127  memset(&f, 0, sizeof(Flow));
1128  memset(&tv, 0, sizeof(ThreadVars));
1129  memset(&stt, 0, sizeof(StreamTcpThread));
1130  memset(&tcph, 0, sizeof(TCPHdr));
1131  memset(&addr, 0, sizeof(addr));
1132  memset(&ipv4h, 0, sizeof(ipv4h));
1133  FLOW_INITIALIZE(&f);
1134  p->flow = &f;
1135  int ret = 0;
1136 
1137  StreamTcpUTInit(&stt.ra_ctx);
1138 
1139  /* Load the config string in to parser */
1141  ConfInit();
1142  ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string));
1143 
1144  /* Get the IP address as string and add it to Host info tree for lookups */
1145  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1146  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1147  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1148  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1149  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1150  addr.s_addr = inet_addr("192.168.0.1");
1151  tcph.th_win = htons(5480);
1152  tcph.th_seq = htonl(10);
1153  tcph.th_ack = htonl(20);
1154  tcph.th_flags = TH_ACK | TH_PUSH;
1155  p->tcph = &tcph;
1156  p->dst.family = AF_INET;
1157  p->dst.address.address_un_data32[0] = addr.s_addr;
1158  p->ip4h = &ipv4h;
1159 
1160  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1161  p->payload = payload;
1162  p->payload_len = 3;
1163 
1164  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1165  goto end;
1166 
1167  p->tcph->th_seq = htonl(20);
1168  p->tcph->th_ack = htonl(13);
1169  p->tcph->th_flags = TH_ACK | TH_PUSH;
1171 
1172  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1173  p->payload = payload;
1174  p->payload_len = 3;
1175 
1176  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1177  goto end;
1178 
1179  p->tcph->th_seq = htonl(15);
1180  p->tcph->th_ack = htonl(23);
1181  p->tcph->th_flags = TH_ACK | TH_PUSH;
1183 
1184  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1185  p->payload = payload;
1186  p->payload_len = 3;
1187 
1188  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1189  goto end;
1190 
1191  p->tcph->th_seq = htonl(14);
1192  p->tcph->th_ack = htonl(23);
1193  p->tcph->th_flags = TH_ACK | TH_PUSH;
1195 
1196  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1197  p->payload = payload;
1198  p->payload_len = 3;
1199 
1200  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1201  goto end;
1202 
1203  addr.s_addr = inet_addr("192.168.0.2");
1204  p->tcph->th_seq = htonl(25);
1205  p->tcph->th_ack = htonl(13);
1206  p->tcph->th_flags = TH_ACK | TH_PUSH;
1208  p->dst.address.address_un_data32[0] = addr.s_addr;
1209 
1210  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1211  p->payload = payload;
1212  p->payload_len = 3;
1213 
1214  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1215  goto end;
1216 
1217  p->tcph->th_seq = htonl(24);
1218  p->tcph->th_ack = htonl(13);
1219  p->tcph->th_flags = TH_ACK | TH_PUSH;
1221 
1222  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1223  p->payload = payload;
1224  p->payload_len = 3;
1225 
1226  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1227  goto end;
1228 
1229  if (!stream_config.midstream) {
1230  ret = 1;
1231  goto end;
1232  }
1233  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1234  goto end;
1235 
1236  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1237  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1238  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1239  " server.next_seq %" PRIu32 "\n",
1240  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1241  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1242  goto end;
1243  }
1244 
1245  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1246  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1247  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1248  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1249  " should be %" PRIu8 "\n",
1250  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1251  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1252  goto end;
1253  }
1255 
1256  ret = 1;
1257 end:
1258  ConfDeInit();
1260  SCFree(p);
1261  FLOW_DESTROY(&f);
1263  return ret;
1264 }
1265 
1266 /**
1267  * \test Test the setting up a TCP session using the 4WHS:
1268  * SYN, SYN, SYN/ACK, ACK
1269  *
1270  * \retval On success it returns 1 and on failure 0.
1271  */
1272 
1273 static int StreamTcp4WHSTest01(void)
1274 {
1275  int ret = 0;
1276  Packet *p = PacketGetFromAlloc();
1277  FAIL_IF_NULL(p);
1278  Flow f;
1279  ThreadVars tv;
1280  StreamTcpThread stt;
1281  TCPHdr tcph;
1282  PacketQueueNoLock pq;
1283  memset(&pq, 0, sizeof(PacketQueueNoLock));
1284  memset(&f, 0, sizeof(Flow));
1285  memset(&tv, 0, sizeof(ThreadVars));
1286  memset(&stt, 0, sizeof(StreamTcpThread));
1287  memset(&tcph, 0, sizeof(TCPHdr));
1288  FLOW_INITIALIZE(&f);
1289  p->flow = &f;
1290 
1291  StreamTcpUTInit(&stt.ra_ctx);
1292 
1293  tcph.th_win = htons(5480);
1294  tcph.th_seq = htonl(10);
1295  tcph.th_ack = 0;
1296  tcph.th_flags = TH_SYN;
1297  p->tcph = &tcph;
1298 
1299  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1300  goto end;
1301 
1302  p->tcph->th_seq = htonl(20);
1303  p->tcph->th_ack = 0;
1304  p->tcph->th_flags = TH_SYN;
1306 
1307  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1308  goto end;
1309 
1310  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1311  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1312  goto end;
1313  }
1314 
1315  p->tcph->th_seq = htonl(10);
1316  p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1317  p->tcph->th_flags = TH_SYN | TH_ACK;
1319 
1320  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1321  goto end;
1322 
1323  p->tcph->th_seq = htonl(21);
1324  p->tcph->th_ack = htonl(10);
1325  p->tcph->th_flags = TH_ACK;
1327 
1328  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1329  goto end;
1330 
1331  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1332  printf("state is not ESTABLISHED: ");
1333  goto end;
1334  }
1335 
1336  ret = 1;
1337 end:
1339  SCFree(p);
1340  FLOW_DESTROY(&f);
1342  return ret;
1343 }
1344 
1345 /**
1346  * \test set up a TCP session using the 4WHS:
1347  * SYN, SYN, SYN/ACK, ACK, but the SYN/ACK does
1348  * not have the right SEQ
1349  *
1350  * \retval On success it returns 1 and on failure 0.
1351  */
1352 
1353 static int StreamTcp4WHSTest02(void)
1354 {
1355  int ret = 0;
1356  Packet *p = PacketGetFromAlloc();
1357  FAIL_IF_NULL(p);
1358  Flow f;
1359  ThreadVars tv;
1360  StreamTcpThread stt;
1361  TCPHdr tcph;
1362  PacketQueueNoLock pq;
1363  memset(&pq, 0, sizeof(PacketQueueNoLock));
1364  memset(&f, 0, sizeof(Flow));
1365  memset(&tv, 0, sizeof(ThreadVars));
1366  memset(&stt, 0, sizeof(StreamTcpThread));
1367  memset(&tcph, 0, sizeof(TCPHdr));
1368  FLOW_INITIALIZE(&f);
1369  p->flow = &f;
1370 
1371  StreamTcpUTInit(&stt.ra_ctx);
1372 
1373  tcph.th_win = htons(5480);
1374  tcph.th_seq = htonl(10);
1375  tcph.th_ack = 0;
1376  tcph.th_flags = TH_SYN;
1377  p->tcph = &tcph;
1378 
1379  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1380  goto end;
1381 
1382  p->tcph->th_seq = htonl(20);
1383  p->tcph->th_ack = 0;
1384  p->tcph->th_flags = TH_SYN;
1386 
1387  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1388  goto end;
1389 
1390  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1391  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1392  goto end;
1393  }
1394 
1395  p->tcph->th_seq = htonl(30);
1396  p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */
1397  p->tcph->th_flags = TH_SYN | TH_ACK;
1399 
1400  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) {
1401  printf("SYN/ACK pkt not rejected but it should have: ");
1402  goto end;
1403  }
1404 
1405  ret = 1;
1406 end:
1408  SCFree(p);
1409  FLOW_DESTROY(&f);
1411  return ret;
1412 }
1413 
1414 /**
1415  * \test set up a TCP session using the 4WHS:
1416  * SYN, SYN, SYN/ACK, ACK: however the SYN/ACK and ACK
1417  * are part of a normal 3WHS
1418  *
1419  * \retval On success it returns 1 and on failure 0.
1420  */
1421 
1422 static int StreamTcp4WHSTest03(void)
1423 {
1424  int ret = 0;
1425  Packet *p = PacketGetFromAlloc();
1426  FAIL_IF(unlikely(p == NULL));
1427  Flow f;
1428  ThreadVars tv;
1429  StreamTcpThread stt;
1430  TCPHdr tcph;
1431  PacketQueueNoLock pq;
1432  memset(&pq, 0, sizeof(PacketQueueNoLock));
1433  memset(&f, 0, sizeof(Flow));
1434  memset(&tv, 0, sizeof(ThreadVars));
1435  memset(&stt, 0, sizeof(StreamTcpThread));
1436  memset(&tcph, 0, sizeof(TCPHdr));
1437  FLOW_INITIALIZE(&f);
1438  p->flow = &f;
1439 
1440  StreamTcpUTInit(&stt.ra_ctx);
1441 
1442  tcph.th_win = htons(5480);
1443  tcph.th_seq = htonl(10);
1444  tcph.th_ack = 0;
1445  tcph.th_flags = TH_SYN;
1446  p->tcph = &tcph;
1447 
1448  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1449  goto end;
1450 
1451  p->tcph->th_seq = htonl(20);
1452  p->tcph->th_ack = 0;
1453  p->tcph->th_flags = TH_SYN;
1455 
1456  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1457  goto end;
1458 
1459  if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) {
1460  printf("STREAMTCP_FLAG_4WHS flag not set: ");
1461  goto end;
1462  }
1463 
1464  p->tcph->th_seq = htonl(30);
1465  p->tcph->th_ack = htonl(11);
1466  p->tcph->th_flags = TH_SYN | TH_ACK;
1468 
1469  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1470  goto end;
1471 
1472  p->tcph->th_seq = htonl(11);
1473  p->tcph->th_ack = htonl(31);
1474  p->tcph->th_flags = TH_ACK;
1476 
1477  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1478  goto end;
1479 
1480  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) {
1481  printf("state is not ESTABLISHED: ");
1482  goto end;
1483  }
1484 
1485  ret = 1;
1486 end:
1488  SCFree(p);
1489  FLOW_DESTROY(&f);
1491  return ret;
1492 }
1493 
1494 /**
1495  * \test Test the setting up a OS policy. Te OS policy values are defined in
1496  * the config string "dummy_conf_string1"
1497  *
1498  * \retval On success it returns 1 and on failure 0
1499  */
1500 
1501 static int StreamTcpTest15(void)
1502 {
1503  Packet *p = PacketGetFromAlloc();
1504  FAIL_IF_NULL(p);
1505  Flow f;
1506  ThreadVars tv;
1507  StreamTcpThread stt;
1508  TCPHdr tcph;
1509  uint8_t payload[4];
1510  struct in_addr addr;
1511  IPV4Hdr ipv4h;
1512  char os_policy_name[10] = "windows";
1513  const char *ip_addr;
1514  PacketQueueNoLock pq;
1515  memset(&pq, 0, sizeof(PacketQueueNoLock));
1516 
1517  memset(&f, 0, sizeof(Flow));
1518  memset(&tv, 0, sizeof(ThreadVars));
1519  memset(&stt, 0, sizeof(StreamTcpThread));
1520  memset(&tcph, 0, sizeof(TCPHdr));
1521  memset(&addr, 0, sizeof(addr));
1522  memset(&ipv4h, 0, sizeof(ipv4h));
1523  FLOW_INITIALIZE(&f);
1524  p->flow = &f;
1525  int ret = 0;
1526 
1527  StreamTcpUTInit(&stt.ra_ctx);
1528 
1529  /* Load the config string in to parser */
1531  ConfInit();
1532  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1533 
1534  /* Get the IP address as string and add it to Host info tree for lookups */
1535  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1536  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1537  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1538  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1539  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1540  addr.s_addr = inet_addr("192.168.0.20");
1541  tcph.th_win = htons(5480);
1542  tcph.th_seq = htonl(10);
1543  tcph.th_ack = htonl(20);
1544  tcph.th_flags = TH_ACK | TH_PUSH;
1545  p->tcph = &tcph;
1546  p->dst.family = AF_INET;
1547  p->dst.address.address_un_data32[0] = addr.s_addr;
1548  p->ip4h = &ipv4h;
1549 
1550  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1551  p->payload = payload;
1552  p->payload_len = 3;
1553 
1554  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1555  goto end;
1556 
1557  p->tcph->th_seq = htonl(20);
1558  p->tcph->th_ack = htonl(13);
1559  p->tcph->th_flags = TH_ACK | TH_PUSH;
1561 
1562  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1563  p->payload = payload;
1564  p->payload_len = 3;
1565 
1566  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1567  goto end;
1568 
1569  p->tcph->th_seq = htonl(15);
1570  p->tcph->th_ack = htonl(23);
1571  p->tcph->th_flags = TH_ACK | TH_PUSH;
1573 
1574  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1575  p->payload = payload;
1576  p->payload_len = 3;
1577 
1578  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1579  goto end;
1580 
1581  p->tcph->th_seq = htonl(14);
1582  p->tcph->th_ack = htonl(23);
1583  p->tcph->th_flags = TH_ACK | TH_PUSH;
1585 
1586  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1587  p->payload = payload;
1588  p->payload_len = 3;
1589 
1590  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1591  goto end;
1592 
1593  addr.s_addr = inet_addr("192.168.1.20");
1594  p->tcph->th_seq = htonl(25);
1595  p->tcph->th_ack = htonl(13);
1596  p->tcph->th_flags = TH_ACK | TH_PUSH;
1598  p->dst.address.address_un_data32[0] = addr.s_addr;
1599 
1600  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1601  p->payload = payload;
1602  p->payload_len = 3;
1603 
1604  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1605  goto end;
1606 
1607  p->tcph->th_seq = htonl(24);
1608  p->tcph->th_ack = htonl(13);
1609  p->tcph->th_flags = TH_ACK | TH_PUSH;
1611 
1612  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1613  p->payload = payload;
1614  p->payload_len = 3;
1615 
1616  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1617  goto end;
1618 
1619  if (!stream_config.midstream) {
1620  ret = 1;
1621  goto end;
1622  }
1623  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1624  goto end;
1625 
1626  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1627  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1628  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1629  " server.next_seq %" PRIu32 "\n",
1630  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1631  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1632  goto end;
1633  }
1634 
1635  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_WINDOWS &&
1636  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) {
1637  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1638  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1639  " should be %" PRIu8 "\n",
1640  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_WINDOWS,
1641  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_LINUX);
1642  goto end;
1643  }
1645 
1646  ret = 1;
1647 end:
1648  ConfDeInit();
1650  SCFree(p);
1651  FLOW_DESTROY(&f);
1653  return ret;
1654 }
1655 
1656 /**
1657  * \test Test the setting up a OS policy. Te OS policy values are defined in
1658  * the config string "dummy_conf_string1"
1659  *
1660  * \retval On success it returns 1 and on failure 0
1661  */
1662 
1663 static int StreamTcpTest16(void)
1664 {
1665  Packet *p = PacketGetFromAlloc();
1666  FAIL_IF_NULL(p);
1667  Flow f;
1668  ThreadVars tv;
1669  StreamTcpThread stt;
1670  TCPHdr tcph;
1671  uint8_t payload[4];
1672  struct in_addr addr;
1673  IPV4Hdr ipv4h;
1674  char os_policy_name[10] = "windows";
1675  const char *ip_addr;
1676  PacketQueueNoLock pq;
1677  memset(&pq, 0, sizeof(PacketQueueNoLock));
1678 
1679  memset(&f, 0, sizeof(Flow));
1680  memset(&tv, 0, sizeof(ThreadVars));
1681  memset(&stt, 0, sizeof(StreamTcpThread));
1682  memset(&tcph, 0, sizeof(TCPHdr));
1683  memset(&addr, 0, sizeof(addr));
1684  memset(&ipv4h, 0, sizeof(ipv4h));
1685  FLOW_INITIALIZE(&f);
1686  p->flow = &f;
1687  int ret = 0;
1688 
1689  StreamTcpUTInit(&stt.ra_ctx);
1690 
1691  /* Load the config string in to parser */
1693  ConfInit();
1694  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1695 
1696  /* Get the IP address as string and add it to Host info tree for lookups */
1697  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1698  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1699  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1700  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1701  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1702  addr.s_addr = inet_addr("192.168.0.1");
1703  tcph.th_win = htons(5480);
1704  tcph.th_seq = htonl(10);
1705  tcph.th_ack = htonl(20);
1706  tcph.th_flags = TH_ACK | TH_PUSH;
1707  p->tcph = &tcph;
1708  p->dst.family = AF_INET;
1709  p->dst.address.address_un_data32[0] = addr.s_addr;
1710  p->ip4h = &ipv4h;
1711 
1712  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1713  p->payload = payload;
1714  p->payload_len = 3;
1715 
1716  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1717  goto end;
1718 
1719  p->tcph->th_seq = htonl(20);
1720  p->tcph->th_ack = htonl(13);
1721  p->tcph->th_flags = TH_ACK | TH_PUSH;
1723 
1724  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1725  p->payload = payload;
1726  p->payload_len = 3;
1727 
1728  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1729  goto end;
1730 
1731  p->tcph->th_seq = htonl(15);
1732  p->tcph->th_ack = htonl(23);
1733  p->tcph->th_flags = TH_ACK | TH_PUSH;
1735 
1736  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1737  p->payload = payload;
1738  p->payload_len = 3;
1739 
1740  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1741  goto end;
1742 
1743  p->tcph->th_seq = htonl(14);
1744  p->tcph->th_ack = htonl(23);
1745  p->tcph->th_flags = TH_ACK | TH_PUSH;
1747 
1748  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1749  p->payload = payload;
1750  p->payload_len = 3;
1751 
1752  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1753  goto end;
1754 
1755  addr.s_addr = inet_addr("192.168.1.1");
1756  p->tcph->th_seq = htonl(25);
1757  p->tcph->th_ack = htonl(13);
1758  p->tcph->th_flags = TH_ACK | TH_PUSH;
1760  p->dst.address.address_un_data32[0] = addr.s_addr;
1761 
1762  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1763  p->payload = payload;
1764  p->payload_len = 3;
1765 
1766  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1767  goto end;
1768 
1769  p->tcph->th_seq = htonl(24);
1770  p->tcph->th_ack = htonl(13);
1771  p->tcph->th_flags = TH_ACK | TH_PUSH;
1773 
1774  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1775  p->payload = payload;
1776  p->payload_len = 3;
1777 
1778  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1779  goto end;
1780 
1781  if (!stream_config.midstream) {
1782  ret = 1;
1783  goto end;
1784  }
1785  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1786  goto end;
1787 
1788  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1789  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1790  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1791  " server.next_seq %" PRIu32 "\n",
1792  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1793  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1794  goto end;
1795  }
1796 
1797  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1798  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_WINDOWS) {
1799  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1800  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1801  " should be %" PRIu8 "\n",
1802  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1803  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_WINDOWS);
1804  goto end;
1805  }
1807 
1808  ret = 1;
1809 end:
1810  ConfDeInit();
1812  SCFree(p);
1813  FLOW_DESTROY(&f);
1815  return ret;
1816 }
1817 
1818 /**
1819  * \test Test the setting up a OS policy. Te OS policy values are defined in
1820  * the config string "dummy_conf_string1". To check the setting of
1821  * Default os policy
1822  *
1823  * \retval On success it returns 1 and on failure 0
1824  */
1825 
1826 static int StreamTcpTest17(void)
1827 {
1828  Packet *p = PacketGetFromAlloc();
1829  FAIL_IF_NULL(p);
1830  Flow f;
1831  ThreadVars tv;
1832  StreamTcpThread stt;
1833  TCPHdr tcph;
1834  uint8_t payload[4];
1835  struct in_addr addr;
1836  IPV4Hdr ipv4h;
1837  char os_policy_name[10] = "windows";
1838  const char *ip_addr;
1839  PacketQueueNoLock pq;
1840  memset(&pq, 0, sizeof(PacketQueueNoLock));
1841 
1842  memset(&f, 0, sizeof(Flow));
1843  memset(&tv, 0, sizeof(ThreadVars));
1844  memset(&stt, 0, sizeof(StreamTcpThread));
1845  memset(&tcph, 0, sizeof(TCPHdr));
1846  memset(&addr, 0, sizeof(addr));
1847  memset(&ipv4h, 0, sizeof(ipv4h));
1848  FLOW_INITIALIZE(&f);
1849  p->flow = &f;
1850  int ret = 0;
1851 
1852  StreamTcpUTInit(&stt.ra_ctx);
1853 
1854  /* Load the config string in to parser */
1856  ConfInit();
1857  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
1858 
1859  /* Get the IP address as string and add it to Host info tree for lookups */
1860  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1861  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1862  strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name));
1863  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
1864  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
1865  addr.s_addr = inet_addr("192.168.0.1");
1866  tcph.th_win = htons(5480);
1867  tcph.th_seq = htonl(10);
1868  tcph.th_ack = htonl(20);
1869  tcph.th_flags = TH_ACK | TH_PUSH;
1870  p->tcph = &tcph;
1871  p->dst.family = AF_INET;
1872  p->dst.address.address_un_data32[0] = addr.s_addr;
1873  p->ip4h = &ipv4h;
1874 
1875  StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/
1876  p->payload = payload;
1877  p->payload_len = 3;
1878 
1879  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1880  goto end;
1881 
1882  p->tcph->th_seq = htonl(20);
1883  p->tcph->th_ack = htonl(13);
1884  p->tcph->th_flags = TH_ACK | TH_PUSH;
1886 
1887  StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/
1888  p->payload = payload;
1889  p->payload_len = 3;
1890 
1891  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1892  goto end;
1893 
1894  p->tcph->th_seq = htonl(15);
1895  p->tcph->th_ack = htonl(23);
1896  p->tcph->th_flags = TH_ACK | TH_PUSH;
1898 
1899  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1900  p->payload = payload;
1901  p->payload_len = 3;
1902 
1903  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1904  goto end;
1905 
1906  p->tcph->th_seq = htonl(14);
1907  p->tcph->th_ack = htonl(23);
1908  p->tcph->th_flags = TH_ACK | TH_PUSH;
1910 
1911  StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/
1912  p->payload = payload;
1913  p->payload_len = 3;
1914 
1915  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1916  goto end;
1917 
1918  addr.s_addr = inet_addr("10.1.1.1");
1919  p->tcph->th_seq = htonl(25);
1920  p->tcph->th_ack = htonl(13);
1921  p->tcph->th_flags = TH_ACK | TH_PUSH;
1923  p->dst.address.address_un_data32[0] = addr.s_addr;
1924 
1925  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1926  p->payload = payload;
1927  p->payload_len = 3;
1928 
1929  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1930  goto end;
1931 
1932  p->tcph->th_seq = htonl(24);
1933  p->tcph->th_ack = htonl(13);
1934  p->tcph->th_flags = TH_ACK | TH_PUSH;
1936 
1937  StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/
1938  p->payload = payload;
1939  p->payload_len = 3;
1940 
1941  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
1942  goto end;
1943 
1944  if (!stream_config.midstream) {
1945  ret = 1;
1946  goto end;
1947  }
1948  if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED)
1949  goto end;
1950 
1951  if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 &&
1952  ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) {
1953  printf("failed in next_seq match client.next_seq %" PRIu32 ""
1954  " server.next_seq %" PRIu32 "\n",
1955  ((TcpSession *)(p->flow->protoctx))->client.next_seq,
1956  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
1957  goto end;
1958  }
1959 
1960  if (((TcpSession *)(p->flow->protoctx))->client.os_policy != OS_POLICY_LINUX &&
1961  ((TcpSession *)(p->flow->protoctx))->server.os_policy != OS_POLICY_DEFAULT) {
1962  printf("failed in setting up OS policy, client.os_policy: %" PRIu8 ""
1963  " should be %" PRIu8 " and server.os_policy: %" PRIu8 ""
1964  " should be %" PRIu8 "\n",
1965  ((TcpSession *)(p->flow->protoctx))->client.os_policy, (uint8_t)OS_POLICY_LINUX,
1966  ((TcpSession *)(p->flow->protoctx))->server.os_policy, (uint8_t)OS_POLICY_DEFAULT);
1967  goto end;
1968  }
1970 
1971  ret = 1;
1972 end:
1973  ConfDeInit();
1975  SCFree(p);
1976  FLOW_DESTROY(&f);
1978  return ret;
1979 }
1980 
1981 /** \test Test the various OS policies based on different IP addresses from
1982  confuguration defined in 'dummy_conf_string1' */
1983 static int StreamTcpTest18(void)
1984 {
1985  StreamTcpThread stt;
1986  struct in_addr addr;
1987  char os_policy_name[10] = "windows";
1988  const char *ip_addr;
1989  TcpStream stream;
1990  Packet *p = PacketGetFromAlloc();
1991  FAIL_IF_NULL(p);
1992  IPV4Hdr ipv4h;
1993  int ret = 0;
1994 
1995  memset(&addr, 0, sizeof(addr));
1996  memset(&stream, 0, sizeof(stream));
1997  memset(&ipv4h, 0, sizeof(ipv4h));
1998 
1999  StreamTcpUTInit(&stt.ra_ctx);
2001 
2002  /* Load the config string in to parser */
2004  ConfInit();
2005  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2006 
2007  /* Get the IP address as string and add it to Host info tree for lookups */
2008  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2009  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2010 
2011  p->dst.family = AF_INET;
2012  p->ip4h = &ipv4h;
2013  addr.s_addr = inet_addr("192.168.1.1");
2014  p->dst.address.address_un_data32[0] = addr.s_addr;
2015  StreamTcpSetOSPolicy(&stream, p);
2016 
2017  if (stream.os_policy != OS_POLICY_WINDOWS)
2018  goto end;
2019 
2020  ret = 1;
2021 end:
2022  ConfDeInit();
2024  SCFree(p);
2026  return ret;
2027 }
2028 /** \test Test the various OS policies based on different IP addresses from
2029  confuguration defined in 'dummy_conf_string1' */
2030 static int StreamTcpTest19(void)
2031 {
2032  StreamTcpThread stt;
2033  struct in_addr addr;
2034  char os_policy_name[10] = "windows";
2035  const char *ip_addr;
2036  TcpStream stream;
2037  Packet *p = PacketGetFromAlloc();
2038  FAIL_IF_NULL(p);
2039  IPV4Hdr ipv4h;
2040  int ret = 0;
2041 
2042  memset(&addr, 0, sizeof(addr));
2043  memset(&stream, 0, sizeof(stream));
2044  memset(&ipv4h, 0, sizeof(ipv4h));
2045 
2046  StreamTcpUTInit(&stt.ra_ctx);
2048 
2049  /* Load the config string in to parser */
2051  ConfInit();
2052  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2053 
2054  /* Get the IP address as string and add it to Host info tree for lookups */
2055  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2056  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2057 
2058  p->dst.family = AF_INET;
2059  p->ip4h = &ipv4h;
2060  addr.s_addr = inet_addr("192.168.0.30");
2061  p->dst.address.address_un_data32[0] = addr.s_addr;
2062  StreamTcpSetOSPolicy(&stream, p);
2063 
2064  if (stream.os_policy != OS_POLICY_WINDOWS) {
2065  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 ": ",
2066  (uint8_t)OS_POLICY_WINDOWS, stream.os_policy);
2067  goto end;
2068  }
2069 
2070  ret = 1;
2071 end:
2072  ConfDeInit();
2074  SCFree(p);
2076  return ret;
2077 }
2078 /** \test Test the various OS policies based on different IP addresses from
2079  confuguration defined in 'dummy_conf_string1' */
2080 static int StreamTcpTest20(void)
2081 {
2082  StreamTcpThread stt;
2083  struct in_addr addr;
2084  char os_policy_name[10] = "linux";
2085  const char *ip_addr;
2086  TcpStream stream;
2087  Packet *p = PacketGetFromAlloc();
2088  FAIL_IF_NULL(p);
2089  IPV4Hdr ipv4h;
2090  int ret = 0;
2091 
2092  memset(&addr, 0, sizeof(addr));
2093  memset(&stream, 0, sizeof(stream));
2094  memset(&ipv4h, 0, sizeof(ipv4h));
2095 
2096  StreamTcpUTInit(&stt.ra_ctx);
2098 
2099  /* Load the config string in to parser */
2101  ConfInit();
2102  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2103 
2104  /* Get the IP address as string and add it to Host info tree for lookups */
2105  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2106  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2107 
2108  p->dst.family = AF_INET;
2109  p->ip4h = &ipv4h;
2110  addr.s_addr = inet_addr("192.168.0.1");
2111  p->dst.address.address_un_data32[0] = addr.s_addr;
2112  StreamTcpSetOSPolicy(&stream, p);
2113 
2114  if (stream.os_policy != OS_POLICY_LINUX) {
2115  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2116  stream.os_policy);
2117  goto end;
2118  }
2119 
2120  ret = 1;
2121 end:
2122  ConfDeInit();
2124  SCFree(p);
2126  return ret;
2127 }
2128 /** \test Test the various OS policies based on different IP addresses from
2129  confuguration defined in 'dummy_conf_string1' */
2130 static int StreamTcpTest21(void)
2131 {
2132  StreamTcpThread stt;
2133  struct in_addr addr;
2134  char os_policy_name[10] = "linux";
2135  const char *ip_addr;
2136  TcpStream stream;
2137  Packet *p = PacketGetFromAlloc();
2138  FAIL_IF_NULL(p);
2139  IPV4Hdr ipv4h;
2140  int ret = 0;
2141 
2142  memset(&addr, 0, sizeof(addr));
2143  memset(&stream, 0, sizeof(stream));
2144  memset(&ipv4h, 0, sizeof(ipv4h));
2145 
2146  StreamTcpUTInit(&stt.ra_ctx);
2148 
2149  /* Load the config string in to parser */
2151  ConfInit();
2152  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2153 
2154  /* Get the IP address as string and add it to Host info tree for lookups */
2155  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2156  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2157 
2158  p->dst.family = AF_INET;
2159  p->ip4h = &ipv4h;
2160  addr.s_addr = inet_addr("192.168.1.30");
2161  p->dst.address.address_un_data32[0] = addr.s_addr;
2162  StreamTcpSetOSPolicy(&stream, p);
2163 
2164  if (stream.os_policy != OS_POLICY_LINUX) {
2165  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n", (uint8_t)OS_POLICY_LINUX,
2166  stream.os_policy);
2167  goto end;
2168  }
2169 
2170  ret = 1;
2171 end:
2172  ConfDeInit();
2174  SCFree(p);
2176  return ret;
2177 }
2178 /** \test Test the various OS policies based on different IP addresses from
2179  confuguration defined in 'dummy_conf_string1' */
2180 static int StreamTcpTest22(void)
2181 {
2182  StreamTcpThread stt;
2183  struct in_addr addr;
2184  char os_policy_name[10] = "windows";
2185  const char *ip_addr;
2186  TcpStream stream;
2187  Packet *p = PacketGetFromAlloc();
2188  FAIL_IF_NULL(p);
2189  IPV4Hdr ipv4h;
2190  int ret = 0;
2191 
2192  memset(&addr, 0, sizeof(addr));
2193  memset(&stream, 0, sizeof(stream));
2194  memset(&ipv4h, 0, sizeof(ipv4h));
2195 
2196  StreamTcpUTInit(&stt.ra_ctx);
2198 
2199  /* Load the config string in to parser */
2201  ConfInit();
2202  ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1));
2203 
2204  /* Get the IP address as string and add it to Host info tree for lookups */
2205  ip_addr = StreamTcpParseOSPolicy(os_policy_name);
2206  SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1);
2207 
2208  p->dst.family = AF_INET;
2209  p->ip4h = &ipv4h;
2210  addr.s_addr = inet_addr("123.231.2.1");
2211  p->dst.address.address_un_data32[0] = addr.s_addr;
2212  StreamTcpSetOSPolicy(&stream, p);
2213 
2214  if (stream.os_policy != OS_POLICY_DEFAULT) {
2215  printf("expected os_policy: %" PRIu8 " but received %" PRIu8 "\n",
2216  (uint8_t)OS_POLICY_DEFAULT, stream.os_policy);
2217  goto end;
2218  }
2219 
2220  ret = 1;
2221 end:
2222  ConfDeInit();
2224  SCFree(p);
2226  return ret;
2227 }
2228 
2229 /** \test Test the stream mem leaks conditions. */
2230 static int StreamTcpTest23(void)
2231 {
2232  StreamTcpThread stt;
2233  TcpSession ssn;
2234  Flow f;
2235  TCPHdr tcph;
2236  uint8_t packet[1460] = "";
2237  ThreadVars tv;
2238  PacketQueueNoLock pq;
2239 
2240  Packet *p = PacketGetFromAlloc();
2241  FAIL_IF(p == NULL);
2242 
2243  memset(&pq, 0, sizeof(PacketQueueNoLock));
2244  memset(&f, 0, sizeof(Flow));
2245  memset(&tcph, 0, sizeof(TCPHdr));
2246  memset(&tv, 0, sizeof(ThreadVars));
2247 
2248  StreamTcpUTInit(&stt.ra_ctx);
2250  FLOW_INITIALIZE(&f);
2252  f.protoctx = &ssn;
2253  p->src.family = AF_INET;
2254  p->dst.family = AF_INET;
2255  p->proto = IPPROTO_TCP;
2256  p->flow = &f;
2257  tcph.th_win = 5480;
2258  tcph.th_flags = TH_PUSH | TH_ACK;
2259  p->tcph = &tcph;
2261  p->payload = packet;
2262  SET_ISN(&ssn.client, 3184324452UL);
2263 
2264  p->tcph->th_seq = htonl(3184324453UL);
2265  p->tcph->th_ack = htonl(3373419609UL);
2266  p->payload_len = 2;
2267 
2268  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2269 
2270  p->tcph->th_seq = htonl(3184324455UL);
2271  p->tcph->th_ack = htonl(3373419621UL);
2272  p->payload_len = 2;
2273 
2274  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2275 
2276  p->tcph->th_seq = htonl(3184324453UL);
2277  p->tcph->th_ack = htonl(3373419621UL);
2278  p->payload_len = 6;
2279 
2280  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2281 
2282  TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2283  FAIL_IF_NULL(seg);
2284  FAIL_IF(TCP_SEG_LEN(seg) != 2);
2285 
2287  SCFree(p);
2288  FLOW_DESTROY(&f);
2290  FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2291  PASS;
2292 }
2293 
2294 /** \test Test the stream mem leaks conditions. */
2295 static int StreamTcpTest24(void)
2296 {
2297  StreamTcpThread stt;
2298  TcpSession ssn;
2299  Packet *p = PacketGetFromAlloc();
2300  FAIL_IF(p == NULL);
2301  Flow f;
2302  TCPHdr tcph;
2303  uint8_t packet[1460] = "";
2304  ThreadVars tv;
2305  memset(&tv, 0, sizeof(ThreadVars));
2306  PacketQueueNoLock pq;
2307  memset(&pq, 0, sizeof(PacketQueueNoLock));
2308 
2309  StreamTcpUTInit(&stt.ra_ctx);
2311 
2312  memset(&f, 0, sizeof(Flow));
2313  memset(&tcph, 0, sizeof(TCPHdr));
2314  FLOW_INITIALIZE(&f);
2316  f.protoctx = &ssn;
2317  p->src.family = AF_INET;
2318  p->dst.family = AF_INET;
2319  p->proto = IPPROTO_TCP;
2320  p->flow = &f;
2321  tcph.th_win = 5480;
2322  tcph.th_flags = TH_PUSH | TH_ACK;
2323  p->tcph = &tcph;
2325  p->payload = packet;
2326  // ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL;
2327  SET_ISN(&ssn.client, 3184324453UL);
2328 
2329  p->tcph->th_seq = htonl(3184324455UL);
2330  p->tcph->th_ack = htonl(3373419621UL);
2331  p->payload_len = 4;
2332 
2333  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2334 
2335  p->tcph->th_seq = htonl(3184324459UL);
2336  p->tcph->th_ack = htonl(3373419633UL);
2337  p->payload_len = 2;
2338 
2339  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2340 
2341  p->tcph->th_seq = htonl(3184324459UL);
2342  p->tcph->th_ack = htonl(3373419657UL);
2343  p->payload_len = 4;
2344 
2345  FAIL_IF(StreamTcpReassembleHandleSegment(&tv, stt.ra_ctx, &ssn, &ssn.client, p, &pq) == -1);
2346 
2347  TcpSegment *seg = RB_MAX(TCPSEG, &ssn.client.seg_tree);
2348  FAIL_IF_NULL(seg);
2349  FAIL_IF(TCP_SEG_LEN(seg) != 4);
2350 
2352  SCFree(p);
2353  FLOW_DESTROY(&f);
2355  FAIL_IF(SC_ATOMIC_GET(st_memuse) > 0);
2356  PASS;
2357 }
2358 
2359 /**
2360  * \test Test the initialization of tcp streams with congestion flags
2361  *
2362  * \retval On success it returns 1 and on failure 0.
2363  */
2364 static int StreamTcpTest25(void)
2365 {
2366  Packet *p = PacketGetFromAlloc();
2367  FAIL_IF_NULL(p);
2368  Flow f;
2369  ThreadVars tv;
2370  StreamTcpThread stt;
2371  uint8_t payload[4];
2372  TCPHdr tcph;
2373  int ret = 0;
2374  PacketQueueNoLock pq;
2375  memset(&pq, 0, sizeof(PacketQueueNoLock));
2376 
2377  memset(&f, 0, sizeof(Flow));
2378  memset(&tv, 0, sizeof(ThreadVars));
2379  memset(&stt, 0, sizeof(StreamTcpThread));
2380  memset(&tcph, 0, sizeof(TCPHdr));
2381 
2382  FLOW_INITIALIZE(&f);
2383  p->flow = &f;
2384  tcph.th_win = htons(5480);
2385  tcph.th_flags = TH_SYN | TH_CWR;
2386  p->tcph = &tcph;
2388  StreamTcpUTInit(&stt.ra_ctx);
2389 
2390  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2391  goto end;
2392 
2393  p->tcph->th_ack = htonl(1);
2394  p->tcph->th_flags = TH_SYN | TH_ACK;
2396 
2397  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2398  goto end;
2399 
2400  p->tcph->th_ack = htonl(1);
2401  p->tcph->th_seq = htonl(1);
2402  p->tcph->th_flags = TH_ACK;
2404 
2405  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2406  goto end;
2407 
2408  p->tcph->th_ack = htonl(1);
2409  p->tcph->th_seq = htonl(2);
2410  p->tcph->th_flags = TH_PUSH | TH_ACK;
2412 
2413  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2414  p->payload = payload;
2415  p->payload_len = 3;
2416 
2417  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2418  goto end;
2419 
2421  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2422  goto end;
2423 
2424  p->tcph->th_ack = htonl(1);
2425  p->tcph->th_seq = htonl(6);
2426  p->tcph->th_flags = TH_PUSH | TH_ACK;
2428 
2429  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2430  p->payload = payload;
2431  p->payload_len = 3;
2432 
2433  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2434  goto end;
2435 
2437  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2438  goto end;
2439 
2441 
2442  ret = 1;
2443 end:
2444  SCFree(p);
2445  FLOW_DESTROY(&f);
2447  return ret;
2448 }
2449 
2450 /**
2451  * \test Test the initialization of tcp streams with congestion flags
2452  *
2453  * \retval On success it returns 1 and on failure 0.
2454  */
2455 static int StreamTcpTest26(void)
2456 {
2457  Packet *p = PacketGetFromAlloc();
2458  FAIL_IF_NULL(p);
2459  Flow f;
2460  ThreadVars tv;
2461  StreamTcpThread stt;
2462  uint8_t payload[4];
2463  TCPHdr tcph;
2464  int ret = 0;
2465  PacketQueueNoLock pq;
2466  memset(&pq, 0, sizeof(PacketQueueNoLock));
2467 
2468  memset(&f, 0, sizeof(Flow));
2469  memset(&tv, 0, sizeof(ThreadVars));
2470  memset(&stt, 0, sizeof(StreamTcpThread));
2471  memset(&tcph, 0, sizeof(TCPHdr));
2472 
2473  FLOW_INITIALIZE(&f);
2474  p->flow = &f;
2475  tcph.th_win = htons(5480);
2476  tcph.th_flags = TH_SYN | TH_ECN;
2477  p->tcph = &tcph;
2479 
2480  StreamTcpUTInit(&stt.ra_ctx);
2481 
2482  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2483  goto end;
2484 
2485  p->tcph->th_ack = htonl(1);
2486  p->tcph->th_flags = TH_SYN | TH_ACK;
2488 
2489  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2490  goto end;
2491 
2492  p->tcph->th_ack = htonl(1);
2493  p->tcph->th_seq = htonl(1);
2494  p->tcph->th_flags = TH_ACK;
2496 
2497  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2498  goto end;
2499 
2500  p->tcph->th_ack = htonl(1);
2501  p->tcph->th_seq = htonl(2);
2502  p->tcph->th_flags = TH_PUSH | TH_ACK;
2504 
2505  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2506  p->payload = payload;
2507  p->payload_len = 3;
2508 
2509  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2510  goto end;
2511 
2513  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2514  goto end;
2515 
2516  p->tcph->th_ack = htonl(1);
2517  p->tcph->th_seq = htonl(6);
2518  p->tcph->th_flags = TH_PUSH | TH_ACK;
2520 
2521  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2522  p->payload = payload;
2523  p->payload_len = 3;
2524 
2525  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2526  goto end;
2527 
2529  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2530  goto end;
2531 
2533 
2534  ret = 1;
2535 end:
2536  SCFree(p);
2537  FLOW_DESTROY(&f);
2539  return ret;
2540 }
2541 
2542 /**
2543  * \test Test the initialization of tcp streams with congestion flags
2544  *
2545  * \retval On success it returns 1 and on failure 0.
2546  */
2547 static int StreamTcpTest27(void)
2548 {
2549  Packet *p = PacketGetFromAlloc();
2550  FAIL_IF_NULL(p);
2551  Flow f;
2552  ThreadVars tv;
2553  StreamTcpThread stt;
2554  uint8_t payload[4];
2555  TCPHdr tcph;
2556  int ret = 0;
2557  PacketQueueNoLock pq;
2558  memset(&pq, 0, sizeof(PacketQueueNoLock));
2559 
2560  memset(&f, 0, sizeof(Flow));
2561  memset(&tv, 0, sizeof(ThreadVars));
2562  memset(&stt, 0, sizeof(StreamTcpThread));
2563  memset(&tcph, 0, sizeof(TCPHdr));
2564 
2565  FLOW_INITIALIZE(&f);
2566  p->flow = &f;
2567  tcph.th_win = htons(5480);
2568  tcph.th_flags = TH_SYN | TH_CWR | TH_ECN;
2569  p->tcph = &tcph;
2571 
2572  StreamTcpUTInit(&stt.ra_ctx);
2573 
2574  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
2575  goto end;
2576 
2577  p->tcph->th_ack = htonl(1);
2578  p->tcph->th_flags = TH_SYN | TH_ACK;
2580 
2581  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2582  goto end;
2583 
2584  p->tcph->th_ack = htonl(1);
2585  p->tcph->th_seq = htonl(1);
2586  p->tcph->th_flags = TH_ACK;
2588 
2589  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2590  goto end;
2591 
2592  p->tcph->th_ack = htonl(1);
2593  p->tcph->th_seq = htonl(2);
2594  p->tcph->th_flags = TH_PUSH | TH_ACK;
2596 
2597  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
2598  p->payload = payload;
2599  p->payload_len = 3;
2600 
2601  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2602  goto end;
2603 
2605  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2606  goto end;
2607 
2608  p->tcph->th_ack = htonl(1);
2609  p->tcph->th_seq = htonl(6);
2610  p->tcph->th_flags = TH_PUSH | TH_ACK;
2612 
2613  StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/
2614  p->payload = payload;
2615  p->payload_len = 3;
2616 
2617  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2618  goto end;
2619 
2621  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL)
2622  goto end;
2623 
2625 
2626  ret = 1;
2627 end:
2628  SCFree(p);
2629  FLOW_DESTROY(&f);
2631  return ret;
2632 }
2633 
2634 /** \test Test the memcap incrementing/decrementing and memcap check */
2635 static int StreamTcpTest28(void)
2636 {
2637  StreamTcpThread stt;
2638  StreamTcpUTInit(&stt.ra_ctx);
2639 
2640  uint32_t memuse = SC_ATOMIC_GET(st_memuse);
2641 
2642  StreamTcpIncrMemuse(500);
2643  FAIL_IF(SC_ATOMIC_GET(st_memuse) != (memuse + 500));
2644 
2645  StreamTcpDecrMemuse(500);
2646  FAIL_IF(SC_ATOMIC_GET(st_memuse) != memuse);
2647 
2648  FAIL_IF(StreamTcpCheckMemcap(500) != 1);
2649 
2650  FAIL_IF(StreamTcpCheckMemcap((memuse + SC_ATOMIC_GET(stream_config.memcap))) != 0);
2651 
2653 
2654  FAIL_IF(SC_ATOMIC_GET(st_memuse) != 0);
2655  PASS;
2656 }
2657 
2658 #if 0
2659 /**
2660  * \test Test the resetting of the sesison with bad checksum packet and later
2661  * send the malicious contents on the session. Engine should drop the
2662  * packet with the bad checksum.
2663  *
2664  * \retval On success it returns 1 and on failure 0.
2665  */
2666 static int StreamTcpTest29(void)
2667 {
2668  Packet p;
2669  Flow f;
2670  ThreadVars tv;
2671  StreamTcpThread stt;
2672  TCPHdr tcph;
2673  TcpSession ssn;
2674  IPV4Hdr ipv4h;
2675  struct in_addr addr;
2676  struct in_addr addr1;
2677  TCPCache tcpc;
2678  TCPVars tcpvars;
2679  TcpStream server;
2680  TcpStream client;
2681 
2682  memset (&p, 0, SIZE_OF_PACKET);
2683  memset (&f, 0, sizeof(Flow));
2684  memset(&tv, 0, sizeof (ThreadVars));
2685  memset(&stt, 0, sizeof (StreamTcpThread));
2686  memset(&tcph, 0, sizeof (TCPHdr));
2687  memset (&ipv4h, 0, sizeof(IPV4Hdr));
2688  memset (&addr, 0, sizeof(addr));
2689  memset (&addr1, 0, sizeof(addr1));
2690  memset (&tcpc, 0, sizeof(tcpc));
2691  memset (&tcpvars, 0, sizeof(tcpvars));
2692  memset(&ssn, 0, sizeof (TcpSession));
2693  memset(&server, 0, sizeof (TcpStream));
2694  memset(&client, 0, sizeof (TcpStream));
2695  uint8_t packet[1460] = "";
2696  int result = 1;
2697 
2698  FLOW_INITIALIZE(&f);
2699  StreamTcpInitConfig(true);
2700 
2701  /* prevent L7 from kicking in */
2702 
2704  p.src.family = AF_INET;
2705  p.dst.family = AF_INET;
2706  p.proto = IPPROTO_TCP;
2707  p.flow = &f;
2708  tcph.th_win = 5480;
2709  p.tcph = &tcph;
2710  p.payload = packet;
2711  p.ip4h = &ipv4h;
2712  p.tcpc = tcpc;
2713  p.tcpc.level4_comp_csum = -1;
2714  tcpvars.hlen = 20;
2715  p.tcpvars = tcpvars;
2716  ssn.state = TCP_ESTABLISHED;
2717  addr.s_addr = inet_addr("10.1.3.53");
2718  p.dst.address.address_un_data32[0] = addr.s_addr;
2719  addr1.s_addr = inet_addr("10.1.3.7");
2720  p.src.address.address_un_data32[0] = addr1.s_addr;
2721  f.protoctx = &ssn;
2722  stt.ra_ctx = ra_ctx;
2723  ssn.server = server;
2724  ssn.client = client;
2725  ssn.client.isn = 10;
2726  ssn.client.window = 5184;
2727  ssn.client.last_ack = 10;
2728  ssn.client.ra_base_seq = 10;
2729  ssn.client.next_win = 5184;
2730  ssn.server.isn = 119197101;
2731  ssn.server.window = 5184;
2732  ssn.server.next_win = 5184;
2733  ssn.server.last_ack = 119197101;
2734  ssn.server.ra_base_seq = 119197101;
2735 
2736  tcph.th_flags = TH_PUSH | TH_ACK;
2738  p.tcph->th_seq = htonl(11);
2739  p.tcph->th_ack = htonl(119197102);
2740  p.payload_len = 4;
2741  p.ip4h->ip_src = addr1;
2742  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
2743  (uint16_t *)p.tcph,
2744  (p.payload_len +
2745  p.tcpvars.hlen) );
2746 
2747  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2748  printf("failed in segment reassmebling\n");
2749  result &= 0;
2750  goto end;
2751  }
2752 
2753  tcph.th_flags = TH_ACK;
2755  p.tcph->th_seq = htonl(119197102);
2756  p.tcph->th_ack = htonl(15);
2757  p.payload_len = 0;
2758  p.ip4h->ip_src = addr;
2759  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
2760  (uint16_t *)p.tcph,
2761  (p.payload_len +
2762  p.tcpvars.hlen) );
2763 
2764  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2765  printf("failed in segment reassmebling\n");
2766  result &= 0;
2767  goto end;
2768  }
2769 
2770  tcph.th_flags = TH_RST | TH_ACK;
2772  p.tcph->th_seq = htonl(15);
2773  p.tcph->th_ack = htonl(119197102);
2774  p.payload_len = 0;
2775  p.ip4h->ip_src = addr1;
2776  p.tcph->th_sum = 12345;
2777 
2778  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2779  printf("failed in segment reassmebling\n");
2780  result &= 0;
2781  goto end;
2782  }
2783 
2784  if (ssn.state != TCP_ESTABLISHED) {
2785  printf("the ssn.state should be TCP_ESTABLISHED(%"PRIu8"), not %"PRIu8""
2786  "\n", TCP_ESTABLISHED, ssn.state);
2787  result &= 0;
2788  goto end;
2789  }
2790 
2791 end:
2793  StreamTcpFreeConfig(true);
2794  return result;
2795 }
2796 
2797 /**
2798  * \test Test the overlapping of the packet with bad checksum packet and later
2799  * send the malicious contents on the session. Engine should drop the
2800  * packet with the bad checksum.
2801  *
2802  * \retval On success it returns 1 and on failure 0.
2803  */
2804 static int StreamTcpTest30(void)
2805 {
2806  Packet p;
2807  Flow f;
2808  ThreadVars tv;
2809  StreamTcpThread stt;
2810  TCPHdr tcph;
2811  TcpSession ssn;
2812  IPV4Hdr ipv4h;
2813  struct in_addr addr;
2814  struct in_addr addr1;
2815  TCPCache tcpc;
2816  TCPVars tcpvars;
2817  TcpStream server;
2818  TcpStream client;
2819 
2820  memset (&p, 0, SIZE_OF_PACKET);
2821  memset (&f, 0, sizeof(Flow));
2822  memset(&tv, 0, sizeof (ThreadVars));
2823  memset(&stt, 0, sizeof (StreamTcpThread));
2824  memset(&tcph, 0, sizeof (TCPHdr));
2825  memset (&ipv4h, 0, sizeof(IPV4Hdr));
2826  memset (&addr, 0, sizeof(addr));
2827  memset (&addr1, 0, sizeof(addr1));
2828  memset (&tcpc, 0, sizeof(tcpc));
2829  memset (&tcpvars, 0, sizeof(tcpvars));
2830  memset(&ssn, 0, sizeof (TcpSession));
2831  memset(&server, 0, sizeof (TcpStream));
2832  memset(&client, 0, sizeof (TcpStream));
2833  uint8_t payload[9] = "AAAAAAAAA";
2834  uint8_t payload1[9] = "GET /EVIL";
2835  uint8_t expected_content[9] = { 0x47, 0x45, 0x54, 0x20, 0x2f, 0x45, 0x56,
2836  0x49, 0x4c };
2837  int result = 1;
2838 
2839  FLOW_INITIALIZE(&f);
2840  StreamTcpInitConfig(true);
2841 
2842  /* prevent L7 from kicking in */
2843 
2845  p.src.family = AF_INET;
2846  p.dst.family = AF_INET;
2847  p.proto = IPPROTO_TCP;
2848  p.flow = &f;
2849  tcph.th_win = 5480;
2850  p.tcph = &tcph;
2851  p.payload = payload;
2852  p.ip4h = &ipv4h;
2853  p.tcpc = tcpc;
2854  p.tcpc.level4_comp_csum = -1;
2855  p.tcpvars = tcpvars;
2856  ssn.state = TCP_ESTABLISHED;
2857  addr.s_addr = inet_addr("10.1.3.53");
2858  p.dst.address.address_un_data32[0] = addr.s_addr;
2859  addr1.s_addr = inet_addr("10.1.3.7");
2860  p.src.address.address_un_data32[0] = addr1.s_addr;
2861  f.protoctx = &ssn;
2862  stt.ra_ctx = ra_ctx;
2863  ssn.server = server;
2864  ssn.client = client;
2865  ssn.client.isn = 10;
2866  ssn.client.window = 5184;
2867  ssn.client.last_ack = 10;
2868  ssn.client.ra_base_seq = 10;
2869  ssn.client.next_win = 5184;
2870  ssn.server.isn = 1351079940;
2871  ssn.server.window = 5184;
2872  ssn.server.next_win = 1351088132;
2873  ssn.server.last_ack = 1351079940;
2874  ssn.server.ra_base_seq = 1351079940;
2875 
2876  tcph.th_flags = TH_PUSH | TH_ACK;
2878  p.tcph->th_seq = htonl(11);
2879  p.tcph->th_ack = htonl(1351079940);
2880  p.payload_len = 9;
2881  p.ip4h->ip_src = addr1;
2882  p.tcph->th_sum = 12345;
2883 
2884  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2885  printf("failed in segment reassmebling\n");
2886  result &= 0;
2887  goto end;
2888  }
2889 
2890  tcph.th_flags = TH_PUSH | TH_ACK;
2892  p.tcph->th_seq = htonl(11);
2893  p.tcph->th_ack = htonl(1351079940);
2894  p.payload = payload1;
2895  p.payload_len = 9;
2896  p.ip4h->ip_src = addr1;
2897  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
2898  (uint16_t *)p.tcph,
2899  (p.payload_len +
2900  p.tcpvars.hlen) );
2901 
2902  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2903  printf("failed in segment reassmebling\n");
2904  result &= 0;
2905  goto end;
2906  }
2907 
2908  tcph.th_flags = TH_ACK;
2910  p.tcph->th_seq = htonl(1351079940);
2911  p.tcph->th_ack = htonl(20);
2912  p.payload_len = 0;
2913  p.ip4h->ip_src = addr;
2914  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
2915  (uint16_t *)p.tcph,
2916  (p.payload_len +
2917  p.tcpvars.hlen) );
2918 
2919  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
2920  printf("failed in segment reassmebling\n");
2921  result &= 0;
2922  goto end;
2923  }
2924 
2925  if (StreamTcpCheckStreamContents(expected_content, 9, &ssn.client) != 1) {
2926  printf("the contents are not as expected(GET /EVIL), contents are: ");
2927  PrintRawDataFp(stdout, ssn.client.seg_list->payload, 9);
2928  result &= 0;
2929  goto end;
2930  }
2931 
2932 end:
2934  StreamTcpFreeConfig(true);
2935  return result;
2936 }
2937 
2938 /**
2939  * \test Test the multiple SYN packet handling with bad checksum and timestamp
2940  * value. Engine should drop the bad checksum packet and establish
2941  * TCP session correctly.
2942  *
2943  * \retval On success it returns 1 and on failure 0.
2944  */
2945 static int StreamTcpTest31(void)
2946 {
2947  Packet p;
2948  Flow f;
2949  ThreadVars tv;
2950  StreamTcpThread stt;
2951  TCPHdr tcph;
2952  TcpSession ssn;
2953  IPV4Hdr ipv4h;
2955  struct in_addr addr;
2956  struct in_addr addr1;
2957  TCPCache tcpc;
2958  TCPVars tcpvars;
2959  TcpStream server;
2960  TcpStream client;
2961  TCPOpt tcpopt;
2962 
2963  memset (&p, 0, SIZE_OF_PACKET);
2964  memset (&f, 0, sizeof(Flow));
2965  memset(&tv, 0, sizeof (ThreadVars));
2966  memset(&stt, 0, sizeof (StreamTcpThread));
2967  memset(&tcph, 0, sizeof (TCPHdr));
2968  memset (&ipv4h, 0, sizeof(IPV4Hdr));
2969  memset (&addr, 0, sizeof(addr));
2970  memset (&addr1, 0, sizeof(addr1));
2971  memset (&tcpc, 0, sizeof(tcpc));
2972  memset (&tcpvars, 0, sizeof(tcpvars));
2973  memset(&ssn, 0, sizeof (TcpSession));
2974  memset(&server, 0, sizeof (TcpStream));
2975  memset(&client, 0, sizeof (TcpStream));
2976  memset(&tcpopt, 0, sizeof (TCPOpt));
2977  int result = 1;
2978 
2979  StreamTcpInitConfig(true);
2980 
2981  FLOW_INITIALIZE(&f);
2982  /* prevent L7 from kicking in */
2983 
2985  p.src.family = AF_INET;
2986  p.dst.family = AF_INET;
2987  p.proto = IPPROTO_TCP;
2988  p.flow = &f;
2989  tcph.th_win = 5480;
2990  p.tcph = &tcph;
2991  p.ip4h = &ipv4h;
2992  p.tcpc = tcpc;
2993  p.tcpc.level4_comp_csum = -1;
2994  p.tcpvars = tcpvars;
2995  p.tcpvars.ts = &tcpopt;
2996  addr.s_addr = inet_addr("10.1.3.53");
2997  p.dst.address.address_un_data32[0] = addr.s_addr;
2998  addr1.s_addr = inet_addr("10.1.3.7");
2999  p.src.address.address_un_data32[0] = addr1.s_addr;
3000  f.protoctx = &ssn;
3001  stt.ra_ctx = ra_ctx;
3002  ssn.server = server;
3003  ssn.client = client;
3004  ssn.client.isn = 10;
3005  ssn.client.window = 5184;
3006  ssn.client.last_ack = 10;
3007  ssn.client.ra_base_seq = 10;
3008  ssn.client.next_win = 5184;
3009  ssn.server.isn = 1351079940;
3010  ssn.server.window = 5184;
3011  ssn.server.next_win = 1351088132;
3012  ssn.server.last_ack = 1351079940;
3013  ssn.server.ra_base_seq = 1351079940;
3014 
3015  tcph.th_flags = TH_SYN;
3017  p.tcph->th_seq = htonl(10);
3018  p.payload_len = 0;
3019  p.ip4h->ip_src = addr1;
3020  p.tcpc.ts1 = 100;
3021  p.tcph->th_sum = 12345;
3022 
3023  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
3024  printf("failed in segment reassmebling\n");
3025  result &= 0;
3026  goto end;
3027  }
3028 
3029  tcph.th_flags = TH_SYN;
3031  p.tcph->th_seq = htonl(10);
3032  p.payload_len = 0;
3033  p.ip4h->ip_src = addr1;
3034  p.tcpc.ts1 = 10;
3035  p.tcpc.level4_comp_csum = -1;
3036  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
3037  (uint16_t *)p.tcph,
3038  (p.payload_len +
3039  p.tcpvars.hlen) );
3040 
3041  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
3042  printf("failed in segment reassmebling\n");
3043  result &= 0;
3044  goto end;
3045  }
3046 
3048  tcph.th_flags = TH_SYN | TH_ACK;
3050  p.tcph->th_seq = htonl(1351079940);
3051  p.tcph->th_ack = htonl(11);
3052  p.payload_len = 0;
3053  p.tcpc.ts1 = 10;
3054  p.ip4h->ip_src = addr;
3055  p.tcpc.level4_comp_csum = -1;
3056  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
3057  (uint16_t *)p.tcph,
3058  (p.payload_len +
3059  p.tcpvars.hlen) );
3060 
3061  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
3062  printf("failed in segment reassmebling\n");
3063  result &= 0;
3064  goto end;
3065  }
3066 
3067  tcph.th_flags = TH_ACK;
3069  p.tcph->th_seq = htonl(11);
3070  p.tcph->th_ack = htonl(1351079941);
3071  p.payload_len = 0;
3072  p.tcpc.ts1 = 10;
3073  p.ip4h->ip_src = addr1;
3074  p.tcpc.level4_comp_csum = -1;
3075  p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src),
3076  (uint16_t *)p.tcph,
3077  (p.payload_len +
3078  p.tcpvars.hlen) );
3079 
3080  if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) {
3081  printf("failed in segment reassmebling\n");
3082  result &= 0;
3083  goto end;
3084  }
3085 
3086  if (ssn.state != TCP_ESTABLISHED) {
3087  printf("the should have been changed to TCP_ESTABLISHED!!\n ");
3088  result &= 0;
3089  goto end;
3090  }
3091 
3092 end:
3094  StreamTcpFreeConfig(true);
3095  return result;
3096 }
3097 
3098 /**
3099  * \test Test the initialization of tcp streams with ECN & CWR flags
3100  *
3101  * \retval On success it returns 1 and on failure 0.
3102  */
3103 static int StreamTcpTest32(void)
3104 {
3105  Packet p;
3106  Flow f;
3107  ThreadVars tv;
3108  StreamTcpThread stt;
3109  uint8_t payload[4];
3110  TCPHdr tcph;
3112  int ret = 0;
3113  PacketQueueNoLock pq;
3114  memset(&pq,0,sizeof(PacketQueueNoLock));
3115 
3116  memset (&p, 0, SIZE_OF_PACKET);
3117  memset (&f, 0, sizeof(Flow));
3118  memset(&tv, 0, sizeof (ThreadVars));
3119  memset(&stt, 0, sizeof (StreamTcpThread));
3120  memset(&tcph, 0, sizeof (TCPHdr));
3121 
3122  FLOW_INITIALIZE(&f);
3123  stt.ra_ctx = ra_ctx;
3124  p.flow = &f;
3125  tcph.th_win = htons(5480);
3126  tcph.th_flags = TH_SYN | TH_CWR | TH_ECN;
3127  p.tcph = &tcph;
3129 
3130  StreamTcpInitConfig(true);
3131 
3132  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3133  goto end;
3134 
3135  p.tcph->th_ack = htonl(1);
3136  p.tcph->th_flags = TH_SYN | TH_ACK | TH_ECN;
3138 
3139  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3140  printf("failed in processing packet\n");
3141  goto end;
3142  }
3143 
3144  p.tcph->th_ack = htonl(1);
3145  p.tcph->th_seq = htonl(1);
3146  p.tcph->th_flags = TH_ACK | TH_ECN | TH_CWR;
3148 
3149  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3150  printf("failed in processing packet\n");
3151  goto end;
3152  }
3153 
3154  p.tcph->th_ack = htonl(1);
3155  p.tcph->th_seq = htonl(2);
3156  p.tcph->th_flags = TH_PUSH | TH_ACK | TH_ECN | TH_CWR;
3158 
3159  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3160  p.payload = payload;
3161  p.payload_len = 3;
3162 
3163  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3164  printf("failed in processing packet\n");
3165  goto end;
3166  }
3167 
3169  p.tcph->th_flags = TH_ACK;
3170  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3171  printf("failed in processing packet\n");
3172  goto end;
3173  }
3174 
3175  if (((TcpSession *)p.flow->protoctx)->state != TCP_ESTABLISHED) {
3176  printf("the TCP state should be TCP_ESTABLISEHD\n");
3177  goto end;
3178  }
3180 
3181  ret = 1;
3182 end:
3183  StreamTcpFreeConfig(true);
3184  return ret;
3185 }
3186 
3187 /**
3188  * \test Test the allocation of TCP session for a given packet when the same
3189  * ports have been used to start the new session after resetting the
3190  * previous session.
3191  *
3192  * \retval On success it returns 1 and on failure 0.
3193  */
3194 
3195 static int StreamTcpTest33 (void)
3196 {
3197  Packet p;
3198  Flow f;
3199  ThreadVars tv;
3200  StreamTcpThread stt;
3201  TCPHdr tcph;
3202  TcpReassemblyThreadCtx ra_ctx;
3203  PacketQueueNoLock pq;
3204  memset(&pq,0,sizeof(PacketQueueNoLock));
3205  memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx));
3206  memset (&p, 0, SIZE_OF_PACKET);
3207  memset (&f, 0, sizeof(Flow));
3208  memset(&tv, 0, sizeof (ThreadVars));
3209  memset(&stt, 0, sizeof (StreamTcpThread));
3210  memset(&tcph, 0, sizeof (TCPHdr));
3211 
3212  FLOW_INITIALIZE(&f);
3213  p.flow = &f;
3214  tcph.th_win = htons(5480);
3215  tcph.th_flags = TH_SYN;
3216  p.tcph = &tcph;
3218  int ret = 0;
3219  stt.ra_ctx = &ra_ctx;
3220 
3221  StreamTcpInitConfig(true);
3222 
3223  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3224  goto end;
3225 
3226  p.tcph->th_ack = htonl(1);
3227  p.tcph->th_flags = TH_SYN | TH_ACK;
3229 
3230  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3231  goto end;
3232 
3233  p.tcph->th_ack = htonl(1);
3234  p.tcph->th_seq = htonl(1);
3235  p.tcph->th_flags = TH_ACK;
3237 
3238  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3239  goto end;
3240 
3241  p.tcph->th_ack = htonl(1);
3242  p.tcph->th_seq = htonl(1);
3243  p.tcph->th_flags = TH_RST | TH_ACK;
3245 
3246  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3247  goto end;
3248 
3249  if (((TcpSession *)(p.flow->protoctx))->state != TCP_CLOSED) {
3250  printf("Tcp session should have been closed\n");
3251  goto end;
3252  }
3253 
3254  p.tcph->th_seq = htonl(1);
3255  p.tcph->th_flags = TH_SYN;
3257 
3258  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3259  goto end;
3260 
3261  p.tcph->th_seq = htonl(1);
3262  p.tcph->th_ack = htonl(2);
3263  p.tcph->th_flags = TH_SYN | TH_ACK;
3265 
3266  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3267  goto end;
3268 
3269  p.tcph->th_ack = htonl(2);
3270  p.tcph->th_seq = htonl(2);
3271  p.tcph->th_flags = TH_ACK;
3273 
3274  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3275  goto end;
3276 
3277  if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) {
3278  printf("Tcp session should have been ESTABLISHED\n");
3279  goto end;
3280  }
3281 
3282  ret = 1;
3283 end:
3285  StreamTcpFreeConfig(true);
3286  return ret;
3287 }
3288 
3289 /**
3290  * \test Test the allocation of TCP session for a given packet when the SYN
3291  * packet is sent with the PUSH flag set.
3292  *
3293  * \retval On success it returns 1 and on failure 0.
3294  */
3295 
3296 static int StreamTcpTest34 (void)
3297 {
3298  Packet p;
3299  Flow f;
3300  ThreadVars tv;
3301  StreamTcpThread stt;
3302  TCPHdr tcph;
3303  TcpReassemblyThreadCtx ra_ctx;
3304  PacketQueueNoLock pq;
3305  memset(&pq,0,sizeof(PacketQueueNoLock));
3306  memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx));
3307  memset (&p, 0, SIZE_OF_PACKET);
3308  memset (&f, 0, sizeof(Flow));
3309  memset(&tv, 0, sizeof (ThreadVars));
3310  memset(&stt, 0, sizeof (StreamTcpThread));
3311  memset(&tcph, 0, sizeof (TCPHdr));
3312 
3313  FLOW_INITIALIZE(&f);
3314  p.flow = &f;
3315  tcph.th_win = htons(5480);
3316  tcph.th_flags = TH_SYN|TH_PUSH;
3317  p.tcph = &tcph;
3319  int ret = 0;
3320  stt.ra_ctx = &ra_ctx;
3321 
3322  StreamTcpInitConfig(true);
3323 
3324  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3325  goto end;
3326 
3327  p.tcph->th_ack = htonl(1);
3328  p.tcph->th_flags = TH_SYN | TH_ACK;
3330 
3331  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3332  goto end;
3333 
3334  p.tcph->th_ack = htonl(1);
3335  p.tcph->th_seq = htonl(1);
3336  p.tcph->th_flags = TH_ACK;
3338 
3339  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3340  goto end;
3341 
3342  if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) {
3343  printf("Tcp session should have been establisehd\n");
3344  goto end;
3345  }
3346 
3347  ret = 1;
3348 end:
3350  StreamTcpFreeConfig(true);
3351  return ret;
3352 }
3353 
3354 /**
3355  * \test Test the allocation of TCP session for a given packet when the SYN
3356  * packet is sent with the URG flag set.
3357  *
3358  * \retval On success it returns 1 and on failure 0.
3359  */
3360 
3361 static int StreamTcpTest35 (void)
3362 {
3363  Packet p;
3364  Flow f;
3365  ThreadVars tv;
3366  StreamTcpThread stt;
3367  TCPHdr tcph;
3368  TcpReassemblyThreadCtx ra_ctx;
3369  PacketQueueNoLock pq;
3370  memset(&pq,0,sizeof(PacketQueueNoLock));
3371  memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx));
3372  memset (&p, 0, SIZE_OF_PACKET);
3373  memset (&f, 0, sizeof(Flow));
3374  memset(&tv, 0, sizeof (ThreadVars));
3375  memset(&stt, 0, sizeof (StreamTcpThread));
3376  memset(&tcph, 0, sizeof (TCPHdr));
3377 
3378  FLOW_INITIALIZE(&f);
3379  p.flow = &f;
3380  tcph.th_win = htons(5480);
3381  tcph.th_flags = TH_SYN|TH_URG;
3382  p.tcph = &tcph;
3384  int ret = 0;
3385  stt.ra_ctx = &ra_ctx;
3386 
3387  StreamTcpInitConfig(true);
3388 
3389  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3390  goto end;
3391 
3392  p.tcph->th_ack = htonl(1);
3393  p.tcph->th_flags = TH_SYN | TH_ACK;
3395 
3396  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3397  goto end;
3398 
3399  p.tcph->th_ack = htonl(1);
3400  p.tcph->th_seq = htonl(1);
3401  p.tcph->th_flags = TH_ACK;
3403 
3404  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1)
3405  goto end;
3406 
3407  if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) {
3408  printf("Tcp session should have been establisehd\n");
3409  goto end;
3410  }
3411 
3412  ret = 1;
3413 end:
3415  StreamTcpFreeConfig(true);
3416  return ret;
3417 }
3418 
3419 /**
3420  * \test Test the processing of PSH and URG flag in tcp session.
3421  *
3422  * \retval On success it returns 1 and on failure 0.
3423  */
3424 static int StreamTcpTest36(void)
3425 {
3426  Packet p;
3427  Flow f;
3428  ThreadVars tv;
3429  StreamTcpThread stt;
3430  uint8_t payload[4];
3431  TCPHdr tcph;
3433  int ret = 0;
3434  PacketQueueNoLock pq;
3435  memset(&pq,0,sizeof(PacketQueueNoLock));
3436 
3437  memset (&p, 0, SIZE_OF_PACKET);
3438  memset (&f, 0, sizeof(Flow));
3439  memset(&tv, 0, sizeof (ThreadVars));
3440  memset(&stt, 0, sizeof (StreamTcpThread));
3441  memset(&tcph, 0, sizeof (TCPHdr));
3442 
3443  FLOW_INITIALIZE(&f);
3444  stt.ra_ctx = ra_ctx;
3445  p.flow = &f;
3446  tcph.th_win = htons(5480);
3447  tcph.th_flags = TH_SYN;
3448  p.tcph = &tcph;
3450 
3451  StreamTcpInitConfig(true);
3452 
3453  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) {
3454  printf("failed in processing packet\n");
3455  goto end;
3456  }
3457 
3458  p.tcph->th_ack = htonl(1);
3459  p.tcph->th_flags = TH_SYN | TH_ACK;
3461 
3462  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3463  printf("failed in processing packet\n");
3464  goto end;
3465  }
3466 
3467  p.tcph->th_ack = htonl(1);
3468  p.tcph->th_seq = htonl(1);
3469  p.tcph->th_flags = TH_ACK;
3471 
3472  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3473  printf("failed in processing packet\n");
3474  goto end;
3475  }
3476 
3477  if (((TcpSession *)p.flow->protoctx)->state != TCP_ESTABLISHED) {
3478  printf("the TCP state should be TCP_ESTABLISEHD\n");
3479  goto end;
3480  }
3481 
3482  p.tcph->th_ack = htonl(2);
3483  p.tcph->th_seq = htonl(1);
3484  p.tcph->th_flags = TH_PUSH | TH_ACK | TH_URG;
3486 
3487  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3488  p.payload = payload;
3489  p.payload_len = 3;
3490 
3491  if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) {
3492  printf("failed in processing packet\n");
3493  goto end;
3494  }
3495 
3496  if (((TcpSession *)p.flow->protoctx)->client.next_seq != 4) {
3497  printf("the ssn->client.next_seq should be 4, but it is %"PRIu32"\n",
3498  ((TcpSession *)p.flow->protoctx)->client.next_seq);
3499  goto end;
3500  }
3501 
3503 
3504  ret = 1;
3505 end:
3506  StreamTcpFreeConfig(true);
3507  return ret;
3508 }
3509 #endif
3510 
3511 /**
3512  * \test Test the processing of out of order FIN packets in tcp session.
3513  *
3514  * \retval On success it returns 1 and on failure 0.
3515  */
3516 static int StreamTcpTest37(void)
3517 {
3518  Packet *p = PacketGetFromAlloc();
3519  FAIL_IF_NULL(p);
3520  Flow f;
3521  ThreadVars tv;
3522  StreamTcpThread stt;
3523  uint8_t payload[4];
3524  TCPHdr tcph;
3525  int ret = 0;
3526  PacketQueueNoLock pq;
3527  memset(&pq, 0, sizeof(PacketQueueNoLock));
3528 
3529  memset(&f, 0, sizeof(Flow));
3530  memset(&tv, 0, sizeof(ThreadVars));
3531  memset(&stt, 0, sizeof(StreamTcpThread));
3532  memset(&tcph, 0, sizeof(TCPHdr));
3533 
3534  FLOW_INITIALIZE(&f);
3535 
3536  p->flow = &f;
3537  tcph.th_win = htons(5480);
3538  tcph.th_flags = TH_SYN;
3539  p->tcph = &tcph;
3541 
3542  StreamTcpUTInit(&stt.ra_ctx);
3543 
3544  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3545  printf("failed in processing packet\n");
3546  goto end;
3547  }
3548 
3549  p->tcph->th_ack = htonl(1);
3550  p->tcph->th_flags = TH_SYN | TH_ACK;
3552 
3553  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
3554  printf("failed in processing packet\n");
3555  goto end;
3556  }
3557 
3558  p->tcph->th_ack = htonl(1);
3559  p->tcph->th_seq = htonl(1);
3560  p->tcph->th_flags = TH_ACK;
3562 
3563  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
3564  printf("failed in processing packet\n");
3565  goto end;
3566  }
3567 
3568  if (((TcpSession *)p->flow->protoctx)->state != TCP_ESTABLISHED) {
3569  printf("the TCP state should be TCP_ESTABLISEHD\n");
3570  goto end;
3571  }
3572 
3573  p->tcph->th_ack = htonl(2);
3574  p->tcph->th_seq = htonl(4);
3575  p->tcph->th_flags = TH_ACK | TH_FIN;
3577 
3578  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
3579  printf("failed in processing packet\n");
3580  goto end;
3581  }
3582 
3583  if (((TcpSession *)p->flow->protoctx)->state != TCP_CLOSE_WAIT) {
3584  printf("the TCP state should be TCP_CLOSE_WAIT\n");
3585  goto end;
3586  }
3587 
3588  p->tcph->th_ack = htonl(1);
3589  p->tcph->th_seq = htonl(1);
3590  p->tcph->th_flags = TH_PUSH | TH_ACK;
3592 
3593  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3594  p->payload = payload;
3595  p->payload_len = 3;
3596 
3597  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
3598  printf("failed in processing packet\n");
3599  goto end;
3600  }
3601 
3602  p->tcph->th_ack = htonl(4);
3603  p->tcph->th_seq = htonl(2);
3604  p->tcph->th_flags = TH_ACK;
3605  p->payload_len = 0;
3607 
3608  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) {
3609  printf("failed in processing packet\n");
3610  goto end;
3611  }
3612 
3613  TcpStream *stream = &(((TcpSession *)p->flow->protoctx)->client);
3614  FAIL_IF(STREAM_RAW_PROGRESS(stream) != 0); // no detect no progress update
3615 
3617 
3618  ret = 1;
3619 end:
3620  SCFree(p);
3621  FLOW_DESTROY(&f);
3623  return ret;
3624 }
3625 
3626 /**
3627  * \test Test the validation of the ACK number before setting up the
3628  * stream.last_ack.
3629  *
3630  * \retval On success it returns 1 and on failure 0.
3631  */
3632 
3633 static int StreamTcpTest38(void)
3634 {
3635  int ret = 0;
3636  Flow f;
3637  ThreadVars tv;
3638  StreamTcpThread stt;
3639  uint8_t payload[128];
3640  TCPHdr tcph;
3641  PacketQueueNoLock pq;
3642 
3643  memset(&f, 0, sizeof(Flow));
3644  memset(&tv, 0, sizeof(ThreadVars));
3645  memset(&stt, 0, sizeof(StreamTcpThread));
3646  memset(&tcph, 0, sizeof(TCPHdr));
3647  memset(&pq, 0, sizeof(PacketQueueNoLock));
3648 
3649  Packet *p = PacketGetFromAlloc();
3650  FAIL_IF_NULL(p);
3651 
3652  FLOW_INITIALIZE(&f);
3653  p->flow = &f;
3654  tcph.th_win = htons(5480);
3655  tcph.th_flags = TH_SYN;
3656  p->tcph = &tcph;
3658 
3659  StreamTcpUTInit(&stt.ra_ctx);
3660  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3661  printf("failed in processing packet in StreamTcpPacket\n");
3662  goto end;
3663  }
3664 
3665  p->tcph->th_ack = htonl(1);
3666  p->tcph->th_flags = TH_SYN | TH_ACK;
3668 
3669  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3670  printf("failed in processing packet in StreamTcpPacket\n");
3671  goto end;
3672  }
3673 
3674  p->tcph->th_ack = htonl(1);
3675  p->tcph->th_seq = htonl(1);
3676  p->tcph->th_flags = TH_ACK;
3678 
3679  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3680  printf("failed in processing packet in StreamTcpPacket\n");
3681  goto end;
3682  }
3683 
3684  p->tcph->th_ack = htonl(29847);
3685  p->tcph->th_seq = htonl(2);
3686  p->tcph->th_flags = TH_PUSH | TH_ACK;
3688 
3689  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3690  p->payload = payload;
3691  p->payload_len = 3;
3692 
3693  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3694  printf("failed in processing packet in StreamTcpPacket\n");
3695  goto end;
3696  }
3697 
3698  /* last_ack value should be 1 as the previous sent ACK value is out of
3699  window */
3700  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 1) {
3701  printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
3702  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3703  goto end;
3704  }
3705 
3706  p->tcph->th_ack = htonl(1);
3707  p->tcph->th_seq = htonl(1);
3708  p->tcph->th_flags = TH_PUSH | TH_ACK;
3710 
3711  StreamTcpCreateTestPacket(payload, 0x41, 127, 128); /*AAA*/
3712  p->payload = payload;
3713  p->payload_len = 127;
3714 
3715  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3716  printf("failed in processing packet in StreamTcpPacket\n");
3717  goto end;
3718  }
3719 
3720  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 128) {
3721  printf("the server.next_seq should be 128, but it is %" PRIu32 "\n",
3722  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
3723  goto end;
3724  }
3725 
3726  p->tcph->th_ack = htonl(256); // in window, but beyond next_seq
3727  p->tcph->th_seq = htonl(5);
3728  p->tcph->th_flags = TH_PUSH | TH_ACK;
3730 
3731  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3732  p->payload = payload;
3733  p->payload_len = 3;
3734 
3735  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3736  printf("failed in processing packet in StreamTcpPacket\n");
3737  goto end;
3738  }
3739 
3740  /* last_ack value should be 256, as the previous sent ACK value
3741  is inside window */
3742  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
3743  printf("the server.last_ack should be 1, but it is %" PRIu32 "\n",
3744  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3745  goto end;
3746  }
3747 
3748  p->tcph->th_ack = htonl(128);
3749  p->tcph->th_seq = htonl(8);
3750  p->tcph->th_flags = TH_PUSH | TH_ACK;
3752 
3753  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3754  p->payload = payload;
3755  p->payload_len = 3;
3756 
3757  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3758  printf("failed in processing packet in StreamTcpPacket\n");
3759  goto end;
3760  }
3761 
3762  /* last_ack value should be 256 as the previous sent ACK value is inside
3763  window */
3764  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) {
3765  printf("the server.last_ack should be 256, but it is %" PRIu32 "\n",
3766  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3767  goto end;
3768  }
3769 
3770  ret = 1;
3771 
3772 end:
3774  SCFree(p);
3775  FLOW_DESTROY(&f);
3777  return ret;
3778 }
3779 
3780 /**
3781  * \test Test the validation of the ACK number before setting up the
3782  * stream.last_ack and update the next_seq after loosing the .
3783  *
3784  * \retval On success it returns 1 and on failure 0.
3785  */
3786 
3787 static int StreamTcpTest39(void)
3788 {
3789  Flow f;
3790  ThreadVars tv;
3791  StreamTcpThread stt;
3792  uint8_t payload[4];
3793  TCPHdr tcph;
3794  PacketQueueNoLock pq;
3795 
3796  memset(&f, 0, sizeof(Flow));
3797  memset(&tv, 0, sizeof(ThreadVars));
3798  memset(&stt, 0, sizeof(StreamTcpThread));
3799  memset(&tcph, 0, sizeof(TCPHdr));
3800  memset(&pq, 0, sizeof(PacketQueueNoLock));
3801 
3802  Packet *p = PacketGetFromAlloc();
3803  FAIL_IF_NULL(p);
3804 
3805  FLOW_INITIALIZE(&f);
3806  p->flow = &f;
3807  tcph.th_win = htons(5480);
3808  tcph.th_flags = TH_SYN;
3809  p->tcph = &tcph;
3811  int ret = 0;
3812 
3813  StreamTcpUTInit(&stt.ra_ctx);
3814 
3815  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3816  printf("failed in processing packet in StreamTcpPacket\n");
3817  goto end;
3818  }
3819 
3820  p->tcph->th_ack = htonl(1);
3821  p->tcph->th_flags = TH_SYN | TH_ACK;
3823 
3824  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3825  printf("failed in processing packet in StreamTcpPacket\n");
3826  goto end;
3827  }
3828 
3829  p->tcph->th_ack = htonl(1);
3830  p->tcph->th_seq = htonl(1);
3831  p->tcph->th_flags = TH_ACK;
3833 
3834  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3835  printf("failed in processing packet in StreamTcpPacket\n");
3836  goto end;
3837  }
3838 
3839  p->tcph->th_ack = htonl(1);
3840  p->tcph->th_seq = htonl(1);
3841  p->tcph->th_flags = TH_PUSH | TH_ACK;
3843 
3844  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3845  p->payload = payload;
3846  p->payload_len = 3;
3847 
3848  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3849  printf("failed in processing packet in StreamTcpPacket\n");
3850  goto end;
3851  }
3852 
3853  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 4) {
3854  printf("the server.next_seq should be 4, but it is %" PRIu32 "\n",
3855  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
3856  goto end;
3857  }
3858 
3859  p->tcph->th_ack = htonl(4);
3860  p->tcph->th_seq = htonl(2);
3861  p->tcph->th_flags = TH_PUSH | TH_ACK;
3863 
3864  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3865  p->payload = payload;
3866  p->payload_len = 3;
3867 
3868  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3869  printf("failed in processing packet in StreamTcpPacket\n");
3870  goto end;
3871  }
3872 
3873  /* last_ack value should be 4 as the previous sent ACK value is inside
3874  window */
3875  if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 4) {
3876  printf("the server.last_ack should be 4, but it is %" PRIu32 "\n",
3877  ((TcpSession *)(p->flow->protoctx))->server.last_ack);
3878  goto end;
3879  }
3880 
3881  p->tcph->th_seq = htonl(4);
3882  p->tcph->th_ack = htonl(5);
3883  p->tcph->th_flags = TH_PUSH | TH_ACK;
3885 
3886  StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/
3887  p->payload = payload;
3888  p->payload_len = 3;
3889 
3890  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) {
3891  printf("failed in processing packet in StreamTcpPacket\n");
3892  goto end;
3893  }
3894 
3895  /* next_seq value should be 2987 as the previous sent ACK value is inside
3896  window */
3897  if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 7) {
3898  printf("the server.next_seq should be 7, but it is %" PRIu32 "\n",
3899  ((TcpSession *)(p->flow->protoctx))->server.next_seq);
3900  goto end;
3901  }
3902 
3903  ret = 1;
3904 
3905 end:
3907  SCFree(p);
3908  FLOW_DESTROY(&f);
3910  return ret;
3911 }
3912 
3913 /** \test multiple different SYN/ACK, pick first */
3914 static int StreamTcpTest42(void)
3915 {
3916  int ret = 0;
3917  Flow f;
3918  ThreadVars tv;
3919  StreamTcpThread stt;
3920  TCPHdr tcph;
3921  PacketQueueNoLock pq;
3922  Packet *p = PacketGetFromAlloc();
3923  FAIL_IF_NULL(p);
3924  TcpSession *ssn;
3925 
3926  memset(&pq, 0, sizeof(PacketQueueNoLock));
3927  memset(&f, 0, sizeof(Flow));
3928  memset(&tv, 0, sizeof(ThreadVars));
3929  memset(&stt, 0, sizeof(StreamTcpThread));
3930  memset(&tcph, 0, sizeof(TCPHdr));
3931 
3932  StreamTcpUTInit(&stt.ra_ctx);
3933 
3934  FLOW_INITIALIZE(&f);
3935  p->tcph = &tcph;
3936  tcph.th_win = htons(5480);
3937  p->flow = &f;
3938 
3939  /* SYN pkt */
3940  tcph.th_flags = TH_SYN;
3941  tcph.th_seq = htonl(100);
3943 
3944  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3945  goto end;
3946 
3947  /* SYN/ACK */
3948  p->tcph->th_seq = htonl(500);
3949  p->tcph->th_ack = htonl(101);
3950  p->tcph->th_flags = TH_SYN | TH_ACK;
3952 
3953  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3954  goto end;
3955 
3956  /* SYN/ACK */
3957  p->tcph->th_seq = htonl(1000);
3958  p->tcph->th_ack = htonl(101);
3959  p->tcph->th_flags = TH_SYN | TH_ACK;
3961 
3962  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3963  goto end;
3964 
3965  /* ACK */
3966  p->tcph->th_ack = htonl(501);
3967  p->tcph->th_seq = htonl(101);
3968  p->tcph->th_flags = TH_ACK;
3970 
3971  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
3972  goto end;
3973 
3974  ssn = p->flow->protoctx;
3975 
3976  if (ssn->state != TCP_ESTABLISHED) {
3977  printf("state not TCP_ESTABLISHED: ");
3978  goto end;
3979  }
3980 
3981  if (ssn->server.isn != 500) {
3982  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 500);
3983  goto end;
3984  }
3985  if (ssn->client.isn != 100) {
3986  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
3987  goto end;
3988  }
3989 
3991 
3992  ret = 1;
3993 end:
3994  SCFree(p);
3995  FLOW_DESTROY(&f);
3997  return ret;
3998 }
3999 
4000 /** \test multiple different SYN/ACK, pick second */
4001 static int StreamTcpTest43(void)
4002 {
4003  int ret = 0;
4004  Flow f;
4005  ThreadVars tv;
4006  StreamTcpThread stt;
4007  TCPHdr tcph;
4008  PacketQueueNoLock pq;
4009  Packet *p = PacketGetFromAlloc();
4010  FAIL_IF_NULL(p);
4011  TcpSession *ssn;
4012 
4013  memset(&pq, 0, sizeof(PacketQueueNoLock));
4014  memset(&f, 0, sizeof(Flow));
4015  memset(&tv, 0, sizeof(ThreadVars));
4016  memset(&stt, 0, sizeof(StreamTcpThread));
4017  memset(&tcph, 0, sizeof(TCPHdr));
4018 
4019  StreamTcpUTInit(&stt.ra_ctx);
4020 
4021  FLOW_INITIALIZE(&f);
4022  p->tcph = &tcph;
4023  tcph.th_win = htons(5480);
4024  p->flow = &f;
4025 
4026  /* SYN pkt */
4027  tcph.th_flags = TH_SYN;
4028  tcph.th_seq = htonl(100);
4030 
4031  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4032  goto end;
4033 
4034  /* SYN/ACK */
4035  p->tcph->th_seq = htonl(500);
4036  p->tcph->th_ack = htonl(101);
4037  p->tcph->th_flags = TH_SYN | TH_ACK;
4039 
4040  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4041  goto end;
4042 
4043  /* SYN/ACK */
4044  p->tcph->th_seq = htonl(1000);
4045  p->tcph->th_ack = htonl(101);
4046  p->tcph->th_flags = TH_SYN | TH_ACK;
4048 
4049  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4050  goto end;
4051 
4052  /* ACK */
4053  p->tcph->th_ack = htonl(1001);
4054  p->tcph->th_seq = htonl(101);
4055  p->tcph->th_flags = TH_ACK;
4057 
4058  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4059  goto end;
4060 
4061  ssn = p->flow->protoctx;
4062 
4063  if (ssn->state != TCP_ESTABLISHED) {
4064  printf("state not TCP_ESTABLISHED: ");
4065  goto end;
4066  }
4067 
4068  if (ssn->server.isn != 1000) {
4069  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
4070  goto end;
4071  }
4072  if (ssn->client.isn != 100) {
4073  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
4074  goto end;
4075  }
4076 
4078 
4079  ret = 1;
4080 end:
4081  SCFree(p);
4082  FLOW_DESTROY(&f);
4084  return ret;
4085 }
4086 
4087 /** \test multiple different SYN/ACK, pick neither */
4088 static int StreamTcpTest44(void)
4089 {
4090  int ret = 0;
4091  Flow f;
4092  ThreadVars tv;
4093  StreamTcpThread stt;
4094  TCPHdr tcph;
4095  PacketQueueNoLock pq;
4096  Packet *p = PacketGetFromAlloc();
4097  FAIL_IF_NULL(p);
4098  TcpSession *ssn;
4099 
4100  memset(&pq, 0, sizeof(PacketQueueNoLock));
4101  memset(&f, 0, sizeof(Flow));
4102  memset(&tv, 0, sizeof(ThreadVars));
4103  memset(&stt, 0, sizeof(StreamTcpThread));
4104  memset(&tcph, 0, sizeof(TCPHdr));
4105 
4106  StreamTcpUTInit(&stt.ra_ctx);
4107 
4108  FLOW_INITIALIZE(&f);
4109  p->tcph = &tcph;
4110  tcph.th_win = htons(5480);
4111  p->flow = &f;
4112 
4113  /* SYN pkt */
4114  tcph.th_flags = TH_SYN;
4115  tcph.th_seq = htonl(100);
4117 
4118  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4119  goto end;
4120 
4121  /* SYN/ACK */
4122  p->tcph->th_seq = htonl(500);
4123  p->tcph->th_ack = htonl(101);
4124  p->tcph->th_flags = TH_SYN | TH_ACK;
4126 
4127  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4128  goto end;
4129 
4130  /* SYN/ACK */
4131  p->tcph->th_seq = htonl(1000);
4132  p->tcph->th_ack = htonl(101);
4133  p->tcph->th_flags = TH_SYN | TH_ACK;
4135 
4136  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4137  goto end;
4138 
4139  /* ACK */
4140  p->tcph->th_ack = htonl(3001);
4141  p->tcph->th_seq = htonl(101);
4142  p->tcph->th_flags = TH_ACK;
4144 
4145  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
4146  goto end;
4147 
4148  ssn = p->flow->protoctx;
4149 
4150  if (ssn->state != TCP_SYN_RECV) {
4151  SCLogDebug("state not TCP_SYN_RECV");
4152  goto end;
4153  }
4154 
4155  if (ssn->client.isn != 100) {
4156  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
4157  goto end;
4158  }
4159 
4161 
4162  ret = 1;
4163 end:
4164  SCFree(p);
4165  FLOW_DESTROY(&f);
4167  return ret;
4168 }
4169 
4170 /** \test multiple different SYN/ACK, over the limit */
4171 static int StreamTcpTest45(void)
4172 {
4173  int ret = 0;
4174  Flow f;
4175  ThreadVars tv;
4176  StreamTcpThread stt;
4177  TCPHdr tcph;
4178  PacketQueueNoLock pq;
4179  Packet *p = PacketGetFromAlloc();
4180  FAIL_IF_NULL(p);
4181  TcpSession *ssn;
4182 
4183  memset(&pq, 0, sizeof(PacketQueueNoLock));
4184  memset(&f, 0, sizeof(Flow));
4185  memset(&tv, 0, sizeof(ThreadVars));
4186  memset(&stt, 0, sizeof(StreamTcpThread));
4187  memset(&tcph, 0, sizeof(TCPHdr));
4188 
4189  StreamTcpUTInit(&stt.ra_ctx);
4191 
4192  FLOW_INITIALIZE(&f);
4193  p->tcph = &tcph;
4194  tcph.th_win = htons(5480);
4195  p->flow = &f;
4196 
4197  /* SYN pkt */
4198  tcph.th_flags = TH_SYN;
4199  tcph.th_seq = htonl(100);
4201 
4202  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4203  goto end;
4204 
4205  /* SYN/ACK */
4206  p->tcph->th_seq = htonl(500);
4207  p->tcph->th_ack = htonl(101);
4208  p->tcph->th_flags = TH_SYN | TH_ACK;
4210 
4211  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4212  goto end;
4213 
4214  /* SYN/ACK */
4215  p->tcph->th_seq = htonl(1000);
4216  p->tcph->th_ack = htonl(101);
4217  p->tcph->th_flags = TH_SYN | TH_ACK;
4219 
4220  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4221  goto end;
4222 
4223  /* SYN/ACK */
4224  p->tcph->th_seq = htonl(2000);
4225  p->tcph->th_ack = htonl(101);
4226  p->tcph->th_flags = TH_SYN | TH_ACK;
4228 
4229  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4230  goto end;
4231 
4232  /* SYN/ACK */
4233  p->tcph->th_seq = htonl(3000);
4234  p->tcph->th_ack = htonl(101);
4235  p->tcph->th_flags = TH_SYN | TH_ACK;
4237 
4238  if (StreamTcpPacket(&tv, p, &stt, &pq) != -1)
4239  goto end;
4240 
4241  /* ACK */
4242  p->tcph->th_ack = htonl(1001);
4243  p->tcph->th_seq = htonl(101);
4244  p->tcph->th_flags = TH_ACK;
4246 
4247  if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
4248  goto end;
4249 
4250  ssn = p->flow->protoctx;
4251 
4252  if (ssn->state != TCP_ESTABLISHED) {
4253  printf("state not TCP_ESTABLISHED: ");
4254  goto end;
4255  }
4256 
4257  if (ssn->server.isn != 1000) {
4258  SCLogDebug("ssn->server.isn %" PRIu32 " != %" PRIu32 "", ssn->server.isn, 1000);
4259  goto end;
4260  }
4261  if (ssn->client.isn != 100) {
4262  SCLogDebug("ssn->client.isn %" PRIu32 " != %" PRIu32 "", ssn->client.isn, 100);
4263  goto end;
4264  }
4265 
4267 
4268  ret = 1;
4269 end:
4270  SCFree(p);
4272  return ret;
4273 }
4274 
4276 {
4277  UtRegisterTest("StreamTcpTest01 -- TCP session allocation", StreamTcpTest01);
4278  UtRegisterTest("StreamTcpTest02 -- TCP session deallocation", StreamTcpTest02);
4279  UtRegisterTest("StreamTcpTest03 -- SYN missed MidStream session", StreamTcpTest03);
4280  UtRegisterTest("StreamTcpTest04 -- SYN/ACK missed MidStream session", StreamTcpTest04);
4281  UtRegisterTest("StreamTcpTest05 -- 3WHS missed MidStream session", StreamTcpTest05);
4282  UtRegisterTest("StreamTcpTest06 -- FIN, RST message MidStream session", StreamTcpTest06);
4283  UtRegisterTest("StreamTcpTest07 -- PAWS invalid timestamp", StreamTcpTest07);
4284  UtRegisterTest("StreamTcpTest08 -- PAWS valid timestamp", StreamTcpTest08);
4285  UtRegisterTest("StreamTcpTest09 -- No Client Reassembly", StreamTcpTest09);
4286  UtRegisterTest("StreamTcpTest10 -- No missed packet Async stream", StreamTcpTest10);
4287  UtRegisterTest("StreamTcpTest11 -- SYN missed Async stream", StreamTcpTest11);
4288  UtRegisterTest("StreamTcpTest12 -- SYN/ACK missed Async stream", StreamTcpTest12);
4289  UtRegisterTest("StreamTcpTest13 -- opposite stream packets for Async "
4290  "stream",
4291  StreamTcpTest13);
4292  UtRegisterTest("StreamTcp4WHSTest01", StreamTcp4WHSTest01);
4293  UtRegisterTest("StreamTcp4WHSTest02", StreamTcp4WHSTest02);
4294  UtRegisterTest("StreamTcp4WHSTest03", StreamTcp4WHSTest03);
4295  UtRegisterTest("StreamTcpTest14 -- setup OS policy", StreamTcpTest14);
4296  UtRegisterTest("StreamTcpTest15 -- setup OS policy", StreamTcpTest15);
4297  UtRegisterTest("StreamTcpTest16 -- setup OS policy", StreamTcpTest16);
4298  UtRegisterTest("StreamTcpTest17 -- setup OS policy", StreamTcpTest17);
4299  UtRegisterTest("StreamTcpTest18 -- setup OS policy", StreamTcpTest18);
4300  UtRegisterTest("StreamTcpTest19 -- setup OS policy", StreamTcpTest19);
4301  UtRegisterTest("StreamTcpTest20 -- setup OS policy", StreamTcpTest20);
4302  UtRegisterTest("StreamTcpTest21 -- setup OS policy", StreamTcpTest21);
4303  UtRegisterTest("StreamTcpTest22 -- setup OS policy", StreamTcpTest22);
4304  UtRegisterTest("StreamTcpTest23 -- stream memory leaks", StreamTcpTest23);
4305  UtRegisterTest("StreamTcpTest24 -- stream memory leaks", StreamTcpTest24);
4306  UtRegisterTest("StreamTcpTest25 -- test ecn/cwr sessions", StreamTcpTest25);
4307  UtRegisterTest("StreamTcpTest26 -- test ecn/cwr sessions", StreamTcpTest26);
4308  UtRegisterTest("StreamTcpTest27 -- test ecn/cwr sessions", StreamTcpTest27);
4309  UtRegisterTest("StreamTcpTest28 -- Memcap Test", StreamTcpTest28);
4310 
4311 #if 0 /* VJ 2010/09/01 disabled since they blow up on Fedora and Fedora is \
4312  * right about blowing up. The checksum functions are not used properly \
4313  * in the tests. */
4314  UtRegisterTest("StreamTcpTest29 -- Badchecksum Reset Test", StreamTcpTest29, 1);
4315  UtRegisterTest("StreamTcpTest30 -- Badchecksum Overlap Test", StreamTcpTest30, 1);
4316  UtRegisterTest("StreamTcpTest31 -- MultipleSyns Test", StreamTcpTest31, 1);
4317  UtRegisterTest("StreamTcpTest32 -- Bogus CWR Test", StreamTcpTest32, 1);
4318  UtRegisterTest("StreamTcpTest33 -- RST-SYN Again Test", StreamTcpTest33, 1);
4319  UtRegisterTest("StreamTcpTest34 -- SYN-PUSH Test", StreamTcpTest34, 1);
4320  UtRegisterTest("StreamTcpTest35 -- SYN-URG Test", StreamTcpTest35, 1);
4321  UtRegisterTest("StreamTcpTest36 -- PUSH-URG Test", StreamTcpTest36, 1);
4322 #endif
4323  UtRegisterTest("StreamTcpTest37 -- Out of order FIN Test", StreamTcpTest37);
4324 
4325  UtRegisterTest("StreamTcpTest38 -- validate ACK", StreamTcpTest38);
4326  UtRegisterTest("StreamTcpTest39 -- update next_seq", StreamTcpTest39);
4327 
4328  UtRegisterTest("StreamTcpTest42 -- SYN/ACK queue", StreamTcpTest42);
4329  UtRegisterTest("StreamTcpTest43 -- SYN/ACK queue", StreamTcpTest43);
4330  UtRegisterTest("StreamTcpTest44 -- SYN/ACK queue", StreamTcpTest44);
4331  UtRegisterTest("StreamTcpTest45 -- SYN/ACK queue", StreamTcpTest45);
4332 
4333  /* set up the reassembly tests as well */
4335 
4337 }
StreamTcpIncrMemuse
void StreamTcpIncrMemuse(uint64_t size)
Definition: stream-tcp.c:128
TCP_SYN_RECV
@ TCP_SYN_RECV
Definition: stream-tcp-private.h:142
Packet_::proto
uint8_t proto
Definition: decode.h:436
TcpStream_
Definition: stream-tcp-private.h:94
TCPOpt_
Definition: decode-tcp.h:130
StreamTcpSessionPktFree
void StreamTcpSessionPktFree(Packet *p)
Function to return the stream segments back to the pool.
Definition: stream-tcp.c:283
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:101
TCPVars_::ts_set
bool ts_set
Definition: decode-tcp.h:159
SCReturnCharPtr
#define SCReturnCharPtr(x)
Definition: util-debug.h:312
TCP_SEG_LEN
#define TCP_SEG_LEN(seg)
Definition: stream-tcp-private.h:82
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
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:123
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
TCPVars_
Definition: decode-tcp.h:155
StreamTcpThread_
Definition: stream-tcp.h:70
StreamTcpSetSessionNoReassemblyFlag
void StreamTcpSetSessionNoReassemblyFlag(TcpSession *ssn, char direction)
disable reassembly
Definition: stream-tcp.c:5994
Packet_::payload
uint8_t * payload
Definition: decode.h:551
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:768
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
TcpStream_::os_policy
uint8_t os_policy
Definition: stream-tcp-private.h:98
Flow_
Flow data structure.
Definition: flow.h:353
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
StreamTcpSackRegisterTests
void StreamTcpSackRegisterTests(void)
Definition: stream-tcp-sack.c:885
TcpStreamCnf_::async_oneside
int async_oneside
Definition: stream-tcp.h:59
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
RB_MIN
#define RB_MIN(name, x)
Definition: tree.h:778
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:143
Address_::address_un_data32
uint32_t address_un_data32[4]
Definition: decode.h:122
Packet_::tcpvars
TCPVars tcpvars
Definition: decode.h:523
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
Flow_::protoctx
void * protoctx
Definition: flow.h:451
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:552
PacketQueueNoLock_
simple fifo queue for packets
Definition: packet-queue.h:32
TcpSession_::flags
uint16_t flags
Definition: stream-tcp-private.h:269
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
IPV4Hdr_::ip_src
struct in_addr ip_src
Definition: decode-ipv4.h:82
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
TcpStream_::last_ack
uint32_t last_ack
Definition: stream-tcp-private.h:103
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:330
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:485
StreamTcpReassembleInitThreadCtx
TcpReassemblyThreadCtx * StreamTcpReassembleInitThreadCtx(ThreadVars *tv)
Definition: stream-tcp-reassemble.c:434
StreamTcpUTInit
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
Definition: stream-tcp-util.c:44
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
TCP_CLOSE_WAIT
@ TCP_CLOSE_WAIT
Definition: stream-tcp-private.h:148
TCPVars_::ts_ecr
uint32_t ts_ecr
Definition: decode-tcp.h:161
Packet_::level4_comp_csum
int32_t level4_comp_csum
Definition: decode.h:507
StreamTcpCheckMemcap
int StreamTcpCheckMemcap(uint64_t size)
Check if alloc'ing "size" would mean we're over memcap.
Definition: stream-tcp.c:168
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
STREAMTCP_FLAG_ASYNC
#define STREAMTCP_FLAG_ASYNC
Definition: stream-tcp-private.h:170
SC_ERR_UNKNOWN_VALUE
@ SC_ERR_UNKNOWN_VALUE
Definition: util-error.h:159
RB_MAX
#define RB_MAX(name, x)
Definition: tree.h:779
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
StreamTcp
TmEcode StreamTcp(ThreadVars *tv, Packet *p, void *data, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5279
OS_POLICY_LINUX
@ OS_POLICY_LINUX
Definition: stream-tcp-reassemble.h:40
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:4861
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:262
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:487
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:2014
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:634
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:141
TRUE
#define TRUE
Definition: suricata-common.h:33
StreamTcpReassembleHandleSegment
int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, PacketQueueNoLock *pq)
Definition: stream-tcp-reassemble.c:1828
TcpStream_::next_win
uint32_t next_win
Definition: stream-tcp-private.h:104
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:119
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:249
TcpStreamCnf_::max_synack_queued
uint8_t max_synack_queued
Definition: stream-tcp.h:54
TcpSegment
Definition: stream-tcp-private.h:61
Packet_
Definition: decode.h:414
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:509
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:105
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:698
Address_::address
union Address_::@31 address
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:226
OS_POLICY_BSD
@ OS_POLICY_BSD
Definition: stream-tcp-reassemble.h:37
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
SCHInfoCleanResources
void SCHInfoCleanResources(void)
Definition: util-host-os-info.c:318
IPV4Hdr_
Definition: decode-ipv4.h:71
StreamTcpUTClearSession
void StreamTcpUTClearSession(TcpSession *ssn)
Definition: stream-tcp-util.c:71
TCPVars_::ts_val
uint32_t ts_val
Definition: decode-tcp.h:160
TCP_CLOSED
@ TCP_CLOSED
Definition: stream-tcp-private.h:150
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
Packet_::flow
struct Flow_ * flow
Definition: decode.h:451
STREAMTCP_FLAG_TIMESTAMP
#define STREAMTCP_FLAG_TIMESTAMP
Definition: stream-tcp-private.h:164
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:670
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:710
StreamTcpRegisterTests
void StreamTcpRegisterTests(void)
Definition: stream-tcp.c:4275
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
TcpStreamCnf_::midstream
bool midstream
Definition: stream-tcp.h:58
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:151
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
ConfInit
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:113
StreamTcpUTSetupSession
void StreamTcpUTSetupSession(TcpSession *ssn)
Definition: stream-tcp-util.c:62
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
SCFree
#define SCFree(p)
Definition: util-mem.h:61
TH_CWR
#define TH_CWR
Definition: decode-tcp.h:43
OS_POLICY_WINDOWS
@ OS_POLICY_WINDOWS
Definition: stream-tcp-reassemble.h:47
StreamTcpThread_::ra_ctx
TcpReassemblyThreadCtx * ra_ctx
Definition: stream-tcp.h:103
tcpvars
#define tcpvars
Definition: decode.h:527
StreamTcpReturnStreamSegments
void StreamTcpReturnStreamSegments(TcpStream *)
return all segments in this stream into the pool(s)
Definition: stream-tcp-reassemble.c:315
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:60
SET_ISN
#define SET_ISN(stream, setseq)
Definition: stream-tcp.c:29
Address_::family
char family
Definition: decode.h:120
Packet_::dst
Address dst
Definition: decode.h:419
ConfDeInit
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:721
StreamTcpReassembleRegisterTests
void StreamTcpReassembleRegisterTests(void)
The Function Register the Unit tests to test the reassembly engine for various OS policies.
Definition: stream-tcp-reassemble.c:3731
OS_POLICY_DEFAULT
#define OS_POLICY_DEFAULT
Definition: stream-tcp-reassemble.h:82
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
STREAMTCP_FLAG_4WHS
#define STREAMTCP_FLAG_4WHS
Definition: stream-tcp-private.h:173
TcpSession_
Definition: stream-tcp-private.h:260
StreamTcpDecrMemuse
void StreamTcpDecrMemuse(uint64_t size)
Definition: stream-tcp.c:135
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
Packet_::src
Address src
Definition: decode.h:418
STREAM_RAW_PROGRESS
#define STREAM_RAW_PROGRESS(stream)
Definition: stream-tcp-private.h:133
StreamTcpCheckStreamContents
int StreamTcpCheckStreamContents(uint8_t *stream_policy, uint16_t sp_size, TcpStream *stream)
The Function Checks the reassembled stream contents against predefined stream contents according to O...
Definition: stream-tcp-reassemble.c:2031