/
removal-hooks.zeek
79 lines (67 loc) · 2.47 KB
/
removal-hooks.zeek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
##! Adds a framework for registering "connection removal hooks".
##! All registered hooks for a given connection get run within the
##! :zeek:see:`connection_state_remove` event for that connection.
##! This functionality is useful from a performance/scaling concern:
##! if every new protocol-analysis script uses
##! :zeek:see:`connection_state_remove` to implement its finalization/cleanup
##! logic, then all connections take the performance hit of dispatching that
##! event, even if they aren't related to that specific protocol.
module Conn;
export {
## A hook function for use with either :zeek:see:`Conn::register_removal_hook`
## or :zeek:see:`Conn::unregister_removal_hook`. The :zeek:see:`connection`
## argument refers to the connection currently being removed within a
## :zeek:see:`connection_state_remove` event.
type RemovalHook: hook(c: connection);
## Register a hook that will later be called during a connection's
## :zeek:see:`connection_state_remove` event.
##
## c: The associated connection whose :zeek:see:`connection_state_remove`
## event should trigger a callback to *hk*.
##
## hk: The hook function to use as a callback.
##
## Returns: false if the provided hook was previously registered, else true.
global register_removal_hook: function(c: connection, hk: RemovalHook): bool;
## Unregister a hook that would have been called during a connection's
## :zeek:see:`connection_state_remove` event such that it will no longer
## be called.
##
## c: The associated connection whose :zeek:see:`connection_state_remove`
## event could have triggered a callback to *hk*.
##
## hk: The hook function that would have been used as a callback.
##
## Returns: true if the provided hook was previously registered, else false.
global unregister_removal_hook: function(c: connection, hk: RemovalHook): bool;
}
redef record connection += {
removal_hooks: set[RemovalHook] &optional;
};
function register_removal_hook(c: connection, hk: RemovalHook): bool
{
if ( c?$removal_hooks )
{
if ( hk in c$removal_hooks )
return F;
add c$removal_hooks[hk];
return T;
}
c$removal_hooks = set(hk);
return T;
}
function unregister_removal_hook(c: connection, hk: RemovalHook): bool
{
if ( ! c?$removal_hooks )
return F;
if ( hk !in c$removal_hooks )
return F;
delete c$removal_hooks[hk];
return T;
}
event connection_state_remove(c: connection) &priority=-3
{
if ( c?$removal_hooks )
for ( removal_hook in c$removal_hooks )
hook removal_hook(c);
}