Coverage Report

Created: 2024-02-25 06:37

/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_ */