/src/ntopng/include/GenericHashEntry.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * |
3 | | * (C) 2013-24 - ntop.org |
4 | | * |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | | * |
20 | | */ |
21 | | |
22 | | #ifndef _GENERIC_HASH_ENTRY_H_ |
23 | | #define _GENERIC_HASH_ENTRY_H_ |
24 | | |
25 | | #include "ntop_includes.h" |
26 | | |
27 | | class Generichash; |
28 | | |
29 | | /** @class GenericHashEntry |
30 | | * @brief Base hash entry class. |
31 | | * @details Defined the base hash entry class for ntopng. |
32 | | * |
33 | | * This class handle entries placed in hash tables built |
34 | | * with class GenericHash. |
35 | | * |
36 | | * GenericHashEntry has a lifecycle which is written into |
37 | | * the enum HashEntryState and is implemented as a finite states |
38 | | * machine. States are: |
39 | | * |
40 | | * - hash_entry_state_active. This state is the default one which |
41 | | * is set as soon as the GenericHashEntry is instantiated. |
42 | | * |
43 | | * - hash_entry_state_idle. This state is set by method purgeIdle |
44 | | * in class GenericHash and is used to explicitly mark the entry |
45 | | * as idle. NOTE that purgeIdle is always called inline, that is, |
46 | | * in the thread which receives the incoming packets (or incoming |
47 | | * flows). Once the entry has been marked as hash_entry_state_idle, |
48 | | * the inline thread will not be able to fetch the entry again. Howevever, |
49 | | * before deleting the entry, an extra transition is needed to make sure |
50 | | * also a non-inline periodic thread has seen the entry. |
51 | | * |
52 | | * - hash_entry_state_ready_to_be_purged. This state is set by |
53 | | * non-inline periodic threads, generally from method updateStats, |
54 | | * only after the inline thread has set state hash_entry_state_idle. This |
55 | | * guarantees that also a non-inline thread has seen the entry before |
56 | | * cleaning it up and freeing its memory. Once this state has been set, |
57 | | * the inline-thread will perform the actual delete to free the memory. |
58 | | * |
59 | | * The following diagram recaps the states transitions |
60 | | * |
61 | | * ..new.. |
62 | | * | |
63 | | * | |
64 | | * v |
65 | | * hash_entry_state_active |
66 | | * | |
67 | | * | [inline] |
68 | | * v |
69 | | * hash_entry_state_idle |
70 | | * | |
71 | | * | [non-inline] |
72 | | * v |
73 | | * hash_entry_state_ready_to_be_purged |
74 | | * | |
75 | | * | |
76 | | * v |
77 | | * ...deleted... |
78 | | * |
79 | | * @ingroup MonitoringData |
80 | | * |
81 | | */ |
82 | | class GenericHashEntry { |
83 | | private: |
84 | | GenericHashEntry *hash_next; /**< Pointer of next hash entry.*/ |
85 | | HashEntryState hash_entry_state; |
86 | | GenericHash *hash_table; |
87 | | |
88 | | /** |
89 | | * @brief Set one of the states of the hash entry in its lifecycle. |
90 | | * |
91 | | * @param s A state of the enum HashEntryState |
92 | | */ |
93 | | void set_state(HashEntryState s); |
94 | | |
95 | | protected: |
96 | | std::atomic<int32_t> num_uses; |
97 | | time_t first_seen; /**< Time of first seen. */ |
98 | | time_t last_seen; /**< Time of last seen. */ |
99 | | NetworkInterface *iface; /**< Pointer of network interface. */ |
100 | | |
101 | | public: |
102 | | /** |
103 | | * @brief A Constructor |
104 | | * @details Creating a new GenericHashEntry. |
105 | | * |
106 | | * @param _iface Network interface pointer for the new hash. |
107 | | * @return A new Instance of GenericHashEntry. |
108 | | */ |
109 | | GenericHashEntry(NetworkInterface *_iface); |
110 | | |
111 | | /** |
112 | | * @brief A destructor. |
113 | | * @details Virtual method. |
114 | | * |
115 | | * @return Delete the instance. |
116 | | */ |
117 | | virtual ~GenericHashEntry(); |
118 | | |
119 | | /** |
120 | | * @brief Get the first seen time. |
121 | | * @details Inline method. |
122 | | * |
123 | | * @return Time of first seen. |
124 | | */ |
125 | 2.48k | inline time_t get_first_seen() const { return (first_seen); }; |
126 | | |
127 | | /** |
128 | | * @brief Get the last seen time. |
129 | | * @details Inline method. |
130 | | * |
131 | | * @return Time of last seen. |
132 | | */ |
133 | 44.5k | inline time_t get_last_seen() const { return (last_seen); }; |
134 | | |
135 | | /** |
136 | | * @brief Get the next hash entry. |
137 | | * @details Inline method. |
138 | | * |
139 | | * @return Return the next hash entry. |
140 | | */ |
141 | 155k | inline GenericHashEntry *next() { return (hash_next); }; |
142 | | |
143 | | /** |
144 | | * @brief Set a pointer to the hash table this entry |
145 | | * hash been added to |
146 | | */ |
147 | 58.5k | void set_hash_table(GenericHash *gh) { hash_table = gh; }; |
148 | | |
149 | 0 | inline GenericHash *get_hash_table() { return (hash_table); }; |
150 | | |
151 | | /** |
152 | | * @brief Set and id to uniquely identify this |
153 | | * hash entry into the hash table (class GenericHash) |
154 | | * it belongs to. |
155 | | */ |
156 | 43.5k | virtual void set_hash_entry_id(u_int32_t hash_entry_id){}; |
157 | | |
158 | | /** |
159 | | * @brief Set the next hash entry. |
160 | | * @details Inline method. |
161 | | * |
162 | | * @param n Hash entry to set as next hash entry. |
163 | | */ |
164 | 59.0k | inline void set_next(GenericHashEntry *n) { hash_next = n; }; |
165 | | |
166 | | /** |
167 | | * @brief Set the hash entry state to idle. Must be called inline |
168 | | * with packets/flows processing. |
169 | | * |
170 | | */ |
171 | 5.96k | virtual void set_hash_entry_state_idle() { |
172 | 5.96k | set_state(hash_entry_state_idle); |
173 | 5.96k | }; |
174 | | |
175 | | /** |
176 | | * @brief Set the hash entry state to active |
177 | | */ |
178 | 8.38k | inline void set_hash_entry_state_active() { |
179 | 8.38k | set_state(hash_entry_state_active); |
180 | 8.38k | }; |
181 | | |
182 | | /** |
183 | | * @brief Set the hash entry state to not yet detected (nDPI) |
184 | | */ |
185 | 9.34k | inline void set_hash_entry_state_flow_notyetdetected() { |
186 | 9.34k | set_state(hash_entry_state_flow_notyetdetected); |
187 | 9.34k | }; |
188 | | |
189 | | /** |
190 | | * @brief Set the hash entry state to protocol detected (nDPI). |
191 | | * Note that unknown (protocol) is a valid protocol |
192 | | */ |
193 | 12.5k | inline void set_hash_entry_state_flow_protocoldetected() { |
194 | 12.5k | set_state(hash_entry_state_flow_protocoldetected); |
195 | 12.5k | }; |
196 | | |
197 | | /** |
198 | | * @brief Set the hash entry state to allocated |
199 | | */ |
200 | 14.9k | inline void set_hash_entry_state_allocated() { |
201 | | /* |
202 | | We don't check anything here as it's used by flows to step back |
203 | | to the initial state |
204 | | */ |
205 | 14.9k | hash_entry_state = hash_entry_state_allocated; |
206 | 14.9k | }; |
207 | | |
208 | | /** |
209 | | * @brief Determine whether this entry is ready for the transition to the idle |
210 | | * state |
211 | | * |
212 | | */ |
213 | 3.18k | virtual bool is_hash_entry_state_idle_transition_ready() { |
214 | 3.18k | return ((getUses() == 0) && is_active_entry_now_idle(MAX_HASH_ENTRY_IDLE)); |
215 | 3.18k | } |
216 | | |
217 | | /** |
218 | | * @brief Determine whether this active entry can be considered idle |
219 | | * |
220 | | */ |
221 | | virtual bool is_active_entry_now_idle(u_int max_idleness) const; |
222 | | |
223 | | /** |
224 | | * @brief Function in charge of updating periodic entry stats (e.g., its |
225 | | * throughput or L7 traffic) |
226 | | * |
227 | | * @param user_date A pointer to user submitted data potentially necessary for |
228 | | * the update |
229 | | * @param quick Only perform minimal operations |
230 | | * |
231 | | */ |
232 | | virtual void periodic_stats_update(const struct timeval *tv); |
233 | 518k | inline HashEntryState get_state() const { return (hash_entry_state); } |
234 | | void updateSeen(); |
235 | | void updateSeen(time_t _last_seen); |
236 | 0 | bool equal(GenericHashEntry *b) { return ((this == b) ? true : false); }; |
237 | 159k | inline NetworkInterface *getInterface() { return (iface); }; |
238 | 357k | inline bool idle() const { return (get_state() > hash_entry_state_active); } |
239 | 3.18k | virtual void housekeep(time_t t) { return; }; |
240 | 1.55k | inline u_int get_duration() const { return ((u_int)((1 + last_seen) - first_seen)); }; |
241 | 0 | virtual u_int32_t key() { return (0); }; |
242 | 0 | virtual char *get_string_key(char *buf, u_int buf_len) const { buf[0] = '\0'; return (buf); }; |
243 | 105k | void incUses() { num_uses++; } |
244 | 105k | void decUses() { num_uses--; } |
245 | 98.7k | int32_t getUses() const { return (num_uses); } |
246 | | |
247 | | virtual void getJSONObject(json_object *obj, DetailsLevel details_level); |
248 | | }; |
249 | | |
250 | | #endif /* _GENERIC_HASH_ENTRY_H_ */ |