Code "cleanups." I confess that I sometimes went beyond the TODO
[freeradius.git] / src / main / radiusd.c
1 /*
2  * radiusd.c    Main loop of the radius server.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2000,2001  The FreeRADIUS server project
21  * Copyright 1999,2000  Miquel van Smoorenburg <miquels@cistron.nl>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  * Copyright 2000  Alan Curry <pacman-radius@cqc.com>
24  * Copyright 2000  Jeff Carneal <jeff@apex.net>
25  * Copyright 2000  Chad Miller <cmiller@surfsouth.com>
26  */
27
28 /* don't look here for the version, run radiusd -v or look in version.c */
29 static const char rcsid[] =
30 "$Id$";
31
32 #include "autoconf.h"
33 #include "libradius.h"
34
35 #include <sys/socket.h>
36 #include <sys/file.h>
37
38 #if HAVE_NETINET_IN_H
39 #       include <netinet/in.h>
40 #endif
41
42 #include <stdlib.h>
43 #include <string.h>
44 #include <netdb.h>
45 #include <fcntl.h>
46 #include <ctype.h>
47
48 #if HAVE_UNISTD_H
49 #       include <unistd.h>
50 #endif
51
52 #include <signal.h>
53
54 #if HAVE_GETOPT_H
55 #       include <getopt.h>
56 #endif
57
58 #if HAVE_SYS_SELECT_H
59 #       include <sys/select.h>
60 #endif
61
62 #if HAVE_SYSLOG_H
63 #       include <syslog.h>
64 #endif
65
66 #if HAVE_SYS_WAIT_H
67 #       include <sys/wait.h>
68 #endif
69 #ifndef WEXITSTATUS
70 #       define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
71 #endif
72 #ifndef WIFEXITED
73 #       define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
74 #endif
75
76 #include <assert.h>
77
78 #include "radiusd.h"
79 #include "conffile.h"
80 #include "modules.h"
81 #include "request_list.h"
82
83 #if WITH_SNMP
84 #       include "radius_snmp.h"
85 #endif
86
87 #include <sys/resource.h>
88
89 #include <grp.h>
90 #include <pwd.h>
91
92 /*
93  *  Global variables.
94  */
95 const char *progname = NULL;
96 const char *radius_dir = NULL;
97 const char *radacct_dir = NULL;
98 const char *radlog_dir = NULL;
99 const char *radlib_dir = NULL;
100 int log_stripped_names;
101 int debug_flag;
102 int use_dbm = FALSE;
103 uint32_t myip = INADDR_ANY;
104 int log_auth_detail = FALSE;
105 int auth_port = 0;
106 int acct_port;
107 int proxy_port;
108 int proxy_retry_delay = RETRY_DELAY;
109 int proxy_retry_count = RETRY_COUNT;
110 int proxy_synchronous = TRUE;
111 int need_reload = FALSE;
112 struct main_config_t mainconfig;
113
114 static int got_child = FALSE;
115 static int authfd;
116 int acctfd;
117 int proxyfd;
118 static pid_t radius_pid;
119 static int request_num_counter = 0; /* per-request unique ID */
120
121 /*
122  *  Configuration items.
123  */
124 static int allow_core_dumps = FALSE;
125 static int max_request_time = MAX_REQUEST_TIME;
126 static int cleanup_delay = CLEANUP_DELAY;
127 static int max_requests = MAX_REQUESTS;
128 static int dont_fork = FALSE;
129 static const char *pid_file = NULL;
130 static uid_t server_uid;
131 static gid_t server_gid;
132 static const char *uid_name = NULL;
133 static const char *gid_name = NULL;
134 static int proxy_requests = TRUE;
135 int spawn_flag = TRUE;
136 static struct rlimit core_limits;
137
138 static void usage(void);
139
140 static void sig_fatal (int);
141 static void sig_hup (int);
142
143 static void rad_reject(REQUEST *request);
144 static struct timeval *rad_clean_list(time_t curtime);
145 static REQUEST *rad_check_list(REQUEST *);
146 static REQUEST *proxy_check_list(REQUEST *request);
147 static int refresh_request(REQUEST *request, void *data);
148 #ifndef WITH_THREAD_POOL
149 static int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
150 #else
151 extern int rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
152 #endif
153
154 /*
155  *  Map the proxy server configuration parameters to variables.
156  */
157 static CONF_PARSER proxy_config[] = {
158         { "retry_delay",  PW_TYPE_INTEGER, 0, &proxy_retry_delay, Stringify(RETRY_DELAY) },
159         { "retry_count",  PW_TYPE_INTEGER, 0, &proxy_retry_count, Stringify(RETRY_COUNT) },
160         { "synchronous",  PW_TYPE_BOOLEAN, 0, &proxy_synchronous, "yes" },
161         { NULL, -1, 0, NULL, NULL }
162 };
163
164 /*
165  *  A mapping of configuration file names to internal variables
166  */
167 static CONF_PARSER server_config[] = {
168         { "max_request_time", PW_TYPE_INTEGER, 0, &max_request_time, Stringify(MAX_REQUEST_TIME) },
169         { "cleanup_delay", PW_TYPE_INTEGER, 0, &cleanup_delay, Stringify(CLEANUP_DELAY) },
170         { "max_requests", PW_TYPE_INTEGER, 0, &max_requests, Stringify(MAX_REQUESTS) },
171         { "port", PW_TYPE_INTEGER, 0, &auth_port, Stringify(PW_AUTH_UDP_PORT) },
172         { "allow_core_dumps", PW_TYPE_BOOLEAN, 0, &allow_core_dumps, "no" },
173         { "log_stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names,"no" },
174         { "log_auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, "no" },
175         { "log_auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, "no" },
176         { "log_auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, "no" },
177         { "pidfile", PW_TYPE_STRING_PTR, 0, &pid_file, "${run_dir}/radiusd.pid"},
178         { "bind_address", PW_TYPE_IPADDR, 0, &myip, "*" },
179         { "user", PW_TYPE_STRING_PTR, 0, &uid_name, "nobody"},
180         { "group", PW_TYPE_STRING_PTR, 0, &gid_name, "nobody"},
181         { "usercollide", PW_TYPE_BOOLEAN, 0, &mainconfig.do_usercollide,  "no" },
182         { "lower_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_user, "no" },
183         { "lower_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_pass, "no" },
184         { "nospace_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_user, "no" },
185         { "nospace_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_pass, "no" },
186         { "proxy_requests", PW_TYPE_BOOLEAN, 0, &proxy_requests, "yes" },
187         { "proxy", PW_TYPE_SUBSECTION, 0, proxy_config, NULL },
188         { NULL, -1, 0, NULL, NULL }
189 };
190
191 /*
192  *  Read config files.
193  */
194 static int reread_config(int reload)
195 {
196         int pid = getpid();
197         CONF_SECTION *cs;
198
199         if (!reload) {
200                 radlog(L_INFO, "Starting - reading configuration files ...");
201         } else if (pid == radius_pid) {
202                 radlog(L_INFO, "Reloading configuration files.");
203         }
204
205         /* First read radiusd.conf */
206         DEBUG2("reread_config:  reading radiusd.conf");
207         if (read_radius_conf_file() < 0) {
208                 radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
209                 return -1;
210         }
211
212         /*
213          *  And parse the server's configuration values.
214          */
215         cs = cf_section_find(NULL);
216         if (cs == NULL) {
217                 radlog(L_ERR|L_CONS, "No configuration information in radiusd.conf!");
218                 return -1;
219         }
220         cf_section_parse(cs, NULL, server_config);
221
222         /*
223          *  Reload the modules.
224          */
225         DEBUG2("read_config_files:  entering modules setup");
226         if (setup_modules() < 0) {
227                 radlog(L_ERR|L_CONS, "Errors setting up modules");
228                 return -1;
229         }
230
231         /*
232          *  Go update our behaviour, based on the configuration
233          *  changes.
234          */
235         if (allow_core_dumps) {
236                 if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
237                         radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
238                                         strerror(errno));
239                         exit(1);
240
241                         /*
242                          *  If we're running as a daemon, and core
243                          *  dumps are enabled, log that information.
244                          */
245                 } else if ((core_limits.rlim_cur != 0) && !debug_flag)
246                         radlog(L_INFO, "Core dumps are enabled.");
247
248         } else if (!debug_flag) {
249                 /*
250                  *  Not debugging.  Set the core size to zero, to
251                  *  prevent security breaches.  i.e. People
252                  *  reading passwords from the 'core' file.
253                  */
254                 struct rlimit limits;
255
256                 limits.rlim_cur = 0;
257                 limits.rlim_max = core_limits.rlim_max;
258                 
259                 if (setrlimit(RLIMIT_CORE, &limits) < 0) {
260                         radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
261                                         strerror(errno));
262                         exit(1);
263                 }
264         }
265
266         /*
267          *  Set the UID and GID, but only if we're NOT running
268          *  in debugging mode.
269          */
270         if (!debug_flag) {
271
272                 /*
273                  *  Set group.
274                  */
275                 if (gid_name != NULL) {
276                         struct group *gr;
277
278                         gr = getgrnam(gid_name);
279                         if (gr == NULL) {
280                                 radlog(L_ERR|L_CONS, "Cannot switch to Group %s: %s", gid_name, strerror(errno));
281                                 exit(1);
282                         }
283                         server_gid = gr->gr_gid;
284                         if (setgid(server_gid) < 0) {
285                                 radlog(L_ERR|L_CONS, "Failed setting Group to %s: %s", gid_name, strerror(errno));
286                                 exit(1);
287                         }
288                 }
289
290                 /*
291                  *  Set UID.
292                  */
293                 if (uid_name != NULL) {
294                         struct passwd *pw;
295
296                         pw = getpwnam(uid_name);
297                         if (pw == NULL) {
298                                 radlog(L_ERR|L_CONS, "Cannot switch to User %s: %s", uid_name, strerror(errno));
299                                 exit(1);
300                         }
301                         server_uid = pw->pw_uid;
302                         if (setuid(server_uid) < 0) {
303                                 radlog(L_ERR|L_CONS, "Failed setting User to %s: %s", uid_name, strerror(errno));
304                                 exit(1);
305                         }
306                 }
307         }
308
309         return 0;
310 }
311
312 /*
313  *  Parse a string into a syslog facility level.
314  */
315 static int str2fac(const char *s)
316 {
317 #ifdef LOG_KERN
318         if(!strcmp(s, "kern"))
319                 return LOG_KERN;
320         else
321 #endif
322 #ifdef LOG_USER
323         if(!strcmp(s, "user"))
324                 return LOG_USER;
325         else
326 #endif
327 #ifdef LOG_MAIL
328         if(!strcmp(s, "mail"))
329                 return LOG_MAIL;
330         else
331 #endif
332 #ifdef LOG_DAEMON
333         if(!strcmp(s, "daemon"))
334                 return LOG_DAEMON;
335         else
336 #endif
337 #ifdef LOG_AUTH
338         if(!strcmp(s, "auth"))
339                 return LOG_AUTH;
340         else
341 #endif
342 #ifdef LOG_SYSLOG
343         if(!strcmp(s, "auth"))
344                 return LOG_AUTH;
345         else
346 #endif
347 #ifdef LOG_LPR
348         if(!strcmp(s, "lpr"))
349                 return LOG_LPR;
350         else
351 #endif
352 #ifdef LOG_NEWS
353         if(!strcmp(s, "news"))
354                 return LOG_NEWS;
355         else
356 #endif
357 #ifdef LOG_UUCP
358         if(!strcmp(s, "uucp"))
359                 return LOG_UUCP;
360         else
361 #endif
362 #ifdef LOG_CRON
363         if(!strcmp(s, "cron"))
364                 return LOG_CRON;
365         else
366 #endif
367 #ifdef LOG_AUTHPRIV
368         if(!strcmp(s, "authpriv"))
369                 return LOG_AUTHPRIV;
370         else
371 #endif
372 #ifdef LOG_FTP
373         if(!strcmp(s, "ftp"))
374                 return LOG_FTP;
375         else
376 #endif
377 #ifdef LOG_LOCAL0
378         if(!strcmp(s, "local0"))
379                 return LOG_LOCAL0;
380         else
381 #endif
382 #ifdef LOG_LOCAL1
383         if(!strcmp(s, "local1"))
384                 return LOG_LOCAL1;
385         else
386 #endif
387 #ifdef LOG_LOCAL2
388         if(!strcmp(s, "local2"))
389                 return LOG_LOCAL2;
390         else
391 #endif
392 #ifdef LOG_LOCAL3
393         if(!strcmp(s, "local3"))
394                 return LOG_LOCAL3;
395         else
396 #endif
397 #ifdef LOG_LOCAL4
398         if(!strcmp(s, "local4"))
399                 return LOG_LOCAL4;
400         else
401 #endif
402 #ifdef LOG_LOCAL5
403         if(!strcmp(s, "local5"))
404                 return LOG_LOCAL5;
405         else
406 #endif
407 #ifdef LOG_LOCAL6
408         if(!strcmp(s, "local6"))
409                 return LOG_LOCAL6;
410         else
411 #endif
412 #ifdef LOG_LOCAL7
413         if(!strcmp(s, "local7"))
414                 return LOG_LOCAL7;
415         else
416 #endif
417         {
418                 fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
419                         progname, s);
420                 exit(1);
421         }
422         
423         /* this should never be reached */
424         return LOG_DAEMON;
425 }
426
427 int main(int argc, char **argv)
428 {
429         REQUEST *request;
430         RADIUS_PACKET *packet;
431         u_char *secret;
432         unsigned char buffer[4096];
433         struct sockaddr_in salocal;
434         struct sockaddr_in *sa;
435         fd_set readfds;
436         int result;
437         int argval;
438         int t;
439         int pid;
440         int i;
441         int fd = 0;
442         int devnull;
443         int status;
444         int syslog_facility = LOG_DAEMON;
445         int radius_port = 0;
446         struct servent *svp;
447         struct timeval *tv = NULL;
448
449 #ifdef OSFC2
450         set_auth_parameters(argc,argv);
451 #endif
452
453         /*
454          *  Open /dev/null, and make sure filedescriptors
455          *  0, 1 and 2 are connected to something.
456          */
457         devnull = 0;
458         while (devnull >= 0 && devnull < 3)
459                 devnull = open("/dev/null", O_RDWR);
460
461         if ((progname = strrchr(argv[0], '/')) == NULL)
462                 progname = argv[0];
463         else
464                 progname++;
465
466         debug_flag = 0;
467         spawn_flag = TRUE;
468         radius_dir = strdup(RADIUS_DIR);
469
470         signal(SIGHUP, sig_hup);
471         signal(SIGINT, sig_fatal);
472         signal(SIGQUIT, sig_fatal);
473 #if WITH_SNMP
474         signal(SIGPIPE, SIG_IGN);
475 #endif
476 #ifdef SIGTRAP
477         signal(SIGTRAP, sig_fatal);
478 #endif
479 #ifdef SIGIOT
480         signal(SIGIOT, sig_fatal);
481 #endif
482
483         /*
484          *  Pooled threads and child threads define their own
485          *  signal handler.
486          */
487 #ifndef WITH_THREAD_POOL
488 #ifndef HAVE_PTHREAD_H
489         signal(SIGTERM, sig_fatal);
490 #endif
491 #endif
492         signal(SIGCHLD, sig_cleanup);
493 #if 0
494         signal(SIGFPE, sig_fatal);
495         signal(SIGSEGV, sig_fatal);
496         signal(SIGILL, sig_fatal);
497 #endif
498
499         /*
500          *  Close unused file descriptors.
501          */
502         for (t = 32; t >= 3; t--)
503                 if(t!=devnull) 
504                         close(t);
505
506         /*
507          *  Process the options.
508          */
509         while((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:p:sSvxXyz")) != EOF) {
510
511                 switch(argval) {
512
513                         case 'A':
514                                 log_auth_detail = TRUE;
515                                 break;
516
517                         case 'a':
518                                 radacct_dir = strdup(optarg);
519                                 break;
520                         
521 #if defined(WITH_DBM) || defined(WITH_NDBM)
522                         case 'b':
523                                 use_dbm++;
524                                 break;
525 #endif
526                         case 'c':
527                                 /* ignore for backwards compatibility with Cistron */
528                                 break;
529
530                         case 'd':
531                                 radius_dir = strdup(optarg);
532                                 break;
533                         
534                         case 'f':
535                                 dont_fork = TRUE;
536                                 break;
537
538                         case 'h':
539                                 usage();
540                                 break;
541
542                         case 'i':
543                                 if ((myip = ip_getaddr(optarg)) == INADDR_NONE) {
544                                         fprintf(stderr, "radiusd: %s: host unknown\n",
545                                                 optarg);
546                                         exit(1);
547                                 }
548                                 break;
549                         
550                         case 'l':
551                                 radlog_dir = strdup(optarg);
552                                 break;
553                         
554                                 /*
555                                  *  We should also have this as a configuration
556                                  *  file directive.
557                                  */
558                         case 'g':
559                                 syslog_facility = str2fac(optarg);
560                                 break;
561
562                         case 'S':
563                                 log_stripped_names++;
564                                 break;
565
566                         case 'p':
567                                 radius_port = atoi(optarg);
568                                 break;
569
570                         case 's':       /* Single process mode */
571                                 spawn_flag = FALSE;
572                                 break;
573
574                         case 'v':
575                                 version();
576                                 break;
577
578                                 /*
579                                  *  BIG debugging mode for users who are
580                                  *  TOO LAZY to type '-sfxxyz -l stdout' themselves.
581                                  */
582                         case 'X':
583                                 spawn_flag = FALSE;
584                                 dont_fork = TRUE;
585                                 debug_flag = 2;
586                                 librad_debug = 2;
587                                 mainconfig.log_auth = TRUE;
588                                 mainconfig.log_auth_badpass = TRUE;
589                                 mainconfig.log_auth_goodpass = TRUE;
590                                 radlog_dir = strdup("stdout");
591                                 break;
592
593                         case 'x':
594                                 debug_flag++;
595                                 librad_debug++;
596                                 break;
597                         
598                         case 'y':
599                                 mainconfig.log_auth = TRUE;
600                                 mainconfig.log_auth_badpass = TRUE;
601                                 break;
602
603                         case 'z':
604                                 mainconfig.log_auth_badpass = TRUE;
605                                 mainconfig.log_auth_goodpass = TRUE;
606                                 break;
607
608                         default:
609                                 usage();
610                                 break;
611                 }
612         }
613
614         /*
615          *  Get out PID: the configuration file reader uses it.
616          */
617         radius_pid = getpid();
618
619         /*
620          *  Get the current maximum for core files.
621          */
622         if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
623                 radlog(L_ERR|L_CONS, "Failed to get current core limit:"
624                                 "  %s", strerror(errno));
625                 exit(1);
626         }
627
628         /*
629          *  Read the configuration files, BEFORE doing anything else.
630          */
631         if (reread_config(0) < 0) {
632                 exit(1);
633         }
634
635 #if HAVE_SYSLOG_H
636         /*
637          *  If they asked for syslog, then give it to them.
638          *  Also, initialize the logging facility with the
639          *  configuration that they asked for.
640          */
641         if (!strcmp(radlog_dir, "syslog")) {
642                 openlog(progname, LOG_PID, syslog_facility);
643         }
644         /* Do you want a warning if -g is used without a -l to activate it? */
645 #endif
646
647         /*
648          *  Initialize the request list.
649          */
650         rl_init();
651
652         /*
653          *  We prefer (in order) the port from the command-line,
654          *  then the port from the configuration file, then
655          *  the port that the system names "radius", then
656          *  1645.
657          */
658         if (radius_port != 0) {
659                 auth_port = radius_port;
660         } /* else auth_port is set from the config file */
661         
662         /*
663          *  Maybe auth_port *wasn't* set from the config file,
664          *  or the config file set it to zero.
665          */
666         acct_port = 0;
667         if (auth_port == 0) {
668                 svp = getservbyname ("radius", "udp");
669                 if (svp != NULL) {
670                         auth_port = ntohs(svp->s_port);
671
672                         /*
673                          *  We're getting auth_port from
674                          *  /etc/services, get acct_port from
675                          *  there, too.
676                          */
677                         svp = getservbyname ("radacct", "udp");
678                         if (svp != NULL) 
679                                 acct_port = ntohs(svp->s_port);
680                 } else {
681                         auth_port = PW_AUTH_UDP_PORT;
682                 }
683         }
684
685         /*
686          *  Open Authentication socket.
687          *
688          */
689         authfd = socket (AF_INET, SOCK_DGRAM, 0);
690         if (authfd < 0) {
691                 perror("auth socket");
692                 exit(1);
693         }
694
695         sa = (struct sockaddr_in *) &salocal;
696         memset ((char *) sa, '\0', sizeof(salocal));
697         sa->sin_family = AF_INET;
698         sa->sin_addr.s_addr = myip;
699         sa->sin_port = htons(auth_port);
700
701         result = bind (authfd, & salocal, sizeof(*sa));
702         if (result < 0) {
703                 perror ("auth bind");
704                 DEBUG("  There appears to be another RADIUS server already running on the authentication port UDP %d.", auth_port);
705                 exit(1);
706         }
707
708         /*
709          *  Open Accounting Socket.
710          *
711          *  If we haven't already gotten acct_port from /etc/services,
712          *  then make it auth_port + 1.
713          */
714         if (acct_port == 0) 
715                 acct_port = auth_port + 1;
716         
717         acctfd = socket (AF_INET, SOCK_DGRAM, 0);
718         if (acctfd < 0) {
719                 perror ("acct socket");
720                 exit(1);
721         }
722
723         sa = (struct sockaddr_in *) &salocal;
724         memset ((char *) sa, '\0', sizeof(salocal));
725         sa->sin_family = AF_INET;
726         sa->sin_addr.s_addr = myip;
727         sa->sin_port = htons(acct_port);
728
729         result = bind (acctfd, & salocal, sizeof(*sa));
730         if (result < 0) {
731                 perror ("acct bind");
732                 DEBUG("  There appears to be another RADIUS server already running on the accounting port UDP %d.", acct_port);
733                 exit(1);
734         }
735
736         /*
737          *  If we're proxying requests, open the proxy FD.
738          *  Otherwise, don't do anything.
739          */
740         if (proxy_requests == TRUE) {
741                 /*
742                  *  Open Proxy Socket.
743                  */
744                 proxyfd = socket (AF_INET, SOCK_DGRAM, 0);
745                 if (proxyfd < 0) {
746                         perror ("proxy socket");
747                         exit(1);
748                 }
749                 
750                 sa = (struct sockaddr_in *) &salocal;
751                 memset((char *) sa, '\0', sizeof(salocal));
752                 sa->sin_family = AF_INET;
753                 sa->sin_addr.s_addr = myip;
754                 
755                 /*
756                  *  Set the proxy port to be one more than the
757                  *  accounting port.
758                  */
759                 for (proxy_port = acct_port + 1; proxy_port < 64000; proxy_port++) {
760                         sa->sin_port = htons(proxy_port);
761                         result = bind(proxyfd, & salocal, sizeof(*sa));
762                         if (result == 0) {
763                                 break;
764                         }
765                 }
766                 
767                 /*
768                  *  Couldn't find a port to which we could bind.
769                  */
770                 if (proxy_port == 64000) {
771                         perror("proxy bind");
772                         exit(1);
773                 }
774
775         } else {
776                 /*
777                  *  NOT proxying requests, set the FD to a bad value.
778                  */
779                 proxyfd = -1;
780                 proxy_port = 0;
781         }
782
783         /*
784          *  Register built-in compare functions.
785          */
786         pair_builtincompare_init();
787
788 #if WITH_SNMP
789         radius_snmp_init();
790 #endif
791
792 #if 0
793         /*
794          *  Connect 0, 1 and 2 to /dev/null.
795          */
796         if (!debug_flag && devnull >= 0) {
797                 dup2(devnull, 0);
798                 if (strcmp(radlog_dir, "stdout") != 0) {
799                         dup2(devnull, 1);
800                 }
801                 dup2(devnull, 2);
802                 if (devnull > 2) close(devnull);
803         }
804 #endif
805
806         /*
807          *  Disconnect from session
808          */
809         if (debug_flag == 0 && dont_fork == 0) {
810                 pid = fork();
811                 if(pid < 0) {
812                         radlog(L_ERR|L_CONS, "Couldn't fork");
813                         exit(1);
814                 }
815
816                 /*
817                  *  The parent exits, so the child can run in the background.
818                  */
819                 if(pid > 0) {
820                         exit(0);
821                 }
822 #if HAVE_SETSID
823                 setsid();
824 #endif
825         }
826
827         /*
828          *  Ensure that we're using the CORRECT pid after forking,
829          *  NOT the one we started with.
830          */
831         radius_pid = getpid();
832
833         /*
834          *  Only write the PID file if we're running as a daemon.
835          *
836          *  And write it AFTER we've forked, so that we write the
837          *  correct PID.
838          */
839         if (dont_fork == FALSE) {
840                 FILE *fp;
841
842                 fp = fopen(pid_file, "w");
843                 if (fp != NULL) {
844                         fprintf(fp, "%d\n", (int) radius_pid);
845                         fclose(fp);
846                 } else {
847                         radlog(L_ERR|L_CONS, "Failed writing process id to file %s: %s\n",
848                                         pid_file, strerror(errno));
849                 }
850         }
851
852 #if WITH_THREAD_POOL
853         /*
854          *  If we're spawning children, set up the thread pool.
855          */
856         if (spawn_flag == TRUE) {
857                 thread_pool_init();
858         }
859 #endif
860
861         /*
862          *  Use linebuffered or unbuffered stdout if
863          *  the debug flag is on.
864          */
865         if (debug_flag == TRUE) 
866                 setlinebuf(stdout);
867
868         if (myip == 0) {
869                 strcpy((char *)buffer, "*");
870         } else {
871                 ip_ntoa((char *)buffer, myip);
872         }
873
874         if (proxy_requests == TRUE) {
875                 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp, with proxy on %d/udp.",
876                                 buffer, auth_port, acct_port, proxy_port);
877         } else {
878                 radlog(L_INFO, "Listening on IP address %s, ports %d/udp and %d/udp.",
879                                 buffer, auth_port, acct_port);
880         }
881
882         /*
883          *  Note that we NO LONGER fork an accounting process!
884          *  We used to do it for historical reasons, but that
885          *  is no excuse...
886          */
887         radlog(L_INFO, "Ready to process requests.");
888
889         /*
890          *  Receive user requests
891          */
892         for(;;) {
893                 if (need_reload) {
894                         if (reread_config(TRUE) < 0) {
895                                 exit(1);
896                         }
897                         need_reload = FALSE;
898                         radlog(L_INFO, "Ready to process requests.");
899                 }
900
901                 FD_ZERO(&readfds);
902                 if (authfd >= 0)
903                         FD_SET(authfd, &readfds);
904                 if (acctfd >= 0)
905                         FD_SET(acctfd, &readfds);
906                 if (proxyfd >= 0)
907                         FD_SET(proxyfd, &readfds);
908 #ifdef WITH_SNMP
909                 if (rad_snmp.smux_fd >= 0)
910                         FD_SET(rad_snmp.smux_fd, &readfds);
911 #endif
912
913                 status = select(32, &readfds, NULL, NULL, tv);
914                 if (status == -1) {
915                         /*
916                          *  On interrupts, we clean up the
917                          *  request list.
918                          */
919                         if (errno == EINTR) {
920                                 tv = rad_clean_list(time(NULL));
921                                 continue;
922                         }
923                         radlog(L_ERR, "Unexpected error in select(): %s",
924                                         strerror(errno));
925                         sig_fatal(101);
926                 }
927
928                 /*
929                  *  Loop over the open socket FD's, reading any data.
930                  */
931                 for (i = 0; i < 3; i++) {
932
933                         if (i == 0) fd = authfd;
934                         if (i == 1) fd = acctfd;
935                         if (i == 2) fd = proxyfd;
936                         if (fd < 0 || !FD_ISSET(fd, &readfds))
937                                 continue;
938                         /*
939                          *  Receive the packet.
940                          */
941                         packet = rad_recv(fd);
942                         if (packet == NULL) {
943                                 radlog(L_ERR, "%s", librad_errstr);
944                                 continue;
945                         }
946 #if WITH_SNMP
947                         if (fd == acctfd)
948                                 rad_snmp.acct.total_requests++;
949                         if (fd == authfd)
950                                 rad_snmp.auth.total_requests++;
951 #endif
952
953                         /*
954                          *  Check if we know this client for
955                          *  authfd and acctfd.  Check if we know
956                          *  this proxy for proxyfd.
957                          */
958                         if(fd != proxyfd) {
959                                 RADCLIENT *cl;
960                                 if ((cl = client_find(packet->src_ipaddr)) == NULL) {
961                                         radlog(L_ERR, "Ignoring request from unknown client %s:%d",
962                                         ip_ntoa(buffer, packet->src_ipaddr),
963                                         packet->src_port);
964                                         rad_free(&packet);
965                                         continue;
966                                 } else {
967                                         secret = cl->secret;
968                                 }
969                                 
970                         } else {    /* It came in on the proxy port */
971                                 REALM *rl;
972                                 if ((rl = realm_findbyaddr(packet->src_ipaddr)) == NULL) {
973                                         radlog(L_ERR, "Ignoring request from unknown proxy %s:%d",
974                                         ip_ntoa(buffer, packet->src_ipaddr),
975                                         packet->src_port);
976                                         rad_free(&packet);
977                                         continue;
978                                 } else {
979                                         secret = rl->secret;
980                                 }
981                         }
982
983                         /*
984                          *  Do yet another check, to see if the
985                          *  packet code is valid.  We only understand
986                          *  a few, so stripping off obviously invalid
987                          *  packets here will make our life easier.
988                          */
989                         if (packet->code > PW_ACCESS_CHALLENGE) {
990                                 radlog(L_ERR, "Ignoring request from client %s:%d with unknown code %d", buffer, packet->src_port, packet->code);
991                                 rad_free(&packet);
992                                 continue;
993                         }
994
995                         request = rad_malloc(sizeof(REQUEST));
996                         memset(request, 0, sizeof(REQUEST));
997 #ifndef NDEBUG
998                         request->magic = REQUEST_MAGIC;
999 #endif
1000                         request->packet = packet;
1001                         request->proxy = NULL;
1002                         request->reply = NULL;
1003                         request->proxy_reply = NULL;
1004                         request->config_items = NULL;
1005                         request->username = NULL;
1006                         request->password = NULL;
1007                         request->timestamp = time(NULL);
1008                         request->number = request_num_counter++;
1009                         request->child_pid = NO_SUCH_CHILD_PID;
1010                         request->container = NULL;
1011                         strNcpy(request->secret, (char *)secret, sizeof(request->secret));
1012                         rad_process(request, spawn_flag);
1013                 } /* loop over authfd, acctfd, proxyfd */
1014
1015 #if WITH_SNMP
1016                 /*
1017                  *  After handling all authentication/accounting
1018                  *  requests, THEN process any pending SMUX/SNMP
1019                  *  queries.
1020                  *
1021                  *  Note that the handling is done in the main server,
1022                  *  which probably isn't a Good Thing.  It really
1023                  *  should be wrapped, and handled in a thread pool.
1024                  */
1025                 if ((rad_snmp.smux_fd >= 0) &&
1026                                 FD_ISSET(rad_snmp.smux_fd, &readfds) &&
1027                                 (rad_snmp.smux_event == SMUX_READ)) {
1028                         smux_read();
1029                 }
1030                 
1031                 /*
1032                  *  If we've got to re-connect, then do so now,
1033                  *  before calling select again.
1034                  */
1035                 if (rad_snmp.smux_event == SMUX_CONNECT) {
1036                         smux_connect();
1037                 }
1038 #endif
1039
1040                 /*
1041                  *  After processing all new requests,
1042                  *  check if we've got to delete old requests
1043                  *  from the request list.
1044                  */
1045                 tv = rad_clean_list(time(NULL));
1046
1047         } /* loop forever */
1048 }
1049
1050
1051 /*
1052  *  Process supported requests:
1053  *
1054  *      PW_AUTHENTICATION_REQUEST - Authentication request from
1055  *       a client network access server.
1056  *
1057  *      PW_ACCOUNTING_REQUEST - Accounting request from
1058  *       a client network access server.
1059  *
1060  *      PW_AUTHENTICATION_ACK
1061  *      PW_AUTHENTICATION_REJECT
1062  *      PW_ACCOUNTING_RESPONSE - Reply from a remote Radius server.
1063  *       Relay reply back to original NAS.
1064  *
1065  */
1066 int rad_process(REQUEST *request, int dospawn)
1067 {
1068         RAD_REQUEST_FUNP fun;
1069
1070         fun = NULL;
1071
1072         assert(request->magic == REQUEST_MAGIC);
1073
1074         switch(request->packet->code) {
1075                 default:
1076                         radlog(L_ERR, "Unknown packet type %d from client %s:%d "
1077                                         "- ID %d : IGNORED", request->packet->code, 
1078                                         client_name(request->packet->src_ipaddr), request->packet->src_port,
1079                                         request->packet->id); 
1080                         request_free(&request);
1081                         return -1;
1082                         break;
1083
1084                 case PW_AUTHENTICATION_REQUEST:
1085                         /*
1086                          *  Check for requests sent to the wrong port,
1087                          *  and ignore them, if so.
1088                          */
1089                         if (request->packet->sockfd != authfd) {
1090                                 radlog(L_ERR, "Request packet code %d sent to authentication port from "
1091                                         "client %s:%d - ID %d : IGNORED", request->packet->code,
1092                                         client_name(request->packet->src_ipaddr), request->packet->src_port,
1093                                 request->packet->id);
1094                                 request_free(&request);
1095                                 return -1;
1096                         }
1097                         fun = rad_authenticate;
1098                         break;
1099
1100                 case PW_ACCOUNTING_REQUEST:
1101                         /*
1102                          *  Check for requests sent to the wrong port,
1103                          *  and ignore them, if so.
1104                          */
1105                         if (request->packet->sockfd != acctfd) {
1106                                 radlog(L_ERR, "Request packet code %d sent to accounting port from "
1107                                         "client %s:%d - ID %d : IGNORED", request->packet->code,
1108                                         client_name(request->packet->src_ipaddr), request->packet->src_port,
1109                                         request->packet->id);
1110                                 request_free(&request);
1111                                 return -1;
1112                         }
1113                         fun = rad_accounting;
1114                         break;
1115
1116                 case PW_AUTHENTICATION_ACK:
1117                 case PW_AUTHENTICATION_REJECT:
1118                 case PW_ACCOUNTING_RESPONSE:
1119                         /*
1120                          *  Replies NOT sent to the proxy port get an
1121                          *  error message logged, and the packet is
1122                          *  dropped.
1123                          */
1124                         if (request->packet->sockfd != proxyfd) {
1125                                 radlog(L_ERR, "Reply packet code %d sent to request port from "
1126                                                 "client %s:%d - ID %d : IGNORED", request->packet->code,
1127                                                 client_name(request->packet->src_ipaddr), request->packet->src_port,
1128                                                 request->packet->id);
1129                                 request_free(&request);
1130                                 return -1;
1131                         }
1132                         if (request->packet->code != PW_ACCOUNTING_RESPONSE) {
1133                                 fun = rad_authenticate;
1134                         } else {
1135                                 fun = rad_accounting;
1136                         }
1137                         break;
1138
1139                 case PW_PASSWORD_REQUEST:
1140                         /*
1141                          *  We don't support this anymore.
1142                          */
1143                         radlog(L_ERR, "Deprecated password change request from client %s:%d - ID %d : IGNORED",
1144                                         client_name(request->packet->src_ipaddr), request->packet->src_port,
1145                                         request->packet->id);
1146                         request_free(&request);
1147                         return -1;
1148                         break;
1149         }
1150
1151         /*
1152          *  Check for a duplicate, or error.
1153          *  Throw away the the request if so.
1154          */
1155         request = rad_check_list(request);
1156         if (request == NULL) {
1157                 return 0;
1158         }
1159         
1160         assert(request->magic == REQUEST_MAGIC);
1161
1162         /*
1163          *  The request passes many of our sanity checks.  From
1164          *  here on in, if anything goes wrong, we send a reject
1165          *  message, instead of dropping the packet.
1166          *
1167          *  Build the reply template from the request template.
1168          */
1169         if ((request->reply = rad_alloc(0)) == NULL) {
1170                 radlog(L_ERR, "No memory");
1171                 exit(1);
1172         }
1173         request->reply->sockfd = request->packet->sockfd;
1174         request->reply->dst_ipaddr = request->packet->src_ipaddr;
1175         request->reply->dst_port = request->packet->src_port;
1176         request->reply->id = request->packet->id;
1177         request->reply->code = 0; /* UNKNOWN code */
1178         memcpy(request->reply->vector, request->packet->vector, sizeof(request->reply->vector));
1179         request->reply->vps = NULL;
1180         request->reply->data = NULL;
1181         request->reply->data_len = 0;
1182
1183         /*
1184          *  If we're spawning a child thread, let it do all of
1185          *  the work of handling a request, and exit.
1186          */
1187         if (dospawn == TRUE) {
1188                 /*
1189                  *  Maybe the spawn failed.  If so, then we
1190                  *  trivially reject the request (because we can't
1191                  *  handle it), and return.
1192                  */
1193                 if (rad_spawn_child(request, fun) < 0) {
1194                         rad_reject(request);
1195                         request->finished = TRUE;
1196                 }
1197                 return 0;
1198         }
1199
1200         rad_respond(request, fun);
1201         return 0;
1202 }
1203
1204 /*
1205  *  Reject a request, by sending a trivial reply packet.
1206  */
1207 static void rad_reject(REQUEST *request)
1208 {
1209         VALUE_PAIR *vps;
1210         
1211         DEBUG2("Server rejecting request %d.", request->number);
1212         switch (request->packet->code) {
1213                 /*
1214                  *  Accounting requests, etc. get dropped on the floor.
1215                  */
1216                 case PW_ACCOUNTING_REQUEST:
1217                 default:
1218                         break;
1219
1220                 /*
1221                  *  Authentication requests get their Proxy-State
1222                  *  attributes copied over, and an otherwise blank
1223                  *  reject message sent.
1224                  */
1225                 case PW_AUTHENTICATION_REQUEST:
1226                         request->reply->code = PW_AUTHENTICATION_REJECT; 
1227
1228                         /*
1229                          *  Need to copy Proxy-State from request->packet->vps
1230                          */
1231                         vps = paircopy2(request->packet->vps, PW_PROXY_STATE);
1232                         if (vps != NULL)
1233                                 pairadd(&(request->reply->vps), vps);
1234                         break;
1235         }
1236         
1237         /*
1238          *  If a reply exists, send it.
1239          */
1240         if (request->reply->code != 0) 
1241                 rad_send(request->reply, request->secret);
1242 }
1243
1244 /*
1245  *  Perform any RFC specified cleaning of outgoing replies
1246  */
1247 static void rfc_clean(RADIUS_PACKET *packet)
1248 {
1249         VALUE_PAIR *vps = NULL;
1250         
1251         switch (packet->code) {
1252                 default:
1253                         break;
1254                         
1255                         /*
1256                          *  Authentication REJECT's can have only
1257                          *  Reply-Mesaage and Proxy-State.  We delete
1258                          *  everything other than Reply-Message, and
1259                          *  Proxy-State is added below, just before
1260                          *  the reply is sent.
1261                          */
1262                 case PW_AUTHENTICATION_REJECT:
1263                         pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
1264                         pairfree(&packet->vps);
1265                         packet->vps = vps;
1266                         break;
1267         }
1268 }
1269
1270 /* 
1271  * FIXME:  The next two functions should all
1272  * be in a module.  But not until we have
1273  * more control over module execution.
1274  * -jcarneal
1275  */
1276
1277 /*
1278  *  Lowercase the string value of a pair.
1279  */
1280 static int rad_lowerpair(REQUEST *request, VALUE_PAIR *vp) {
1281         if (vp == NULL) {
1282                 return -1;
1283         }
1284
1285         rad_lowercase(vp->strvalue);
1286         DEBUG2("rad_lowerpair:  %s now '%s'", vp->name, vp->strvalue);
1287         return 0;
1288 }
1289
1290 /*
1291  *  Remove spaces in a pair.
1292  */
1293 static int rad_rmspace_pair(REQUEST *request, VALUE_PAIR *vp) {
1294         if (vp == NULL) {
1295                 return -1;
1296         }
1297         
1298         rad_rmspace(vp->strvalue);
1299         vp->length = strlen(vp->strvalue);
1300         DEBUG2("rad_rmspace_pair:  %s now '%s'", vp->name, vp->strvalue);
1301         
1302         return 0;
1303 }
1304
1305 /*
1306  *  Respond to a request packet.
1307  *
1308  *  Maybe we reply, maybe we don't.
1309  *  Maybe we proxy the request to another server, or else maybe
1310  *  we replicate it to another server.
1311  */
1312 int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
1313 {
1314         RADIUS_PACKET *packet, *original;
1315         const char *secret;
1316         int finished = FALSE;
1317         int proxy_sent = 0;
1318         int reprocess = 0;
1319         
1320         /*
1321          *  Put the decoded packet into it's proper place.
1322          */
1323         if (request->proxy_reply != NULL) {
1324                 packet = request->proxy_reply;
1325                 secret = request->proxysecret;
1326                 original = request->proxy;
1327         } else {
1328                 packet = request->packet;
1329                 secret = request->secret;
1330                 original = NULL;
1331         }
1332
1333         assert(request->magic == REQUEST_MAGIC);
1334         
1335         /*
1336          *  Decode the packet, verifying it's signature,
1337          *  and parsing the attributes into structures.
1338          *
1339          *  Note that we do this CPU-intensive work in
1340          *  a child thread, not the master.  This helps to
1341          *  spread the load a little bit.
1342          *
1343          *  Internal requests (ones that never go on the
1344          *  wire) have ->data==NULL (data is the wire
1345          *  format) and don't need to be "decoded"
1346          */
1347         if (packet->data && rad_decode(packet, original, secret) != 0) {
1348                 radlog(L_ERR, "%s", librad_errstr);
1349                 rad_reject(request);
1350                 goto finished_request;
1351         }
1352         
1353         /*
1354          *  For proxy replies, remove non-allowed
1355          *  attributes from the list of VP's.
1356          */
1357         if (request->proxy) {
1358                 int replicating;
1359                 replicating = proxy_receive(request);
1360                 if (replicating != 0) {
1361                         goto next_request;
1362                 }
1363         }
1364         
1365         /*
1366          *  We should have a User-Name attribute now.
1367          */
1368         if (request->username == NULL) {
1369                 request->username = pairfind(request->packet->vps,
1370                                 PW_USER_NAME);
1371         }
1372
1373         /*
1374          *  We have the semaphore, and have decoded the packet.
1375          *  Let's process the request.
1376          */
1377         assert(request->magic == REQUEST_MAGIC);
1378
1379         /* 
1380          *  FIXME:  All this lowercase/nospace junk will be moved
1381          *  into a module after module failover is fully in place
1382          *
1383          *  See if we have to lower user/pass before processing
1384          */
1385         if(strcmp(mainconfig.do_lower_user, "before") == 0)
1386                 rad_lowerpair(request, request->username);
1387         if(strcmp(mainconfig.do_lower_pass, "before") == 0)
1388                 rad_lowerpair(request, rad_getpass(request));
1389
1390         if(strcmp(mainconfig.do_nospace_user, "before") == 0)
1391                 rad_rmspace_pair(request, request->username);
1392         if(strcmp(mainconfig.do_nospace_pass, "before") == 0)
1393                 rad_rmspace_pair(request, rad_getpass(request));
1394
1395         (*fun)(request);
1396
1397         /* See if we have to lower user/pass after processing */
1398         if(strcmp(mainconfig.do_lower_user, "after") == 0) {
1399                 rad_lowerpair(request, request->username);
1400                 reprocess = 1;
1401         }
1402         if(strcmp(mainconfig.do_lower_pass, "after") == 0) {
1403                 rad_lowerpair(request, rad_getpass(request));
1404                 reprocess = 1;
1405         }
1406         if(strcmp(mainconfig.do_nospace_user, "after") == 0) {
1407                 rad_rmspace_pair(request, request->username);
1408                 reprocess = 1;
1409         }
1410         if(strcmp(mainconfig.do_nospace_pass, "after") == 0) {
1411                 rad_rmspace_pair(request, rad_getpass(request));
1412                 reprocess = 1;
1413         }
1414
1415         /* Reprocess if we rejected last time */
1416         if ((fun == rad_authenticate) &&
1417                         (request->reply->code == PW_AUTHENTICATION_REJECT) &&
1418                         (reprocess))  {
1419                 pairfree(&request->config_items);
1420                 (*fun)(request);
1421         }
1422         
1423         /*
1424          *  If we don't already have a proxy
1425          *  packet for this request, we MIGHT have
1426          *  to go proxy it.
1427          */
1428         if (proxy_requests) {
1429                 if (request->proxy == NULL) {
1430                         proxy_sent = proxy_send(request);
1431                         
1432                         /*
1433                          *  sent==1 means it's been proxied.  The child
1434                          *  is done handling the request, but the request
1435                          *  is NOT finished!
1436                          */
1437                         if (proxy_sent == 1) {
1438                                 goto postpone_request;
1439                         }
1440                 }
1441         } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
1442                 (request->reply == NULL)) {
1443                 /*
1444                  *  We're not configured to reply to the packet,
1445                  *  and we're not proxying, so the DEFAULT behaviour
1446                  *  is to REJECT the user.
1447                  */
1448                 DEBUG2("There was no response configured: rejecting request %d", request->number);
1449                 rad_reject(request);
1450                 goto finished_request;
1451         }
1452
1453         /*
1454          *  If we have a reply to send, copy the Proxy-State
1455          *  attributes from the request to the tail of the reply,
1456          *  and send the packet.
1457          */
1458         assert(request->magic == REQUEST_MAGIC);
1459         if (request->reply->code != 0) {
1460                 VALUE_PAIR *vp = NULL;
1461
1462                 /*
1463                  *  Perform RFC limitations on outgoing replies.
1464                  */
1465                 rfc_clean(request->reply);
1466
1467                 /*
1468                  *  Need to copy Proxy-State from request->packet->vps
1469                  */
1470                 vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
1471                 if (vp != NULL) 
1472                         pairadd(&(request->reply->vps), vp);
1473
1474                 rad_send(request->reply, request->secret);
1475         }
1476
1477         /*
1478          *  We're done processing the request, set the
1479          *  request to be finished, clean up as necessary,
1480          *  and forget about the request.
1481          */
1482
1483 finished_request:
1484
1485         /*
1486          *  We're done handling the request.  Free up the linked
1487          *  lists of value pairs.  This might take a long time,
1488          *  so it's more efficient to do it in a child thread,
1489          *  instead of in the main handler when it eventually
1490          *  gets around to deleting the request.
1491          *
1492          *  Also, no one should be using these items after the
1493          *  request is finished, and the reply is sent.  Cleaning
1494          *  them up here ensures that they're not being used again.
1495          *
1496          *  Hmm... cleaning them up in the child thread also seems
1497          *  to make the server run more efficiently!
1498          */
1499
1500         /*  If we proxied this request, it's not safe to delete it until
1501          *  after the proxy reply
1502          */
1503         if (proxy_sent)
1504                 goto postpone_request;
1505
1506         if (request->packet && request->packet->vps) {
1507                 pairfree(&request->packet->vps);
1508                 request->username = NULL;
1509                 request->password = NULL;
1510         }
1511         if (request->reply && request->reply->vps) {
1512                 pairfree(&request->reply->vps);
1513         }
1514
1515         if (request->config_items) pairfree(&request->config_items);
1516
1517         DEBUG2("Finished request %d", request->number);
1518         finished = TRUE;
1519         
1520         /*
1521          *  Go to the next request, without marking
1522          *  the current one as finished.
1523          */
1524 next_request:
1525         DEBUG2("Going to the next request");
1526
1527 #if WITH_THREAD_POOL
1528         request->child_pid = NO_SUCH_CHILD_PID;
1529 #endif
1530         request->finished = finished; /* do as the LAST thing before exiting */
1531
1532 postpone_request:
1533         return 0;
1534 }
1535
1536 typedef struct rad_walk_t {
1537         time_t  now;
1538         time_t  smallest;
1539 } rad_walk_t;
1540
1541 /*
1542  *  Clean up the request list, every so often.
1543  *
1544  *  This is done by walking through ALL of the list, and
1545  *  - marking any requests which are finished, and expired
1546  *  - killing any processes which are NOT finished after a delay
1547  *  - deleting any marked requests.
1548  */
1549 static REQUEST *last_request = NULL;
1550 static struct timeval *rad_clean_list(time_t now)
1551 {
1552         /*
1553          *  Static variables, so that we don't do all of this work
1554          *  more than once per second.
1555          *
1556          *  Note that we have 'tv' and 'last_tv'.  'last_tv' is
1557          *  pointed to by 'last_tv_ptr', and depending on the
1558          *  system implementation of select(), it MAY be modified.
1559          *
1560          *  In that was, we want to use the ORIGINAL value, from
1561          *  'tv', and wipe out the (possibly modified) last_tv.
1562          */
1563         static time_t last_cleaned_list = 0;
1564         static struct timeval tv, *last_tv_ptr = NULL;
1565         static struct timeval last_tv;
1566
1567         rad_walk_t info;
1568
1569         info.now = now;
1570         info.smallest = -1;
1571
1572         /*
1573          *  If we've already set up the timeout or cleaned the
1574          *  request list this second, then don't do it again.  We
1575          *  simply return the sleep delay from last time.
1576          *
1577          *  Note that if we returned NULL last time, there was nothing
1578          *  to do.  BUT we've been woken up since then, which can only
1579          *  happen if we received a packet.  And if we've received a
1580          *  packet, then there's some work to do in the future.
1581          *
1582          *  FIXME: We can probably use gettimeofday() for finer clock
1583          *  resolution, as the current method will cause it to sleep
1584          *  too long...
1585          */
1586         if ((last_tv_ptr != NULL) &&
1587         (last_cleaned_list == now) &&
1588         (tv.tv_sec != 0)) {             
1589                 int i;
1590
1591                 /*
1592                  *  If we're NOT walking the entire request list,
1593                  *  then we want to iteratively check the request
1594                  *  list.
1595                  *
1596                  *  If there is NO previous request, go look for one.
1597                  */
1598                 if (!last_request) 
1599                         last_request = rl_next(last_request);
1600
1601                 /*
1602                  *  On average, there will be one request per
1603                  *  'cleanup_delay' requests, which needs to be
1604                  *  serviced.
1605                  *
1606                  *  And only do this servicing, if we have a request
1607                  *  to service.
1608                  */
1609                 if (last_request) 
1610                         for (i = 0; i < cleanup_delay; i++) {
1611                                 REQUEST *next;
1612                         
1613                                 /*
1614                                  *  This function call MAY delete the
1615                                  *  request pointed to by 'last_request'.
1616                                  */
1617                                 next = rl_next(last_request);
1618                                 refresh_request(last_request, &info);
1619                                 last_request = next;
1620
1621                                 /*
1622                                  *  Nothing to do any more, exit.
1623                                  */
1624                                 if (!last_request) 
1625                                         break;
1626                         }
1627
1628                 last_tv = tv;
1629                 DEBUG2("Waking up in %d seconds...",
1630                                 (int) last_tv_ptr->tv_sec);
1631                 return last_tv_ptr;
1632         }
1633         last_cleaned_list = now;
1634         last_request = NULL;
1635         DEBUG2("--- Walking the entire request list ---");
1636
1637 #if WITH_THREAD_POOL
1638         /*
1639          *  Only clean the thread pool if we've spawned child threads.
1640          */
1641         if (spawn_flag) {
1642                 thread_pool_clean(now);
1643         }
1644 #endif
1645         
1646         /*
1647          *  Hmmm... this is Big Magic.  We make it seem like
1648          *  there's an additional second to wait, for a whole
1649          *  host of reasons which I can't explain adequately,
1650          *  but which cause the code to Just Work Right.
1651          */
1652         info.now--;
1653
1654         rl_walk(refresh_request, &info);
1655
1656         /*
1657          *  We haven't found a time at which we need to wake up.
1658          *  Return NULL, so that the select() call will sleep forever.
1659          */
1660         if (info.smallest < 0) {
1661                 DEBUG2("Nothing to do.  Sleeping until we see a request.");
1662                 last_tv_ptr = NULL;
1663                 return NULL;
1664         }
1665         /*
1666          *  Set the time (in seconds) for how long we're
1667          *  supposed to sleep.
1668          */
1669         tv.tv_sec = info.smallest;
1670         tv.tv_usec = 0;
1671         DEBUG2("Waking up in %d seconds...", (int) info.smallest);
1672
1673         /*
1674          *  Remember how long we should sleep for.
1675          */
1676         last_tv = tv;
1677         last_tv_ptr = &last_tv;
1678         return last_tv_ptr;
1679 }
1680
1681 /*
1682  *  Walk through the request list, cleaning up complete child
1683  *  requests, and verifing that there is only one process
1684  *  responding to each request (duplicate requests are filtered
1685  *  out).
1686  *
1687  *  Also, check if the request is a reply from a request proxied to
1688  *  a remote server.  If so, play games with the request, and return
1689  *  the old one.
1690  */
1691 static REQUEST *rad_check_list(REQUEST *request)
1692 {
1693         REQUEST         *curreq;
1694         time_t          now;
1695
1696         /*
1697          *  If the request has come in on the proxy FD, then
1698          *  it's a proxy reply, so pass it through the proxy
1699          *  code for checking the REQUEST list.
1700          */
1701         if (request->packet->sockfd == proxyfd) {
1702                 return proxy_check_list(request);
1703
1704                 /*
1705                  *  If the request already has a proxy packet,
1706                  *  then it obviously is not a new request, either.
1707                  */
1708         } else if (request->proxy != NULL) {
1709                 return request;
1710         }
1711
1712         now = request->timestamp; /* good enough for our purposes */
1713
1714         /*
1715          *  Look for an existing copy of this request.
1716          */
1717         curreq = rl_find(request);
1718         if (curreq != NULL) {
1719                 /*
1720                  *  We now check the authentication vectors.
1721                  *  If the client has sent us a request with
1722                  *  identical code && ID, but different vector,
1723                  *  then they MUST have gotten our response, so
1724                  *  we can delete the original request, and process
1725                  *  the new one.
1726                  *
1727                  *  If the vectors are the same, then it's a duplicate
1728                  *  request, and we can send a duplicate reply.
1729                  */
1730                 if (memcmp(curreq->packet->vector, request->packet->vector,
1731                                 sizeof(request->packet->vector)) == 0) {
1732                         /*
1733                          *  Maybe we've saved a reply packet.  If so,
1734                          *  re-send it.  Otherwise, just complain.
1735                          */
1736                         if (curreq->reply) {
1737                                 radlog(L_INFO, "Sending duplicate authentication reply"
1738                                                 " to client %s:%d - ID: %d", client_name(curreq->packet->src_ipaddr),
1739                                                 curreq->packet->src_port, curreq->packet->id);
1740
1741                                 rad_send(curreq->reply, curreq->secret);
1742
1743                                 /*
1744                                  *  There's no reply, but maybe there's
1745                                  *  an outstanding proxy request.
1746                                  *
1747                                  *  If so, then kick the proxy again.
1748                                  */
1749                         } else if (curreq->proxy != NULL) {
1750                                 if (proxy_synchronous) {
1751                                         DEBUG2("Sending duplicate proxy request to client %s:%d - ID: %d",
1752                                                         client_name(curreq->proxy->dst_ipaddr), request->packet->src_port,
1753                                                         curreq->proxy->id);
1754
1755                                         curreq->proxy_next_try = request->timestamp + proxy_retry_delay;
1756                                         rad_send(curreq->proxy, curreq->proxysecret);
1757                                 } else {
1758                                         DEBUG2("Ignoring duplicate authentication packet"
1759                                                         " from client %s:%d - ID: %d, due to outstanding proxy request.",
1760                                                         client_name(request->packet->src_ipaddr),
1761                                                         request->packet->src_port,
1762                                                         request->packet->id);
1763                                 }
1764                         } else {
1765                                 /*
1766                                  *  This request wasn't proxied.
1767                                  */
1768                                 radlog(L_ERR, "Dropping duplicate authentication packet"
1769                                                 " from client %s:%d - ID: %d", client_name(request->packet->src_ipaddr),
1770                                                 request->packet->src_port, request->packet->id);
1771                         }
1772
1773                         /*
1774                          *  Delete the duplicate request.
1775                          */
1776                         request_free(&request);
1777                         return NULL;
1778                         
1779                         /*
1780                          *  The packet vectors are different, so
1781                          *  we can delete the old request from
1782                          *  the list.
1783                          */
1784                 } else if (curreq->finished) {
1785                         if (last_request == curreq) {
1786                                 last_request = rl_next(last_request);
1787                         }
1788                         rl_delete(curreq);
1789
1790                         /*
1791                          *  ??? the client sent us a new request
1792                          *  with the same ID, while we were
1793                          *  processing the old one!  What should
1794                          *  we do?
1795                          *
1796                          *  Right now, we just drop the new packet..
1797                          */
1798                 } else {
1799                         radlog(L_ERR, "Dropping conflicting authentication packet"
1800                                         " from client %s:%d - ID: %d",
1801                                         client_name(request->packet->src_ipaddr),
1802                                         request->packet->src_port,
1803                                         request->packet->id);
1804                                 request_free(&request);
1805                                 return NULL;
1806                 }
1807         } /* a similar packet already exists. */
1808
1809         /*
1810          *  Count the total number of requests, to see if there
1811          *  are too many.  If so, return with an error.
1812          */
1813         if (max_requests) {
1814                 int request_count = rl_num_requests();
1815                 
1816                 /*
1817                  *  This is a new request.  Let's see if it
1818                  *  makes us go over our configured bounds.
1819                  */
1820                 if (request_count > max_requests) {
1821                         radlog(L_ERR, "Dropping request (%d is too many): "
1822                                         "from client %s:%d - ID: %d", request_count, 
1823                                         client_name(request->packet->src_ipaddr),
1824                                         request->packet->src_port,
1825                                         request->packet->id);
1826                         radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
1827                                         "\tThe value for 'max_requests' is probably set too low.\n");
1828                         request_free(&request);
1829                         return NULL;
1830                 }
1831         }
1832
1833         /*
1834          *  Add this request to the list
1835          */
1836         rl_add(request);
1837
1838         /*
1839          *  And return the request to be handled.
1840          */
1841         return request;
1842 }
1843
1844 #ifndef WITH_THREAD_POOL
1845 #if HAVE_PTHREAD_H
1846 typedef struct spawn_thread_t {
1847         REQUEST *request;
1848         RAD_REQUEST_FUNP fun;
1849 } spawn_thread_t;
1850
1851 /*
1852  *  If the child *thread* gets a termination signal,
1853  *  then exit from the thread.
1854  */
1855 static void sig_term(int sig)
1856 {
1857         sig = sig;  /* -Wunused */
1858         pthread_exit(NULL);
1859 }
1860
1861 /*
1862  *  Spawn a new child thread to handle this request, and ONLY
1863  *  this request.
1864  */
1865 static void *rad_spawn_thread(void *arg)
1866 {
1867         int replicating;
1868         spawn_thread_t *data = (spawn_thread_t *)arg;
1869         
1870         /*
1871          *  Note that this behaviour only works on Linux.
1872          *
1873          *  It's generally NOT the thing to do, and should
1874          *  be fixed somehow.
1875          *
1876          *  Q: How do we signal a hung thread, and tell it to
1877          *  kill itself?
1878          */
1879         signal(SIGTERM, sig_term);
1880         
1881         /*
1882          *  Keep only allowed attributes in the request.
1883          */
1884         if (data->request->proxy) {
1885                 replicating = proxy_receive(data->request);
1886                 if (replicating != 0) {
1887                         data->request->finished = TRUE;
1888                         free(data);
1889                         return NULL;
1890                 }
1891         }
1892         
1893         rad_respond(data->request, data->fun);
1894         data->request->child_pid = NO_SUCH_CHILD_PID;
1895         free(data);
1896         return NULL;
1897 }
1898 #endif
1899 #endif
1900
1901 /*
1902  *  If we're using the thread pool, then the function in
1903  *  'threads.c' replaces this one.
1904  */
1905 #ifndef WITH_THREAD_POOL
1906 /*
1907  *  Spawns a child process or thread to perform
1908  *  authentication/accounting and respond to RADIUS clients.
1909  */
1910 static int rad_spawn_child(REQUEST *request, RAD_REQUEST_FUNP fun)
1911 {
1912         child_pid_t             child_pid;
1913
1914 #if HAVE_PTHREAD_H
1915         int rcode;
1916         spawn_thread_t *data;
1917
1918         data = (spawn_thread_t *) rad_malloc(sizeof(spawn_thread_t));
1919         memset(data, 0, sizeof(data));
1920         data->request = request;
1921         data->fun = fun;
1922
1923         /*
1924          *  Create a child thread, complaining on error.
1925          */
1926         rcode = pthread_create(&child_pid, NULL, rad_spawn_thread, data);
1927         if (rcode != 0) {
1928                 radlog(L_ERR, "Thread create failed for request from nas %s - ID: %d : %s",
1929                                 nas_name2(request->packet), request->packet->id, strerror(errno));
1930                 return -1;
1931         }
1932
1933         /*
1934          *  Detach it, so it's state is automagically cleaned up on exit.
1935          */
1936         pthread_detach(child_pid);
1937
1938 #else
1939         /*
1940          *  fork our child
1941          */
1942         child_pid = fork();
1943         if (child_pid < 0) {
1944                 radlog(L_ERR, "Fork failed for request from nas %s - ID: %d",
1945                                 nas_name2(request->packet),
1946                                 request->packet->id);
1947                 return -1;
1948         }
1949
1950         if (child_pid == 0) {
1951
1952                 /*
1953                  *  This is the child, it should go ahead and respond
1954                  */
1955                 signal(SIGCHLD, SIG_DFL);
1956                 rad_respond(request, fun);
1957                 exit(0);
1958         }
1959 #endif
1960
1961         /*
1962          *  Register the Child
1963          */
1964         request->child_pid = child_pid;
1965         return 0;
1966 }
1967 #endif /* WITH_THREAD_POOL */
1968
1969 /*ARGSUSED*/
1970 void sig_cleanup(int sig)
1971 {
1972 #ifndef HAVE_PTHREAD_H
1973         int i;
1974         int status;
1975         child_pid_t pid;
1976         REQUEST *curreq;
1977 #endif
1978
1979         sig = sig; /* -Wunused */
1980  
1981         got_child = FALSE;
1982
1983         /*
1984          *  Reset the signal handler, if required.
1985          */
1986         reset_signal(SIGCHLD, sig_cleanup);
1987         
1988         /*
1989          *  If we're using pthreads, then there are NO child processes,
1990          *  so the waitpid() call, and the following code, is useless.
1991          */
1992 #ifndef HAVE_PTHREAD_H
1993         for (;;) {
1994                 pid = waitpid((pid_t)-1, &status, WNOHANG);
1995                 if (pid <= 0)
1996                         return;
1997
1998                 /*
1999                  *  Check to see if the child did a bad thing.
2000                  *  If so, kill ALL processes in the current
2001                  *  process group, to prevent further attacks.
2002                  */
2003                 if (debug_flag && (WIFSIGNALED(status))) {
2004                         radlog(L_ERR|L_CONS, "MASTER: Child PID %d failed to catch signal %d: killing all active servers.\n",
2005                                         pid, WTERMSIG(status));
2006                         kill(0, SIGTERM);
2007                         exit(1);
2008                 }
2009
2010                 /*
2011                  *  Loop over ALL of the active requests, looking
2012                  *  for the one which caused the signal.
2013                  */
2014                 for (curreq = rl_next(NULL); curreq != NULL; curreq = rl_next(curreq)) {
2015                         if (curreq->child_pid == pid) {
2016                                 curreq->child_pid = NO_SUCH_CHILD_PID;
2017                                 break;
2018                         }
2019                 }
2020         }
2021 #endif /* !defined HAVE_PTHREAD_H */
2022 }
2023
2024 /*
2025  *  Display the syntax for starting this program.
2026  */
2027 static void usage(void)
2028 {
2029         fprintf(stderr,
2030                         "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-"
2031 #if defined(WITH_DBM) || defined(WITH_NDBM)
2032                         "b"
2033 #endif
2034                         "AcfnsSvXxyz]\n", progname);
2035         fprintf(stderr, "Options:\n\n");
2036         fprintf(stderr, "  -a acct_dir     use accounting directory 'acct_dir'.\n");
2037         fprintf(stderr, "  -A              Log auth detail.\n");
2038 #if defined(WITH_DBM) || defined(WITH_NDBM)
2039         fprintf(stderr, "  -b              Use DBM.\n");
2040 #endif
2041         fprintf(stderr, "  -d db_dir       Use database directory 'db_dir'.\n");
2042         fprintf(stderr, "  -f              Run as a foreground process, not a daemon.\n");
2043         fprintf(stderr, "  -h              Print this help message.\n");
2044         fprintf(stderr, "  -i address      Listen only in the given IP address.\n");
2045         fprintf(stderr, "  -l log_dir      Log messages to 'log_dir'.  Special values are:\n");
2046         fprintf(stderr, "                  stdout == log all messages to standard output.\n");
2047         fprintf(stderr, "                  syslog == log all messages to the system logger.\n");
2048         fprintf(stderr, "  -p port         Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
2049         fprintf(stderr, "  -s              Do not spawn child processes to handle requests.\n");
2050         fprintf(stderr, "  -S              Log stripped names.\n");
2051         fprintf(stderr, "  -v              Print server version information.\n");
2052         fprintf(stderr, "  -X              Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
2053         fprintf(stderr, "  -x              Turn on partial debugging. (-xx gives more debugging).\n");
2054         fprintf(stderr, "  -y              Log authentication failures, with password.\n");
2055         fprintf(stderr, "  -z              Log authentication successes, with password.\n");
2056         exit(1);
2057 }
2058
2059
2060 /*
2061  *  We got a fatal signal. Clean up and exit.
2062  */
2063 static void sig_fatal(int sig)
2064 {
2065         const char *me = "MASTER: ";
2066
2067         if (radius_pid != getpid()) {
2068                 me = "CHILD: ";
2069         }
2070
2071         switch(sig) {
2072                 case 100:
2073                         radlog(L_ERR, "%saccounting process died - exit.", me);
2074                         break;
2075                 case 101:
2076                         radlog(L_ERR, "%sfailed in select() - exit.", me);
2077                         break;
2078                 case SIGTERM:
2079                         radlog(L_INFO, "%sexit.", me);
2080                         break;
2081                 default:
2082                         radlog(L_ERR, "%sexit on signal (%d)", me, sig);
2083                         break;
2084         }
2085
2086         /*
2087          *  We're running as a daemon, we're the MASTER daemon,
2088          *  and we got a fatal signal.  Tear the rest of the
2089          *  daemons down, as something absolutely horrible happened.
2090          */
2091         if ((debug_flag == 0) && (dont_fork == 0) &&
2092                         (radius_pid == getpid())) {
2093                 /*
2094                  *      Kill all of the processes in the current
2095                  *  process group.
2096                  */
2097                 kill(0, SIGKILL);
2098         }
2099
2100         exit(sig == SIGTERM ? 0 : 1);
2101 }
2102
2103
2104 /*
2105  *  We got the hangup signal.
2106  *  Re-read the configuration files.
2107  */
2108 /*ARGSUSED*/
2109 static void sig_hup(int sig)
2110 {
2111         sig = sig; /* -Wunused */
2112         reset_signal(SIGHUP, sig_hup);
2113
2114         /*
2115          *  Only do the reload if we're the main server, both
2116          *  for processes, and for threads.
2117          */
2118         if (getpid() == radius_pid) {
2119                 need_reload = TRUE;
2120         }
2121 #ifdef WITH_SNMP
2122         rad_snmp.smux_failures = 0;
2123         rad_snmp.smux_event = SMUX_CONNECT;
2124 #endif
2125 }
2126
2127 /*
2128  *  Do a proxy check of the REQUEST list when using the new proxy code.
2129  */
2130 static REQUEST *proxy_check_list(REQUEST *request)
2131 {
2132         REQUEST *oldreq;
2133         
2134         /*
2135          *  Find the original request in the request list
2136          */
2137         oldreq = rl_find_proxy(request);
2138         if (oldreq) {
2139                 /*
2140                  *  If there is already a reply,
2141                  *  maybe the new one is a duplicate?
2142                  */
2143                 if (oldreq->proxy_reply) {
2144                         if (memcmp(oldreq->proxy_reply->vector,
2145                                         request->packet->vector,
2146                                         sizeof(oldreq->proxy_reply->vector)) == 0) {
2147                                 DEBUG2("Ignoring duplicate proxy reply");
2148                                 request_free(&request);
2149                                 return NULL;
2150                         } else {
2151                                 /*
2152                                  *  ??? The home server gave us a new
2153                                  *  proxy reply, which doesn't match
2154                                  *  the old one.  Delete it!
2155                                  */
2156                                 DEBUG2("Ignoring conflicting proxy reply");
2157                                 request_free(&request);
2158                                 return NULL;
2159                         }
2160                 } /* else there's no reply yet. */
2161
2162         } else {
2163                 /*
2164                  *  If we haven't found the old request, complain.
2165                  */
2166                 radlog(L_PROXY, "No request found for proxy reply from server %s - ID %d",
2167                                 client_name(request->packet->src_ipaddr),
2168                                 request->packet->id);
2169                 request_free(&request);
2170                 return NULL;
2171         }
2172
2173         /*
2174          *  Refresh the old request, and update it with the proxy reply.
2175          *
2176          *  ??? Can we delete the proxy request here?
2177          *  Is there any more need for it?
2178          */
2179         oldreq->timestamp = request->timestamp;
2180         oldreq->proxy_reply = request->packet;
2181         request->packet = NULL;
2182         request_free(&request);
2183         return oldreq;
2184 }
2185
2186 /*
2187  *  Refresh a request, by using proxy_retry_delay, cleanup_delay,
2188  *  max_request_time, etc.
2189  *
2190  *  When walking over the request list, all of the per-request
2191  *  magic is done here.
2192  */
2193 static int refresh_request(REQUEST *request, void *data)
2194 {
2195         rad_walk_t *info = (rad_walk_t *) data;
2196         time_t difference;
2197         child_pid_t child_pid;
2198
2199         assert(request->magic == REQUEST_MAGIC);
2200
2201         /*
2202          *  If the request has finished processing,
2203          *  AND it's child has been cleaned up,
2204          *  AND it's time to clean up the request,
2205          *      OR, it's an accounting request.
2206          *  THEN, go delete it.
2207          *
2208          *  If this is an accounting request, we delete it
2209          *  immediately, as there CANNOT be duplicate accounting
2210          *  packets.  If there are, then something else is
2211          *  seriously wrong...
2212          */
2213         if (request->finished &&
2214                         (request->child_pid == NO_SUCH_CHILD_PID) &&
2215                         ((request->timestamp + cleanup_delay <= info->now) ||
2216                         (request->packet->code == PW_ACCOUNTING_REQUEST))) {
2217                 /*
2218                  *  Request completed, delete it, and unlink it
2219                  *  from the currently 'alive' list of requests.
2220                  */
2221                 DEBUG2("Cleaning up request %d ID %d with timestamp %08lx",
2222                                 request->number, request->packet->id,
2223                                 (unsigned long)request->timestamp);
2224                 
2225                 /*
2226                  *  Delete the request.
2227                  */
2228                 rl_delete(request);
2229                 return RL_WALK_CONTINUE;
2230         }
2231
2232         /*
2233          *  Maybe the child process
2234          *  handling the request has hung:
2235          *  kill it, and continue.
2236          */
2237         if ((request->timestamp + max_request_time) <= info->now) {
2238                 if (request->child_pid != NO_SUCH_CHILD_PID) {
2239                         /*
2240                          *  This request seems to have hung
2241                          *   - kill it
2242                          */
2243                         child_pid = request->child_pid;
2244                         radlog(L_ERR, "Killing unresponsive child %ld for request %d",
2245                                         child_pid, request->number);
2246                         child_kill(child_pid, SIGTERM);
2247                 } /* else no proxy reply, quietly fail */
2248                 
2249                 /*
2250                  *  Delete the request.
2251                  */
2252                 rl_delete(request);
2253                 return RL_WALK_CONTINUE;
2254         }
2255
2256         /*
2257          *  The request is finished.
2258          */
2259         if (request->finished) goto setup_timeout;
2260
2261         /*
2262          *  We're not proxying requests at all.
2263          */
2264         if (!proxy_requests) goto setup_timeout;
2265
2266         /*
2267          *  We're proxying synchronously, so the retry_delay is zero.
2268          *  Some other code takes care of retrying the proxy requests.
2269          */
2270         if (proxy_retry_delay == 0) goto setup_timeout;
2271
2272         /*
2273          *  There is no proxied request for this packet, so there's
2274          *  no proxy retries.
2275          */
2276         if (!request->proxy) goto setup_timeout;
2277
2278         /*
2279          *  We've already seen the proxy reply, so we don't need
2280          *  to send another proxy request.
2281          */
2282         if (request->proxy_reply) goto setup_timeout;
2283
2284         /*
2285          *  It's not yet time to re-send this proxied request.
2286          */
2287         if (request->proxy_next_try > info->now) goto setup_timeout;
2288         
2289         /*
2290          *  If the proxy retry count is zero, then
2291          *  we've sent the last try, and have NOT received
2292          *  a reply from the end server.  In that case,
2293          *  we don't bother trying again, but just mark
2294          *  the request as finished, and go to the next one.
2295          */
2296         if (request->proxy_try_count == 0) {
2297                 request->finished = TRUE;
2298                 rad_reject(request);
2299                 goto setup_timeout;
2300         }
2301
2302         /*
2303          *  We're trying one more time, so count down
2304          *  the tries, and set the next try time.
2305          */
2306         request->proxy_try_count--;
2307         request->proxy_next_try = info->now + proxy_retry_delay;
2308                 
2309         /* Fix up Acct-Delay-Time */
2310         if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
2311                 VALUE_PAIR *delaypair;
2312                 delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
2313                 
2314                 if (!delaypair) {
2315                         delaypair = paircreate(PW_ACCT_DELAY_TIME,
2316                                         PW_TYPE_INTEGER);
2317                         if (!delaypair) {
2318                                 radlog(L_ERR|L_CONS, "no memory");
2319                                 exit(1);
2320                         }
2321                         pairadd(&request->proxy->vps, delaypair);
2322                 }
2323                 delaypair->lvalue = info->now - request->proxy->timestamp;
2324                         
2325                 /* Must recompile the valuepairs to wire format */
2326                 free(request->proxy->data);
2327                 request->proxy->data = NULL;
2328         } /* proxy accounting request */
2329         
2330         /*
2331          *  Send the proxy packet.
2332          */
2333         rad_send(request->proxy, request->proxysecret);
2334
2335 setup_timeout:
2336         /*
2337          *  Don't do more long-term checks, if we've got to wake
2338          *  up now.
2339          */
2340         if (info->smallest == 0) {
2341                 return RL_WALK_CONTINUE;
2342         }
2343
2344         /*
2345          *  The request is finished.  Wake up when it's time to
2346          *  clean it up.
2347          */
2348         if (request->finished) {
2349                 difference = (request->timestamp + cleanup_delay) - info->now;
2350                 
2351         } else if (request->proxy && !request->proxy_reply) {
2352                 /*
2353                  *  The request is NOT finished, but there is an
2354                  *  outstanding proxy request, with no matching
2355                  *  proxy reply.
2356                  *
2357                  *  Wake up when it's time to re-send
2358                  *  the proxy request.
2359                  */
2360                 difference = request->proxy_next_try - info->now;
2361                 
2362         } else {
2363                 /*
2364                  *  The request is NOT finished.
2365                  *
2366                  *  Wake up when it's time to kill the errant
2367                  *  thread/process.
2368                  */
2369                 difference = (request->timestamp + max_request_time) - info->now;
2370         }
2371
2372         /*
2373          *  If the server is CPU starved, then we CAN miss a time
2374          *  for servicing requests.  In which case the 'difference'
2375          *  value will be negative.  select() doesn't like that,
2376          *  so we fix it.
2377          */
2378         if (difference < 0) {
2379                 difference = 0;
2380         }
2381
2382         /*
2383          *  Update the 'smallest' time.
2384          */
2385         if ((info->smallest < 0) ||
2386                 (difference < info->smallest)) {
2387                 info->smallest = difference;
2388         }
2389
2390         return RL_WALK_CONTINUE;
2391 }