1 /*
2  *  Copyright (c) 2011-2019, Peter Haag
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *
8  *   * Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *   * Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *   * Neither the name of the author nor the names of its contributors may be
14  *     used to endorse or promote products derived from this software without
15  *     specific prior written permission.
16  *
17  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  *  POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 #ifndef _FLOWTREE_H
32 #define _FLOWTREE_H 1
33 
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37 
38 #include <sys/types.h>
39 #ifdef HAVE_STDINT_H
40 #include <stdint.h>
41 #endif
42 #include <sys/time.h>
43 
44 #include <time.h>
45 #include <signal.h>
46 
47 #include "collector.h"
48 #include "rbtree.h"
49 
50 #define v4 ip_union._v4
51 #define v6 ip_union._v6
52 
53 struct FlowNode {
54 	// tree
55 	RB_ENTRY(FlowNode) entry;
56 
57 	// linked list
58 	struct FlowNode *left;
59 	struct FlowNode *right;
60 
61 	struct FlowNode *biflow;
62 
63 	// flow key
64 	// IP addr
65 	ip_addr_t	src_addr;
66 	ip_addr_t	dst_addr;
67 
68 	uint16_t	src_port;
69 	uint16_t	dst_port;
70 	uint8_t		proto;
71 	uint8_t		version;
72 	uint16_t	_ENDKEY_;
73 	// End of flow key
74 
75 	ip_addr_t	tun_src_addr;
76 	ip_addr_t	tun_dst_addr;
77 	uint8_t		tun_proto;
78 
79 #define NODE_FREE	0xA5
80 #define NODE_IN_USE	0x5A
81 	uint16_t	memflag;	// internal houskeeping flag
82 	uint8_t		flags;
83 #define FIN_NODE 1
84 #define SIGNAL_NODE 255
85 	uint8_t		fin;		// double use:  1: fin received - flow can be exported, if complete
86 							//            255: empty node - used to wake up flow thread priodically on quite lines
87 
88 	// flow stat data
89 	struct timeval	t_first;
90 	struct timeval	t_last;
91 
92 	uint32_t	packets;	// summed up number of packets
93 	uint32_t	bytes;		// summed up number of bytes
94 
95 	struct FlowNode *rev_node;
96 	struct latency_s {
97 		uint64_t    client;
98 		uint64_t    server;
99 		uint64_t    application;
100 		uint32_t	flag;
101 		struct timeval t_request;
102 	} latency;
103 };
104 
105 typedef struct NodeList_s {
106 	struct FlowNode *list;
107 	struct FlowNode *last;
108 	sig_atomic_t	list_lock;
109 	pthread_mutex_t m_list;
110 	pthread_cond_t  c_list;
111 	uint32_t length;
112 	uint32_t waiting;
113 	uint64_t waits;
114 } NodeList_t;
115 
116 
117 /* flow tree type */
118 typedef RB_HEAD(FlowTree, FlowNode) FlowTree_t;
119 
120 // Insert the RB prototypes here
121 RB_PROTOTYPE(FlowTree, FlowNode, entry, FlowNodeCMP);
122 
123 int Init_FlowTree(uint32_t CacheSize, int32_t expireActive, int32_t expireInactive);
124 
125 void Dispose_FlowTree(void);
126 
127 uint32_t Flush_FlowTree(FlowSource_t *fs);
128 
129 uint32_t Expire_FlowTree(FlowSource_t *fs, time_t when);
130 
131 struct FlowNode *Lookup_Node(struct FlowNode *node);
132 
133 struct FlowNode *New_Node(void);
134 
135 void Free_Node(struct FlowNode *node);
136 
137 void CacheCheck(FlowSource_t *fs, time_t when, int live);
138 
139 int AddNodeData(struct FlowNode *node, uint32_t seq, void *payload, uint32_t size);
140 
141 struct FlowNode *Insert_Node(struct FlowNode *node);
142 
143 void Remove_Node(struct FlowNode *node);
144 
145 int Link_RevNode(struct FlowNode *node);
146 
147 // Node list functions
148 NodeList_t *NewNodeList(void);
149 
150 void DisposeNodeList(NodeList_t *NodeList);
151 
152 void Push_Node(NodeList_t *NodeList, struct FlowNode *node);
153 
154 struct FlowNode *Pop_Node(NodeList_t *NodeList, int *done);
155 
156 void DumpList(NodeList_t *NodeList);
157 
158 // Stat functions
159 void DumpNodeStat(NodeList_t *NodeList);
160 
161 #endif // _FLOWTREE_H
162