Mercurial > hg > freeDiameter
comparison extensions/app_radgw/rgw_plugins.c @ 256:042af0000c0a
Ported the auth plugin
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Fri, 16 Apr 2010 16:57:39 +0900 |
parents | cb4307a1cd29 |
children | 5df55136361b |
comparison
equal
deleted
inserted
replaced
255:cb4307a1cd29 | 256:042af0000c0a |
---|---|
51 struct rgwp_config *cs; /* the (private) state returned by rgwp_conf_parse */ | 51 struct rgwp_config *cs; /* the (private) state returned by rgwp_conf_parse */ |
52 | 52 |
53 int type; /* this extension is called for messages received on this(these) server port(s) only */ | 53 int type; /* this extension is called for messages received on this(these) server port(s) only */ |
54 unsigned char *cc; /* array of command codes, or NULL for all cc */ | 54 unsigned char *cc; /* array of command codes, or NULL for all cc */ |
55 size_t cc_len; /* size of the previous array */ | 55 size_t cc_len; /* size of the previous array */ |
56 | |
57 char *plgname; /* basename of the plugin, for debug messages. To be freed when object is detroyed */ | |
58 char *conffile; /* configuration file passed to the extension, or "(null)". To be freed when object is destroyed */ | |
59 }; | 56 }; |
60 | 57 |
61 /* Accelerators for each command code (one for each port). These accelerators are built on-demand, as a cache, after start_cache function has been called. */ | 58 /* Accelerators for each command code (one for each port). These accelerators are built on-demand, as a cache, after start_cache function has been called. */ |
62 static struct fd_list plg_accel_auth = FD_LIST_INITIALIZER(plg_accel_auth); | 59 static struct fd_list plg_accel_auth = FD_LIST_INITIALIZER(plg_accel_auth); |
63 static struct fd_list plg_accel_acct = FD_LIST_INITIALIZER(plg_accel_acct); | 60 static struct fd_list plg_accel_acct = FD_LIST_INITIALIZER(plg_accel_acct); |
174 | 171 |
175 int rgw_plg_add( char * plgfile, char * conffile, int type, unsigned char ** codes_array, size_t codes_sz ) | 172 int rgw_plg_add( char * plgfile, char * conffile, int type, unsigned char ** codes_array, size_t codes_sz ) |
176 { | 173 { |
177 struct plg_descr * new; | 174 struct plg_descr * new; |
178 int ret = 0; | 175 int ret = 0; |
179 char * tmp; | |
180 | 176 |
181 TRACE_ENTRY("%p %p %d %p %zi", plgfile, conffile, type, codes_array, codes_sz); | 177 TRACE_ENTRY("%p %p %d %p %zi", plgfile, conffile, type, codes_array, codes_sz); |
182 | 178 |
183 CHECK_PARAMS( plgfile && type && codes_array && (cache_started == 0) ); | 179 CHECK_PARAMS( plgfile && type && codes_array && (cache_started == 0) ); |
184 | |
185 CHECK_MALLOC( tmp = strdup(plgfile) ); | |
186 | 180 |
187 CHECK_MALLOC( new = malloc(sizeof(struct plg_descr)) ); | 181 CHECK_MALLOC( new = malloc(sizeof(struct plg_descr)) ); |
188 memset(new, 0, sizeof(struct plg_descr)); | 182 memset(new, 0, sizeof(struct plg_descr)); |
189 | 183 |
190 fd_list_init(&new->chain, new); | 184 fd_list_init(&new->chain, new); |
191 | |
192 /* Copy names, for debug */ | |
193 CHECK_MALLOC( new->plgname = strdup(basename(tmp)) ); /* basename is a stupid function :( */ | |
194 free(tmp); | |
195 CHECK_MALLOC( new->conffile = conffile ?: strdup("(null)") ); | |
196 | 185 |
197 /* Try and load the plugin */ | 186 /* Try and load the plugin */ |
198 TRACE_DEBUG(FULL, "Loading plugin: %s", plgfile); | 187 TRACE_DEBUG(FULL, "Loading plugin: %s", plgfile); |
199 new->dlo = dlopen(plgfile, RTLD_NOW | RTLD_GLOBAL); | 188 new->dlo = dlopen(plgfile, RTLD_NOW | RTLD_GLOBAL); |
200 if (new->dlo == NULL) { | 189 if (new->dlo == NULL) { |
209 /* An error occured */ | 198 /* An error occured */ |
210 fd_log_debug("Unable to resolve 'rgwp_descriptor' in plugin '%s':\n %s\n", plgfile, dlerror()); | 199 fd_log_debug("Unable to resolve 'rgwp_descriptor' in plugin '%s':\n %s\n", plgfile, dlerror()); |
211 goto error; | 200 goto error; |
212 } | 201 } |
213 | 202 |
214 /* Now parse the configuration file, this will initialize all extension states and store it in the returned pointer (the subextensions must be re-entrant) */ | 203 TRACE_DEBUG(FULL, "Plugin '%s' found in file '%s'", new->descriptor->rgwp_name, plgfile); |
204 | |
205 /* Now parse the configuration file, this will initialize all plugin states and store it in the "cs" pointer (the plugin must be re-entrant, so no global state) */ | |
215 if (new->descriptor->rgwp_conf_parse) { | 206 if (new->descriptor->rgwp_conf_parse) { |
216 TRACE_DEBUG(FULL, "Parsing plugin conf file: %s", new->conffile ); | 207 CHECK_FCT_DO( (*(new->descriptor->rgwp_conf_parse))(conffile, &new->cs), |
217 new->cs = (*(new->descriptor->rgwp_conf_parse))(conffile); | 208 { |
218 if (new->cs == NULL) { | 209 fd_log_debug("An error occurred while parsing configuration file '%s' in plugin '%s', aborting...\n", conffile, plgfile); |
219 fd_log_debug("An error occurred while parsing configuration file '%s' in plugin '%s', aborting...\n", new->conffile, new->plgname); | 210 goto error; |
220 goto error; | 211 } ); |
221 } | |
222 TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s%s%s%s' initialized.", new->plgname, conffile ? " (" : "", conffile ? new->conffile : "", conffile ? ")" : ""); | |
223 } | 212 } |
224 | 213 |
225 /* Now sort the array (very simple algorithm, but this list is usually small) of command codes and save */ | 214 /* Now sort the array (very simple algorithm, but this list is usually small) of command codes and save */ |
226 if (*codes_array && codes_sz) { | 215 if (*codes_array && codes_sz) { |
227 int i; | 216 int i; |
280 fd_log_debug("[app_radgw] --- List of registered plugins:\n"); | 269 fd_log_debug("[app_radgw] --- List of registered plugins:\n"); |
281 for (ptr = plg_list.next; ptr != &plg_list; ptr = ptr->next) { | 270 for (ptr = plg_list.next; ptr != &plg_list; ptr = ptr->next) { |
282 | 271 |
283 plg = (struct plg_descr *)ptr; | 272 plg = (struct plg_descr *)ptr; |
284 | 273 |
285 fd_log_debug(" %-25s ( %-25s ) - types: %s%s, codes: ", | 274 fd_log_debug(" %-25s ( %p ) - types: %s%s, codes: ", |
286 plg->plgname, | 275 plg->descriptor->rgwp_name, |
287 basename(plg->conffile), | 276 plg->cs, |
288 plg->type & RGW_PLG_TYPE_AUTH ? "Au" : " ", | 277 plg->type & RGW_PLG_TYPE_AUTH ? "Au" : " ", |
289 plg->type & RGW_PLG_TYPE_ACCT ? "Ac" : " "); | 278 plg->type & RGW_PLG_TYPE_ACCT ? "Ac" : " "); |
290 | 279 |
291 if (plg->cc) { | 280 if (plg->cc) { |
292 int i; | 281 int i; |
314 struct plg_accel * accel = (struct plg_accel *)ptraccel; | 303 struct plg_accel * accel = (struct plg_accel *)ptraccel; |
315 fd_log_debug(" auth, code %02hhu:\n", accel->ccode); | 304 fd_log_debug(" auth, code %02hhu:\n", accel->ccode); |
316 | 305 |
317 for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) { | 306 for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) { |
318 struct plg_accel_item * item = (struct plg_accel_item *)ptr; | 307 struct plg_accel_item * item = (struct plg_accel_item *)ptr; |
319 fd_log_debug(" %-15s (%s)\n", item->plg->plgname, basename(item->plg->conffile)); | 308 fd_log_debug(" %-15s (%p)\n", item->plg->descriptor->rgwp_name, item->plg->cs); |
320 } | 309 } |
321 } | 310 } |
322 for (ptraccel = plg_accel_acct.next; ptraccel != &plg_accel_acct; ptraccel = ptraccel->next) { | 311 for (ptraccel = plg_accel_acct.next; ptraccel != &plg_accel_acct; ptraccel = ptraccel->next) { |
323 struct plg_accel * accel = (struct plg_accel *)ptraccel; | 312 struct plg_accel * accel = (struct plg_accel *)ptraccel; |
324 fd_log_debug(" acct, code %02hhu:\n", accel->ccode); | 313 fd_log_debug(" acct, code %02hhu:\n", accel->ccode); |
325 | 314 |
326 for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) { | 315 for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) { |
327 struct plg_accel_item * item = (struct plg_accel_item *)ptr; | 316 struct plg_accel_item * item = (struct plg_accel_item *)ptr; |
328 fd_log_debug(" %-15s (%s)\n", item->plg->plgname, basename(item->plg->conffile)); | 317 fd_log_debug(" %-15s (%p)\n", item->plg->descriptor->rgwp_name, item->plg->cs); |
329 } | 318 } |
330 } | 319 } |
331 | 320 |
332 | 321 |
333 CHECK_POSIX_DO( pthread_rwlock_unlock(&plg_lock), ); | 322 CHECK_POSIX_DO( pthread_rwlock_unlock(&plg_lock), ); |
356 /* Loop in the list of extensions */ | 345 /* Loop in the list of extensions */ |
357 for (li = head->next; li != head; li = li->next) { | 346 for (li = head->next; li != head; li = li->next) { |
358 struct plg_descr * plg = ((struct plg_accel_item *) li)->plg; | 347 struct plg_descr * plg = ((struct plg_accel_item *) li)->plg; |
359 | 348 |
360 if (plg->descriptor->rgwp_rad_req) { | 349 if (plg->descriptor->rgwp_rad_req) { |
361 TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->plgname); | 350 TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name); |
362 ret = (*plg->descriptor->rgwp_rad_req)(plg->cs, *session, &(*rad)->radius, &rad_ans, diam_msg, cli); | 351 ret = (*plg->descriptor->rgwp_rad_req)(plg->cs, *session, &(*rad)->radius, &rad_ans, diam_msg, cli); |
363 if (ret) | 352 if (ret) |
364 break; | 353 break; |
365 } else { | 354 } else { |
366 TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->plgname); | 355 TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->descriptor->rgwp_name); |
367 } | 356 } |
368 } | 357 } |
369 | 358 |
370 CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); | 359 CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); |
371 | 360 |
417 /* Loop in the list of extensions */ | 406 /* Loop in the list of extensions */ |
418 for (li = head->next; li != head; li = li->next) { | 407 for (li = head->next; li != head; li = li->next) { |
419 struct plg_descr * plg = ((struct plg_accel_item *) li)->plg; | 408 struct plg_descr * plg = ((struct plg_accel_item *) li)->plg; |
420 | 409 |
421 if (plg->descriptor->rgwp_diam_ans) { | 410 if (plg->descriptor->rgwp_diam_ans) { |
422 TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->plgname); | 411 TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name); |
423 ret = (*plg->descriptor->rgwp_diam_ans)(plg->cs, session, diam_ans, rad_ans, (void *)cli); | 412 ret = (*plg->descriptor->rgwp_diam_ans)(plg->cs, session, diam_ans, rad_ans, (void *)cli); |
424 if (ret) | 413 if (ret) |
425 break; | 414 break; |
426 } else { | 415 } else { |
427 TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->plgname); | 416 TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->descriptor->rgwp_name); |
428 } | 417 } |
429 } | 418 } |
430 | 419 |
431 CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); | 420 CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); |
432 | 421 |
490 | 479 |
491 /* Now destroy all plugins information */ | 480 /* Now destroy all plugins information */ |
492 while ( ! FD_IS_LIST_EMPTY(&plg_list) ) { | 481 while ( ! FD_IS_LIST_EMPTY(&plg_list) ) { |
493 struct plg_descr * plg = (struct plg_descr *) plg_list.next; | 482 struct plg_descr * plg = (struct plg_descr *) plg_list.next; |
494 fd_list_unlink(&plg->chain); | 483 fd_list_unlink(&plg->chain); |
495 free(plg->conffile); | |
496 free(plg->cc); | 484 free(plg->cc); |
497 if (plg->cs && plg->descriptor && plg->descriptor->rgwp_conf_free ) { | 485 if (plg->descriptor && plg->descriptor->rgwp_conf_free ) { |
498 TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s' cleaning up...", plg->plgname); | 486 TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s' cleaning up...", plg->descriptor->rgwp_name); |
499 (*plg->descriptor->rgwp_conf_free)(plg->cs); | 487 (*plg->descriptor->rgwp_conf_free)(plg->cs); |
500 } | 488 } |
501 free(plg->plgname); | 489 if (plg->dlo) |
502 dlclose(plg->dlo); | 490 dlclose(plg->dlo); |
503 free(plg); | 491 free(plg); |
504 } | 492 } |
505 | 493 |
506 CHECK_POSIX_DO( pthread_rwlock_unlock( &plg_lock), ); | 494 CHECK_POSIX_DO( pthread_rwlock_unlock( &plg_lock), ); |
507 } | 495 } |