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