Moved the 'clients', 'realms', and 'config' variables into the
authoraland <aland>
Mon, 28 Oct 2002 19:13:31 +0000 (19:13 +0000)
committeraland <aland>
Mon, 28 Oct 2002 19:13:31 +0000 (19:13 +0000)
'mainfconfig' data structure, so everyone can see them.

Moved the signal handling code to be a bit better (yet again)

When receiving a SIGTERM, (or any other fatal signal), try
our best to clean up and exit.

src/include/radiusd.h
src/main/client.c
src/main/conffile.c
src/main/files.c
src/main/radiusd.c

index 2cf964d..6c05dca 100644 (file)
@@ -11,6 +11,7 @@
 #include "radpaths.h"
 #include "conf.h"
 #include "missing.h"
+#include "conffile.h"
 
 #include <stdarg.h>
 
@@ -138,6 +139,9 @@ typedef struct main_config_t {
        char            *nospace_time;
        char            *log_file;
        char            *checkrad;
+       CONF_SECTION    *config;
+       RADCLIENT       *clients;
+       REALM           *realms;
 } MAIN_CONFIG_T;
 
 #define DEBUG  if(debug_flag)log_debug
@@ -245,10 +249,12 @@ int               read_clients_file(const char *file);
 RADCLIENT      *client_find(uint32_t ipno);
 const char     *client_name(uint32_t ipno);
 void           client_walk(void);
+void           clients_free(RADCLIENT *cl);
 
 /* files.c */
 REALM          *realm_find(const char *, int);
 REALM          *realm_findbyaddr(uint32_t ipno, int port);
+void           realm_free(REALM *cl);
 void           realm_disable(uint32_t ipno, int port);
 int            pairlist_read(const char *file, PAIR_LIST **list, int complain);
 void           pairlist_free(PAIR_LIST **);
index aaa55f0..6d82ca0 100644 (file)
@@ -42,12 +42,10 @@ static const char rcsid[] = "$Id$";
 #include "radiusd.h"
 #include "conffile.h"
 
-RADCLIENT *clients = NULL;
-
 /*
  *     Free a RADCLIENT list.
  */
