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