1
+ //! For each connection, the Retina framework applies multiple filtering stages as
2
+ //! packets are received in order to determine (1) whether packets from that connection
3
+ //! should continue to be processed and (2) what to do with these packets.
4
+ //!
5
+ //! Each connection is associated with a set of Actions. These actions specify the
6
+ //! operations the framework will perform for the connection *now or in the future*:
7
+ //! e.g., probe for the application-layer protocol (until it is identified), deliver
8
+ //! the connection (when it has terminated), deliver all subsequent packets in the
9
+ //! connection, etc. An empty Actions struct will cause the connection to be dropped.
10
+ //!
11
+ //! Each filter stage returns a set of actions and a set of terminal actions.
12
+ //! The terminal actions are the subset of actions that are maintained through
13
+ //! the next filter stage.
1
14
use bitmask_enum:: bitmask;
2
- /// For each connectionn, the Retina framework applies multiple filtering stages as
3
- /// packets are received in order to determine (1) whether packets from that connection
4
- /// should continue to be processed and (2) what to do with these packets.
5
- ///
6
- /// Each connection is associated with a set of Actions. These actions specify the
7
- /// operations the framework will perform for the connection *now or in the future*:
8
- /// e.g., probe for the application-layer protocol (until it is identified), deliver
9
- /// the connection (when it has terminated), deliver all subsequent packets in the
10
- /// connection, etc. An empty Actions struct will cause the connection to be dropped.
11
- ///
12
- /// Each filter stage returns a set of actions and a set of terminal actions.
13
- /// The terminal actions are the subset of actions that are maintained through
14
- /// the next filter stage.
15
15
use std:: fmt;
16
16
17
17
#[ bitmask]
18
18
#[ bitmask_config( vec_debug) ]
19
19
pub enum ActionData {
20
- // Packet actions //
21
20
/// Forward new packet to connection tracker
22
21
/// Should only be used in the PacketContinue filter
23
22
PacketContinue ,
@@ -36,7 +35,6 @@ pub enum ActionData {
36
35
/// datatype that requires tracking and delivering packets.
37
36
PacketTrack ,
38
37
39
- // Connection/session actions //
40
38
/// Probe for (identify) the application-layer protocol
41
39
ProtoProbe ,
42
40
/// Once the application-layer protocl is identified, apply the ProtocolFilter.
@@ -60,6 +58,7 @@ pub enum ActionData {
60
58
ConnDeliver ,
61
59
}
62
60
61
+ /// Actions maintained per-connection
63
62
#[ derive( Debug , Clone , Hash , Eq , PartialEq ) ]
64
63
pub struct Actions {
65
64
/// All actions (terminal and non-terminal) that should
@@ -69,7 +68,7 @@ pub struct Actions {
69
68
/// regardless of what the next filter returns
70
69
/// E.g., if a terminal match for a connection-level filter
71
70
/// occurs at the packet layer, we should continue tracking
72
- /// the connection without re-applying that filter.
71
+ /// the connection regardless of later filter results .
73
72
pub terminal_actions : ActionData ,
74
73
}
75
74
@@ -80,46 +79,46 @@ impl Default for Actions {
80
79
}
81
80
82
81
impl Actions {
83
- /// Create an empty Actions bitmask
82
+ // Create an empty Actions bitmask
84
83
pub fn new ( ) -> Self {
85
84
Self {
86
85
data : ActionData :: none ( ) ,
87
86
terminal_actions : ActionData :: none ( ) ,
88
87
}
89
88
}
90
89
91
- /// Store the result of a new filter
92
- /// Used at runtime after application of next filter
90
+ // Store the result of a new filter
91
+ // Used at runtime after application of next filter
93
92
#[ inline]
94
93
pub fn update ( & mut self , actions : & Actions ) {
95
94
self . data = self . terminal_actions | actions. data ;
96
95
self . terminal_actions |= actions. terminal_actions ;
97
96
}
98
97
99
- /// Combine terminal and non-terminal actions
100
- /// Used for building a filter tree at compile time and when
101
- /// applying a filter at runtime if additional conditions are met.
98
+ // Combine terminal and non-terminal actions
99
+ // Used for building a filter tree at compile time and when
100
+ // applying a filter at runtime if additional conditions are met.
102
101
#[ inline]
103
102
pub fn push ( & mut self , actions : & Actions ) {
104
103
self . data |= actions. data ;
105
104
self . terminal_actions |= actions. terminal_actions ;
106
105
}
107
106
108
- /// Returns true if no actions are set (i.e., the connection can
109
- /// be dropped by the framework).
107
+ // Returns true if no actions are set (i.e., the connection can
108
+ // be dropped by the framework).
110
109
#[ inline]
111
110
pub fn drop ( & self ) -> bool {
112
111
self . data . is_none ( ) && self . terminal_actions . is_none ( )
113
112
}
114
113
115
- /// Update `self` to contain only actions not in `actions`
114
+ // Update `self` to contain only actions not in `actions`
116
115
#[ inline]
117
116
pub ( crate ) fn clear_intersection ( & mut self , actions : & Actions ) {
118
117
self . data &= actions. data . not ( ) ;
119
118
self . terminal_actions &= actions. data . not ( ) ;
120
119
}
121
120
122
- /// Conn tracker must deliver each PDU to tracked data when received
121
+ // Conn tracker must deliver each PDU to tracked data when received
123
122
#[ inline]
124
123
pub ( crate ) fn update_pdu ( & self ) -> bool {
125
124
self . data . intersects ( ActionData :: UpdatePDU )
@@ -148,7 +147,7 @@ impl Actions {
148
147
self . data . intersects ( ActionData :: PacketCache )
149
148
}
150
149
151
- /// True if application-layer probing or parsing should be applied
150
+ // True if application-layer probing or parsing should be applied
152
151
#[ inline]
153
152
pub ( crate ) fn parse_any ( & self ) -> bool {
154
153
self . data . intersects (
@@ -167,51 +166,51 @@ impl Actions {
167
166
self . data == ActionData :: ConnDeliver
168
167
}
169
168
170
- /// True if the session filter should be applied
169
+ // True if the session filter should be applied
171
170
#[ inline]
172
171
pub ( crate ) fn apply_session_filter ( & mut self ) -> bool {
173
172
// \note deliver filter is in session filter
174
173
self . data
175
174
. intersects ( ActionData :: SessionFilter | ActionData :: SessionDeliver )
176
175
}
177
176
178
- /// True if the protocol filter should be applied
177
+ // True if the protocol filter should be applied
179
178
#[ inline]
180
179
pub ( crate ) fn apply_proto_filter ( & mut self ) -> bool {
181
180
self . data . contains ( ActionData :: ProtoFilter )
182
181
}
183
182
184
- /// True if the framework should probe for the app-layer protocol
183
+ // True if the framework should probe for the app-layer protocol
185
184
#[ inline]
186
185
pub ( crate ) fn session_probe ( & self ) -> bool {
187
186
self . data
188
187
. intersects ( ActionData :: ProtoProbe | ActionData :: ProtoFilter )
189
188
}
190
189
191
- /// True if the framework should parse application-layer data
190
+ // True if the framework should parse application-layer data
192
191
#[ inline]
193
192
pub ( crate ) fn session_parse ( & self ) -> bool {
194
193
self . data . intersects (
195
194
ActionData :: SessionDeliver | ActionData :: SessionFilter | ActionData :: SessionTrack ,
196
195
) && !self . session_probe ( ) // still at probing stage
197
196
}
198
197
199
- /// True if the framework should buffer parsed sessions
198
+ // True if the framework should buffer parsed sessions
200
199
#[ inline]
201
200
pub ( crate ) fn session_track ( & self ) -> bool {
202
201
self . data . intersects ( ActionData :: SessionTrack )
203
202
}
204
203
205
- /// True if the framework should deliver future packets in this connection
204
+ // True if the framework should deliver future packets in this connection
206
205
#[ inline]
207
206
pub ( crate ) fn packet_deliver ( & self ) -> bool {
208
207
self . data . intersects ( ActionData :: PacketDeliver )
209
208
}
210
209
211
- /// After parsing a session, the framework must decide whether to continue
212
- /// probing for sessions depending on the protocol
213
- /// If no further parsing is required (e.g., TLS Handshake), this method
214
- /// should be invoked.
210
+ // After parsing a session, the framework must decide whether to continue
211
+ // probing for sessions depending on the protocol
212
+ // If no further parsing is required (e.g., TLS Handshake), this method
213
+ // should be invoked.
215
214
#[ inline]
216
215
pub ( crate ) fn session_clear_parse ( & mut self ) {
217
216
self . clear_mask (
@@ -222,8 +221,8 @@ impl Actions {
222
221
) ;
223
222
}
224
223
225
- /// Subscription requires protocol probe/parse but matched at packet stage
226
- /// Update action to reflect state transition to protocol parsing
224
+ // Subscription requires protocol probe/parse but matched at packet stage
225
+ // Update action to reflect state transition to protocol parsing
227
226
#[ inline]
228
227
pub ( crate ) fn session_done_probe ( & mut self ) {
229
228
if self . terminal_actions . contains ( ActionData :: ProtoProbe ) {
@@ -235,8 +234,8 @@ impl Actions {
235
234
}
236
235
}
237
236
238
- /// Some app-layer protocols revert to probing after session is parsed
239
- /// This is done if more sessions are expected
237
+ // Some app-layer protocols revert to probing after session is parsed
238
+ // This is done if more sessions are expected
240
239
pub ( crate ) fn session_set_probe ( & mut self ) {
241
240
// If protocol probing was set at the PacketFilter stage (i.e.,
242
241
// terminal match for a subscription that requires parsing sessions),
@@ -263,20 +262,20 @@ impl Actions {
263
262
*/
264
263
}
265
264
266
- /// True if the connection should be delivered at termination
265
+ // True if the connection should be delivered at termination
267
266
#[ inline]
268
267
pub ( crate ) fn connection_matched ( & self ) -> bool {
269
268
self . terminal_actions . intersects ( ActionData :: ConnDeliver )
270
269
}
271
270
272
- /// Clear all actions
271
+ // Clear all actions
273
272
#[ inline]
274
273
pub ( crate ) fn clear ( & mut self ) {
275
274
self . terminal_actions = ActionData :: none ( ) ;
276
275
self . data = ActionData :: none ( ) ;
277
276
}
278
277
279
- /// Clear a subset of actions
278
+ // Clear a subset of actions
280
279
#[ inline]
281
280
pub ( crate ) fn clear_mask ( & mut self , mask : ActionData ) {
282
281
self . data &= mask. not ( ) ;
0 commit comments