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