1 #ifdef SNORT_RELOAD
2
3 #include "appdata_adjuster.h"
4 #include "sfxhash.h"
5
6 #ifdef REG_TEST
7 #include "reg_test.h"
8 #endif
9
10 //SharedObjectDeleteBegins
11 #include "reload.h"
12 #include "preprocessors/session_api.h"
13 //SharedObjectDeleteEnds
14 /*SharedObjectAddStarts
15 #include "sf_dynamic_preprocessor.h"
16 SharedObjectAddEnds */
17
18 ///////////////////////////////////////////////////
19
20
21 #define HASH_ROWS 1024
22 #define IDLE_SPEED 512
23 #define REGULAR_SPEED 32
24
25 struct _appdata_adjuster{
26 SFXHASH *h;
27 uint32_t protocol_id;
28 PreprocMemUsedFunc totalPreprocMemInUse;
29 size_t new_cap;
30 };
31
32 //preproc_memcap may be used in the future for hash optimization
ada_init(PreprocMemUsedFunc totalPreprocMemInUse,uint32_t protocol_id,size_t preproc_memcap)33 APPDATA_ADJUSTER * ada_init( PreprocMemUsedFunc totalPreprocMemInUse, uint32_t protocol_id, size_t preproc_memcap )
34 {
35 APPDATA_ADJUSTER *a;
36 a = calloc(1,sizeof(APPDATA_ADJUSTER));
37 if (!a)
38 return NULL;
39
40 SFXHASH *h = sfxhash_new(HASH_ROWS, sizeof(void *), 0, 0, 0, NULL, NULL, 0);
41 if (!h)
42 {
43 free(a);
44 return NULL;
45 }
46
47 a->h = h;
48 a->protocol_id = protocol_id;
49 a->totalPreprocMemInUse = totalPreprocMemInUse;
50
51 return a;
52 }
53
ada_delete(APPDATA_ADJUSTER * a)54 void ada_delete( APPDATA_ADJUSTER *a )
55 {
56 if (!a)
57 return;
58
59 sfxhash_delete(a->h);
60 free(a);
61 }
62
ada_add(APPDATA_ADJUSTER * a,void * appData,void * scb)63 void ada_add( APPDATA_ADJUSTER *a, void *appData, void *scb )
64 {
65 if (!a || !appData || !scb)
66 return;
67
68 sfxhash_add(a->h, &appData, scb);
69 }
70
ada_appdata_freed(APPDATA_ADJUSTER * a,void * appData)71 void ada_appdata_freed( APPDATA_ADJUSTER *a, void *appData )
72 {
73 if (!a || !appData)
74 return;
75 sfxhash_remove(a->h, &appData);
76 }
77
delete_app_data(SFXHASH * h,uint32_t protocol_id)78 static void delete_app_data( SFXHASH *h, uint32_t protocol_id )
79 {
80 SFXHASH_NODE *node = sfxhash_lru_node(h);
81 if (!node)
82 return;
83
84 session_api->set_application_data(node->data,protocol_id,NULL,NULL);
85 }
86
ada_reload_adjust_func(bool idle,tSfPolicyId raPolicyId,void * userData)87 bool ada_reload_adjust_func( bool idle, tSfPolicyId raPolicyId, void *userData )
88 {
89 unsigned work_done;
90 unsigned speed = idle ? IDLE_SPEED : REGULAR_SPEED;
91 if (userData == NULL)
92 return false;
93 APPDATA_ADJUSTER *a = (APPDATA_ADJUSTER *) userData;
94
95 #ifdef REG_TEST
96 if (REG_TEST_FLAG_APPDATA_ADJUSTER_RELOAD & getRegTestFlags())
97 {
98 printf("ada_reload_adjust func newmemcap %zu\n", a->new_cap);
99 printf("ada_reload_adjust_func meminuse-before %zu\n", a->totalPreprocMemInUse());
100 }
101 #endif
102
103 for (work_done = 0; work_done<speed && sfxhash_ghead(a->h) && a->new_cap < a->totalPreprocMemInUse(); work_done++)
104 {
105 delete_app_data(a->h, a->protocol_id);
106 }
107
108 #ifdef REG_TEST
109 if (REG_TEST_FLAG_APPDATA_ADJUSTER_RELOAD & getRegTestFlags())
110 {
111 printf("ada_reload_adjust_func meminuse-after %zu\n", a->totalPreprocMemInUse());
112 printf("ada_reload_adjust_func ghead %d\n", sfxhash_ghead(a->h) != 0);
113 }
114 #endif
115
116 bool done_deleting_sessions = a->new_cap >= a->totalPreprocMemInUse() || !sfxhash_ghead(a->h);
117 #ifdef REG_TEST
118 if (done_deleting_sessions && REG_TEST_FLAG_APPDATA_ADJUSTER_RELOAD & getRegTestFlags())
119 {
120 printf("ada_reload_adjust_func done 1\n");
121 }
122 #endif
123 return done_deleting_sessions;
124 }
125
ada_reload_adjust_func_disable(bool idle,tSfPolicyId raPolicyId,void * userData)126 static bool ada_reload_adjust_func_disable( bool idle, tSfPolicyId raPolicyId, void *userData )
127 {
128 APPDATA_ADJUSTER **adaPointer = (APPDATA_ADJUSTER **) userData;
129 APPDATA_ADJUSTER *ada = *adaPointer;
130 if (ada_reload_adjust_func(idle, raPolicyId, ada))
131 {
132 ada_delete(ada);
133 *adaPointer = NULL;
134 return true;
135 }
136 return false;
137 }
138
ada_reload_adjust_register(APPDATA_ADJUSTER * a,tSfPolicyId policy_id,struct _SnortConfig * snortConfig,const char * raName,size_t new_cap)139 int ada_reload_adjust_register( APPDATA_ADJUSTER *a, tSfPolicyId policy_id, struct _SnortConfig *snortConfig, const char *raName, size_t new_cap )
140 {
141 if (!a || !snortConfig || !raName)
142 return -1;
143 a->new_cap = new_cap;
144 return ReloadAdjustRegister(snortConfig, raName, policy_id, ada_reload_adjust_func, (void *) a, NULL);
145 }
146
ada_set_new_cap(APPDATA_ADJUSTER * a,size_t new_cap)147 void ada_set_new_cap( APPDATA_ADJUSTER *a, size_t new_cap )
148 {
149 if (!a)
150 return;
151 a->new_cap = new_cap;
152 }
153
154 //in a preprocessor, if you have APPDATA_ADJUSTER *ada = ada_init(....
155 //then when you call ada_reload_disable(&ada,....
ada_reload_disable(APPDATA_ADJUSTER ** aPointer,struct _SnortConfig * snortConfig,const char * raName,tSfPolicyId policy_id)156 int ada_reload_disable( APPDATA_ADJUSTER **aPointer, struct _SnortConfig *snortConfig, const char *raName, tSfPolicyId policy_id)
157 {
158 if (!aPointer || !(*aPointer)|| !snortConfig || !raName)
159 return -1;
160
161 (*aPointer)->new_cap = 0;
162 return ReloadAdjustRegister(snortConfig, raName, policy_id, ada_reload_adjust_func_disable, (void *) aPointer, NULL);
163 }
164
165 #endif
166
167