int module_post_auth(int type, REQUEST *request);
int indexed_modcall(int comp, int idx, REQUEST *request);
+/*
+ * For now, these are strongly tied together.
+ */
+int virtual_servers_load(CONF_SECTION *config);
+void virtual_servers_free(time_t when);
+
+
#endif /* RADIUS_MODULES_H */
char *request_log_file = NULL;
char *debug_condition = NULL;
+typedef struct cached_config_t {
+ struct cached_config_t *next;
+ time_t created;
+ CONF_SECTION *cs;
+} cached_config_t;
+
+static cached_config_t *cs_cache = NULL;
+
/*
* Temporary local variables for parsing the configuration
* file.
CONF_PAIR *cp;
CONF_SECTION *cs;
struct stat statbuf;
+ cached_config_t *cc;
char buffer[1024];
if (stat(radius_dir, &statbuf) < 0) {
}
}
+ cc = rad_malloc(sizeof(*cc));
+ memset(cc, 0, sizeof(*cc));
+
+ cc->cs = cs;
+ rad_assert(cs_cache == NULL);
+ cs_cache = cc;
+
return 0;
}
*/
int free_mainconfig(void)
{
+ cached_config_t *cc, *next;
+
+ virtual_servers_free(0);
+
+ /*
+ * Free all of the cached configurations.
+ */
+ for (cc = cs_cache; cc != NULL; cc = next) {
+ next = cc->next;
+ cf_section_free(&cc->cs);
+ free(cc);
+ }
+
/*
* Clean up the configuration data
* structures.
*/
- cf_section_free(&mainconfig.config);
realms_free();
listen_free(&mainconfig.listen);
dict_free();
void hup_mainconfig(void)
{
+ cached_config_t *cc;
+ CONF_SECTION *cs;
+ char buffer[1024];
+
+ /* Read the configuration file */
+ snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf",
+ radius_dir, mainconfig.name);
+ if ((cs = cf_file_read(buffer)) == NULL) {
+ radlog(L_ERR, "Failed to re-read %s", buffer);
+ return;
+ }
+
+ cc = rad_malloc(sizeof(*cc));
+ memset(cc, 0, sizeof(*cc));
+
+ cc->created = time(NULL);
+ cc->cs = cs;
+ cc->next = cs_cache;
+ cs_cache = cc;
+
+ /*
+ * Load new servers BEFORE freeing old ones.
+ */
+ virtual_servers_load(cs);
+
+ virtual_servers_free(cc->created - 120);
+
+ /*
+ * Unfortunatelty... we use the OLD configuration here.
+ */
module_hup(cf_section_sub_find(mainconfig.config, "modules"));
}
typedef struct virtual_server_t {
const char *name;
+ time_t created;
CONF_SECTION *cs;
rbtree_t *components;
struct virtual_server_t *next;
free(server);
}
+void virtual_servers_free(time_t when)
+{
+ int i;
+ virtual_server_t **last;
+
+ for (i = 0; i < VIRTUAL_SERVER_HASH_SIZE; i++) {
+ virtual_server_t *server, *next;
+
+ last = &virtual_servers[i];
+ for (server = virtual_servers[i];
+ server != NULL;
+ server = next) {
+ next = server->next;
+
+ /*
+ * If we delete it, fix the links so that
+ * we don't orphan anything.
+ *
+ * Otherwise, the last pointer gets set to
+ * the one we didn't delete.
+ */
+ if ((when == 0) || (server->created < when)) {
+ *last = server->next;
+ virtual_server_free(server);
+ } else {
+ last = &(server->next);
+ }
+ }
+ }
+}
+
static void indexed_modcallable_free(void *data)
{
indexed_modcallable *c = data;
*/
int detach_modules(void)
{
- int i;
-
- for (i = 0; i < VIRTUAL_SERVER_HASH_SIZE; i++) {
- virtual_server_t *server, *next;
-
- for (server = virtual_servers[i];
- server != NULL;
- server = next) {
- next = server->next;
- virtual_server_free(server);
- }
- }
-
rbtree_free(instance_tree);
rbtree_free(module_tree);
memset(server, 0, sizeof(*server));
server->name = name;
+ server->created = time(NULL);
server->cs = cs;
server->components = components;
/*
* Load all of the virtual servers.
*/
-int virtual_server_load(CONF_SECTION *config)
+int virtual_servers_load(CONF_SECTION *config)
{
int null_server = FALSE;
CONF_SECTION *cs;
return 0;
}
-
int module_hup_module(CONF_SECTION *cs, module_instance_t *node, time_t when)
{
void *insthandle = NULL;
}
}
- if (virtual_server_load(config) < 0) return -1;
+ if (virtual_servers_load(config) < 0) return -1;
return 0;
}