Mercurial > hg > freeDiameter
comparison extensions/rt_ereg/rtereg.c @ 1387:d70f5f6cb306
rt_ereg: improve logging and locking
author | Thomas Klausner <tk@giga.or.at> |
---|---|
date | Tue, 15 Oct 2019 16:25:47 +0200 |
parents | f1b65381c1e7 |
children | c48725959e63 |
comparison
equal
deleted
inserted
replaced
1386:6e4737d332e7 | 1387:d70f5f6cb306 |
---|---|
91 /* Does this pattern match the value? */ | 91 /* Does this pattern match the value? */ |
92 struct rtereg_rule * r = &rtereg_conf[conf].rules[i]; | 92 struct rtereg_rule * r = &rtereg_conf[conf].rules[i]; |
93 int err = 0; | 93 int err = 0; |
94 struct fd_list * c; | 94 struct fd_list * c; |
95 | 95 |
96 TRACE_DEBUG(ANNOYING, "Attempt pattern matching of '%.*s' with rule '%s'", (int)len, value, r->pattern); | 96 LOG_D("[rt_ereg] attempting pattern matching of '%.*s' with rule '%s'", (int)len, value, r->pattern); |
97 | 97 |
98 #ifdef HAVE_REG_STARTEND | 98 #ifdef HAVE_REG_STARTEND |
99 { | 99 { |
100 regmatch_t pmatch[1]; | 100 regmatch_t pmatch[1]; |
101 memset(pmatch, 0, sizeof(pmatch)); | 101 memset(pmatch, 0, sizeof(pmatch)); |
116 if (err != 0) { | 116 if (err != 0) { |
117 char * errstr; | 117 char * errstr; |
118 size_t bl; | 118 size_t bl; |
119 | 119 |
120 /* Error while compiling the regex */ | 120 /* Error while compiling the regex */ |
121 TRACE_DEBUG(INFO, "Error while executing the regular expression '%s':", r->pattern); | 121 LOG_E("[rt_ereg] error while executing the regular expression '%s':", r->pattern); |
122 | 122 |
123 /* Get the error message size */ | 123 /* Get the error message size */ |
124 bl = regerror(err, &r->preg, NULL, 0); | 124 bl = regerror(err, &r->preg, NULL, 0); |
125 | 125 |
126 /* Alloc the buffer for error message */ | 126 /* Alloc the buffer for error message */ |
127 CHECK_MALLOC( errstr = malloc(bl) ); | 127 CHECK_MALLOC( errstr = malloc(bl) ); |
128 | 128 |
129 /* Get the error message content */ | 129 /* Get the error message content */ |
130 regerror(err, &r->preg, errstr, bl); | 130 regerror(err, &r->preg, errstr, bl); |
131 TRACE_DEBUG(INFO, "\t%s", errstr); | 131 LOG_E("\t%s", errstr); |
132 | 132 |
133 /* Free the buffer, return the error */ | 133 /* Free the buffer, return the error */ |
134 free(errstr); | 134 free(errstr); |
135 | 135 |
136 return (err == REG_ESPACE) ? ENOMEM : EINVAL; | 136 return (err == REG_ESPACE) ? ENOMEM : EINVAL; |
137 } | 137 } |
138 | 138 |
139 /* From this point, the expression matched the AVP value */ | 139 /* From this point, the expression matched the AVP value */ |
140 TRACE_DEBUG(FULL, "[rt_ereg] Match: '%s' to value '%.*s' => '%s' += %d", | 140 LOG_D("[rt_ereg] Match: '%s' to value '%.*s' => '%s' += %d", r->pattern, (int)len, value, r->server, r->score); |
141 r->pattern, | |
142 (int)len, | |
143 value, | |
144 r->server, | |
145 r->score); | |
146 | 141 |
147 for (c = candidates->next; c != candidates; c = c->next) { | 142 for (c = candidates->next; c != candidates; c = c->next) { |
148 struct rtd_candidate * cand = (struct rtd_candidate *)c; | 143 struct rtd_candidate * cand = (struct rtd_candidate *)c; |
149 | 144 |
150 if (strcmp(r->server, cand->diamid) == 0) { | 145 if (strcmp(r->server, cand->diamid) == 0) { |
165 struct avp_hdr *avp_hdr = NULL; | 160 struct avp_hdr *avp_hdr = NULL; |
166 | 161 |
167 /* iterate over all AVPs and try to find a match */ | 162 /* iterate over all AVPs and try to find a match */ |
168 // for (i = 0; i<rtereg_conf[j].level; i++) { | 163 // for (i = 0; i<rtereg_conf[j].level; i++) { |
169 if (level > rtereg_conf[conf_index].level) { | 164 if (level > rtereg_conf[conf_index].level) { |
170 TRACE_DEBUG(INFO, "internal error, dug too deep"); | 165 LOG_E("internal error, dug too deep"); |
171 return 1; | 166 return 1; |
172 } | 167 } |
173 what = rtereg_conf[conf_index].avps[level]; | 168 what = rtereg_conf[conf_index].avps[level]; |
174 | 169 |
175 CHECK_FCT(fd_dict_getval(what, &dictdata)); | 170 CHECK_FCT(fd_dict_getval(what, &dictdata)); |
176 CHECK_FCT(fd_msg_browse(where, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL)); | 171 CHECK_FCT(fd_msg_browse(where, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL)); |
177 while (nextavp) { | 172 while (nextavp) { |
178 CHECK_FCT(fd_msg_avp_hdr(nextavp, &avp_hdr)); | 173 CHECK_FCT(fd_msg_avp_hdr(nextavp, &avp_hdr)); |
179 if ((avp_hdr->avp_code == dictdata.avp_code) && (avp_hdr->avp_vendor == dictdata.avp_vendor)) { | 174 if ((avp_hdr->avp_code == dictdata.avp_code) && (avp_hdr->avp_vendor == dictdata.avp_vendor)) { |
180 if (level != rtereg_conf[conf_index].level - 1) { | 175 if (level != rtereg_conf[conf_index].level - 1) { |
181 TRACE_DEBUG(INFO, "[rt_ereg] found grouped AVP %d (vendor %d), digging deeper", avp_hdr->avp_code, avp_hdr->avp_vendor); | 176 LOG_D("[rt_ereg] found grouped AVP %d (vendor %d), digging deeper", avp_hdr->avp_code, avp_hdr->avp_vendor); |
182 CHECK_FCT(find_avp(nextavp, conf_index, level+1, candidates)); | 177 CHECK_FCT(find_avp(nextavp, conf_index, level+1, candidates)); |
183 } else { | 178 } else { |
184 TRACE_DEBUG(INFO, "[rt_ereg] found AVP %d (vendor %d)", avp_hdr->avp_code, avp_hdr->avp_vendor); | 179 struct dictionary * dict; |
180 LOG_D("[rt_ereg] found AVP %d (vendor %d)", avp_hdr->avp_code, avp_hdr->avp_vendor); | |
181 CHECK_FCT(fd_dict_getdict(what, &dict)); | |
182 CHECK_FCT_DO(fd_msg_parse_dict(nextavp, dict, NULL), /* nothing */); | |
185 if (avp_hdr->avp_value != NULL) { | 183 if (avp_hdr->avp_value != NULL) { |
184 LOG_A("avp_hdr->avp_value NOT NULL, matching"); | |
186 #ifndef HAVE_REG_STARTEND | 185 #ifndef HAVE_REG_STARTEND |
187 int ret; | 186 int ret; |
188 | 187 |
189 /* Lock the buffer */ | 188 /* Lock the buffer */ |
190 CHECK_POSIX( pthread_mutex_lock(&mtx) ); | 189 CHECK_POSIX( pthread_mutex_lock(&mtx) ); |
221 static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates) | 220 static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates) |
222 { | 221 { |
223 msg_or_avp *where; | 222 msg_or_avp *where; |
224 int j, ret; | 223 int j, ret; |
225 | 224 |
226 TRACE_ENTRY("%p %p %p", cbdata, *pmsg, candidates); | 225 LOG_A("[rt_ereg] rtereg_out arguments: %p %p %p", cbdata, *pmsg, candidates); |
227 | 226 |
228 CHECK_PARAMS(pmsg && *pmsg && candidates); | 227 CHECK_PARAMS(pmsg && *pmsg && candidates); |
229 | 228 |
230 if (pthread_rwlock_rdlock(&rte_lock) != 0) { | 229 if (pthread_rwlock_rdlock(&rte_lock) != 0) { |
231 fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME); | 230 fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME); |
236 if (!FD_IS_LIST_EMPTY(candidates)) { | 235 if (!FD_IS_LIST_EMPTY(candidates)) { |
237 /* Now search the AVPs in the message */ | 236 /* Now search the AVPs in the message */ |
238 | 237 |
239 for (j=0; j<rtereg_conf_size; j++) { | 238 for (j=0; j<rtereg_conf_size; j++) { |
240 where = *pmsg; | 239 where = *pmsg; |
241 TRACE_DEBUG(INFO, "[rt_ereg] iterating over AVP group %d", j); | 240 LOG_D("[rt_ereg] iterating over AVP group %d", j); |
242 if ((ret=find_avp(where, j, 0, candidates)) != 0) { | 241 if ((ret=find_avp(where, j, 0, candidates)) != 0) { |
243 break; | 242 break; |
244 } | 243 } |
245 } | 244 } |
246 } | 245 } |
299 } | 298 } |
300 | 299 |
301 /* entry point */ | 300 /* entry point */ |
302 static int rtereg_entry(char * conffile) | 301 static int rtereg_entry(char * conffile) |
303 { | 302 { |
304 TRACE_ENTRY("%p", conffile); | 303 LOG_A("[rt_ereg] started with conffile '%p'", conffile); |
305 | 304 |
306 rt_ereg_config_file = conffile; | 305 rt_ereg_config_file = conffile; |
307 | 306 |
308 if (rtereg_init() != 0) { | 307 if (rtereg_init() != 0) { |
309 return 1; | 308 return 1; |
310 } | 309 } |
311 | 310 |
312 /* Register reload callback */ | 311 /* Register reload callback */ |
313 CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr)); | 312 CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr)); |
314 | 313 |
319 | 318 |
320 static int rtereg_init_config(void) | 319 static int rtereg_init_config(void) |
321 { | 320 { |
322 /* Initialize the configuration */ | 321 /* Initialize the configuration */ |
323 if ((rtereg_conf=malloc(sizeof(*rtereg_conf))) == NULL) { | 322 if ((rtereg_conf=malloc(sizeof(*rtereg_conf))) == NULL) { |
324 TRACE_DEBUG(INFO, "malloc failured"); | 323 LOG_E("[rt_ereg] malloc failured"); |
325 return 1; | 324 return 1; |
326 } | 325 } |
327 rtereg_conf_size = 1; | 326 rtereg_conf_size = 1; |
328 memset(rtereg_conf, 0, sizeof(*rtereg_conf)); | 327 memset(rtereg_conf, 0, sizeof(*rtereg_conf)); |
329 | 328 |
330 /* Parse the configuration file */ | 329 /* Parse the configuration file */ |
364 } | 363 } |
365 | 364 |
366 /* Unload */ | 365 /* Unload */ |
367 static void rtereg_fini(void) | 366 static void rtereg_fini(void) |
368 { | 367 { |
369 TRACE_ENTRY(); | |
370 | |
371 /* Unregister the cb */ | 368 /* Unregister the cb */ |
372 CHECK_FCT_DO( fd_rt_out_unregister ( rtereg_hdl, NULL ), /* continue */ ); | 369 CHECK_FCT_DO( fd_rt_out_unregister ( rtereg_hdl, NULL ), /* continue */ ); |
373 | 370 |
371 #ifndef HAVE_REG_STARTEND | |
372 free(buf); | |
373 buf = NULL; | |
374 #endif /* HAVE_REG_STARTEND */ | |
375 | |
376 if (pthread_rwlock_wrlock(&rte_lock) != 0) { | |
377 fd_log_error("%s: write-locking failed in fini, giving up", MODULE_NAME); | |
378 return; | |
379 } | |
374 /* Destroy the data */ | 380 /* Destroy the data */ |
375 rtereg_conf_free(rtereg_conf, rtereg_conf_size); | 381 rtereg_conf_free(rtereg_conf, rtereg_conf_size); |
376 rtereg_conf = NULL; | 382 rtereg_conf = NULL; |
377 rtereg_conf_size = 0; | 383 rtereg_conf_size = 0; |
378 #ifndef HAVE_REG_STARTEND | 384 |
379 free(buf); | 385 if (pthread_rwlock_unlock(&rte_lock) != 0) { |
380 buf = NULL; | 386 fd_log_error("%s: write-unlocking failed in fini", MODULE_NAME); |
381 #endif /* HAVE_REG_STARTEND */ | 387 return; |
388 } | |
382 | 389 |
383 /* Done */ | 390 /* Done */ |
384 return ; | 391 return ; |
385 } | 392 } |
386 | 393 |