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
"Welcome to our mercurial repository"