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