Be less agressive about marking home servers as zombie.
[freeradius.git] / src / main / event.c
1 /*
2  * event.c      Server event handling
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2007  The FreeRADIUS server project
21  * Copyright 2007  Alan DeKok <aland@deployingradius.com>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/event.h>
30 #include <freeradius-devel/detail.h>
31
32 #include <freeradius-devel/rad_assert.h>
33
34 #include <signal.h>
35 #include <fcntl.h>
36
37 #ifdef HAVE_SYS_WAIT_H
38 #       include <sys/wait.h>
39 #endif
40
41 #define USEC (1000000)
42
43 extern pid_t radius_pid;
44 extern int dont_fork;
45 extern int check_config;
46 extern char *debug_condition;
47
48 /*
49  *      Ridiculous amounts of local state.
50  */
51 static fr_event_list_t  *el = NULL;
52 static fr_packet_list_t *pl = NULL;
53 static int                      request_num_counter = 0;
54 static struct timeval           now;
55 time_t                          fr_start_time;
56 static int                      have_children;
57 static int                      just_started = TRUE;
58
59 #ifndef __MINGW32__
60 #ifdef HAVE_PTHREAD_H
61 #define WITH_SELF_PIPE (1)
62 #endif
63 #endif
64
65 #ifdef WITH_SELF_PIPE
66 static int self_pipe[2];
67 #endif
68
69 #ifdef HAVE_PTHREAD_H
70 #ifdef WITH_PROXY
71 static pthread_mutex_t  proxy_mutex;
72 static rad_listen_t *proxy_listener_list = NULL;
73 static int proxy_no_new_sockets = FALSE;
74 #endif
75
76 #define PTHREAD_MUTEX_LOCK if (have_children) pthread_mutex_lock
77 #define PTHREAD_MUTEX_UNLOCK if (have_children) pthread_mutex_unlock
78
79 static pthread_t NO_SUCH_CHILD_PID;
80 #else
81 /*
82  *      This is easier than ifdef's throughout the code.
83  */
84 #define PTHREAD_MUTEX_LOCK(_x)
85 #define PTHREAD_MUTEX_UNLOCK(_x)
86 #endif
87
88 /*
89  *      We need mutexes around the event FD list *only* in certain
90  *      cases.
91  */
92 #if defined (HAVE_PTHREAD_H) && (defined(WITH_PROXY) || defined(WITH_TCP))
93 static pthread_mutex_t  fd_mutex;
94 #define FD_MUTEX_LOCK if (have_children) pthread_mutex_lock
95 #define FD_MUTEX_UNLOCK if (have_children) pthread_mutex_unlock
96 #else
97 /*
98  *      This is easier than ifdef's throughout the code.
99  */
100 #define FD_MUTEX_LOCK(_x)
101 #define FD_MUTEX_UNLOCK(_x)
102 #endif
103
104
105 #define INSERT_EVENT(_function, _ctx) if (!fr_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev))) { _rad_panic(__FILE__, __LINE__, "Failed to insert event"); }
106
107 #ifdef WITH_PROXY
108 static fr_packet_list_t *proxy_list = NULL;
109 static void remove_from_proxy_hash(REQUEST *request);
110
111 static void check_for_zombie_home_server(REQUEST *request);
112 #else
113 #define remove_from_proxy_hash(foo)
114 #endif
115
116 static void request_post_handler(REQUEST *request);
117 static void wait_a_bit(void *ctx);
118 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd, void *ctx);
119 #ifdef WITH_DETAIL
120 static void event_poll_detail(void *ctx);
121 #endif
122
123 static void NEVER_RETURNS _rad_panic(const char *file, unsigned int line,
124                                     const char *msg)
125 {
126         radlog(L_ERR, "[%s:%d] %s", file, line, msg);
127         _exit(1);
128 }
129
130 #define rad_panic(x) _rad_panic(__FILE__, __LINE__, x)
131
132
133 static void tv_add(struct timeval *tv, int usec_delay)
134 {
135         if (usec_delay > USEC) {
136                 tv->tv_sec += usec_delay / USEC;
137                 usec_delay %= USEC;
138         }
139         tv->tv_usec += usec_delay;
140
141         if (tv->tv_usec > USEC) {
142                 tv->tv_sec += tv->tv_usec / USEC;
143                 tv->tv_usec %= USEC;
144         }
145 }
146
147 static void remove_from_request_hash(REQUEST *request)
148 {
149         if (!request->in_request_hash) return;
150
151         fr_packet_list_yank(pl, request->packet);
152         request->in_request_hash = FALSE;
153
154         /*
155          *      FIXME: Move this to a "statistics" thread?
156          *      Or (short term) add a mutex lock around it.
157          */
158         request_stats_final(request);
159
160 #ifdef WITH_TCP
161         request->listener->count--;
162 #endif
163 }
164
165 static void ev_request_free(REQUEST **prequest)
166 {
167         REQUEST *request;
168         
169         if (!prequest || !*prequest) return;
170
171         request = *prequest;
172
173 #ifdef WITH_COA
174         if (request->coa) {
175                 /*
176                  *      Divorce the child from the parent first,
177                  *      then clean up the child.
178                  */
179                 request->coa->parent = NULL;
180                 ev_request_free(&request->coa);
181         }
182
183         /*
184          *      Divorce the parent from the child, and leave the
185          *      parent still alive.
186          */
187         if (request->parent && (request->parent->coa == request)) {
188                 request->parent->coa = NULL;
189         }
190 #endif
191
192         if (request->ev) fr_event_delete(el, &request->ev);
193 #ifdef WITH_PROXY
194         if (request->in_proxy_hash) remove_from_proxy_hash(request);
195 #endif
196         if (request->in_request_hash) remove_from_request_hash(request);
197
198         request_free(prequest);
199 }
200
201 #ifdef WITH_PROXY
202 static REQUEST *lookup_in_proxy_hash(RADIUS_PACKET *reply)
203 {
204         RADIUS_PACKET **proxy_p;
205         REQUEST *request;
206
207         PTHREAD_MUTEX_LOCK(&proxy_mutex);
208         proxy_p = fr_packet_list_find_byreply(proxy_list, reply);
209
210         if (!proxy_p) {
211                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
212                 return NULL;
213         }
214
215         request = fr_packet2myptr(REQUEST, proxy, proxy_p);
216         request->num_proxied_responses++; /* needs to be protected by lock */
217
218         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
219
220         return request;
221 }
222
223
224 static void remove_from_proxy_hash(REQUEST *request)
225 {
226         /*
227          *      Check this without grabbing the mutex because it's a
228          *      lot faster that way.
229          */
230         if (!request->in_proxy_hash) return;
231
232         /*
233          *      The "not in hash" flag is definitive.  However, if the
234          *      flag says that it IS in the hash, there might still be
235          *      a race condition where it isn't.
236          */
237         PTHREAD_MUTEX_LOCK(&proxy_mutex);
238
239         if (!request->in_proxy_hash) {
240                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
241                 return;
242         }
243
244         fr_packet_list_yank(proxy_list, request->proxy);
245         fr_packet_list_id_free(proxy_list, request->proxy);
246
247         /*
248          *      On the FIRST reply, decrement the count of outstanding
249          *      requests.  Note that this is NOT the count of sent
250          *      packets, but whether or not the home server has
251          *      responded at all.
252          */
253         if (!request->proxy_reply &&
254             request->home_server &&
255             request->home_server->currently_outstanding) {
256                 request->home_server->currently_outstanding--;
257         }
258
259 #ifdef WITH_TCP
260         request->proxy_listener->count--;
261         request->proxy_listener = NULL;
262 #endif
263
264         /*
265          *      Got from YES in hash, to NO, not in hash while we hold
266          *      the mutex.  This guarantees that when another thread
267          *      grabs the mutex, the "not in hash" flag is correct.
268          */
269         request->in_proxy_hash = FALSE;
270
271         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
272 }
273 #endif  /* WITH_PROXY */
274
275 #ifdef WITH_TCP
276 static int remove_all_requests(void *ctx, void *data)
277 {
278         rad_listen_t *this = ctx;
279         RADIUS_PACKET **packet_p = data;
280         REQUEST *request;
281         
282         request = fr_packet2myptr(REQUEST, packet, packet_p);
283         if (request->packet->sockfd != this->fd) return 0;
284
285         switch (request->child_state) {
286         case REQUEST_RUNNING:
287                 rad_assert(request->ev != NULL); /* or it's lost forever */
288         case REQUEST_QUEUED:
289                 request->master_state = REQUEST_STOP_PROCESSING;
290                 return 0;
291
292                 /*
293                  *      Waiting for a reply.  There's no point in
294                  *      doing anything else.  We remove it from the
295                  *      request hash so that we can close the upstream
296                  *      socket.
297                  */
298         case REQUEST_PROXIED:
299                 remove_from_request_hash(request);
300                 request->child_state = REQUEST_DONE;
301                 return 0;
302
303         case REQUEST_REJECT_DELAY:
304         case REQUEST_CLEANUP_DELAY:
305         case REQUEST_DONE:
306                 ev_request_free(&request);
307                 break;
308         }
309
310         return 0;
311 }
312
313 #ifdef WITH_PROXY
314 static int remove_all_proxied_requests(void *ctx, void *data)
315 {
316         rad_listen_t *this = ctx;
317         RADIUS_PACKET **proxy_p = data;
318         REQUEST *request;
319         
320         request = fr_packet2myptr(REQUEST, proxy, proxy_p);
321         if (request->proxy->sockfd != this->fd) return 0;
322
323         switch (request->child_state) {
324         case REQUEST_RUNNING:
325                 rad_assert(request->ev != NULL); /* or it's lost forever */
326         case REQUEST_QUEUED:
327                 request->master_state = REQUEST_STOP_PROCESSING;
328                 return 0;
329
330                 /*
331                  *      Eventually we will discover that there is no
332                  *      response to the proxied request.
333                  */
334         case REQUEST_PROXIED:
335                 break;
336
337                 /*
338                  *      Keep it in the cache for duplicate detection.
339                  */
340         case REQUEST_REJECT_DELAY:
341         case REQUEST_CLEANUP_DELAY:
342         case REQUEST_DONE:
343                 break;
344         }
345
346         remove_from_proxy_hash(request);
347         return 0;
348 }
349 #endif  /* WITH_PROXY */
350 #endif  /* WITH_TCP */
351
352
353 #ifdef WITH_PROXY
354 static int insert_into_proxy_hash(REQUEST *request)
355 {
356         char buf[128];
357         int rcode, tries;
358         void *proxy_listener;
359
360         rad_assert(request->proxy != NULL);
361         rad_assert(proxy_list != NULL);
362
363         tries = 1;
364 retry:
365         PTHREAD_MUTEX_LOCK(&proxy_mutex);
366         rcode = fr_packet_list_id_alloc(proxy_list,
367                                         request->home_server->proto,
368                                         request->proxy, &proxy_listener);
369         request->num_proxied_requests = 1;
370         request->num_proxied_responses = 0;
371         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
372         
373         if (!rcode) {
374                 if (proxy_no_new_sockets) return 0;
375
376                 /*
377                  *      Also locks the proxy mutex, so we have to call
378                  *      it with the mutex unlocked.  Some systems
379                  *      don't support recursive mutexes.
380                  */
381                 if (!proxy_new_listener(request->home_server, 0)) {
382                         radlog(L_ERR, "Failed to create a new socket for proxying requests.");
383                         return 0;
384                 }
385                 request->proxy->src_port = 0; /* Use any new socket */
386
387                 tries++;
388                 if (tries > 2) {
389                         RDEBUG2("ERROR: Failed allocating Id for new socket when proxying requests.");
390                         return 0;
391                 }
392                 
393                 goto retry;
394         }
395
396         request->proxy_listener = proxy_listener;
397
398         PTHREAD_MUTEX_LOCK(&proxy_mutex);
399         if (!fr_packet_list_insert(proxy_list, &request->proxy)) {
400                 fr_packet_list_id_free(proxy_list, request->proxy);
401                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
402                 radlog(L_PROXY, "Failed to insert entry into proxy list.");
403                 return 0;
404         }
405
406         request->in_proxy_hash = TRUE;
407
408         /*
409          *      Keep track of maximum outstanding requests to a
410          *      particular home server.  'max_outstanding' is
411          *      enforced in home_server_ldb(), in realms.c.
412          */
413         if (request->home_server) {
414                 request->home_server->currently_outstanding++;
415         }
416
417 #ifdef WITH_TCP
418         request->proxy_listener->count++;
419 #endif
420
421         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
422
423         RDEBUG3(" proxy: allocating destination %s port %d - Id %d",
424                inet_ntop(request->proxy->dst_ipaddr.af,
425                          &request->proxy->dst_ipaddr.ipaddr, buf, sizeof(buf)),
426                request->proxy->dst_port,
427                request->proxy->id);
428
429         return 1;
430 }
431
432
433 /*
434  *      Called as BOTH an event, and in-line from other functions.
435  */
436 static void wait_for_proxy_id_to_expire(void *ctx)
437 {
438         REQUEST *request = ctx;
439
440         rad_assert(request->magic == REQUEST_MAGIC);
441         rad_assert(request->proxy != NULL);
442
443         fr_event_now(el, &now);
444         request->when = request->proxy_when;
445
446 #ifdef WITH_COA
447         if (((request->proxy->code == PW_COA_REQUEST) ||
448              (request->proxy->code == PW_DISCONNECT_REQUEST)) &&
449             (request->packet->code != request->proxy->code)) {
450                 request->when.tv_sec += request->home_server->coa_mrd;
451         } else
452 #endif
453         request->when.tv_sec += request->home_server->response_window;
454
455         if ((request->num_proxied_requests == request->num_proxied_responses) ||
456 #ifdef WITH_TCP
457             (request->home_server->proto == IPPROTO_TCP) ||
458 #endif
459             timercmp(&now, &request->when, >)) {
460                 if (request->packet) {
461                         RDEBUG2("Cleaning up request packet ID %d with timestamp +%d",
462                                request->packet->id,
463                                (unsigned int) (request->timestamp - fr_start_time));
464                 } else {
465                         RDEBUG2("Cleaning up request with timestamp +%d",
466                                (unsigned int) (request->timestamp - fr_start_time));
467                 }
468
469                 ev_request_free(&request);
470                 return;
471         }
472
473         INSERT_EVENT(wait_for_proxy_id_to_expire, request);
474 }
475 #endif
476
477 #ifdef HAVE_PTHREAD_H
478 static void wait_for_child_to_die(void *ctx)
479 {
480         REQUEST *request = ctx;
481
482         rad_assert(request->magic == REQUEST_MAGIC);
483         remove_from_request_hash(request);
484
485         /*
486          *      If it's still queued (waiting for a thread to pick it
487          *      up) OR, it's running AND there's still a child thread
488          *      handling it, THEN delay some more.
489          */
490         if ((request->child_state == REQUEST_QUEUED) ||
491             ((request->child_state == REQUEST_RUNNING) &&
492              (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0))) {
493
494                 /*
495                  *      Cap delay at max_request_time
496                  */
497                 if (request->delay < (USEC * request->root->max_request_time)) {
498                         request->delay += (request->delay >> 1);
499                         radlog_request(L_INFO, 0, request, "WARNING: Child is hung in component %s module %s.",
500                                request->component, request->module);
501                 } else {
502                         request->delay = USEC * request->root->max_request_time;
503                         RDEBUG2("WARNING: Child is still stuck");
504                 }
505                 tv_add(&request->when, request->delay);
506
507                 INSERT_EVENT(wait_for_child_to_die, request);
508                 return;
509         }
510
511         RDEBUG2("Child is finally responsive");
512
513 #ifdef WITH_PROXY
514         if (request->proxy) {
515                 wait_for_proxy_id_to_expire(request);
516                 return;
517         }
518 #endif
519
520         ev_request_free(&request);
521 }
522 #endif
523
524 static void cleanup_delay(void *ctx)
525 {
526         REQUEST *request = ctx;
527
528         rad_assert(request->magic == REQUEST_MAGIC);
529         rad_assert((request->child_state == REQUEST_CLEANUP_DELAY) ||
530                    (request->child_state == REQUEST_DONE));
531
532         remove_from_request_hash(request);
533
534 #ifdef WITH_PROXY
535         if (request->proxy && request->in_proxy_hash) {
536                 wait_for_proxy_id_to_expire(request);
537                 return;
538         }
539 #endif
540
541         RDEBUG2("Cleaning up request packet ID %d with timestamp +%d",
542                 request->packet->id,
543                (unsigned int) (request->timestamp - fr_start_time));
544
545         ev_request_free(&request);
546 }
547
548
549 /*
550  *      In daemon mode, AND this request has debug flags set.
551  */
552 #define DEBUG_PACKET if (!debug_flag && request->options && request->radlog) debug_packet
553
554 static void debug_packet(REQUEST *request, RADIUS_PACKET *packet, int direction)
555 {
556         VALUE_PAIR *vp;
557         char buffer[1024];
558         const char *received, *from;
559         const fr_ipaddr_t *ip;
560         int port;
561
562         if (!packet) return;
563
564         rad_assert(request->radlog != NULL);
565
566         if (direction == 0) {
567                 received = "Received";
568                 from = "from";  /* what else? */
569                 ip = &packet->src_ipaddr;
570                 port = packet->src_port;
571
572         } else {
573                 received = "Sending";
574                 from = "to";    /* hah! */
575                 ip = &packet->dst_ipaddr;
576                 port = packet->dst_port;
577         }
578         
579         /*
580          *      Client-specific debugging re-prints the input
581          *      packet into the client log.
582          *
583          *      This really belongs in a utility library
584          */
585         if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
586                 RDEBUG("%s %s packet %s host %s port %d, id=%d, length=%d",
587                        received, fr_packet_codes[packet->code], from,
588                        inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
589                        port, packet->id, packet->data_len);
590         } else {
591                 RDEBUG("%s packet %s host %s port %d code=%d, id=%d, length=%d",
592                        received, from,
593                        inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
594                        port,
595                        packet->code, packet->id, packet->data_len);
596         }
597
598         for (vp = packet->vps; vp != NULL; vp = vp->next) {
599                 vp_prints(buffer, sizeof(buffer), vp);
600                 request->radlog(L_DBG, 0, request, "\t%s", buffer);
601         }
602 }
603
604 static void reject_delay(void *ctx)
605 {
606         REQUEST *request = ctx;
607
608         rad_assert(request->magic == REQUEST_MAGIC);
609         rad_assert(request->child_state == REQUEST_REJECT_DELAY);
610
611         RDEBUG2("Sending delayed reject");
612
613         DEBUG_PACKET(request, request->reply, 1);
614
615         request->listener->send(request->listener, request);
616
617         request->when.tv_sec += request->root->cleanup_delay;
618         request->child_state = REQUEST_CLEANUP_DELAY;
619
620         INSERT_EVENT(cleanup_delay, request);
621 }
622
623
624 #ifdef WITH_PROXY
625 void revive_home_server(void *ctx)
626 {
627         home_server *home = ctx;
628         char buffer[128];
629
630 #ifdef WITH_TCP
631         rad_assert(home->proto != IPPROTO_TCP);
632 #endif
633
634         home->state = HOME_STATE_ALIVE;
635         home->currently_outstanding = 0;
636         home->revive_time = now;
637
638         /*
639          *      Delete any outstanding events.
640          */
641         if (home->ev) fr_event_delete(el, &home->ev);
642
643         radlog(L_PROXY, "Marking home server %s port %d alive again... we have no idea if it really is alive or not.",
644                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
645                          buffer, sizeof(buffer)),
646                home->port);
647
648 }
649
650
651 static void no_response_to_ping(void *ctx)
652 {
653         REQUEST *request = ctx;
654         home_server *home;
655         char buffer[128];
656
657         rad_assert(request->home_server != NULL);
658
659         home = request->home_server;
660 #ifdef WITH_TCP
661         rad_assert(home->proto != IPPROTO_TCP);
662 #endif
663
664         home->num_received_pings = 0;
665
666         radlog(L_ERR, "No response to status check %d for home server %s port %d",
667                request->number,
668                inet_ntop(request->proxy->dst_ipaddr.af,
669                          &request->proxy->dst_ipaddr.ipaddr,
670                          buffer, sizeof(buffer)),
671                request->proxy->dst_port);
672
673         check_for_zombie_home_server(request);
674
675         wait_for_proxy_id_to_expire(request);
676 }
677
678
679 /*
680  *      Note that we don't care what the value of the code field is.
681  *      If the response has a valid (src ip/port, dst ip/port), id,
682  *      and correctly signed Message-Authenticator, that's good
683  *      enough.
684  */
685 static void received_response_to_ping(REQUEST *request)
686 {
687         home_server *home;
688         char buffer[128];
689
690         rad_assert(request->home_server != NULL);
691
692         home = request->home_server;
693 #ifdef WITH_TCP
694         rad_assert(home->proto != IPPROTO_TCP);
695 #endif
696
697         home->num_received_pings++;
698
699         radlog(L_PROXY, "Received response to status check %d (%d in current sequence)",
700                request->number, home->num_received_pings);
701
702         /*
703          *      Remove the request from any hashes
704          */
705         fr_event_delete(el, &request->ev);
706         remove_from_proxy_hash(request);
707         rad_assert(request->in_request_hash == FALSE);
708
709         /*
710          *      The control socket may have marked the home server as
711          *      alive.  OR, it may have suddenly started responding to
712          *      requests again.  If so, don't re-do the "make alive"
713          *      work.
714          */
715         if (home->state == HOME_STATE_ALIVE) return;
716
717         /*
718          *      We haven't received enough ping responses to mark it
719          *      "alive".  Wait a bit.
720          */
721         if (home->num_received_pings < home->num_pings_to_alive) {
722                 return;
723         }
724
725         home->state = HOME_STATE_ALIVE;
726         home->currently_outstanding = 0;
727         home->revive_time = now;
728
729         if (!fr_event_delete(el, &home->ev)) {
730                 RDEBUG2("Hmm... no event for home server.  Oh well.");
731         }
732
733         radlog(L_PROXY, "Marking home server %s port %d alive",
734                inet_ntop(request->proxy->dst_ipaddr.af,
735                          &request->proxy->dst_ipaddr.ipaddr,
736                          buffer, sizeof(buffer)),
737                request->proxy->dst_port);
738 }
739
740
741 /*
742  *      Called from start of zombie period, OR after control socket
743  *      marks the home server dead.
744  */
745 static void ping_home_server(void *ctx)
746 {
747         uint32_t jitter;
748         home_server *home = ctx;
749         REQUEST *request;
750         VALUE_PAIR *vp;
751
752 #ifdef WITH_TCP
753         rad_assert(home->proto != IPPROTO_TCP);
754 #endif
755
756         if ((home->state == HOME_STATE_ALIVE) ||
757             (home->ping_check == HOME_PING_CHECK_NONE) ||
758             (home->ev != NULL)) {
759                 return;
760         }
761
762         request = request_alloc();
763         request->number = request_num_counter++;
764
765         request->proxy = rad_alloc(1);
766         rad_assert(request->proxy != NULL);
767
768         fr_event_now(el, &request->when);
769         home->when = request->when;
770
771         if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
772                 request->proxy->code = PW_STATUS_SERVER;
773
774                 radius_pairmake(request, &request->proxy->vps,
775                                 "Message-Authenticator", "0x00", T_OP_SET);
776
777         } else if (home->type == HOME_TYPE_AUTH) {
778                 request->proxy->code = PW_AUTHENTICATION_REQUEST;
779
780                 radius_pairmake(request, &request->proxy->vps,
781                                 "User-Name", home->ping_user_name, T_OP_SET);
782                 radius_pairmake(request, &request->proxy->vps,
783                                 "User-Password", home->ping_user_password, T_OP_SET);
784                 radius_pairmake(request, &request->proxy->vps,
785                                 "Service-Type", "Authenticate-Only", T_OP_SET);
786                 radius_pairmake(request, &request->proxy->vps,
787                                 "Message-Authenticator", "0x00", T_OP_SET);
788
789         } else {
790 #ifdef WITH_ACCOUNTING
791                 request->proxy->code = PW_ACCOUNTING_REQUEST;
792                 
793                 radius_pairmake(request, &request->proxy->vps,
794                                 "User-Name", home->ping_user_name, T_OP_SET);
795                 radius_pairmake(request, &request->proxy->vps,
796                                 "Acct-Status-Type", "Stop", T_OP_SET);
797                 radius_pairmake(request, &request->proxy->vps,
798                                 "Acct-Session-Id", "00000000", T_OP_SET);
799                 vp = radius_pairmake(request, &request->proxy->vps,
800                                      "Event-Timestamp", "0", T_OP_SET);
801                 vp->vp_date = now.tv_sec;
802 #else
803                 rad_assert("Internal sanity check failed");
804 #endif
805         }
806
807         radius_pairmake(request, &request->proxy->vps,
808                         "NAS-Identifier", "Status Check. Are you alive?",
809                         T_OP_SET);
810
811         request->proxy->dst_ipaddr = home->ipaddr;
812         request->proxy->dst_port = home->port;
813         request->home_server = home;
814
815         rad_assert(request->proxy_listener == NULL);
816
817         if (!insert_into_proxy_hash(request)) {
818                 radlog(L_PROXY, "Failed to insert status check %d into proxy list.  Discarding it.",
819                        request->number);
820                 ev_request_free(&request);
821                 return;
822         }
823         rad_assert(request->proxy_listener != NULL);
824         request->proxy_listener->send(request->proxy_listener,
825                                       request);
826
827         request->next_callback = NULL;
828         request->child_state = REQUEST_PROXIED;
829         request->when.tv_sec += home->ping_timeout;;
830
831         INSERT_EVENT(no_response_to_ping, request);
832
833         /*
834          *      Add +/- 2s of jitter, as suggested in RFC 3539
835          *      and in the Issues and Fixes draft.
836          */
837         home->when.tv_sec += home->ping_interval - 2;
838
839         jitter = fr_rand();
840         jitter ^= (jitter >> 10);
841         jitter &= ((1 << 23) - 1); /* 22 bits of 1 */
842
843         tv_add(&home->when, jitter);
844
845         INSERT_EVENT(ping_home_server, home);
846 }
847
848
849 void mark_home_server_dead(home_server *home, struct timeval *when)
850 {
851         int previous_state = home->state;
852         char buffer[128];
853
854         radlog(L_PROXY, "Marking home server %s port %d as dead.",
855                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
856                          buffer, sizeof(buffer)),
857                home->port);
858
859         home->state = HOME_STATE_IS_DEAD;
860         home->num_received_pings = 0;
861
862         if (home->ping_check != HOME_PING_CHECK_NONE) {
863                 /*
864                  *      If the control socket marks us dead, start
865                  *      pinging.  Otherwise, we already started
866                  *      pinging when it was marked "zombie".
867                  */
868                 if (previous_state == HOME_STATE_ALIVE) {
869                         ping_home_server(home);
870                 }
871
872         } else {
873                 /*
874                  *      Revive it after a fixed period of time.  This
875                  *      is very, very, bad.
876                  */
877                 home->when = *when;
878                 home->when.tv_sec += home->revive_interval;
879
880                 INSERT_EVENT(revive_home_server, home);
881         }
882 }
883
884 static void check_for_zombie_home_server(REQUEST *request)
885 {
886         home_server *home;
887         struct timeval when;
888
889         home = request->home_server;
890
891         if (home->state != HOME_STATE_ZOMBIE) return;
892
893         when = home->zombie_period_start;
894         when.tv_sec += home->zombie_period;
895
896         fr_event_now(el, &now);
897         if (timercmp(&now, &when, <)) {
898                 return;
899         }
900
901         mark_home_server_dead(home, &request->when);
902 }
903
904 static int proxy_to_virtual_server(REQUEST *request);
905
906 static int virtual_server_handler(UNUSED REQUEST *request)
907 {
908         proxy_to_virtual_server(request);
909         return 0;
910 }
911
912 static void proxy_fallback_handler(REQUEST *request)
913 {
914         /*
915          *      A proper time is required for wait_a_bit.
916          */
917         request->delay = USEC / 10;
918         gettimeofday(&now, NULL);
919         request->next_when = now;
920         tv_add(&request->next_when, request->delay);
921         request->next_callback = wait_a_bit;
922
923         /*
924          *      Re-queue the request.
925          */
926         request->child_state = REQUEST_QUEUED;
927         
928         rad_assert(request->proxy != NULL);
929         thread_pool_addrequest(request, virtual_server_handler);
930
931 #ifdef HAVE_PTHREAD_H
932         /*
933          *      MAY free the request if we're over max_request_time,
934          *      AND we're not in threaded mode!
935          *
936          *      Note that we call this ONLY if we're threaded, as
937          *      if we're NOT threaded, request_post_handler() calls
938          *      wait_a_bit(), which means that "request" may not
939          *      exist any more...
940          */
941         if (have_children) wait_a_bit(request);
942 #endif
943 }
944
945
946 static int setup_post_proxy_fail(REQUEST *request)
947 {
948         DICT_VALUE *dval = NULL;
949         VALUE_PAIR *vp;
950
951         request->child_state = REQUEST_RUNNING;
952
953         if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
954           dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-Authentication");
955
956         } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
957                 dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-Accounting");
958
959 #ifdef WITH_COA
960                 /*
961                  *      See no_response_to_coa_request
962                  */
963         } else if (((request->packet->code >> 8) & 0xff) == PW_COA_REQUEST) {
964                 request->packet->code &= 0xff; /* restore it */
965
966                 if (request->proxy->code == PW_COA_REQUEST) {
967                         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-CoA");
968
969                 } else if (request->proxy->code == PW_DISCONNECT_REQUEST) {
970                         dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail-Disconnect");
971                 } else {
972                         return 0;
973                 }
974
975 #endif
976         } else {
977                 return 0;
978         }
979
980         if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, 0, "Fail");
981
982         if (!dval) {
983                 pairdelete(&request->config_items, PW_POST_PROXY_TYPE, 0);
984                 return 0;
985         }
986
987         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE, 0);
988         if (!vp) vp = radius_paircreate(request, &request->config_items,
989                                         PW_POST_PROXY_TYPE, 0, PW_TYPE_INTEGER);
990         vp->vp_integer = dval->value;
991
992         rad_assert(request->proxy_reply == NULL);
993
994         return 1;
995 }
996
997
998 static int null_handler(UNUSED REQUEST *request)
999 {
1000         return 0;
1001 }
1002
1003 static void post_proxy_fail_handler(REQUEST *request)
1004 {
1005         /*
1006          *      A proper time is required for wait_a_bit.
1007          */
1008         request->delay = USEC / 10;
1009         gettimeofday(&now, NULL);
1010
1011         /*
1012          *      Not set up to run Post-Proxy-Type = Fail.
1013          *
1014          *      Mark the request as still running, and figure out what
1015          *      to do next.
1016          */
1017         if (!setup_post_proxy_fail(request)) {
1018                 request_post_handler(request);
1019
1020         } else {
1021                 /*
1022                  *      Re-queue the request.
1023                  */
1024                 request->child_state = REQUEST_QUEUED;
1025
1026                 /*
1027                  *      There is a post-proxy-type of fail.  We run
1028                  *      the request through the pre/post proxy
1029                  *      handlers, just like it was a real proxied
1030                  *      request.  However, we set the per-request
1031                  *      handler to NULL, as we don't want to do
1032                  *      anything else.
1033                  *
1034                  *      Note that when we're not threaded, this will
1035                  *      process the request even if it's greater than
1036                  *      max_request_time.  That's not fatal.
1037                  */
1038                 request->priority = 0;
1039                 rad_assert(request->proxy != NULL);
1040                 thread_pool_addrequest(request, null_handler);
1041         }
1042
1043         /*
1044          *      MAY free the request if we're over max_request_time,
1045          *      AND we're not in threaded mode!
1046          *
1047          *      Note that we call this ONLY if we're threaded, as
1048          *      if we're NOT threaded, request_post_handler() calls
1049          *      wait_a_bit(), which means that "request" may not
1050          *      exist any more...
1051          */
1052         if (have_children) wait_a_bit(request);
1053 }
1054
1055 /* maybe check this against wait_for_proxy_id_to_expire? */
1056 static void no_response_to_proxied_request(void *ctx)
1057 {
1058         REQUEST *request = ctx;
1059         home_server *home;
1060         char buffer[128];
1061
1062         rad_assert(request->magic == REQUEST_MAGIC);
1063
1064         if (request->master_state == REQUEST_STOP_PROCESSING) {
1065                 ev_request_free(&request);
1066                 return;
1067         }
1068
1069         rad_assert(request->child_state == REQUEST_PROXIED);
1070
1071         /*
1072          *      If we've failed over to an internal home server,
1073          *      replace the callback with the correct one.  This
1074          *      is due to locking issues with child threads...
1075          */
1076         if (request->home_server->server) {
1077                 wait_a_bit(request);
1078                 return;
1079         }
1080
1081 #ifdef WITH_TCP
1082         if (request->home_server->proto != IPPROTO_TCP)
1083 #endif
1084                 check_for_zombie_home_server(request);
1085
1086         home = request->home_server;
1087
1088         /*
1089          *      The default as of 2.1.7 is to allow requests to
1090          *      fail-over to a backup home server when this one does
1091          *      not respond.  The old behavior can be configured as
1092          *      well.
1093          */
1094         if (home->no_response_fail) {
1095                 radlog_request(L_ERR, 0, request, "Rejecting request (proxy Id %d) due to lack of any response from home server %s port %d",
1096                        request->proxy->id,
1097                        inet_ntop(request->proxy->dst_ipaddr.af,
1098                                  &request->proxy->dst_ipaddr.ipaddr,
1099                                  buffer, sizeof(buffer)),
1100                        request->proxy->dst_port);
1101
1102                 post_proxy_fail_handler(request);
1103         } else {
1104                 /*
1105                  *      Enforce max_request_time.
1106                  *
1107                  *      We fail over to another backup home server
1108                  *      when the client re-transmits the request.  If
1109                  *      the client doesn't re-transmit, no fail-over
1110                  *      occurs.
1111                  */
1112                 rad_assert(request->ev == NULL);
1113                 request->child_state = REQUEST_RUNNING;
1114                 wait_a_bit(request);
1115         }
1116
1117         /*
1118          *      Don't touch request due to race conditions
1119          */
1120
1121 #ifdef WITH_TCP
1122         /*
1123          *      Do nothing more.  The home server didn't respond,
1124          *      but that isn't a catastrophic failure.  Some home
1125          *      servers don't respond to packets...
1126          */
1127         if (home->proto == IPPROTO_TCP) {
1128                 /*
1129                  *      FIXME: Set up TCP pinging on this connection.
1130                  *
1131                  *      Maybe the CONNECTION is dead, but the home
1132                  *      server is alive.  In that case, we need to start
1133                  *      pinging on the connection.
1134                  *
1135                  *      This means doing the pinging BEFORE the
1136                  *      post_proxy_fail_handler above, as it may do
1137                  *      something with the request, and cause the
1138                  *      proxy listener to go away!
1139                  */
1140                 return;
1141         }
1142 #endif
1143
1144         /*
1145          *      If it's not alive, don't try to make it a zombie.
1146          */
1147         if (home->state != HOME_STATE_ALIVE) {
1148                 /*
1149                  *      Don't check home->ev due to race conditions.
1150                  */
1151                 return;
1152         }
1153
1154         /*
1155          *      We've received a real packet recently.  Don't mark the
1156          *      server as zombie until we've received NO packets for a
1157          *      while.  The "1/4" of zombie period was chosen rather
1158          *      arbitrarily.  It's a balance between too short, which
1159          *      gives quick fail-over and fail-back, or too long,
1160          *      where the proxy still sends packets to an unresponsive
1161          *      home server.
1162          */
1163         if ((home->last_packet + ((home->zombie_period + 3) / 4)) >= now.tv_sec) {
1164                 return;
1165         }
1166
1167         /*
1168          *      Enable the zombie period when we notice that the home
1169          *      server hasn't responded for a while.  We back-date the
1170          *      zombie period to when we last received a response from
1171          *      the home server.
1172          */
1173         home->state = HOME_STATE_ZOMBIE;
1174         
1175         home->zombie_period_start.tv_sec = home->last_packet;
1176         home->zombie_period_start.tv_sec = USEC / 2;
1177         
1178         fr_event_delete(el, &home->ev);
1179         home->currently_outstanding = 0;
1180         home->num_received_pings = 0;
1181         
1182         radlog(L_PROXY, "Marking home server %s port %d as zombie (it looks like it is dead).",
1183                inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
1184                          buffer, sizeof(buffer)),
1185                home->port);
1186         
1187         /*
1188          *      Start pinging the home server.
1189          */
1190         ping_home_server(home);
1191 }
1192 #endif
1193
1194 static void wait_a_bit(void *ctx)
1195 {
1196         struct timeval when;
1197         REQUEST *request = ctx;
1198         fr_event_callback_t callback = NULL;
1199
1200         rad_assert(request->magic == REQUEST_MAGIC);
1201
1202 #ifdef HAVE_PTHREAD_H
1203         /*
1204          *      The socket was closed.  Tell the request that
1205          *      there is no point in continuing.
1206          */
1207         if (request->listener->status != RAD_LISTEN_STATUS_KNOWN) {
1208                 goto stop_processing;
1209         }
1210 #endif
1211
1212 #ifdef WITH_COA
1213         /*
1214          *      The CoA request is a new (internally generated)
1215          *      request, created in a child thread.  We therefore need
1216          *      some way to tie its events back into the main event
1217          *      handler.
1218          */
1219         if (request->coa && !request->coa->proxy_reply &&
1220             request->coa->next_callback) {
1221                 request->coa->when = request->coa->next_when;
1222                 INSERT_EVENT(request->coa->next_callback, request->coa);
1223                 request->coa->next_callback = NULL;
1224                 request->coa->parent = NULL;
1225                 request->coa = NULL;
1226         }
1227 #endif
1228
1229         switch (request->child_state) {
1230         case REQUEST_QUEUED:
1231         case REQUEST_RUNNING:
1232                 /*
1233                  *      If we're not thread-capable, OR we're capable,
1234                  *      but have been told to run without threads,
1235                  *      complain when the requests is queued for a
1236                  *      thread, or running in a child thread.
1237                  */
1238 #ifdef HAVE_PTHREAD_H
1239                 if (!have_children)
1240 #endif
1241                 {
1242                         rad_assert("We do not have threads, but the request is marked as queued or running in a child thread" == NULL);
1243                         break;
1244                 }
1245
1246 #ifdef HAVE_PTHREAD_H
1247                 /*
1248                  *      If we have threads, wait for the child thread
1249                  *      to stop.
1250                  */
1251                 when = request->received;
1252                 when.tv_sec += request->root->max_request_time;
1253
1254                 /*
1255                  *      Normally called from the event loop with the
1256                  *      proper event loop time.  Otherwise, called from
1257                  *      post proxy fail handler, which sets "now", and
1258                  *      this call won't re-set it, because we're not
1259                  *      in the event loop.
1260                  */
1261                 fr_event_now(el, &now);
1262
1263                 /*
1264                  *      Request still has more time.  Continue
1265                  *      waiting.
1266                  */
1267                 if (timercmp(&now, &when, <)) {
1268                         if (request->delay < (USEC / 10)) {
1269                                 request->delay = USEC / 10;
1270                         }
1271                         request->delay += request->delay >> 1;
1272
1273                         /*
1274                          *      Cap delays at something reasonable.
1275                          */
1276                         if (request->delay > (request->root->max_request_time * USEC)) {
1277                                 request->delay = request->root->max_request_time * USEC;
1278                         }
1279
1280                         request->when = now;
1281                         tv_add(&request->when, request->delay);
1282                         callback = wait_a_bit;
1283                         break;
1284                 }
1285
1286         stop_processing:
1287                 request->master_state = REQUEST_STOP_PROCESSING;
1288
1289                 /*
1290                  *      A child thread MAY still be running on the
1291                  *      request.  Ask the thread to stop working on
1292                  *      the request.
1293                  */
1294                 if (have_children &&
1295                     (pthread_equal(request->child_pid, NO_SUCH_CHILD_PID) == 0)) {
1296                         radlog(L_ERR, "WARNING: Unresponsive child in module %s component %s",
1297                                request->module ? request->module : "<server core>",
1298                                request->component ? request->component : "<server core>");
1299                 }
1300                         
1301                 request->delay = USEC;
1302                 tv_add(&request->when, request->delay);
1303                 callback = wait_for_child_to_die;
1304                 break;
1305 #endif
1306
1307                 /*
1308                  *      Mark the request as no longer running,
1309                  *      and clean it up.
1310                  */
1311         case REQUEST_DONE:
1312 #ifdef HAVE_PTHREAD_H
1313                 request->child_pid = NO_SUCH_CHILD_PID;
1314 #endif
1315
1316 #ifdef WITH_COA
1317                 /*
1318                  *      This is a CoA request.  It's been divorced
1319                  *      from everything else, so we clean it up now.
1320                  */
1321                 if (!request->in_request_hash &&
1322                     request->proxy &&
1323                     (request->packet->code != request->proxy->code) &&
1324                     ((request->proxy->code == PW_COA_REQUEST) ||
1325                      (request->proxy->code == PW_DISCONNECT_REQUEST))) {
1326                         /*
1327                          *      FIXME: Do CoA MIBs
1328                          */
1329                         ev_request_free(&request);
1330                         return;
1331                 }
1332 #endif
1333                 cleanup_delay(request);
1334                 return;
1335
1336         case REQUEST_REJECT_DELAY:
1337         case REQUEST_CLEANUP_DELAY:
1338 #ifdef HAVE_PTHREAD_H
1339                 request->child_pid = NO_SUCH_CHILD_PID;
1340 #endif
1341
1342         case REQUEST_PROXIED:
1343                 rad_assert(request->next_callback != NULL);
1344                 rad_assert(request->next_callback != wait_a_bit);
1345
1346                 request->when = request->next_when;
1347                 callback = request->next_callback;
1348                 request->next_callback = NULL;
1349                 break;
1350
1351         default:
1352                 rad_panic("Internal sanity check failure");
1353                 return;
1354         }
1355
1356         /*
1357          *      Something major went wrong.  Discard the request, and
1358          *      keep running.
1359          *
1360          *      FIXME: No idea why this happens or how to fix it...
1361          *      It seems to happen *only* when requests are proxied,
1362          *      and where the home server doesn't respond.  So it looks
1363          *      like a race condition above, but it happens in debug
1364          *      mode, with no threads...
1365          */
1366         if (!callback) {
1367                 RDEBUG("WARNING: Internal sanity check failed in event handler: Discarding the request!");
1368                 ev_request_free(&request);
1369                 return;
1370         }
1371
1372         INSERT_EVENT(callback, request);
1373 }
1374
1375 #ifdef WITH_COA
1376 static void no_response_to_coa_request(void *ctx)
1377 {
1378         REQUEST *request = ctx;
1379         char buffer[128];
1380
1381         rad_assert(request->magic == REQUEST_MAGIC);
1382         rad_assert(request->child_state == REQUEST_PROXIED);
1383         rad_assert(request->home_server != NULL);
1384         rad_assert(!request->in_request_hash);
1385
1386         radlog(L_ERR, "No response to CoA request sent to %s",
1387                inet_ntop(request->proxy->dst_ipaddr.af,
1388                          &request->proxy->dst_ipaddr.ipaddr,
1389                          buffer, sizeof(buffer)));
1390
1391         /*
1392          *      Hack.
1393          */
1394         request->packet->code |= (PW_COA_REQUEST << 8);
1395         post_proxy_fail_handler(request);
1396 }
1397
1398
1399 static int update_event_timestamp(RADIUS_PACKET *packet, time_t when)
1400 {
1401         VALUE_PAIR *vp;
1402
1403         vp = pairfind(packet->vps, PW_EVENT_TIMESTAMP, 0);
1404         if (!vp) return 0;
1405
1406         vp->vp_date = when;
1407
1408         if (packet->data) {
1409                 free(packet->data);
1410                 packet->data = NULL;
1411                 packet->data_len = 0;
1412         }
1413
1414         return 1;               /* time stamp updated */
1415 }
1416
1417
1418 /*
1419  *      Called when we haven't received a response to a CoA request.
1420  */
1421 static void retransmit_coa_request(void *ctx)
1422 {
1423         int delay, frac;
1424         struct timeval mrd;
1425         REQUEST *request = ctx;
1426
1427         rad_assert(request->magic == REQUEST_MAGIC);
1428         rad_assert(request->child_state == REQUEST_PROXIED);
1429         rad_assert(request->home_server != NULL);
1430         rad_assert(!request->in_request_hash);
1431         rad_assert(request->parent == NULL);
1432         
1433         fr_event_now(el, &now);
1434
1435         /*
1436          *      Cap count at MRC, if it is non-zero.
1437          */
1438         if (request->home_server->coa_mrc &&
1439             (request->num_coa_requests >= request->home_server->coa_mrc)) {
1440                 no_response_to_coa_request(request);
1441                 return;
1442         }
1443
1444         /*
1445          *      RFC 5080 Section 2.2.1
1446          *
1447          *      RT = 2*RTprev + RAND*RTprev
1448          *         = 1.9 * RTprev + rand(0,.2) * RTprev
1449          *         = 1.9 * RTprev + rand(0,1) * (RTprev / 5)
1450          */
1451         delay = fr_rand();
1452         delay ^= (delay >> 16);
1453         delay &= 0xffff;
1454         frac = request->delay / 5;
1455         delay = ((frac >> 16) * delay) + (((frac & 0xffff) * delay) >> 16);
1456
1457         delay += (2 * request->delay) - (request->delay / 10);
1458
1459         /*
1460          *      Cap delay at MRT, if MRT is non-zero.
1461          */
1462         if (request->home_server->coa_mrt &&
1463             (delay > (request->home_server->coa_mrt * USEC))) {
1464                 int mrt_usec = request->home_server->coa_mrt * USEC;
1465
1466                 /*
1467                  *      delay = MRT + RAND * MRT
1468                  *            = 0.9 MRT + rand(0,.2)  * MRT
1469                  */
1470                 delay = fr_rand();
1471                 delay ^= (delay >> 15);
1472                 delay &= 0x1ffff;
1473                 delay = ((mrt_usec >> 16) * delay) + (((mrt_usec & 0xffff) * delay) >> 16);
1474                 delay += mrt_usec - (mrt_usec / 10);
1475         }
1476
1477         request->delay = delay;
1478         request->when = now;
1479         tv_add(&request->when, request->delay);
1480         mrd = request->proxy_when;
1481         mrd.tv_sec += request->home_server->coa_mrd;
1482
1483         /*
1484          *      Cap duration at MRD.
1485          */
1486         if (timercmp(&mrd, &request->when, <)) {
1487                 request->when = mrd;
1488                 INSERT_EVENT(no_response_to_coa_request, request);
1489
1490         } else {
1491                 INSERT_EVENT(retransmit_coa_request, request);
1492         }
1493         
1494         if (update_event_timestamp(request->proxy, now.tv_sec)) {
1495                 /*
1496                  *      Keep a copy of the old Id so that the
1497                  *      re-transmitted request doesn't re-use the old
1498                  *      Id.
1499                  */
1500                 RADIUS_PACKET old = *request->proxy;
1501                 home_server *home = request->home_server;
1502                 rad_listen_t *listener = request->proxy_listener;
1503
1504                 /*
1505                  *      Don't free the old Id on error.
1506                  */
1507                 if (!insert_into_proxy_hash(request)) {
1508                         radlog(L_PROXY,"Failed to insert retransmission of CoA request into proxy list.");
1509                         return;
1510                 }
1511
1512                 /*
1513                  *      Now that we have a new Id, free the old one
1514                  *      and update the various statistics.
1515                  */
1516                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
1517                 fr_packet_list_yank(proxy_list, &old);
1518                 fr_packet_list_id_free(proxy_list, &old);
1519                 if (home) home->currently_outstanding--;
1520 #ifdef WITH_TCP
1521                 if (listener) listener->count--;
1522 #endif
1523                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
1524
1525         } else {                /* FIXME: protect by a mutex? */
1526                 request->num_proxied_requests++;
1527         }
1528
1529         request->num_coa_requests++; /* is NOT reset by code 3 lines above! */
1530
1531         request->proxy_listener->send(request->proxy_listener,
1532                                       request);
1533 }
1534
1535
1536 /*
1537  *      The original request is either DONE, or in CLEANUP_DELAY.
1538  */
1539 static int originated_coa_request(REQUEST *request)
1540 {
1541         int delay, rcode, pre_proxy_type = 0;
1542         VALUE_PAIR *vp;
1543         REQUEST *coa;
1544         fr_ipaddr_t ipaddr;
1545         char buffer[256];
1546
1547         rad_assert(request->proxy == NULL);
1548         rad_assert(!request->in_proxy_hash);
1549         rad_assert(request->proxy_reply == NULL);
1550
1551         /*
1552          *      Check whether we want to originate one, or cancel one.
1553          */
1554         vp = pairfind(request->config_items, PW_SEND_COA_REQUEST, 0);
1555         if (!vp && request->coa) {
1556                 vp = pairfind(request->coa->proxy->vps, PW_SEND_COA_REQUEST, 0);
1557         }
1558
1559         if (vp) {
1560                 if (vp->vp_integer == 0) {
1561                         ev_request_free(&request->coa);
1562                         return 1;       /* success */
1563                 }
1564         }
1565
1566         if (!request->coa) request_alloc_coa(request);
1567         if (!request->coa) return 0;
1568
1569         coa = request->coa;
1570
1571         /*
1572          *      src_ipaddr will be set up in proxy_encode.
1573          */
1574         memset(&ipaddr, 0, sizeof(ipaddr));
1575         vp = pairfind(coa->proxy->vps, PW_PACKET_DST_IP_ADDRESS, 0);
1576         if (vp) {
1577                 ipaddr.af = AF_INET;
1578                 ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1579
1580         } else if ((vp = pairfind(coa->proxy->vps,
1581                                   PW_PACKET_DST_IPV6_ADDRESS, 0)) != NULL) {
1582                 ipaddr.af = AF_INET6;
1583                 ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
1584                 
1585         } else if ((vp = pairfind(coa->proxy->vps,
1586                                   PW_HOME_SERVER_POOL, 0)) != NULL) {
1587                 coa->home_pool = home_pool_byname(vp->vp_strvalue,
1588                                                   HOME_TYPE_COA);
1589                 if (!coa->home_pool) {
1590                         RDEBUG2("WARNING: No such home_server_pool %s",
1591                                vp->vp_strvalue);
1592         fail:
1593                         ev_request_free(&request->coa);
1594                         return 0;
1595                 }
1596
1597                 /*
1598                  *      Prefer
1599                  */
1600         } else if (request->client->coa_pool) {
1601                 coa->home_pool = request->client->coa_pool;
1602
1603         } else if (request->client->coa_server) {
1604                 coa->home_server = request->client->coa_server;
1605
1606         } else {
1607                 /*
1608                  *      If all else fails, send it to the client that
1609                  *      originated this request.
1610                  */
1611                 memcpy(&ipaddr, &request->packet->src_ipaddr, sizeof(ipaddr));
1612         }
1613
1614         /*
1615          *      Use the pool, if it exists.
1616          */
1617         if (coa->home_pool) {
1618                 coa->home_server = home_server_ldb(NULL, coa->home_pool, coa);
1619                 if (!coa->home_server) {
1620                         RDEBUG("WARNING: No live home server for home_server_pool %s", vp->vp_strvalue);
1621                         goto fail;
1622                 }
1623
1624         } else if (!coa->home_server) {
1625                 int port = PW_COA_UDP_PORT;
1626
1627                 vp = pairfind(coa->proxy->vps, PW_PACKET_DST_PORT, 0);
1628                 if (vp) port = vp->vp_integer;
1629
1630                 coa->home_server = home_server_find(&ipaddr, port, IPPROTO_UDP);
1631                 if (!coa->home_server) {
1632                         RDEBUG2("WARNING: Unknown destination %s:%d for CoA request.",
1633                                inet_ntop(ipaddr.af, &ipaddr.ipaddr,
1634                                          buffer, sizeof(buffer)), port);
1635                         goto fail;
1636                 }
1637         }
1638
1639         vp = pairfind(coa->proxy->vps, PW_PACKET_TYPE, 0);
1640         if (vp) {
1641                 switch (vp->vp_integer) {
1642                 case PW_COA_REQUEST:
1643                 case PW_DISCONNECT_REQUEST:
1644                         coa->proxy->code = vp->vp_integer;
1645                         break;
1646                         
1647                 default:
1648                         DEBUG("Cannot set CoA Packet-Type to code %d",
1649                               vp->vp_integer);
1650                         goto fail;
1651                 }
1652         }
1653
1654         if (!coa->proxy->code) coa->proxy->code = PW_COA_REQUEST;
1655
1656         /*
1657          *      The rest of the server code assumes that
1658          *      request->packet && request->reply exist.  Copy them
1659          *      from the original request.
1660          */
1661         rad_assert(coa->packet != NULL);
1662         rad_assert(coa->packet->vps == NULL);
1663         memcpy(coa->packet, request->packet, sizeof(*request->packet));
1664         coa->packet->vps = paircopy(request->packet->vps);
1665         coa->packet->data = NULL;
1666         rad_assert(coa->reply != NULL);
1667         rad_assert(coa->reply->vps == NULL);
1668         memcpy(coa->reply, request->reply, sizeof(*request->reply));
1669         coa->reply->vps = paircopy(request->reply->vps);
1670         coa->reply->data = NULL;
1671         coa->config_items = paircopy(request->config_items);
1672
1673         /*
1674          *      Call the pre-proxy routines.
1675          */
1676         vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE, 0);
1677         if (vp) {
1678                 RDEBUG2("  Found Pre-Proxy-Type %s", vp->vp_strvalue);
1679                 pre_proxy_type = vp->vp_integer;
1680         }
1681
1682         if (coa->home_pool && coa->home_pool->virtual_server) {
1683                 const char *old_server = coa->server;
1684                 
1685                 coa->server = coa->home_pool->virtual_server;
1686                 RDEBUG2(" server %s {", coa->server);
1687                 rcode = module_pre_proxy(pre_proxy_type, coa);
1688                 RDEBUG2(" }");
1689                 coa->server = old_server;
1690         } else {
1691                 rcode = module_pre_proxy(pre_proxy_type, coa);
1692         }
1693         switch (rcode) {
1694         default:
1695                 goto fail;
1696
1697         /*
1698          *      Only send the CoA packet if the pre-proxy code succeeded.
1699          */
1700         case RLM_MODULE_NOOP:
1701         case RLM_MODULE_OK:
1702         case RLM_MODULE_UPDATED:
1703                 break;
1704         }
1705
1706         /*
1707          *      Source IP / port is set when the proxy socket
1708          *      is chosen.
1709          */
1710         coa->proxy->dst_ipaddr = coa->home_server->ipaddr;
1711         coa->proxy->dst_port = coa->home_server->port;
1712
1713         if (!insert_into_proxy_hash(coa)) {
1714                 radlog(L_PROXY, "Failed to insert CoA request into proxy list.");
1715                 goto fail;
1716         }
1717
1718         /*
1719          *      We CANNOT divorce the CoA request from the parent
1720          *      request.  This function is running in a child thread,
1721          *      and we need access to the main event loop in order to
1722          *      to add the timers for the CoA packet.  See
1723          *      wait_a_bit().
1724          */
1725
1726         /*
1727          *      Forget about the original request completely at this
1728          *      point.
1729          */
1730         request = coa;
1731
1732         gettimeofday(&request->proxy_when, NULL);       
1733         request->received = request->next_when = request->proxy_when;
1734         rad_assert(request->proxy_reply == NULL);
1735
1736         /*
1737          *      Implement re-transmit algorithm as per RFC 5080
1738          *      Section 2.2.1.
1739          *
1740          *      We want IRT + RAND*IRT
1741          *      or 0.9 IRT + rand(0,.2) IRT
1742          *
1743          *      2^20 ~ USEC, and we want 2.
1744          *      rand(0,0.2) USEC ~ (rand(0,2^21) / 10)
1745          */
1746         delay = (fr_rand() & ((1 << 22) - 1)) / 10;
1747         request->delay = delay * request->home_server->coa_irt;
1748         delay = request->home_server->coa_irt * USEC;
1749         delay -= delay / 10;
1750         delay += request->delay;
1751      
1752         request->delay = delay;
1753         tv_add(&request->next_when, delay);
1754         request->next_callback = retransmit_coa_request;
1755         
1756         /*
1757          *      Note that we set proxied BEFORE sending the packet.
1758          *
1759          *      Once we send it, the request is tainted, as
1760          *      another thread may have picked it up.  Don't
1761          *      touch it!
1762          */
1763         request->child_pid = NO_SUCH_CHILD_PID;
1764
1765         update_event_timestamp(request->proxy, request->proxy_when.tv_sec);
1766
1767         request->child_state = REQUEST_PROXIED;
1768
1769         DEBUG_PACKET(request, request->proxy, 1);
1770
1771         request->proxy_listener->send(request->proxy_listener,
1772                                       request);
1773         return 1;
1774 }
1775 #endif  /* WITH_COA */
1776
1777 #ifdef WITH_PROXY
1778 static int process_proxy_reply(REQUEST *request)
1779 {
1780         int rcode;
1781         int post_proxy_type = 0;
1782         VALUE_PAIR *vp;
1783         
1784         /*
1785          *      Delete any reply we had accumulated until now.
1786          */
1787         pairfree(&request->reply->vps);
1788         
1789         /*
1790          *      Run the packet through the post-proxy stage,
1791          *      BEFORE playing games with the attributes.
1792          */
1793         vp = pairfind(request->config_items, PW_POST_PROXY_TYPE, 0);
1794         if (vp) {
1795                 RDEBUG2("  Found Post-Proxy-Type %s", vp->vp_strvalue);
1796                 post_proxy_type = vp->vp_integer;
1797         }
1798         
1799         if (request->home_pool && request->home_pool->virtual_server) {
1800                 const char *old_server = request->server;
1801                 
1802                 request->server = request->home_pool->virtual_server;
1803                 RDEBUG2(" server %s {", request->server);
1804                 rcode = module_post_proxy(post_proxy_type, request);
1805                 RDEBUG2(" }");
1806                 request->server = old_server;
1807         } else {
1808                 rcode = module_post_proxy(post_proxy_type, request);
1809         }
1810
1811 #ifdef WITH_COA
1812         if (request->packet->code == request->proxy->code)
1813           /*
1814            *    Don't run the next bit if we originated a CoA
1815            *    packet, after receiving an Access-Request or
1816            *    Accounting-Request.
1817            */
1818 #endif
1819         
1820         /*
1821          *      There may NOT be a proxy reply, as we may be
1822          *      running Post-Proxy-Type = Fail.
1823          */
1824         if (request->proxy_reply) {
1825                 /*
1826                  *      Delete the Proxy-State Attributes from
1827                  *      the reply.  These include Proxy-State
1828                  *      attributes from us and remote server.
1829                  */
1830                 pairdelete(&request->proxy_reply->vps, PW_PROXY_STATE, 0);
1831                 
1832                 /*
1833                  *      Add the attributes left in the proxy
1834                  *      reply to the reply list.
1835                  */
1836                 pairadd(&request->reply->vps, request->proxy_reply->vps);
1837                 request->proxy_reply->vps = NULL;
1838                 
1839                 /*
1840                  *      Free proxy request pairs.
1841                  */
1842                 pairfree(&request->proxy->vps);
1843         }
1844         
1845         switch (rcode) {
1846         default:  /* Don't do anything */
1847                 break;
1848         case RLM_MODULE_FAIL:
1849                 /* FIXME: debug print stuff */
1850                 request->child_state = REQUEST_DONE;
1851                 return 0;
1852                 
1853         case RLM_MODULE_HANDLED:
1854                 /* FIXME: debug print stuff */
1855                 request->child_state = REQUEST_DONE;
1856                 return 0;
1857         }
1858
1859         return 1;
1860 }
1861 #endif
1862
1863 static int request_pre_handler(REQUEST *request)
1864 {
1865         int rcode;
1866
1867         rad_assert(request->magic == REQUEST_MAGIC);
1868         rad_assert(request->packet != NULL);
1869
1870         request->child_state = REQUEST_RUNNING;
1871
1872         /*
1873          *      Don't decode the packet if it's an internal "fake"
1874          *      request.  Instead, just return so that the caller can
1875          *      process it.
1876          */
1877         if (request->packet->dst_port == 0) {
1878                 request->username = pairfind(request->packet->vps,
1879                                              PW_USER_NAME, 0);
1880                 request->password = pairfind(request->packet->vps,
1881                                              PW_USER_PASSWORD, 0);
1882                 return 1;
1883         }
1884
1885 #ifdef WITH_PROXY
1886         /*
1887          *      Put the decoded packet into it's proper place.
1888          */
1889         if (request->proxy_reply != NULL) {
1890                 rcode = request->proxy_listener->decode(request->proxy_listener, request);
1891                 DEBUG_PACKET(request, request->proxy_reply, 0);
1892
1893                 /*
1894                  *      Pro-actively remove it from the proxy hash.
1895                  *      This is later than in 2.1.x, but it means that
1896                  *      the replies are authenticated before being
1897                  *      removed from the hash.
1898                  */
1899                 if ((rcode == 0) &&
1900                     (request->num_proxied_requests <= request->num_proxied_responses)) {
1901                         remove_from_proxy_hash(request);
1902                 }
1903
1904         } else
1905 #endif
1906         if (request->packet->vps == NULL) {
1907                 rcode = request->listener->decode(request->listener, request);
1908                 
1909                 if (debug_condition) {
1910                         int result = FALSE;
1911                         const char *my_debug = debug_condition;
1912
1913                         /*
1914                          *      Ignore parse errors.
1915                          */
1916                         radius_evaluate_condition(request, RLM_MODULE_OK, 0,
1917                                                   &my_debug, 1,
1918                                                   &result);
1919                         if (result) {
1920                                 request->options = 2;
1921                                 request->radlog = radlog_request;
1922                         }
1923                 }
1924                 
1925                 DEBUG_PACKET(request, request->packet, 0);
1926         } else {
1927                 rcode = 0;
1928         }
1929
1930         if (rcode < 0) {
1931                 RDEBUG("%s Dropping packet without response.", fr_strerror());
1932                 request->reply->offset = -2; /* bad authenticator */
1933                 request->child_state = REQUEST_DONE;
1934                 return 0;
1935         }
1936
1937         if (!request->username) {
1938                 request->username = pairfind(request->packet->vps,
1939                                              PW_USER_NAME, 0);
1940         }
1941
1942 #ifdef WITH_PROXY
1943         if (request->proxy) {
1944                 return process_proxy_reply(request);
1945 #endif
1946         }
1947
1948         return 1;
1949 }
1950
1951
1952 #ifdef WITH_PROXY
1953 /*
1954  *      Do state handling when we proxy a request.
1955  */
1956 static int proxy_request(REQUEST *request)
1957 {
1958         struct timeval when;
1959         char buffer[128];
1960
1961 #ifdef WITH_COA
1962         if (request->coa) {
1963                 RDEBUG("WARNING: Cannot proxy and originate CoA packets at the same time.  Cancelling CoA request");
1964                 ev_request_free(&request->coa);
1965         }
1966 #endif
1967
1968         if (request->home_server->server) {
1969                 RDEBUG("ERROR: Cannot proxy to a virtual server.");
1970                 return 0;
1971         }
1972
1973         if (!insert_into_proxy_hash(request)) {
1974                 radlog(L_PROXY, "Failed to insert request into proxy list.");
1975                 return 0;
1976         }
1977
1978         request->proxy_listener->encode(request->proxy_listener, request);
1979
1980         when = request->received;
1981         when.tv_sec += request->root->max_request_time;
1982
1983         gettimeofday(&request->proxy_when, NULL);
1984
1985         request->next_when = request->proxy_when;
1986         request->next_when.tv_sec += request->home_server->response_window;
1987
1988         rad_assert(request->home_server->response_window > 0);
1989
1990         if (timercmp(&when, &request->next_when, <)) {
1991                 request->next_when = when;
1992         }
1993         request->next_callback = no_response_to_proxied_request;
1994
1995         RDEBUG2("Proxying request to home server %s port %d",
1996                inet_ntop(request->proxy->dst_ipaddr.af,
1997                          &request->proxy->dst_ipaddr.ipaddr,
1998                          buffer, sizeof(buffer)),
1999                 request->proxy->dst_port);
2000
2001         /*
2002          *      Note that we set proxied BEFORE sending the packet.
2003          *
2004          *      Once we send it, the request is tainted, as
2005          *      another thread may have picked it up.  Don't
2006          *      touch it!
2007          */
2008 #ifdef HAVE_PTHREAD_H
2009         request->child_pid = NO_SUCH_CHILD_PID;
2010 #endif
2011         request->child_state = REQUEST_PROXIED;
2012
2013         DEBUG_PACKET(request, request->proxy, 1);
2014
2015         request->proxy_listener->send(request->proxy_listener,
2016                                       request);
2017         return 1;
2018 }
2019
2020
2021 /*
2022  *      "Proxy" the request by sending it to a new virtual server.
2023  */
2024 static int proxy_to_virtual_server(REQUEST *request)
2025 {
2026         REQUEST *fake;
2027         RAD_REQUEST_FUNP fun;
2028
2029         if (!request->home_server || !request->home_server->server) return 0;
2030
2031         if (request->parent) {
2032                 RDEBUG2("WARNING: Cancelling proxy request to virtual server %s as this request was itself proxied.", request->home_server->server);
2033                 return 0;
2034         }
2035
2036         fake = request_alloc_fake(request);
2037         if (!fake) {
2038                 RDEBUG2("WARNING: Out of memory");
2039                 return 0;
2040         }
2041
2042         fake->packet->vps = paircopy(request->proxy->vps);
2043         fake->server = request->home_server->server;
2044
2045         if (request->proxy->code == PW_AUTHENTICATION_REQUEST) {
2046                 fun = rad_authenticate;
2047
2048 #ifdef WITH_ACCOUNTING
2049         } else if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
2050                 fun = rad_accounting;
2051 #endif
2052
2053         } else {
2054                 RDEBUG2("Unknown packet type %d", request->proxy->code);
2055                 ev_request_free(&fake);
2056                 return 0;
2057         }
2058
2059         RDEBUG2(">>> Sending proxied request internally to virtual server.");
2060         radius_handle_request(fake, fun);
2061         RDEBUG2("<<< Received proxied response code %d from internal virtual server.", fake->reply->code);
2062
2063         if (fake->reply->code != 0) {
2064                 request->proxy_reply = fake->reply;
2065                 fake->reply = NULL;
2066         } else {
2067                 /*
2068                  *      There was no response
2069                  */
2070                 setup_post_proxy_fail(request);
2071         }
2072
2073         ev_request_free(&fake);
2074
2075         process_proxy_reply(request);
2076
2077         /*
2078          *      Process it through the normal section again, but ONLY
2079          *      if we received a proxy reply..
2080          */
2081         if (request->proxy_reply) {
2082                 if (request->server) RDEBUG("server %s {",
2083                                             request->server != NULL ?
2084                                             request->server : ""); 
2085                 fun(request);
2086                 
2087                 if (request->server) RDEBUG("} # server %s",
2088                                             request->server != NULL ?
2089                                             request->server : "");
2090         }
2091
2092         return 2;               /* success, but NOT '1' !*/
2093 }
2094
2095 /*
2096  *      Return 1 if we did proxy it, or the proxy attempt failed
2097  *      completely.  Either way, the caller doesn't touch the request
2098  *      any more if we return 1.
2099  */
2100 static int successfully_proxied_request(REQUEST *request)
2101 {
2102         int rcode;
2103         int pre_proxy_type = 0;
2104         VALUE_PAIR *realmpair;
2105         VALUE_PAIR *strippedname;
2106         VALUE_PAIR *vp;
2107         char *realmname = NULL;
2108         home_server *home;
2109         REALM *realm = NULL;
2110         home_pool_t *pool;
2111
2112         /*
2113          *      If it was already proxied, do nothing.
2114          *
2115          *      FIXME: This should really be a serious error.
2116          */
2117         if (request->in_proxy_hash ||
2118             (request->proxy_reply && (request->proxy_reply->code != 0))) {
2119                 return 0;
2120         }
2121
2122         realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM, 0);
2123         if (!realmpair || (realmpair->length == 0)) {
2124                 int pool_type;
2125
2126                 vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0);
2127                 if (!vp) return 0;
2128
2129                 switch (request->packet->code) {
2130                 case PW_AUTHENTICATION_REQUEST:
2131                         pool_type = HOME_TYPE_AUTH;
2132                         break;
2133
2134 #ifdef WITH_ACCOUNTING
2135                 case PW_ACCOUNTING_REQUEST:
2136                         pool_type = HOME_TYPE_ACCT;
2137                         break;
2138 #endif
2139
2140 #ifdef WITH_COA
2141                 case PW_COA_REQUEST:
2142                 case PW_DISCONNECT_REQUEST:
2143                         pool_type = HOME_TYPE_COA;
2144                         break;
2145 #endif
2146
2147                 default:
2148                         return 0;
2149                 }
2150
2151                 pool = home_pool_byname(vp->vp_strvalue, pool_type);
2152                 if (!pool) {
2153                         RDEBUG2("ERROR: Cannot proxy to unknown pool %s",
2154                                 vp->vp_strvalue);
2155                         return 0;
2156                 }
2157
2158                 realmname = NULL; /* no realms */
2159                 realm = NULL;
2160                 goto found_pool;
2161         }
2162
2163         realmname = (char *) realmpair->vp_strvalue;
2164
2165         realm = realm_find2(realmname);
2166         if (!realm) {
2167                 RDEBUG2("ERROR: Cannot proxy to unknown realm %s", realmname);
2168                 return 0;
2169         }
2170
2171         /*
2172          *      Figure out which pool to use.
2173          */
2174         if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
2175                 pool = realm->auth_pool;
2176
2177 #ifdef WITH_ACCOUNTING
2178         } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
2179                 pool = realm->acct_pool;
2180 #endif
2181
2182 #ifdef WITH_COA
2183         } else if ((request->packet->code == PW_COA_REQUEST) ||
2184                    (request->packet->code == PW_DISCONNECT_REQUEST)) {
2185                 pool = realm->acct_pool;
2186 #endif
2187
2188         } else {
2189                 rad_panic("Internal sanity check failed");
2190         }
2191
2192         if (!pool) {
2193                 RDEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
2194                        realmname);
2195                 return 0;
2196         }
2197
2198 found_pool:
2199         home = home_server_ldb(realmname, pool, request);
2200         if (!home) {
2201                 RDEBUG2("ERROR: Failed to find live home server for realm %s",
2202                        realmname);
2203                 return -1;
2204         }
2205         request->home_pool = pool;
2206
2207 #ifdef WITH_COA
2208         /*
2209          *      Once we've decided to proxy a request, we cannot send
2210          *      a CoA packet.  So we free up any CoA packet here.
2211          */
2212         ev_request_free(&request->coa);
2213 #endif
2214         /*
2215          *      Remember that we sent the request to a Realm.
2216          */
2217         if (realmname) pairadd(&request->packet->vps,
2218                                pairmake("Realm", realmname, T_OP_EQ));
2219
2220         /*
2221          *      Strip the name, if told to.
2222          *
2223          *      Doing it here catches the case of proxied tunneled
2224          *      requests.
2225          */
2226         if (realm && (realm->striprealm == TRUE) &&
2227            (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME, 0)) != NULL) {
2228                 /*
2229                  *      If there's a Stripped-User-Name attribute in
2230                  *      the request, then use THAT as the User-Name
2231                  *      for the proxied request, instead of the
2232                  *      original name.
2233                  *
2234                  *      This is done by making a copy of the
2235                  *      Stripped-User-Name attribute, turning it into
2236                  *      a User-Name attribute, deleting the
2237                  *      Stripped-User-Name and User-Name attributes
2238                  *      from the vps list, and making the new
2239                  *      User-Name the head of the vps list.
2240                  */
2241                 vp = pairfind(request->proxy->vps, PW_USER_NAME, 0);
2242                 if (!vp) {
2243                         vp = radius_paircreate(request, NULL,
2244                                                PW_USER_NAME, 0, PW_TYPE_STRING);
2245                         rad_assert(vp != NULL); /* handled by above function */
2246                         /* Insert at the START of the list */
2247                         vp->next = request->proxy->vps;
2248                         request->proxy->vps = vp;
2249                 }
2250                 memcpy(vp->vp_strvalue, strippedname->vp_strvalue,
2251                        sizeof(vp->vp_strvalue));
2252                 vp->length = strippedname->length;
2253
2254                 /*
2255                  *      Do NOT delete Stripped-User-Name.
2256                  */
2257         }
2258
2259         /*
2260          *      If there is no PW_CHAP_CHALLENGE attribute but
2261          *      there is a PW_CHAP_PASSWORD we need to add it
2262          *      since we can't use the request authenticator
2263          *      anymore - we changed it.
2264          */
2265         if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
2266             pairfind(request->proxy->vps, PW_CHAP_PASSWORD, 0) &&
2267             pairfind(request->proxy->vps, PW_CHAP_CHALLENGE, 0) == NULL) {
2268                 vp = radius_paircreate(request, &request->proxy->vps,
2269                                        PW_CHAP_CHALLENGE, 0, PW_TYPE_OCTETS);
2270                 vp->length = AUTH_VECTOR_LEN;
2271                 memcpy(vp->vp_strvalue, request->packet->vector, AUTH_VECTOR_LEN);
2272         }
2273
2274         /*
2275          *      The RFC's say we have to do this, but FreeRADIUS
2276          *      doesn't need it.
2277          */
2278         vp = radius_paircreate(request, &request->proxy->vps,
2279                                PW_PROXY_STATE, 0, PW_TYPE_OCTETS);
2280         snprintf(vp->vp_strvalue, sizeof(vp->vp_strvalue), "%d",
2281                  request->packet->id);
2282         vp->length = strlen(vp->vp_strvalue);
2283
2284         /*
2285          *      Should be done BEFORE inserting into proxy hash, as
2286          *      pre-proxy may use this information, or change it.
2287          */
2288         request->proxy->code = request->packet->code;
2289
2290         /*
2291          *      Call the pre-proxy routines.
2292          */
2293         vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE, 0);
2294         if (vp) {
2295                 RDEBUG2("  Found Pre-Proxy-Type %s", vp->vp_strvalue);
2296                 pre_proxy_type = vp->vp_integer;
2297         }
2298
2299         rad_assert(request->home_pool != NULL);
2300
2301         if (request->home_pool->virtual_server) {
2302                 const char *old_server = request->server;
2303                 
2304                 request->server = request->home_pool->virtual_server;
2305                 RDEBUG2(" server %s {", request->server);
2306                 rcode = module_pre_proxy(pre_proxy_type, request);
2307                 RDEBUG2(" }");
2308                         request->server = old_server;
2309         } else {
2310                 rcode = module_pre_proxy(pre_proxy_type, request);
2311         }
2312         switch (rcode) {
2313         case RLM_MODULE_FAIL:
2314         case RLM_MODULE_INVALID:
2315         case RLM_MODULE_NOTFOUND:
2316         case RLM_MODULE_USERLOCK:
2317         default:
2318                 /* FIXME: debug print failed stuff */
2319                 return -1;
2320
2321         case RLM_MODULE_REJECT:
2322         case RLM_MODULE_HANDLED:
2323                 return 0;
2324
2325         /*
2326          *      Only proxy the packet if the pre-proxy code succeeded.
2327          */
2328         case RLM_MODULE_NOOP:
2329         case RLM_MODULE_OK:
2330         case RLM_MODULE_UPDATED:
2331                 break;
2332         }
2333
2334         /*
2335          *      If it's a fake request, don't send the proxy
2336          *      packet.  The outer tunnel session will take
2337          *      care of doing that.
2338          */
2339         if (request->packet->dst_port == 0) {
2340                 request->home_server = NULL;
2341                 return 1;
2342         }
2343
2344         if (request->home_server->server) {
2345                 return proxy_to_virtual_server(request);
2346         }
2347
2348         if (!proxy_request(request)) {
2349                 RDEBUG("ERROR: Failed to proxy request");
2350                 return -1;
2351         }
2352         
2353         return 1;
2354 }
2355 #endif
2356
2357 static void request_post_handler(REQUEST *request)
2358 {
2359         int child_state = -1;
2360         struct timeval when;
2361         VALUE_PAIR *vp;
2362
2363         if ((request->master_state == REQUEST_STOP_PROCESSING) ||
2364             (request->parent &&
2365              (request->parent->master_state == REQUEST_STOP_PROCESSING))) {
2366                 RDEBUG2("request was cancelled.");
2367 #ifdef HAVE_PTHREAD_H
2368                 request->child_pid = NO_SUCH_CHILD_PID;
2369 #endif
2370                 child_state = REQUEST_DONE;
2371                 goto cleanup;
2372         }
2373
2374         if (request->child_state != REQUEST_RUNNING) {
2375                 rad_panic("Internal sanity check failed");
2376         }
2377
2378 #ifdef WITH_COA
2379         /*
2380          *      If it's not in the request hash, it's a CoA request.
2381          *      We hope.
2382          */
2383         if (!request->in_request_hash &&
2384             request->proxy &&
2385             ((request->proxy->code == PW_COA_REQUEST) ||
2386              (request->proxy->code == PW_DISCONNECT_REQUEST))) {
2387                 request->next_callback = NULL;
2388                 child_state = REQUEST_DONE;
2389                 goto cleanup;
2390         }
2391 #endif
2392
2393         /*
2394          *      Catch Auth-Type := Reject BEFORE proxying the packet.
2395          */
2396         if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
2397             (request->reply->code == 0) &&
2398             ((vp = pairfind(request->config_items, PW_AUTH_TYPE, 0)) != NULL) &&
2399             (vp->vp_integer == PW_AUTHTYPE_REJECT)) {
2400                 request->reply->code = PW_AUTHENTICATION_REJECT;
2401         }
2402
2403 #ifdef WITH_PROXY
2404         if (request->root->proxy_requests &&
2405             !request->in_proxy_hash &&
2406             (request->reply->code == 0) &&
2407             (request->packet->dst_port != 0) &&
2408             (request->packet->code != PW_STATUS_SERVER)) {
2409                 int rcode = successfully_proxied_request(request);
2410
2411                 if (rcode == 1) return; /* request is invalid */
2412
2413                 /*
2414                  *      Failed proxying it (dead home servers, etc.)
2415                  *      Run it through Post-Proxy-Type = Fail, and
2416                  *      respond to the request.
2417                  *
2418                  *      Note that we're in a child thread here, so we
2419                  *      do NOT re-schedule the request.  Instead, we
2420                  *      do what we would have done, which is run the
2421                  *      pre-handler, a NULL request handler, and then
2422                  *      the post handler.
2423                  */
2424                 if ((rcode < 0) && setup_post_proxy_fail(request)) {
2425                         request_pre_handler(request);
2426                 }
2427
2428                 /*
2429                  *      Else we weren't supposed to proxy it,
2430                  *      OR we proxied it internally to a virutal server.
2431                  */
2432         }
2433
2434 #ifdef WITH_COA
2435         else if (request->proxy && request->coa) {
2436                 RDEBUG("WARNING: Cannot proxy and originate CoA packets at the same time.  Cancelling CoA request");
2437                 ev_request_free(&request->coa);
2438         }
2439 #endif
2440 #endif
2441
2442         /*
2443          *      Fake requests don't get encoded or signed.  The caller
2444          *      also requires the reply VP's, so we don't free them
2445          *      here!
2446          */
2447         if (request->packet->dst_port == 0) {
2448                 /* FIXME: RDEBUG going to the next request */
2449 #ifdef HAVE_PTHREAD_H
2450                 request->child_pid = NO_SUCH_CHILD_PID;
2451 #endif
2452                 request->child_state = REQUEST_DONE;
2453                 return;
2454         }
2455
2456 #ifdef WITH_PROXY
2457         /*
2458          *      Copy Proxy-State from the request to the reply.
2459          */
2460         vp = paircopy2(request->packet->vps, PW_PROXY_STATE, 0);
2461         if (vp) pairadd(&request->reply->vps, vp);
2462 #endif
2463
2464         /*
2465          *      Access-Requests get delayed or cached.
2466          */
2467         switch (request->packet->code) {
2468         case PW_AUTHENTICATION_REQUEST:
2469                 gettimeofday(&request->next_when, NULL);
2470
2471                 if (request->reply->code == 0) {
2472                         /*
2473                          *      Check if the lack of response is intentional.
2474                          */
2475                         vp = pairfind(request->config_items,
2476                                       PW_RESPONSE_PACKET_TYPE, 0);
2477                         if (!vp) {
2478                                 RDEBUG2("There was no response configured: rejecting request");
2479                                 request->reply->code = PW_AUTHENTICATION_REJECT;
2480
2481                         } else if (vp->vp_integer == 256) {
2482                                 RDEBUG2("Not responding to request");
2483
2484                                 /*
2485                                  *      Force cleanup after a long
2486                                  *      time, so that we don't
2487                                  *      re-process the packet.
2488                                  */
2489                                 request->next_when.tv_sec += request->root->max_request_time;
2490                                 request->next_callback = cleanup_delay;
2491                                 child_state = REQUEST_CLEANUP_DELAY;
2492                                 break;
2493                         } else {
2494                                 request->reply->code = vp->vp_integer;
2495
2496                         }
2497                 }
2498
2499                 /*
2500                  *      Run rejected packets through
2501                  *
2502                  *      Post-Auth-Type = Reject
2503                  */
2504                 if (request->reply->code == PW_AUTHENTICATION_REJECT) {
2505                         pairdelete(&request->config_items, PW_POST_AUTH_TYPE, 0);
2506                         vp = radius_pairmake(request, &request->config_items,
2507                                              "Post-Auth-Type", "Reject",
2508                                              T_OP_SET);
2509                         if (vp) rad_postauth(request);
2510
2511                         /*
2512                          *      If configured, delay Access-Reject packets.
2513                          *
2514                          *      If request->root->reject_delay = 0, we discover
2515                          *      that we have to send the packet now.
2516                          */
2517                         when = request->received;
2518                         when.tv_sec += request->root->reject_delay;
2519
2520                         if (timercmp(&when, &request->next_when, >)) {
2521                                 RDEBUG2("Delaying reject  for %d seconds",
2522                                        request->root->reject_delay);
2523                                 request->next_when = when;
2524                                 request->next_callback = reject_delay;
2525 #ifdef HAVE_PTHREAD_H
2526                                 request->child_pid = NO_SUCH_CHILD_PID;
2527 #endif
2528                                 request->child_state = REQUEST_REJECT_DELAY;
2529                                 return;
2530                         }
2531                 }
2532
2533 #ifdef WITH_COA
2534         case PW_COA_REQUEST:
2535         case PW_DISCONNECT_REQUEST:
2536 #endif
2537                 request->next_when.tv_sec += request->root->cleanup_delay;
2538                 request->next_callback = cleanup_delay;
2539                 child_state = REQUEST_CLEANUP_DELAY;
2540                 break;
2541
2542         case PW_ACCOUNTING_REQUEST:
2543                 request->next_callback = NULL; /* just to be safe */
2544                 child_state = REQUEST_DONE;
2545                 break;
2546
2547                 /*
2548                  *      FIXME: Status-Server should probably not be
2549                  *      handled here...
2550                  */
2551         case PW_STATUS_SERVER:
2552                 request->next_callback = NULL;
2553                 child_state = REQUEST_DONE;
2554                 break;
2555
2556         default:
2557                 /*
2558                  *      DHCP, VMPS, etc.
2559                  */
2560                 request->next_callback = NULL;
2561                 child_state = REQUEST_DONE;
2562                 break;
2563         }
2564
2565         /*
2566          *      Suppress "no reply" packets here, unless we're reading
2567          *      from the "detail" file.  In that case, we've got to
2568          *      tell the detail file handler that the request is dead,
2569          *      and it should re-send it.
2570          *      If configured, encode, sign, and send.
2571          */
2572         if ((request->reply->code != 0) ||
2573             (request->listener->type == RAD_LISTEN_DETAIL)) {
2574                 DEBUG_PACKET(request, request->reply, 1);
2575                 request->listener->send(request->listener, request);
2576         }
2577
2578 #ifdef WITH_COA
2579         /*
2580          *      Now that we've completely processed the request,
2581          *      see if we need to originate a CoA request.  But ONLY
2582          *      if it wasn't proxied.
2583          */
2584         if (!request->proxy &&
2585             (request->packet->code != PW_COA_REQUEST) &&
2586             (request->packet->code != PW_DISCONNECT_REQUEST) &&
2587             (request->coa ||
2588              (pairfind(request->config_items, PW_SEND_COA_REQUEST, 0) != NULL))) {
2589                 if (!originated_coa_request(request)) {
2590                         RDEBUG2("Do CoA Fail handler here");
2591                 }
2592                 /* request->coa is stil set, so we can update events */
2593         }
2594 #endif
2595
2596  cleanup:
2597         /*
2598          *      Clean up.  These are no longer needed.
2599          */
2600         pairfree(&request->config_items);
2601
2602         pairfree(&request->packet->vps);
2603         request->username = NULL;
2604         request->password = NULL;
2605
2606         pairfree(&request->reply->vps);
2607
2608 #ifdef WITH_PROXY
2609         if (request->proxy) {
2610                 pairfree(&request->proxy->vps);
2611
2612                 if (request->proxy_reply) {
2613                         pairfree(&request->proxy_reply->vps);
2614                 }
2615
2616 #if 0
2617                 /*
2618                  *      We're not tracking responses from the home
2619                  *      server, we can therefore free this memory in
2620                  *      the child thread.
2621                  */
2622                 if (!request->in_proxy_hash) {
2623                         rad_free(&request->proxy);
2624                         rad_free(&request->proxy_reply);
2625                         request->home_server = NULL;
2626                 }
2627 #endif
2628         }
2629 #endif
2630
2631         RDEBUG2("Finished request.");
2632         rad_assert(child_state >= 0);
2633         request->child_state = child_state;
2634
2635         /*
2636          *      Single threaded mode: update timers now.
2637          */
2638         if (!have_children) wait_a_bit(request);
2639 }
2640
2641
2642 static void rad_retransmit_packet(REQUEST *request)
2643 {
2644         char buffer[256];
2645
2646 #ifdef WITH_TCP
2647         if (request->home_server->proto == IPPROTO_TCP) {
2648                 DEBUG2("Suppressing duplicate proxied request to home server %s port %d proto TCP - ID: %d",
2649                        inet_ntop(request->proxy->dst_ipaddr.af,
2650                                  &request->proxy->dst_ipaddr.ipaddr,
2651                                  buffer, sizeof(buffer)),
2652                        request->proxy->dst_port,
2653                        request->proxy->id);
2654                 return;         /* don't do anything else */
2655         }
2656 #endif
2657
2658         RDEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
2659                 inet_ntop(request->proxy->dst_ipaddr.af,
2660                           &request->proxy->dst_ipaddr.ipaddr,
2661                           buffer, sizeof(buffer)),
2662                 request->proxy->dst_port,
2663                 request->proxy->id);
2664         request->num_proxied_requests++;
2665
2666         DEBUG_PACKET(request, request->proxy, 1);
2667         request->proxy_listener->send(request->proxy_listener,
2668                                       request);
2669 }
2670
2671
2672 static int rad_retransmit(REQUEST *request)
2673 {
2674         /*
2675          *      If we've just discovered that the home server
2676          *      is dead, OR the socket has been closed, look for
2677          *      another connection to a home server.
2678          */
2679         if ((request->home_server->state == HOME_STATE_IS_DEAD) ||
2680             (request->proxy_listener->status != RAD_LISTEN_STATUS_KNOWN)) {
2681                 home_server *home;
2682                 
2683                 remove_from_proxy_hash(request);
2684                 
2685                 home = home_server_ldb(NULL, request->home_pool, request);
2686                 if (!home) {
2687                         RDEBUG2("ERROR: Failed to find live home server for request");
2688                 no_home_servers:
2689                         /*
2690                          *      Do post-request processing,
2691                          *      and any insertion of necessary
2692                          *      events.
2693                          */
2694                         post_proxy_fail_handler(request);
2695                         return 1;
2696                 }
2697
2698                 request->proxy->code = request->packet->code;
2699
2700                 /*
2701                  *      Free the old packet, to force re-encoding
2702                  */
2703                 free(request->proxy->data);
2704                 request->proxy->data = NULL;
2705                 request->proxy->data_len = 0;
2706
2707                 /*
2708                  *      This request failed over to a virtual
2709                  *      server.  Push it back onto the queue
2710                  *      to be processed.
2711                  */
2712                 if (request->home_server->server) {
2713                         proxy_fallback_handler(request);
2714                         return 1;
2715                 }
2716
2717                 /*
2718                  *      Try to proxy the request.
2719                  */
2720                 if (!proxy_request(request)) {
2721                         RDEBUG("ERROR: Failed to re-proxy request");
2722                         goto no_home_servers;
2723                 }
2724                 return 1;
2725         } /* else the home server is still alive */
2726
2727         rad_retransmit_packet(request);
2728
2729         return 1;
2730 }
2731
2732
2733 static void received_retransmit(REQUEST *request, const RADCLIENT *client)
2734 {
2735
2736         RAD_STATS_TYPE_INC(request->listener, total_dup_requests);
2737         RAD_STATS_CLIENT_INC(request->listener, client, total_dup_requests);
2738         
2739         switch (request->child_state) {
2740         case REQUEST_QUEUED:
2741         case REQUEST_RUNNING:
2742 #ifdef WITH_PROXY
2743         discard:
2744 #endif
2745                 radlog(L_ERR, "Discarding duplicate request from "
2746                        "client %s port %d - ID: %d due to unfinished request %u",
2747                        client->shortname,
2748                        request->packet->src_port,request->packet->id,
2749                        request->number);
2750                 break;
2751
2752 #ifdef WITH_PROXY
2753         case REQUEST_PROXIED:
2754                 /*
2755                  *      We're not supposed to have duplicate
2756                  *      accounting packets.  The other states handle
2757                  *      duplicates fine (discard, or send duplicate
2758                  *      reply).  But we do NOT want to retransmit an
2759                  *      accounting request here, because that would
2760                  *      involve updating the Acct-Delay-Time, and
2761                  *      therefore changing the packet Id, etc.
2762                  *
2763                  *      Instead, we just discard the packet.  We may
2764                  *      eventually respond, or the client will send a
2765                  *      new accounting packet.            
2766                  *
2767                  *      The same comments go for Status-Server, and
2768                  *      other packet types.
2769                  *
2770                  *      FIXME: coa: when we proxy CoA && Disconnect
2771                  *      packets, this logic has to be fixed.
2772                  */
2773                 if (request->packet->code != PW_AUTHENTICATION_REQUEST) {
2774                         goto discard;
2775                 }
2776
2777                 check_for_zombie_home_server(request);
2778
2779                 /*
2780                  *      Home server is still alive, and the proxy
2781                  *      socket is OK.  Just re-send the packet.
2782                  */
2783                 if ((request->home_server->state != HOME_STATE_IS_DEAD) &&
2784                     (request->proxy_listener->status == RAD_LISTEN_STATUS_KNOWN)) {
2785                         rad_retransmit_packet(request);
2786                         break;
2787                 }
2788
2789                 /*
2790                  *      Otherwise, we need to fail over to another
2791                  *      home server, and possibly run "post-proxy-type
2792                  *      fail".  Add an event waiting for the child to
2793                  *      have a result.
2794                  */
2795                 INSERT_EVENT(wait_a_bit, request);
2796
2797                 request->priority = RAD_LISTEN_PROXY;
2798                 thread_pool_addrequest(request, rad_retransmit);
2799                 break;
2800 #endif
2801
2802         case REQUEST_REJECT_DELAY:
2803                 RDEBUG2("Waiting to send Access-Reject "
2804                        "to client %s port %d - ID: %d",
2805                        client->shortname,
2806                        request->packet->src_port, request->packet->id);
2807                 break;
2808
2809         case REQUEST_CLEANUP_DELAY:
2810         case REQUEST_DONE:
2811                 if (request->reply->code == 0) {
2812                         RDEBUG2("Ignoring retransmit from client %s port %d "
2813                                 "- ID: %d, no reply was configured",
2814                                 client->shortname,
2815                                 request->packet->src_port, request->packet->id);
2816                         return;
2817                 }
2818
2819                 /*
2820                  *      FIXME: This sends duplicate replies to
2821                  *      accounting requests, even if Acct-Delay-Time
2822                  *      or Event-Timestamp is in the packet.  In those
2823                  *      cases, the Id should be changed, and the packet
2824                  *      re-calculated.
2825                  */
2826                 RDEBUG2("Sending duplicate reply "
2827                        "to client %s port %d - ID: %d",
2828                        client->shortname,
2829                        request->packet->src_port, request->packet->id);
2830                 DEBUG_PACKET(request, request->reply, 1);
2831                 request->listener->send(request->listener, request);
2832                 break;
2833         }
2834 }
2835
2836
2837 static void received_conflicting_request(REQUEST *request,
2838                                          const RADCLIENT *client)
2839 {
2840         radlog(L_ERR, "Received conflicting packet from "
2841                "client %s port %d - ID: %d due to unfinished request %u.  Giving up on old request.",
2842                client->shortname,
2843                request->packet->src_port, request->packet->id,
2844                request->number);
2845
2846         /*
2847          *      Nuke it from the request hash, so we can receive new
2848          *      packets.
2849          */
2850         remove_from_request_hash(request);
2851
2852         switch (request->child_state) {
2853                 /*
2854                  *      Tell it to stop, and wait for it to do so.
2855                  */
2856         default:
2857                 request->master_state = REQUEST_STOP_PROCESSING;
2858                 request->delay += request->delay >> 1;
2859
2860                 tv_add(&request->when, request->delay);
2861
2862                 INSERT_EVENT(wait_for_child_to_die, request);
2863                 return;
2864
2865                 /*
2866                  *      Catch race conditions.  It may have switched
2867                  *      from running to done while this code is being
2868                  *      executed.
2869                  */
2870         case REQUEST_REJECT_DELAY:
2871         case REQUEST_CLEANUP_DELAY:
2872         case REQUEST_DONE:
2873                 break;
2874         }
2875 }
2876
2877
2878 static int can_handle_new_request(RADIUS_PACKET *packet,
2879                                   RADCLIENT *client,
2880                                   struct main_config_t *root)
2881 {
2882         /*
2883          *      Count the total number of requests, to see if
2884          *      there are too many.  If so, return with an
2885          *      error.
2886          */
2887         if (root->max_requests) {
2888                 int request_count = fr_packet_list_num_elements(pl);
2889
2890                 /*
2891                  *      This is a new request.  Let's see if
2892                  *      it makes us go over our configured
2893                  *      bounds.
2894                  */
2895                 if (request_count > root->max_requests) {
2896                         radlog(L_ERR, "Dropping request (%d is too many): "
2897                                "from client %s port %d - ID: %d", request_count,
2898                                client->shortname,
2899                                packet->src_port, packet->id);
2900                         radlog(L_INFO, "WARNING: Please check the configuration file.\n"
2901                                "\tThe value for 'max_requests' is probably set too low.\n");
2902                         return 0;
2903                 } /* else there were a small number of requests */
2904         } /* else there was no configured limit for requests */
2905
2906         /*
2907          *      FIXME: Add per-client checks.  If one client is sending
2908          *      too many packets, start discarding them.
2909          *
2910          *      We increment the counters here, and decrement them
2911          *      when the response is sent... somewhere in this file.
2912          */
2913
2914         /*
2915          *      FUTURE: Add checks for system load.  If the system is
2916          *      busy, start dropping requests...
2917          *
2918          *      We can probably keep some statistics ourselves...  if
2919          *      there are more requests coming in than we can handle,
2920          *      start dropping some.
2921          */
2922
2923         return 1;
2924 }
2925
2926
2927 int received_request(rad_listen_t *listener,
2928                      RADIUS_PACKET *packet, REQUEST **prequest,
2929                      RADCLIENT *client)
2930 {
2931         RADIUS_PACKET **packet_p;
2932         REQUEST *request = NULL;
2933         struct main_config_t *root = &mainconfig;
2934
2935         packet_p = fr_packet_list_find(pl, packet);
2936         if (packet_p) {
2937                 request = fr_packet2myptr(REQUEST, packet, packet_p);
2938                 rad_assert(request->in_request_hash);
2939
2940                 if ((request->packet->data_len == packet->data_len) &&
2941                     (memcmp(request->packet->vector, packet->vector,
2942                             sizeof(packet->vector)) == 0)) {
2943                         received_retransmit(request, client);
2944                         return 0;
2945                 }
2946
2947                 /*
2948                  *      The new request is different from the old one,
2949                  *      but maybe the old is finished.  If so, delete
2950                  *      the old one.
2951                  */
2952                 switch (request->child_state) {
2953                         struct timeval when;
2954
2955                 default:
2956                         /*
2957                          *      Special hacks for race conditions.
2958                          *      The reply is encoded, and therefore
2959                          *      likely sent.  We received a *new*
2960                          *      packet from the client, likely before
2961                          *      the next line or two of code which
2962                          *      updated the child state.  In this
2963                          *      case, just accept the new request.
2964                          */
2965                         if ((request->reply->code != 0) &&
2966                             request->reply->data) {
2967                                 radlog(L_INFO, "WARNING: Allowing fast client %s port %d - ID: %d for recent request %u.",
2968                                        client->shortname,
2969                                        packet->src_port, packet->id,
2970                                        request->number);
2971                                 remove_from_request_hash(request);
2972                                 request = NULL;
2973                                 break;
2974                         }
2975
2976                         gettimeofday(&when, NULL);
2977                         when.tv_sec -= 1;
2978
2979                         /*
2980                          *      If the cached request was received
2981                          *      within the last second, then we
2982                          *      discard the NEW request instead of the
2983                          *      old one.  This will happen ONLY when
2984                          *      the client is severely broken, and is
2985                          *      sending conflicting packets very
2986                          *      quickly.
2987                          */
2988                         if (timercmp(&when, &request->received, <)) {
2989                                 radlog(L_ERR, "Discarding conflicting packet from "
2990                                        "client %s port %d - ID: %d due to recent request %u.",
2991                                        client->shortname,
2992                                        packet->src_port, packet->id,
2993                                        request->number);
2994                                 return 0;
2995                         }
2996
2997                         received_conflicting_request(request, client);
2998                         request = NULL;
2999                         break;
3000
3001                 case REQUEST_REJECT_DELAY:
3002                 case REQUEST_CLEANUP_DELAY:
3003                         request->child_state = REQUEST_DONE;
3004                 case REQUEST_DONE:
3005                         cleanup_delay(request);
3006                         request = NULL;
3007                         break;
3008                 }
3009         }
3010
3011         /*
3012          *      We may want to quench the new request.
3013          */
3014         if ((listener->type != RAD_LISTEN_DETAIL) &&
3015             !can_handle_new_request(packet, client, root)) {
3016                 return 0;
3017         }
3018
3019         /*
3020          *      Create and initialize the new request.
3021          */
3022         request = request_alloc(); /* never fails */
3023
3024         if ((request->reply = rad_alloc(0)) == NULL) {
3025                 radlog(L_ERR, "No memory");
3026                 return 0;
3027         }
3028
3029         request->listener = listener;
3030         request->client = client;
3031         request->packet = packet;
3032         request->packet->timestamp = request->timestamp;
3033         request->number = request_num_counter++;
3034         request->priority = listener->type;
3035 #ifdef HAVE_PTHREAD_H
3036         request->child_pid = NO_SUCH_CHILD_PID;
3037 #endif
3038
3039         /*
3040          *      Status-Server packets go to the head of the queue.
3041          */
3042         if (request->packet->code == PW_STATUS_SERVER) request->priority = 0;
3043
3044         /*
3045          *      Set virtual server identity
3046          */
3047         if (client->server) {
3048                 request->server = client->server;
3049         } else if (listener->server) {
3050                 request->server = listener->server;
3051         } else {
3052                 request->server = NULL;
3053         }
3054
3055         /*
3056          *      Remember the request in the list.
3057          */
3058         if (!fr_packet_list_insert(pl, &request->packet)) {
3059                 radlog(L_ERR, "Failed to insert request %u in the list of live requests: discarding", request->number);
3060                 ev_request_free(&request);
3061                 return 0;
3062         }
3063
3064         request->in_request_hash = TRUE;
3065         request->root = root;
3066         root->refcount++;
3067 #ifdef WITH_TCP
3068         request->listener->count++;
3069 #endif
3070
3071         /*
3072          *      The request passes many of our sanity checks.
3073          *      From here on in, if anything goes wrong, we
3074          *      send a reject message, instead of dropping the
3075          *      packet.
3076          */
3077
3078         /*
3079          *      Build the reply template from the request.
3080          */
3081
3082         request->reply->sockfd = request->packet->sockfd;
3083         request->reply->dst_ipaddr = request->packet->src_ipaddr;
3084         request->reply->src_ipaddr = request->packet->dst_ipaddr;
3085         request->reply->dst_port = request->packet->src_port;
3086         request->reply->src_port = request->packet->dst_port;
3087         request->reply->id = request->packet->id;
3088         request->reply->code = 0; /* UNKNOWN code */
3089         memcpy(request->reply->vector, request->packet->vector,
3090                sizeof(request->reply->vector));
3091         request->reply->vps = NULL;
3092         request->reply->data = NULL;
3093         request->reply->data_len = 0;
3094
3095         request->master_state = REQUEST_ACTIVE;
3096         request->child_state = REQUEST_QUEUED;
3097         request->next_callback = NULL;
3098
3099         gettimeofday(&request->received, NULL);
3100         request->timestamp = request->received.tv_sec;
3101         request->when = request->received;
3102
3103         request->delay = USEC;
3104
3105         tv_add(&request->when, request->delay);
3106
3107         INSERT_EVENT(wait_a_bit, request);
3108
3109         *prequest = request;
3110         return 1;
3111 }
3112
3113
3114 #ifdef WITH_PROXY
3115 REQUEST *received_proxy_response(RADIUS_PACKET *packet)
3116 {
3117         char            buffer[128];
3118         REQUEST         *request;
3119
3120         /*
3121          *      Lookup *without* removal.  In versions prior to 2.2.0,
3122          *      this did lookup *and* removal.  That method allowed
3123          *      attackers to spoof replies that caused entries to be
3124          *      removed from the proxy hash prior to validation.
3125          */
3126         request = lookup_in_proxy_hash(packet);
3127
3128         if (!request) {
3129                 radlog(L_PROXY, "No outstanding request was found for reply from host %s port %d - ID %d",
3130                        inet_ntop(packet->src_ipaddr.af,
3131                                  &packet->src_ipaddr.ipaddr,
3132                                  buffer, sizeof(buffer)),
3133                        packet->src_port, packet->id);
3134                 return NULL;
3135         }
3136
3137         /*
3138          *      There's a reply: discard it if it's a conflicting one.
3139          */
3140         if (request->proxy_reply) {
3141                 /*
3142                  *      ? The home server gave us a new proxy
3143                  *      reply which doesn't match the old
3144                  *      one.  Delete it.
3145                  */
3146                 if (memcmp(request->proxy_reply->vector,
3147                            packet->vector,
3148                            sizeof(request->proxy_reply->vector)) != 0) {
3149                         RDEBUG2("Ignoring conflicting proxy reply");
3150                         
3151                 
3152                         /* assert that there's an event queued for request? */
3153                         return NULL;
3154                 } /* else it had previously passed verification */
3155
3156                 /*
3157                  *      Verify the packet before doing ANYTHING with
3158                  *      it.  This means we're doing more MD5 checks in
3159                  *      the server core.  However, we can fix that by
3160                  *      moving to multiple threads listening on
3161                  *      sockets.
3162                  *
3163                  *      We do this AFTER looking the request up in the
3164                  *      hash, and AFTER checking if we saw a previous
3165                  *      request.  This helps minimize the DoS effect
3166                  *      of people attacking us with spoofed packets.
3167                  *
3168                  *      FIXME: move the "read from proxy socket" code
3169                  *      into one (or more) threads.  Have it read from
3170                  *      the socket, do the validation, and write a
3171                  *      pointer to the packet into a pipe? Or queue it
3172                  *      to the main server?
3173                  */
3174         } else if (rad_verify(packet, request->proxy,
3175                               request->home_server->secret) != 0) {
3176                 DEBUG("Ignoring spoofed proxy reply.  Signature is invalid");
3177                 return NULL;
3178         }
3179
3180         /*
3181          *      Check (again) if it's a duplicate reply.  We do this
3182          *      after deleting the packet from the proxy hash.
3183          */
3184         if (request->proxy_reply) {
3185                 RDEBUG2("Discarding duplicate reply from host %s port %d  - ID: %d",
3186                         inet_ntop(packet->src_ipaddr.af,
3187                                   &packet->src_ipaddr.ipaddr,
3188                                   buffer, sizeof(buffer)),
3189                         packet->src_port, packet->id);
3190         }
3191
3192         gettimeofday(&now, NULL);
3193
3194         /*
3195          *      "ping" packets have a different algorithm for marking
3196          *      a home server alive.  They also skip all of the CoA,
3197          *      etc. checks.
3198          */
3199         if (!request->packet) {
3200                 request->proxy_reply = packet;
3201 #ifdef WITH_TCP
3202                 rad_assert(request->home_server != NULL);
3203                 if (request->home_server->proto != IPPROTO_TCP)
3204 #endif
3205                         received_response_to_ping(request);
3206                 request->proxy_reply = NULL; /* caller will free it */
3207                 ev_request_free(&request);
3208                 return NULL;
3209         }
3210
3211         /*
3212          *      Maybe move this earlier in the decision process?
3213          *      Having it here means that late or duplicate proxy
3214          *      replies no longer get the home server marked as
3215          *      "alive".  This might be good for stability, though.
3216          *
3217          *      FIXME: Do we really want to do this whenever we
3218          *      receive a packet?  Setting this here means that we
3219          *      mark it alive on *any* packet, even if it's lost all
3220          *      of the *other* packets in the last 10s.
3221          *
3222          *      This behavior could be configurable.
3223          */
3224         request->home_server->state = HOME_STATE_ALIVE;
3225         request->home_server->last_packet = now.tv_sec;
3226         
3227 #ifdef WITH_COA
3228         /*
3229          *      When originating CoA, the "proxy" reply is the reply
3230          *      to the CoA request that we originated.  At this point,
3231          *      the original request is finished, and it has a reply.
3232          *
3233          *      However, if we haven't separated the two requests, do
3234          *      so now.  This is done so that cleaning up the original
3235          *      request won't cause the CoA request to be free'd.  See
3236          *      util.c, request_free()
3237          */
3238         if (request->parent && (request->parent->coa == request)) {
3239                 request->parent->coa = NULL;
3240                 request->parent = NULL;
3241
3242                 /*
3243                  *      The proxied packet was different from the
3244                  *      original packet, AND the proxied packet was
3245                  *      a CoA: allow it.
3246                  */
3247         } else if ((request->packet->code != request->proxy->code) &&
3248                    ((request->proxy->code == PW_COA_REQUEST) ||
3249                     (request->proxy->code == PW_DISCONNECT_REQUEST))) {
3250           /*
3251            *    It's already divorced: do nothing.
3252            */
3253           
3254         } else
3255                 /*
3256                  *      Skip the next set of checks, as the original
3257                  *      reply is cached.  We want to be able to still
3258                  *      process the CoA reply, AND to reference the
3259                  *      original request/reply.
3260                  *
3261                  *      This is getting to be really quite a bit of a
3262                  *      hack.
3263                  */
3264 #endif
3265
3266         /*
3267          *      If there's a reply to the NAS, ignore everything
3268          *      related to proxy responses
3269          */
3270         if (request->reply && request->reply->code != 0) {
3271                 RDEBUG2("Ignoring proxy reply that arrived after we sent a reply to the NAS");
3272                 return NULL;
3273         }
3274
3275 #ifdef WITH_STATS
3276         /*
3277          *      The average includes our time to receive packets and
3278          *      look them up in the hashes, which should be the same
3279          *      for all packets.
3280          *
3281          *      We update the response time only for the FIRST packet
3282          *      we receive.
3283          */
3284         if (request->home_server->ema.window > 0) {
3285                 radius_stats_ema(&request->home_server->ema,
3286                                  &now, &request->proxy_when);
3287         }
3288 #endif
3289
3290         switch (request->child_state) {
3291         case REQUEST_QUEUED:
3292         case REQUEST_RUNNING:
3293                 radlog(L_ERR, "Internal sanity check failed for child state");
3294                 /* FALL-THROUGH */
3295
3296         case REQUEST_REJECT_DELAY:
3297         case REQUEST_CLEANUP_DELAY:
3298         case REQUEST_DONE:
3299                 radlog(L_ERR, "Reply from home server %s port %d  - ID: %d arrived too late for request %u. Try increasing 'retry_delay' or 'max_request_time'",
3300                        inet_ntop(packet->src_ipaddr.af,
3301                                  &packet->src_ipaddr.ipaddr,
3302                                  buffer, sizeof(buffer)),
3303                        packet->src_port, packet->id,
3304                        request->number);
3305                 /* assert that there's an event queued for request? */
3306                 return NULL;
3307
3308         case REQUEST_PROXIED:
3309                 break;
3310         }
3311
3312         request->proxy_reply = packet;
3313
3314 #if 0
3315         /*
3316          *      Perform RTT calculations, as per RFC 2988 (for TCP).
3317          *      Note that we only do so on the first response.
3318          */
3319         if ((request->num_proxied_responses == 1)
3320                 int rtt;
3321                 home_server *home = request->home_server;
3322
3323                 rtt = now.tv_sec - request->proxy_when.tv_sec;
3324                 rtt *= USEC;
3325                 rtt += now.tv_usec;
3326                 rtt -= request->proxy_when.tv_usec;
3327
3328                 if (!home->has_rtt) {
3329                         home->has_rtt = TRUE;
3330
3331                         home->srtt = rtt;
3332                         home->rttvar = rtt / 2;
3333
3334                 } else {
3335                         home->rttvar -= home->rttvar >> 2;
3336                         home->rttvar += (home->srtt - rtt);
3337                         home->srtt -= home->srtt >> 3;
3338                         home->srtt += rtt >> 3;
3339                 }
3340
3341                 home->rto = home->srtt;
3342                 if (home->rttvar > (USEC / 4)) {
3343                         home->rto += home->rttvar * 4;
3344                 } else {
3345                         home->rto += USEC;
3346                 }
3347         }
3348 #endif
3349
3350         request->child_state = REQUEST_QUEUED;
3351         request->when = now;
3352         request->delay = USEC;
3353         request->priority = RAD_LISTEN_PROXY;
3354         tv_add(&request->when, request->delay);
3355
3356         /*
3357          *      Wait a bit will take care of max_request_time
3358          */
3359         INSERT_EVENT(wait_a_bit, request);
3360
3361         return request;
3362 }
3363
3364 #endif /* WITH_PROXY */
3365
3366 #ifdef WITH_TCP
3367 static void tcp_socket_lifetime(void *ctx)
3368 {
3369         rad_listen_t *listener = ctx;
3370         char buffer[256];
3371
3372         listener->print(listener, buffer, sizeof(buffer));
3373
3374         DEBUG("Reached maximum lifetime on socket %s", buffer);
3375
3376         listener->status = RAD_LISTEN_STATUS_CLOSED;
3377         event_new_fd(listener);
3378 }
3379
3380 static void tcp_socket_idle_timeout(void *ctx)
3381 {
3382         rad_listen_t *listener = ctx;
3383         listen_socket_t *sock = listener->data;
3384         char buffer[256];
3385
3386         fr_event_now(el, &now); /* should always succeed... */
3387
3388         rad_assert(sock->home != NULL);
3389
3390         /*
3391          *      We implement idle timeout by polling, because it's
3392          *      cheaper than resetting the idle timeout every time
3393          *      we send / receive a packet.
3394          */
3395         if ((sock->last_packet + sock->home->idle_timeout) > now.tv_sec) {
3396                 struct timeval when;
3397                 void *fun = tcp_socket_idle_timeout;
3398                 
3399                 when.tv_sec = sock->last_packet;
3400                 when.tv_sec += sock->home->idle_timeout;
3401                 when.tv_usec = 0;
3402
3403                 if (sock->home->lifetime &&
3404                     (sock->opened + sock->home->lifetime < when.tv_sec)) {
3405                         when.tv_sec = sock->opened + sock->home->lifetime;
3406                         fun = tcp_socket_lifetime;
3407                 }
3408                 
3409                 if (!fr_event_insert(el, fun, listener, &when, &sock->ev)) {
3410                         rad_panic("Failed to insert event");
3411                 }
3412
3413                 return;
3414         }
3415
3416         listener->print(listener, buffer, sizeof(buffer));
3417         
3418         DEBUG("Reached idle timeout on socket %s", buffer);
3419
3420         listener->status = RAD_LISTEN_STATUS_CLOSED;
3421         event_new_fd(listener);
3422 }
3423 #endif
3424
3425 int event_new_fd(rad_listen_t *this)
3426 {
3427         char buffer[1024];
3428
3429         if (this->status == RAD_LISTEN_STATUS_KNOWN) return 1;
3430
3431         this->print(this, buffer, sizeof(buffer));
3432
3433         if (this->status == RAD_LISTEN_STATUS_INIT) {
3434                 if (just_started) {
3435                         DEBUG("Listening on %s", buffer);
3436                 } else {
3437                         radlog(L_INFO, " ... adding new socket %s", buffer);
3438                 }
3439
3440 #ifdef WITH_PROXY
3441                 /*
3442                  *      Add it to the list of sockets we can use.
3443                  *      Server sockets (i.e. auth/acct) are never
3444                  *      added to the packet list.
3445                  */
3446                 if (this->type == RAD_LISTEN_PROXY) {
3447                         listen_socket_t *sock = this->data;
3448
3449                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3450                         if (!fr_packet_list_socket_add(proxy_list, this->fd,
3451                                                        sock->proto,
3452                                                        &sock->other_ipaddr, sock->other_port,
3453                                                        this)) {
3454
3455                                 proxy_no_new_sockets = TRUE;
3456                                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3457
3458                                 /*
3459                                  *      This is bad.  However, the
3460                                  *      packet list now supports 256
3461                                  *      open sockets, which should
3462                                  *      minimize this problem.
3463                                  */
3464                                 radlog(L_ERR, "Failed adding proxy socket: %s",
3465                                        fr_strerror());
3466                                 return 0;
3467                         }
3468
3469                         if (sock->home) {
3470                                 sock->home->num_connections++;
3471                                 
3472                                 /*
3473                                  *      If necessary, add it to the list of
3474                                  *      new proxy listeners.
3475                                  */
3476                                 if (sock->home->lifetime || sock->home->idle_timeout) {
3477                                         this->next = proxy_listener_list;
3478                                         proxy_listener_list = this;
3479                                 }
3480                         }
3481                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3482
3483                         /*
3484                          *      Tell the main thread that we've added
3485                          *      a proxy listener, but only if we need
3486                          *      to update the event list.  Do this
3487                          *      with the mutex unlocked, to reduce
3488                          *      contention.
3489                          */
3490                         if (sock->home) {
3491                                 if (sock->home->lifetime || sock->home->idle_timeout) {
3492                                         radius_signal_self(RADIUS_SIGNAL_SELF_NEW_FD);
3493                                 }
3494                         }
3495                 }
3496 #endif          
3497
3498 #ifdef WITH_DETAIL
3499                 /*
3500                  *      Detail files are always known, and aren't
3501                  *      put into the socket event loop.
3502                  */
3503                 if (this->type == RAD_LISTEN_DETAIL) {
3504                         this->status = RAD_LISTEN_STATUS_KNOWN;
3505                         
3506                         /*
3507                          *      Set up the first poll interval.
3508                          */
3509                         event_poll_detail(this);
3510                         return 1;
3511                 }
3512 #endif
3513
3514                 FD_MUTEX_LOCK(&fd_mutex);
3515                 if (!fr_event_fd_insert(el, 0, this->fd,
3516                                         event_socket_handler, this)) {
3517                         radlog(L_ERR, "Failed adding event handler for proxy socket!");
3518                         exit(1);
3519                 }
3520                 FD_MUTEX_UNLOCK(&fd_mutex);
3521                 
3522                 this->status = RAD_LISTEN_STATUS_KNOWN;
3523                 return 1;
3524         }
3525
3526         /*
3527          *      Something went wrong with the socket: make it harmless.
3528          */
3529         if (this->status == RAD_LISTEN_STATUS_REMOVE_FD) {
3530                 int devnull;
3531
3532                 /*
3533                  *      Remove it from the list of live FD's.
3534                  */
3535                 FD_MUTEX_LOCK(&fd_mutex);
3536                 fr_event_fd_delete(el, 0, this->fd);
3537                 FD_MUTEX_UNLOCK(&fd_mutex);
3538
3539 #ifdef WITH_TCP
3540                 /*
3541                  *      We track requests using this socket only for
3542                  *      TCP.  For UDP, we don't currently close
3543                  *      sockets.
3544                  */
3545 #ifdef WITH_PROXY
3546                 if (this->type != RAD_LISTEN_PROXY)
3547 #endif
3548                 {
3549                         if (this->count != 0) {
3550                                 fr_packet_list_walk(pl, this,
3551                                                     remove_all_requests);
3552                         }
3553
3554                         if (this->count == 0) {
3555                                 this->status = RAD_LISTEN_STATUS_FINISH;
3556                                 goto finish;
3557                         }
3558                 }               
3559 #ifdef WITH_PROXY
3560                 else {
3561                         int count = this->count;
3562
3563                         /*
3564                          *      Duplicate code
3565                          */
3566                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3567                         if (!fr_packet_list_socket_freeze(proxy_list,
3568                                                           this->fd)) {
3569                                 radlog(L_ERR, "Fatal error freezing socket: %s",
3570                                        fr_strerror());
3571                                 exit(1);
3572                         }
3573
3574                         /*
3575                          *      Doing this with the proxy mutex held
3576                          *      is a Bad Thing.  We should move to
3577                          *      finer-grained mutexes.
3578                          */
3579                         count = this->count;
3580                         if (count > 0) {
3581                                 fr_packet_list_walk(proxy_list, this,
3582                                                     remove_all_proxied_requests);
3583                         }
3584                         count = this->count; /* protected by mutex */
3585                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3586
3587                         if (count == 0) {
3588                                 this->status = RAD_LISTEN_STATUS_FINISH;
3589                                 goto finish;
3590                         }
3591                 }
3592 #endif  /* WITH_PROXY */
3593 #endif  /* WITH_TCP */
3594
3595                 /*
3596                  *      Re-open the socket, pointing it to /dev/null.
3597                  *      This means that all writes proceed without
3598                  *      blocking, and all reads return "no data".
3599                  *
3600                  *      This leaves the socket active, so any child
3601                  *      threads won't go insane.  But it means that
3602                  *      they cannot send or receive any packets.
3603                  *
3604                  *      This is EXTRA work in the normal case, when
3605                  *      sockets are closed without error.  But it lets
3606                  *      us have one simple processing method for all
3607                  *      sockets.
3608                  */
3609                 devnull = open("/dev/null", O_RDWR);
3610                 if (devnull < 0) {
3611                         radlog(L_ERR, "FATAL failure opening /dev/null: %s",
3612                                strerror(errno));
3613                         exit(1);
3614                 }
3615                 if (dup2(devnull, this->fd) < 0) {
3616                         radlog(L_ERR, "FATAL failure closing socket: %s",
3617                                strerror(errno));
3618                         exit(1);
3619                 }
3620                 close(devnull);
3621
3622                 this->status = RAD_LISTEN_STATUS_CLOSED;
3623
3624                 /*
3625                  *      Fall through to the next section.
3626                  */
3627         }
3628
3629 #ifdef WITH_TCP
3630         /*
3631          *      Called ONLY from the main thread.  On the following
3632          *      conditions:
3633          *
3634          *      idle timeout
3635          *      max lifetime
3636          *
3637          *      (and falling through from "forcibly close FD" above)
3638          *      client closed connection on us
3639          *      client sent us a bad packet.
3640          */
3641         if (this->status == RAD_LISTEN_STATUS_CLOSED) {
3642                 int count = this->count;
3643                 rad_assert(this->type != RAD_LISTEN_DETAIL);
3644
3645 #ifdef WITH_PROXY
3646                 /*
3647                  *      Remove it from the list of active sockets, so
3648                  *      that it isn't used when proxying new packets.
3649                  */
3650                 if (this->type == RAD_LISTEN_PROXY) {
3651                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3652                         if (!fr_packet_list_socket_freeze(proxy_list,
3653                                                           this->fd)) {
3654                                 radlog(L_ERR, "Fatal error freezing socket: %s",
3655                                        fr_strerror());
3656                                 exit(1);
3657                         }
3658                         count = this->count; /* protected by mutex */
3659                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3660                 }
3661 #endif
3662
3663                 /*
3664                  *      Requests are still using the socket.  Wait for
3665                  *      them to finish.
3666                  */
3667                 if (count != 0) {
3668                         struct timeval when;
3669                         listen_socket_t *sock = this->data;
3670
3671                         /*
3672                          *      Try again to clean up the socket in 30
3673                          *      seconds.
3674                          */
3675                         gettimeofday(&when, NULL);
3676                         when.tv_sec += 30;
3677                         
3678                         if (!fr_event_insert(el,
3679                                              (fr_event_callback_t) event_new_fd,
3680                                              this, &when, &sock->ev)) {
3681                                 rad_panic("Failed to insert event");
3682                         }
3683                        
3684                         return 1;
3685                 }
3686
3687                 /*
3688                  *      No one is using this socket: we can delete it
3689                  *      immediately.
3690                  */
3691                 this->status = RAD_LISTEN_STATUS_FINISH;
3692         }
3693         
3694 finish:
3695         if (this->status == RAD_LISTEN_STATUS_FINISH) {
3696                 listen_socket_t *sock = this->data;
3697
3698                 rad_assert(this->count == 0);
3699                 radlog(L_INFO, " ... closing socket %s", buffer);
3700
3701                 /*
3702                  *      Remove it from the list of live FD's.  Note
3703                  *      that it MAY also have been removed above.  We
3704                  *      do it again here, to catch the case of sockets
3705                  *      closing on idle timeout, or max
3706                  *      lifetime... AFTER all requests have finished
3707                  *      using it.
3708                  */
3709                 FD_MUTEX_LOCK(&fd_mutex);
3710                 fr_event_fd_delete(el, 0, this->fd);
3711                 FD_MUTEX_UNLOCK(&fd_mutex);
3712                 
3713 #ifdef WITH_PROXY
3714                 /*
3715                  *      Remove it from the list of sockets to be used
3716                  *      when proxying.
3717                  */
3718                 if (this->type == RAD_LISTEN_PROXY) {
3719                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3720                         if (!fr_packet_list_socket_remove(proxy_list,
3721                                                           this->fd, NULL)) {
3722                                 radlog(L_ERR, "Fatal error removing socket: %s",
3723                                        fr_strerror());
3724                                 exit(1);
3725                         }
3726                         if (sock->home) sock->home->num_connections--;
3727                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3728                 }
3729 #endif
3730
3731                 /*
3732                  *      Remove any pending cleanups.
3733                  */
3734                 if (sock->ev) fr_event_delete(el, &sock->ev);
3735
3736                 /*
3737                  *      And finally, close the socket.
3738                  */
3739                 listen_free(&this);
3740         }
3741 #endif  /* WITH_TCP */
3742
3743         return 1;
3744 }
3745
3746 static void handle_signal_self(int flag)
3747 {
3748         if ((flag & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
3749                 if ((flag & RADIUS_SIGNAL_SELF_EXIT) != 0) {
3750                         radlog(L_INFO, "Received TERM signal");
3751                         fr_event_loop_exit(el, 1);
3752                 } else {
3753                         fr_event_loop_exit(el, 2);
3754                 }
3755
3756                 return;
3757         } /* else exit/term flags weren't set */
3758
3759         /*
3760          *      Tell the even loop to stop processing.
3761          */
3762         if ((flag & RADIUS_SIGNAL_SELF_HUP) != 0) {
3763                 time_t when;
3764                 static time_t last_hup = 0;
3765
3766                 when = time(NULL);
3767                 if ((int) (when - last_hup) < 5) {
3768                         radlog(L_INFO, "Ignoring HUP (less than 5s since last one)");
3769                         return;
3770                 }
3771
3772                 radlog(L_INFO, "Received HUP signal.");
3773
3774                 last_hup = when;
3775
3776                 fr_event_loop_exit(el, 0x80);
3777         }
3778
3779 #ifdef WITH_DETAIL
3780         if ((flag & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
3781                 rad_listen_t *this;
3782                 
3783                 /*
3784                  *      FIXME: O(N) loops suck.
3785                  */
3786                 for (this = mainconfig.listen;
3787                      this != NULL;
3788                      this = this->next) {
3789                         if (this->type != RAD_LISTEN_DETAIL) continue;
3790
3791                         /*
3792                          *      This one didn't send the signal, skip
3793                          *      it.
3794                          */
3795                         if (!this->decode(this, NULL)) continue;
3796
3797                         /*
3798                          *      Go service the interrupt.
3799                          */
3800                         event_poll_detail(this);
3801                 }
3802         }
3803 #endif
3804
3805 #ifdef WITH_TCP
3806 #ifdef WITH_PROXY
3807         /*
3808          *      Add event handlers for idle timeouts && maximum lifetime.
3809          */
3810         if ((flag & RADIUS_SIGNAL_SELF_NEW_FD) != 0) {
3811                 struct timeval when;
3812                 void *fun = NULL;
3813
3814                 fr_event_now(el, &now);
3815
3816                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
3817
3818                 while (proxy_listener_list) {
3819                         rad_listen_t *this = proxy_listener_list;
3820                         listen_socket_t *sock = this->data;
3821
3822                         proxy_listener_list = this->next;
3823                         this->next = NULL;
3824
3825                         if (!sock->home) continue; /* skip UDP sockets */
3826
3827                         when = now;
3828
3829                         if (!sock->home->idle_timeout) {
3830                                 rad_assert(sock->home->lifetime != 0);
3831
3832                                 when.tv_sec += sock->home->lifetime;
3833                                 fun = tcp_socket_lifetime;
3834                         } else {
3835                                 rad_assert(sock->home->idle_timeout != 0);
3836
3837                                 when.tv_sec += sock->home->idle_timeout;
3838                                 fun = tcp_socket_idle_timeout;
3839                         }
3840
3841                         if (!fr_event_insert(el, fun, this, &when,
3842                                              &(sock->ev))) {
3843                                 rad_panic("Failed to insert event");
3844                         }
3845                 }
3846
3847                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3848         }
3849 #endif  /* WITH_PROXY */
3850 #endif  /* WITH_TCP */
3851 }
3852
3853 #ifndef WITH_SELF_PIPE
3854 void radius_signal_self(int flag)
3855 {
3856         handle_signal_self(flag);
3857 }
3858 #else
3859 /*
3860  *      Inform ourselves that we received a signal.
3861  */
3862 void radius_signal_self(int flag)
3863 {
3864         ssize_t rcode;
3865         uint8_t buffer[16];
3866
3867         /*
3868          *      The read MUST be non-blocking for this to work.
3869          */
3870         rcode = read(self_pipe[0], buffer, sizeof(buffer));
3871         if (rcode > 0) {
3872                 ssize_t i;
3873
3874                 for (i = 0; i < rcode; i++) {
3875                         buffer[0] |= buffer[i];
3876                 }
3877         } else {
3878                 buffer[0] = 0;
3879         }
3880
3881         buffer[0] |= flag;
3882
3883         write(self_pipe[1], buffer, 1);
3884 }
3885
3886
3887 static void event_signal_handler(UNUSED fr_event_list_t *xel,
3888                                  UNUSED int fd, UNUSED void *ctx)
3889 {
3890         ssize_t i, rcode;
3891         uint8_t buffer[32];
3892
3893         rcode = read(self_pipe[0], buffer, sizeof(buffer));
3894         if (rcode <= 0) return;
3895
3896         /*
3897          *      Merge pending signals.
3898          */
3899         for (i = 0; i < rcode; i++) {
3900                 buffer[0] |= buffer[i];
3901         }
3902
3903         handle_signal_self(buffer[0]);
3904 }
3905 #endif
3906
3907
3908 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd,
3909                                  void *ctx)
3910 {
3911         rad_listen_t *listener = ctx;
3912         RAD_REQUEST_FUNP fun;
3913         REQUEST *request;
3914
3915         rad_assert(xel == el);
3916
3917         xel = xel;
3918
3919         if ((listener->type != RAD_LISTEN_DETAIL) &&
3920             (listener->fd < 0)) {
3921                 char buffer[256];
3922
3923                 listener->print(listener, buffer, sizeof(buffer));
3924                 radlog(L_ERR, "FATAL: Asked to read from closed socket: %s",
3925                        buffer);
3926         
3927                 rad_panic("Socket was closed on us!");
3928                 _exit(1);
3929         }
3930         
3931         if (!listener->recv(listener, &fun, &request)) return;
3932
3933         rad_assert(fun != NULL);
3934         rad_assert(request != NULL);
3935
3936         thread_pool_addrequest(request, fun);
3937 }
3938
3939
3940 /*
3941  *      This function is called periodically to see if this detail
3942  *      file is available for reading.
3943  */
3944 static void event_poll_detail(void *ctx)
3945 {
3946         int delay;
3947         rad_listen_t *this = ctx;
3948         struct timeval when;
3949         listen_detail_t *detail = this->data;
3950
3951         rad_assert(this->type == RAD_LISTEN_DETAIL);
3952
3953         event_socket_handler(el, this->fd, this);
3954
3955         fr_event_now(el, &now);
3956         when = now;
3957
3958         /*
3959          *      Backdoor API to get the delay until the next poll
3960          *      time.
3961          */
3962         delay = this->encode(this, NULL);
3963         tv_add(&when, delay);
3964
3965         if (!fr_event_insert(el, event_poll_detail, this,
3966                              &when, &detail->ev)) {
3967                 radlog(L_ERR, "Failed creating handler");
3968                 exit(1);
3969         }
3970 }
3971
3972
3973 static void event_status(struct timeval *wake)
3974 {
3975 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
3976         int argval;
3977 #endif
3978
3979         if (debug_flag == 0) {
3980                 if (just_started) {
3981                         radlog(L_INFO, "Ready to process requests.");
3982                         just_started = FALSE;
3983                 }
3984                 return;
3985         }
3986
3987         if (!wake) {
3988                 radlog(L_INFO, "Ready to process requests.");
3989
3990         } else if ((wake->tv_sec != 0) ||
3991                    (wake->tv_usec >= 100000)) {
3992                 DEBUG("Waking up in %d.%01u seconds.",
3993                       (int) wake->tv_sec, (unsigned int) wake->tv_usec / 100000);
3994         }
3995
3996
3997         /*
3998          *      FIXME: Put this somewhere else, where it isn't called
3999          *      all of the time...
4000          */
4001
4002 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
4003         /*
4004          *      If there are no child threads, then there may
4005          *      be child processes.  In that case, wait for
4006          *      their exit status, and throw that exit status
4007          *      away.  This helps get rid of zxombie children.
4008          */
4009         while (waitpid(-1, &argval, WNOHANG) > 0) {
4010                 /* do nothing */
4011         }
4012 #endif
4013
4014 }
4015
4016 /*
4017  *      Externally-visibly functions.
4018  */
4019 int radius_event_init(CONF_SECTION *cs, int spawn_flag)
4020 {
4021         rad_listen_t *head = NULL;
4022
4023         if (el) return 0;
4024
4025         time(&fr_start_time);
4026
4027         el = fr_event_list_create(event_status);
4028         if (!el) return 0;
4029
4030         pl = fr_packet_list_create(0);
4031         if (!pl) return 0;      /* leak el */
4032
4033         request_num_counter = 0;
4034
4035 #ifdef WITH_PROXY
4036         if (mainconfig.proxy_requests) {
4037                 /*
4038                  *      Create the tree for managing proxied requests and
4039                  *      responses.
4040                  */
4041                 proxy_list = fr_packet_list_create(1);
4042                 if (!proxy_list) return 0;
4043
4044 #ifdef HAVE_PTHREAD_H
4045                 if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
4046                         radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
4047                                strerror(errno));
4048                         exit(1);
4049                 }
4050 #endif
4051         }
4052 #endif
4053
4054 #ifdef HAVE_PTHREAD_H
4055 #ifndef __MINGW32__
4056         NO_SUCH_CHILD_PID = (pthread_t ) (0);
4057 #else
4058         NO_SUCH_CHILD_PID = pthread_self(); /* not a child thread */
4059 #endif
4060         /*
4061          *      Initialize the threads ONLY if we're spawning, AND
4062          *      we're running normally.
4063          */
4064         if (spawn_flag && !check_config &&
4065             (thread_pool_init(cs, &spawn_flag) < 0)) {
4066                 exit(1);
4067         }
4068 #endif
4069
4070         /*
4071          *      Move all of the thread calls to this file?
4072          *
4073          *      It may be best for the mutexes to be in this file...
4074          */
4075         have_children = spawn_flag;
4076
4077         if (check_config) {
4078                 DEBUG("%s: #### Skipping IP addresses and Ports ####",
4079                        mainconfig.name);
4080                 if (listen_init(cs, &head) < 0) {
4081                         fflush(NULL);
4082                         exit(1);
4083                 }
4084                 return 1;
4085         }
4086
4087 #ifdef WITH_SELF_PIPE
4088         /*
4089          *      Child threads need a pipe to signal us, as do the
4090          *      signal handlers.
4091          */
4092         if (pipe(self_pipe) < 0) {
4093                 radlog(L_ERR, "radiusd: Error opening internal pipe: %s",
4094                        strerror(errno));
4095                 exit(1);
4096         }
4097         if (fcntl(self_pipe[0], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
4098                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
4099                        strerror(errno));
4100                 exit(1);
4101         }
4102         if (fcntl(self_pipe[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
4103                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
4104                        strerror(errno));
4105                 exit(1);
4106         }
4107
4108         if (!fr_event_fd_insert(el, 0, self_pipe[0],
4109                                   event_signal_handler, el)) {
4110                 radlog(L_ERR, "Failed creating handler for signals");
4111                 exit(1);
4112         }
4113 #endif  /* WITH_SELF_PIPE */
4114
4115        DEBUG("%s: #### Opening IP addresses and Ports ####",
4116                mainconfig.name);
4117
4118        /*
4119         *       The server temporarily switches to an unprivileged
4120         *       user very early in the bootstrapping process.
4121         *       However, some sockets MAY require privileged access
4122         *       (bind to device, or to port < 1024, or to raw
4123         *       sockets).  Those sockets need to call suid up/down
4124         *       themselves around the functions that need a privileged
4125         *       uid.
4126         */
4127         if (listen_init(cs, &head) < 0) {
4128                 _exit(1);
4129         }
4130         
4131         mainconfig.listen = head;
4132
4133         /*
4134          *      At this point, no one has any business *ever* going
4135          *      back to root uid.
4136          */
4137         fr_suid_down_permanent();
4138
4139         return 1;
4140 }
4141
4142
4143 static int request_hash_cb(UNUSED void *ctx, void *data)
4144 {
4145         REQUEST *request = fr_packet2myptr(REQUEST, packet, data);
4146
4147 #ifdef WITH_PROXY
4148         rad_assert(request->in_proxy_hash == FALSE);
4149 #endif
4150
4151         ev_request_free(&request);
4152
4153         return 0;
4154 }
4155
4156
4157 #ifdef WITH_PROXY
4158 static int proxy_hash_cb(UNUSED void *ctx, void *data)
4159 {
4160         REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
4161
4162         ev_request_free(&request);
4163
4164         return 0;
4165 }
4166 #endif
4167
4168 void radius_event_free(void)
4169 {
4170         /*
4171          *      FIXME: Stop all threads, or at least check that
4172          *      they're all waiting on the semaphore, and the queues
4173          *      are empty.
4174          */
4175
4176 #ifdef WITH_PROXY
4177         /*
4178          *      There are requests in the proxy hash that aren't
4179          *      referenced from anywhere else.  Remove them first.
4180          */
4181         if (proxy_list) {
4182                 fr_packet_list_walk(proxy_list, NULL, proxy_hash_cb);
4183                 fr_packet_list_free(proxy_list);
4184                 proxy_list = NULL;
4185         }
4186 #endif
4187
4188         fr_packet_list_walk(pl, NULL, request_hash_cb);
4189
4190         fr_packet_list_free(pl);
4191         pl = NULL;
4192
4193         fr_event_list_free(el);
4194 }
4195
4196 int radius_event_process(void)
4197 {
4198         if (!el) return 0;
4199
4200         return fr_event_loop(el);
4201 }
4202
4203 void radius_handle_request(REQUEST *request, RAD_REQUEST_FUNP fun)
4204 {
4205         request->options = RAD_REQUEST_OPTION_DEBUG2;
4206
4207         if (request_pre_handler(request)) {
4208                 rad_assert(fun != NULL);
4209                 rad_assert(request != NULL);
4210                 
4211                 if (request->server) RDEBUG("server %s {",
4212                                             request->server != NULL ?
4213                                             request->server : ""); 
4214                 fun(request);
4215
4216                 if (request->server) RDEBUG("} # server %s",
4217                                              request->server != NULL ?
4218                                             request->server : "");
4219
4220                 request_post_handler(request);
4221         }
4222
4223         DEBUG2("Going to the next request");
4224         return;
4225 }