-static void clients_free(RADCLIENT *cl)
+void clients_free(RADCLIENT *cl)
 {
        RADCLIENT *next;
 
@@ -74,8 +72,8 @@ int read_clients_file(const char *file)
        int lineno = 0;
        char *p;
 
-       clients_free(clients);
-       clients = NULL;
+       clients_free(mainconfig.clients);
+       mainconfig.clients = NULL;
 
        if ((fp = fopen(file, "r")) == NULL) {
                /* The clients file is no longer required.  All configuration
@@ -212,8 +210,8 @@ int read_clients_file(const char *file)
                        strNcpy(c->longname, hostnm, sizeof(c->longname));
                }
 
-               c->next = clients;
-               clients = c;
+               c->next = mainconfig.clients;
+               mainconfig.clients = c;
        }
        fclose(fp);
 
@@ -229,7 +227,7 @@ RADCLIENT *client_find(uint32_t ipaddr)
        RADCLIENT *cl;
        RADCLIENT *match = NULL;
 
-       for (cl = clients; cl; cl = cl->next) {
+       for (cl = mainconfig.clients; cl; cl = cl->next) {
                if ((ipaddr & cl->netmask) == cl->ipaddr) {
                        if ((!match) ||
                            (ntohl(cl->netmask) > ntohl(match->netmask))) {
@@ -250,7 +248,7 @@ void client_walk(void)
        RADCLIENT *cl;
        char host_ipaddr[16];
 
-       for (cl = clients; cl != NULL; cl = cl->next)
+       for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
                radlog(L_ERR, "client: client_walk: %s\n",
                                ip_ntoa(host_ipaddr, cl->ipaddr));
 }
index 7fa7859..1f5965a 100644 (file)
@@ -71,13 +71,9 @@ struct conf_part {
        struct conf_item *children;
 };
 
-CONF_SECTION *config = NULL;
-
 /*
  *     Yucky hacks.
  */
-extern RADCLIENT *clients;
-extern REALM *realms;
 extern int max_proxies;
 
 static int generate_realms(const char *filename);
@@ -833,8 +829,8 @@ int read_radius_conf_file(void)
         *      Free the old configuration data, and replace it
         *      with the new one.
         */
-       cf_section_free(&config);
-       config = cs;
+       cf_section_free(&mainconfig.config);
+       mainconfig.config = cs;
        
        /*
         *      And parse the directory configuration values.
@@ -918,8 +914,8 @@ static int generate_realms(const char *filename)
        char *s, *t, *authhost, *accthost;
 
        tail = &my_realms;
-       for (cs = cf_subsection_find_next(config, NULL, "realm"); cs != NULL;
-                       cs = cf_subsection_find_next(config, cs, "realm")) {
+       for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm"); cs != NULL;
+                       cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
                if (!cs->name2) {
                        radlog(L_CONS|L_ERR, "%s[%d]: Missing realm name", filename, cs->item.lineno);
                        return -1;
@@ -1066,43 +1062,9 @@ static int generate_realms(const char *filename)
         *      And make these realms preferred over the ones
         *      in the 'realms' file.
         */
-       *tail = realms;
-       realms = my_realms;
+       *tail = mainconfig.realms;
+       mainconfig.realms = my_realms;
        
-       /*Setup node and total info for multi-listed realms*/
-       for (c = realms; c; c = c->next) {
-               if(c->chose == 1) {
-                       continue;
-               }
-               else {
-                       int i = 0, b = 0;
-                       REALM *rptr, *r_array[max_proxies];
-                       for(rptr = c; rptr; rptr = rptr->next) {
-                               /*if realm matches*/
-                               if(strcasecmp(rptr->realm, c->realm) == 0) {
-                                       i++;
-                                       r_array[i] = rptr;
-                                       rptr->chose = 1;
-                                       rptr->node = i;
-                               }
-                       }
-                       if (i > 1) {
-                               for(b = 1; b <= i; b++) {
-                                       rptr = r_array[b];
-                                       rptr->total = i;
-                               }
-                       }
-                       else {
-                               c->total = 0;
-                       }
-               }
-       }
-       
-       /*Set chose flag back to default (0) on all realms*/
-       for (c = realms; c; c = c->next) {
-               c->chose = 0;
-       }
-
        return 0;
 }
 
@@ -1117,8 +1079,8 @@ static int generate_clients(const char *filename)
        char            *hostnm, *secret, *shortnm, *netmask;
        char            *nastype, *login, *password;
 
-       for (cs = cf_subsection_find_next(config, NULL, "client"); cs != NULL; 
-                       cs = cf_subsection_find_next(config, cs, "client")) {
+       for (cs = cf_subsection_find_next(mainconfig.config, NULL, "client"); cs != NULL; 
+            cs = cf_subsection_find_next(mainconfig.config, cs, "client")) {
                if (!cs->name2) {
                        radlog(L_CONS|L_ERR, "%s[%d]: Missing client name", filename, cs->item.lineno);
                        return -1;
@@ -1239,8 +1201,8 @@ static int generate_clients(const char *filename)
                if(password != NULL)
                        strcpy(c->password, password);
 
-               c->next = clients;
-               clients = c;
+               c->next =mainconfig. clients;
+               mainconfig.clients = c;
        }
 
        return 0;
@@ -1255,7 +1217,7 @@ CONF_PAIR *cf_pair_find(CONF_SECTION *section, const char *name)
        CONF_ITEM       *ci;
 
        if (section == NULL) {
-               section = config;
+               section = mainconfig.config;
        }
 
        for (ci = section->children; ci; ci = ci->next) {
@@ -1354,9 +1316,9 @@ CONF_PAIR *cf_pair_find_next(CONF_SECTION *section, CONF_PAIR *pair, const char
 CONF_SECTION *cf_section_find(const char *name)
 {
        if (name)
-               return cf_section_sub_find(config, name);
+               return cf_section_sub_find(mainconfig.config, name);
        else
-               return config;
+               return mainconfig.config;
 }
 
 /*
@@ -1446,6 +1408,7 @@ int cf_item_is_section(CONF_ITEM *item)
 }
 
 
+#if 0
 /* 
  * JMG dump_config tries to dump the config structure in a readable format
  * 
@@ -1485,5 +1448,6 @@ static int dump_config_section(CONF_SECTION *cs, int indent)
 
 int dump_config(void)
 {
-       return dump_config_section(config, 0);
+       return dump_config_section(mainconfig.config, 0);
 }
+#endif
index 194e0ff..eb88e3a 100644 (file)
@@ -44,8 +44,6 @@ static const char rcsid[] = "$Id$";
 extern int proxy_dead_time;
 int maximum_proxies;
 
-REALM *realms = NULL;
-
 /*
  *     Free a PAIR_LIST
  */
@@ -349,7 +347,7 @@ static void debug_pair_list(PAIR_LIST *pl)
 /*
  *     Free a REALM list.
  */
-static void realm_free(REALM *cl)
+void realm_free(REALM *cl)
 {
        REALM *next;
 
@@ -374,9 +372,9 @@ int read_realms_file(const char *file)
        int lineno = 0;
        REALM *c, **tail;
 
-       realm_free(realms);
-       realms = NULL;
-       tail = &realms;
+       realm_free(mainconfig.realms);
+       mainconfig.realms = NULL;
+       tail = &mainconfig.realms;
 
        if ((fp = fopen(file, "r")) == NULL) {
                /* The realms file is not mandatory.  If it exists it will
@@ -503,7 +501,7 @@ void realm_disable(uint32_t ipaddr, int port)
        time_t now;
 
        now = time(NULL);
-       for(cl = realms; cl; cl = cl->next)
+       for(cl = mainconfig.realms; cl; cl = cl->next)
                if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
                        cl->active = FALSE;
                        cl->wakeup = now + proxy_dead_time;
@@ -538,7 +536,7 @@ REALM *realm_find(const char *realm, int acct)
                realm = "NULL";
        }
        
-       for (cl = realms; cl; cl = cl->next) {
+       for (cl = mainconfig.realms; cl; cl = cl->next) {
                /*
                 *      Wake up any sleeping realm.
                 */
@@ -579,7 +577,7 @@ REALM *realm_find(const char *realm, int acct)
                        if(cl->total > 1 && cl->ldflag == 1) {
                                /*Get all of the realms from initial list*/
                                for(i = 1; i <= cl->total; i++) {
-                                       for(realmptr = realms; realmptr; 
+                                       for(realmptr = mainconfig.realms; realmptr; 
                                             realmptr = realmptr->next) {
                                                if((strcasecmp(realmptr->realm,
                                                    cl->realm)) == 0 &&
@@ -717,7 +715,7 @@ REALM *realm_findbyaddr(uint32_t ipaddr, int port)
         *      If we get a packet from an end server, then we mark it
         *      as active, and return the realm.
         */
-       for(cl = realms; cl != NULL; cl = cl->next)
+       for(cl = mainconfig.realms; cl != NULL; cl = cl->next)
                if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
                        cl->active = TRUE;
                        return cl;
@@ -736,9 +734,9 @@ void check_proxies(int max_config) {
        REALM *next, *rptr;
        if(max_config > 0) {
                maximum_proxies = max_config;
-               for(rptr=realms; rptr; rptr = rptr->next) {
+               for(rptr=mainconfig.realms; rptr; rptr = rptr->next) {
                        if(rptr->total > max_config || rptr->total >= 1) {
-                               for(next = realms; next; next = next->next) {
+                               for(next = mainconfig.realms; next; next = next->next) {
                                        if(next->ldflag != 0 &&
                                            next->ldflag != 1) {
                                                radlog(L_ERR,
index 57cb4f1..7dd3141 100644 (file)
@@ -548,16 +548,10 @@ int main(int argc, char *argv[])
        spawn_flag = TRUE;
        radius_dir = strdup(RADIUS_DIR);
 
-       signal(SIGHUP, sig_hup);
-       signal(SIGPIPE, SIG_IGN);       
-signal(SIGINT, sig_fatal);
-       signal(SIGQUIT, sig_fatal);
-       signal(SIGTERM, sig_fatal);
-
-       /* this is right for threads, too, right?  
-        * (Threads shouldn't get signals (from us) -- just be pthread_cancel()led.)
+       /*
+        *      Ensure that the configuration is initialized.
         */
-       signal(SIGCHLD, sig_cleanup);
+       memset(&mainconfig, 0, sizeof(mainconfig));
 
        /*  Process the options.  */
        while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
@@ -934,6 +928,30 @@ signal(SIGINT, sig_fatal);
                                buffer, auth_port, acct_port);
        }
 
+       /*
+        *      Now that we've set everything up, we can install the signal
+        *      handlers.  Before this, if we get any signal, we don't know
+        *      what to do, so we might as well do the default, and die.
+        */
+       signal(SIGHUP, sig_hup);
+       signal(SIGPIPE, SIG_IGN);       
+       signal(SIGTERM, sig_fatal);
+
+       /*
+        *      If we're debugging, then a CTRL-C will cause the
+        *      server to die immediately.  Use SIGTERM to shut down
+        *      the server cleanly in that case.
+        */
+       if (debug_flag == 0) {
+               signal(SIGINT, sig_fatal);
+               signal(SIGQUIT, sig_fatal);
+       }
+
+       /* this is right for threads, too, right?  
+        * (Threads shouldn't get signals (from us) -- just be pthread_cancel()led.)
+        */
+       signal(SIGCHLD, sig_cleanup);
+
        radlog(L_INFO, "Ready to process requests.");
        start_time = time(NULL);
 
@@ -941,6 +959,59 @@ signal(SIGINT, sig_fatal);
         *  Receive user requests
         */
        for (;;) {
+               /*
+                *      If we've been told to exit, then do so,
+                *      even if we have data waiting.
+                */
+               if (do_exit) {
+                       DEBUG("Exiting...");
+
+                       /*
+                        *      Ignore the TERM signal: we're about
+                        *      to die.
+                        */
+                       signal(SIGTERM, SIG_IGN);
+
+                       /*
+                        *      Send a TERM signal to all associated
+                        *      processes (including us, which gets
+                        *      ignored.)
+                        */
+                       kill(-radius_pid, SIGTERM);
+
+                       /*
+                        *      FIXME: Kill child threads, and
+                        *      clean up?
+                        */
+
+                       /*
+                        *      Detach any modules.
+                        */
+                       detach_modules();
+                       
+                       /*
+                        *      FIXME: clean up any active REQUEST
+                        *      handles.
+                        */
+
+                       /*
+                        *      Clean up the configuration data
+                        *      structures.
+                        */
+                       cf_section_free(&mainconfig.config);
+                       realm_free(mainconfig.realms);
+                       clients_free(mainconfig.clients);
+
+                       /*
+                        *      SIGTERM gets do_exit=0,
+                        *      and we want to exit cleanly.
+                        *
+                        *      Other signals make us exit
+                        *      with an error status.
+                        */
+                       exit(do_exit - 1);
+               }
+
                if (need_reload) {
                        if (reread_config(TRUE) < 0) {
                                exit(1);
@@ -971,29 +1042,13 @@ signal(SIGINT, sig_fatal);
 #endif
 
                status = select(max_fd + 1, &readfds, NULL, NULL, tv);
-
-               /*
-                *      If we've been told to exit, then do so,
-                *      even if we have data waiting.
-                */
-               if (do_exit) {
-                       DEBUG("Exiting...");
-                       detach_modules();
-                       
-                       /*
-                        *      SIGTERM gets do_exit=0,
-                        *      and we want to exit cleanly.
-                        *
-                        *      Other signals make us exit
-                        *      with an error status.
-                        */
-                       exit(do_exit - 1);
-               }
-
                if (status == -1) {
                        /*
-                        *  On interrupts, we clean up the
-                        *  request list.
+                        *      On interrupts, we clean up the request
+                        *      list.  We then continue with the loop,
+                        *      so that if we're supposed to exit,
+                        *      then the code at the start of the loop
+                        *      catches that, and exits.
                         */
                        if (errno == EINTR) {
                                tv = rad_clean_list(time(NULL));
@@ -2350,46 +2405,18 @@ static void usage(void)
 
 
 /*
- *  We got a fatal signal. Clean up and exit.
+ *     We got a fatal signal.
  */
 static void sig_fatal(int sig)
 {
-       const char *me = "MASTER: ";
-
-       /*
-        *  FIXME: Handle child threads, too...
-        */
-       if (radius_pid != getpid()) {
-               me = "CHILD: ";
-       }
-
        switch(sig) {
                case SIGTERM:
-                       radlog(L_INFO, "%sexit.", me);
                        do_exit = 1;
                        break;
                default:
-                       radlog(L_ERR, "%sexit on signal (%d)", me, sig);
                        do_exit = 2;
                        break;
        }
-
-       /*
-        *  We're running as a daemon, we're the MASTER daemon,
-        *  and we got a fatal signal.  Tear the rest of the
-        *  daemons down, as something absolutely horrible happened.
-        */
-       if ((debug_flag == 0) && (dont_fork == 0)
-#ifndef HAVE_PTHREAD_H
-           && (radius_pid == getpid())
-#endif
-           ) {
-               /*
-                *      Kill all of the processes in the current
-                *      process group.
-                */
-               kill(-radius_pid, SIGTERM);
-       }
 }