Move retransmits + proxy failover into 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 rad_retransmit_packet(REQUEST *request)
2615 {
2616         char buffer[256];
2617
2618 #ifdef WITH_TCP
2619         if (request->home_server->proto == IPPROTO_TCP) {
2620                 DEBUG2("Suppressing duplicate proxied request to home server %s port %d proto TCP - ID: %d",
2621                        inet_ntop(request->proxy->dst_ipaddr.af,
2622                                  &request->proxy->dst_ipaddr.ipaddr,
2623                                  buffer, sizeof(buffer)),
2624                        request->proxy->dst_port,
2625                        request->proxy->id);
2626                 return;         /* don't do anything else */
2627         }
2628 #endif
2629
2630         RDEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
2631                 inet_ntop(request->proxy->dst_ipaddr.af,
2632                           &request->proxy->dst_ipaddr.ipaddr,
2633                           buffer, sizeof(buffer)),
2634                 request->proxy->dst_port,
2635                 request->proxy->id);
2636         request->num_proxied_requests++;
2637
2638         DEBUG_PACKET(request, request->proxy, 1);
2639         request->proxy_listener->send(request->proxy_listener,
2640                                       request);
2641 }
2642
2643
2644 static int rad_retransmit(REQUEST *request)
2645 {
2646         /*
2647          *      If we've just discovered that the home server
2648          *      is dead, OR the socket has been closed, look for
2649          *      another connection to a home server.
2650          */
2651         if ((request->home_server->state == HOME_STATE_IS_DEAD) ||
2652             (request->proxy_listener->status != RAD_LISTEN_STATUS_KNOWN)) {
2653                 home_server *home;
2654                 
2655                 remove_from_proxy_hash(request);
2656                 
2657                 home = home_server_ldb(NULL, request->home_pool, request);
2658                 if (!home) {
2659                         RDEBUG2("Failed to find live home server for request");
2660                 no_home_servers:
2661                         /*
2662                          *      Do post-request processing,
2663                          *      and any insertion of necessary
2664                          *      events.
2665                          */
2666                         post_proxy_fail_handler(request);
2667                         return 1;
2668                 }
2669
2670                 request->proxy->code = request->packet->code;
2671
2672                 /*
2673                  *      Free the old packet, to force re-encoding
2674                  */
2675                 free(request->proxy->data);
2676                 request->proxy->data = NULL;
2677                 request->proxy->data_len = 0;
2678
2679                 /*
2680                  *      This request failed over to a virtual
2681                  *      server.  Push it back onto the queue
2682                  *      to be processed.
2683                  */
2684                 if (request->home_server->server) {
2685                         proxy_fallback_handler(request);
2686                         return 1;
2687                 }
2688
2689                 /*
2690                  *      Try to proxy the request.
2691                  */
2692                 if (!proxy_request(request)) {
2693                         RDEBUG("ERROR: Failed to re-proxy request");
2694                         goto no_home_servers;
2695                 }
2696                 return 1;
2697         } /* else the home server is still alive */
2698
2699         rad_retransmit_packet(request);
2700
2701         return 1;
2702 }
2703
2704
2705 static void received_retransmit(REQUEST *request, const RADCLIENT *client)
2706 {
2707
2708         RAD_STATS_TYPE_INC(request->listener, total_dup_requests);
2709         RAD_STATS_CLIENT_INC(request->listener, client, total_dup_requests);
2710         
2711         switch (request->child_state) {
2712         case REQUEST_QUEUED:
2713         case REQUEST_RUNNING:
2714 #ifdef WITH_PROXY
2715         discard:
2716 #endif
2717                 radlog(L_ERR, "Discarding duplicate request from "
2718                        "client %s port %d - ID: %d due to unfinished request %u",
2719                        client->shortname,
2720                        request->packet->src_port,request->packet->id,
2721                        request->number);
2722                 break;
2723
2724 #ifdef WITH_PROXY
2725         case REQUEST_PROXIED:
2726                 /*
2727                  *      We're not supposed to have duplicate
2728                  *      accounting packets.  The other states handle
2729                  *      duplicates fine (discard, or send duplicate
2730                  *      reply).  But we do NOT want to retransmit an
2731                  *      accounting request here, because that would
2732                  *      involve updating the Acct-Delay-Time, and
2733                  *      therefore changing the packet Id, etc.
2734                  *
2735                  *      Instead, we just discard the packet.  We may
2736                  *      eventually respond, or the client will send a
2737                  *      new accounting packet.            
2738                  *
2739                  *      The same comments go for Status-Server, and
2740                  *      other packet types.
2741                  *
2742                  *      FIXME: coa: when we proxy CoA && Disconnect
2743                  *      packets, this logic has to be fixed.
2744                  */
2745                 if (request->packet->code != PW_AUTHENTICATION_REQUEST) {
2746                         goto discard;
2747                 }
2748
2749                 check_for_zombie_home_server(request);
2750
2751                 /*
2752                  *      Home server is still alive, and the proxy
2753                  *      socket is OK.  Just re-send the packet.
2754                  */
2755                 if ((request->home_server->state != HOME_STATE_IS_DEAD) &&
2756                     (request->proxy_listener->status == RAD_LISTEN_STATUS_KNOWN)) {
2757                         rad_retransmit_packet(request);
2758                         break;
2759                 }
2760
2761                 /*
2762                  *      Otherwise, we need to fail over to another
2763                  *      home server, and possibly run "post-proxy-type
2764                  *      fail".  Add an event waiting for the child to
2765                  *      have a result.
2766                  */
2767                 INSERT_EVENT(wait_a_bit, request);
2768
2769                 request->priority = RAD_LISTEN_PROXY;
2770                 thread_pool_addrequest(request, rad_retransmit);
2771                 break;
2772 #endif
2773
2774         case REQUEST_REJECT_DELAY:
2775                 RDEBUG2("Waiting to send Access-Reject "
2776                        "to client %s port %d - ID: %d",
2777                        client->shortname,
2778                        request->packet->src_port, request->packet->id);
2779                 break;
2780
2781         case REQUEST_CLEANUP_DELAY:
2782         case REQUEST_DONE:
2783                 if (request->reply->code == 0) {
2784                         RDEBUG2("Ignoring retransmit from client %s port %d "
2785                                 "- ID: %d, no reply was configured",
2786                                 client->shortname,
2787                                 request->packet->src_port, request->packet->id);
2788                         return;
2789                 }
2790
2791                 /*
2792                  *      FIXME: This sends duplicate replies to
2793                  *      accounting requests, even if Acct-Delay-Time
2794                  *      or Event-Timestamp is in the packet.  In those
2795                  *      cases, the Id should be changed, and the packet
2796                  *      re-calculated.
2797                  */
2798                 RDEBUG2("Sending duplicate reply "
2799                        "to client %s port %d - ID: %d",
2800                        client->shortname,
2801                        request->packet->src_port, request->packet->id);
2802                 DEBUG_PACKET(request, request->reply, 1);
2803                 request->listener->send(request->listener, request);
2804                 break;
2805         }
2806 }
2807
2808
2809 static void received_conflicting_request(REQUEST *request,
2810                                          const RADCLIENT *client)
2811 {
2812         radlog(L_ERR, "Received conflicting packet from "
2813                "client %s port %d - ID: %d due to unfinished request %u.  Giving up on old request.",
2814                client->shortname,
2815                request->packet->src_port, request->packet->id,
2816                request->number);
2817
2818         /*
2819          *      Nuke it from the request hash, so we can receive new
2820          *      packets.
2821          */
2822         remove_from_request_hash(request);
2823
2824         switch (request->child_state) {
2825                 /*
2826                  *      Tell it to stop, and wait for it to do so.
2827                  */
2828         default:
2829                 request->master_state = REQUEST_STOP_PROCESSING;
2830                 request->delay += request->delay >> 1;
2831
2832                 tv_add(&request->when, request->delay);
2833
2834                 INSERT_EVENT(wait_for_child_to_die, request);
2835                 return;
2836
2837                 /*
2838                  *      Catch race conditions.  It may have switched
2839                  *      from running to done while this code is being
2840                  *      executed.
2841                  */
2842         case REQUEST_REJECT_DELAY:
2843         case REQUEST_CLEANUP_DELAY:
2844         case REQUEST_DONE:
2845                 break;
2846         }
2847 }
2848
2849
2850 static int can_handle_new_request(RADIUS_PACKET *packet,
2851                                   RADCLIENT *client,
2852                                   struct main_config_t *root)
2853 {
2854         /*
2855          *      Count the total number of requests, to see if
2856          *      there are too many.  If so, return with an
2857          *      error.
2858          */
2859         if (root->max_requests) {
2860                 int request_count = fr_packet_list_num_elements(pl);
2861
2862                 /*
2863                  *      This is a new request.  Let's see if
2864                  *      it makes us go over our configured
2865                  *      bounds.
2866                  */
2867                 if (request_count > root->max_requests) {
2868                         radlog(L_ERR, "Dropping request (%d is too many): "
2869                                "from client %s port %d - ID: %d", request_count,
2870                                client->shortname,
2871                                packet->src_port, packet->id);
2872                         radlog(L_INFO, "WARNING: Please check the configuration file.\n"
2873                                "\tThe value for 'max_requests' is probably set too low.\n");
2874                         return 0;
2875                 } /* else there were a small number of requests */
2876         } /* else there was no configured limit for requests */
2877
2878         /*
2879          *      FIXME: Add per-client checks.  If one client is sending
2880          *      too many packets, start discarding them.
2881          *
2882          *      We increment the counters here, and decrement them
2883          *      when the response is sent... somewhere in this file.
2884          */
2885
2886         /*
2887          *      FUTURE: Add checks for system load.  If the system is
2888          *      busy, start dropping requests...
2889          *
2890          *      We can probably keep some statistics ourselves...  if
2891          *      there are more requests coming in than we can handle,
2892          *      start dropping some.
2893          */
2894
2895         return 1;
2896 }
2897
2898
2899 int received_request(rad_listen_t *listener,
2900                      RADIUS_PACKET *packet, REQUEST **prequest,
2901                      RADCLIENT *client)
2902 {
2903         RADIUS_PACKET **packet_p;
2904         REQUEST *request = NULL;
2905         struct main_config_t *root = &mainconfig;
2906
2907         packet_p = fr_packet_list_find(pl, packet);
2908         if (packet_p) {
2909                 request = fr_packet2myptr(REQUEST, packet, packet_p);
2910                 rad_assert(request->in_request_hash);
2911
2912                 if ((request->packet->data_len == packet->data_len) &&
2913                     (memcmp(request->packet->vector, packet->vector,
2914                             sizeof(packet->vector)) == 0)) {
2915                         received_retransmit(request, client);
2916                         return 0;
2917                 }
2918
2919                 /*
2920                  *      The new request is different from the old one,
2921                  *      but maybe the old is finished.  If so, delete
2922                  *      the old one.
2923                  */
2924                 switch (request->child_state) {
2925                         struct timeval when;
2926
2927                 default:
2928                         /*
2929                          *      Special hacks for race conditions.
2930                          *      The reply is encoded, and therefore
2931                          *      likely sent.  We received a *new*
2932                          *      packet from the client, likely before
2933                          *      the next line or two of code which
2934                          *      updated the child state.  In this
2935                          *      case, just accept the new request.
2936                          */
2937                         if ((request->reply->code != 0) &&
2938                             request->reply->data) {
2939                                 radlog(L_INFO, "WARNING: Allowing fast client %s port %d - ID: %d for recent request %u.",
2940                                        client->shortname,
2941                                        packet->src_port, packet->id,
2942                                        request->number);
2943                                 remove_from_request_hash(request);
2944                                 request = NULL;
2945                                 break;
2946                         }
2947
2948                         gettimeofday(&when, NULL);
2949                         when.tv_sec -= 1;
2950
2951                         /*
2952                          *      If the cached request was received
2953                          *      within the last second, then we
2954                          *      discard the NEW request instead of the
2955                          *      old one.  This will happen ONLY when
2956                          *      the client is severely broken, and is
2957                          *      sending conflicting packets very
2958                          *      quickly.
2959                          */
2960                         if (timercmp(&when, &request->received, <)) {
2961                                 radlog(L_ERR, "Discarding conflicting packet from "
2962                                        "client %s port %d - ID: %d due to recent request %u.",
2963                                        client->shortname,
2964                                        packet->src_port, packet->id,
2965                                        request->number);
2966                                 return 0;
2967                         }
2968
2969                         received_conflicting_request(request, client);
2970                         request = NULL;
2971                         break;
2972
2973                 case REQUEST_REJECT_DELAY:
2974                 case REQUEST_CLEANUP_DELAY:
2975                         request->child_state = REQUEST_DONE;
2976                 case REQUEST_DONE:
2977                         cleanup_delay(request);
2978                         request = NULL;
2979                         break;
2980                 }
2981         }
2982
2983         /*
2984          *      We may want to quench the new request.
2985          */
2986         if ((listener->type != RAD_LISTEN_DETAIL) &&
2987             !can_handle_new_request(packet, client, root)) {
2988                 return 0;
2989         }
2990
2991         /*
2992          *      Create and initialize the new request.
2993          */
2994         request = request_alloc(); /* never fails */
2995
2996         if ((request->reply = rad_alloc(0)) == NULL) {
2997                 radlog(L_ERR, "No memory");
2998                 return 0;
2999         }
3000
3001         request->listener = listener;
3002         request->client = client;
3003         request->packet = packet;
3004         request->packet->timestamp = request->timestamp;
3005         request->number = request_num_counter++;
3006         request->priority = listener->type;
3007 #ifdef HAVE_PTHREAD_H
3008         request->child_pid = NO_SUCH_CHILD_PID;
3009 #endif
3010
3011         /*
3012          *      Status-Server packets go to the head of the queue.
3013          */
3014         if (request->packet->code == PW_STATUS_SERVER) request->priority = 0;
3015
3016         /*
3017          *      Set virtual server identity
3018          */
3019         if (client->server) {
3020                 request->server = client->server;
3021         } else if (listener->server) {
3022                 request->server = listener->server;
3023         } else {
3024                 request->server = NULL;
3025         }
3026
3027         /*
3028          *      Remember the request in the list.
3029          */
3030         if (!fr_packet_list_insert(pl, &request->packet)) {
3031                 radlog(L_ERR, "Failed to insert request %u in the list of live requests: discarding", request->number);
3032                 ev_request_free(&request);
3033                 return 0;
3034         }
3035
3036         request->in_request_hash = TRUE;
3037         request->root = root;
3038         root->refcount++;
3039 #ifdef WITH_TCP
3040         request->listener->count++;
3041 #endif
3042
3043         /*
3044          *      The request passes many of our sanity checks.
3045          *      From here on in, if anything goes wrong, we
3046          *      send a reject message, instead of dropping the
3047          *      packet.
3048          */
3049
3050         /*
3051          *      Build the reply template from the request.
3052          */
3053
3054         request->reply->sockfd = request->packet->sockfd;
3055         request->reply->dst_ipaddr = request->packet->src_ipaddr;
3056         request->reply->src_ipaddr = request->packet->dst_ipaddr;
3057         request->reply->dst_port = request->packet->src_port;
3058         request->reply->src_port = request->packet->dst_port;
3059         request->reply->id = request->packet->id;
3060         request->reply->code = 0; /* UNKNOWN code */
3061         memcpy(request->reply->vector, request->packet->vector,
3062                sizeof(request->reply->vector));
3063         request->reply->vps = NULL;
3064         request->reply->data = NULL;
3065         request->reply->data_len = 0;
3066
3067         request->master_state = REQUEST_ACTIVE;
3068         request->child_state = REQUEST_QUEUED;
3069         request->next_callback = NULL;
3070
3071         gettimeofday(&request->received, NULL);
3072         request->timestamp = request->received.tv_sec;
3073         request->when = request->received;
3074
3075         request->delay = USEC;
3076
3077         tv_add(&request->when, request->delay);
3078
3079         INSERT_EVENT(wait_a_bit, request);
3080
3081         *prequest = request;
3082         return 1;
3083 }
3084
3085
3086 #ifdef WITH_PROXY
3087 REQUEST *received_proxy_response(RADIUS_PACKET *packet)
3088 {
3089         char            buffer[128];
3090         REQUEST         *request;
3091
3092         /*
3093          *      Lookup *without* removal.  In versions prior to 2.2.0,
3094          *      this did lookup *and* removal.  That method allowed
3095          *      attackers to spoof replies that caused entries to be
3096          *      removed from the proxy hash prior to validation.
3097          */
3098         request = lookup_in_proxy_hash(packet);
3099
3100         if (!request) {
3101                 radlog(L_PROXY, "No outstanding request was found for reply from host %s port %d - ID %d",
3102                        inet_ntop(packet->src_ipaddr.af,
3103                                  &packet->src_ipaddr.ipaddr,
3104                                  buffer, sizeof(buffer)),
3105                        packet->src_port, packet->id);
3106                 return NULL;
3107         }
3108
3109         /*
3110          *      There's a reply: discard it if it's a conflicting one.
3111          */
3112         if (request->proxy_reply) {
3113                 /*
3114                  *      ? The home server gave us a new proxy
3115                  *      reply which doesn't match the old
3116                  *      one.  Delete it.
3117                  */
3118                 if (memcmp(request->proxy_reply->vector,
3119                            packet->vector,
3120                            sizeof(request->proxy_reply->vector)) != 0) {
3121                         RDEBUG2("Ignoring conflicting proxy reply");
3122                         
3123                 
3124                         /* assert that there's an event queued for request? */
3125                         return NULL;
3126                 } /* else it had previously passed verification */
3127
3128                 /*
3129                  *      Verify the packet before doing ANYTHING with
3130                  *      it.  This means we're doing more MD5 checks in
3131                  *      the server core.  However, we can fix that by
3132                  *      moving to multiple threads listening on
3133                  *      sockets.
3134                  *
3135                  *      We do this AFTER looking the request up in the
3136                  *      hash, and AFTER checking if we saw a previous
3137                  *      request.  This helps minimize the DoS effect
3138                  *      of people attacking us with spoofed packets.
3139                  *
3140                  *      FIXME: move the "read from proxy socket" code
3141                  *      into one (or more) threads.  Have it read from
3142                  *      the socket, do the validation, and write a
3143                  *      pointer to the packet into a pipe? Or queue it
3144                  *      to the main server?
3145                  */
3146         } else if (rad_verify(packet, request->proxy,
3147                               request->home_server->secret) != 0) {
3148                 DEBUG("Ignoring spoofed proxy reply.  Signature is invalid");
3149                 return NULL;
3150         }
3151
3152         /*
3153          *      Check (again) if it's a duplicate reply.  We do this
3154          *      after deleting the packet from the proxy hash.
3155          */
3156         if (request->proxy_reply) {
3157                 RDEBUG2("Discarding duplicate reply from host %s port %d  - ID: %d",
3158                         inet_ntop(packet->src_ipaddr.af,
3159                                   &packet->src_ipaddr.ipaddr,
3160                                   buffer, sizeof(buffer)),
3161                         packet->src_port, packet->id);
3162         }
3163
3164         gettimeofday(&now, NULL);
3165
3166         /*
3167          *      Maybe move this earlier in the decision process?
3168          *      Having it here means that late or duplicate proxy
3169          *      replies no longer get the home server marked as
3170          *      "alive".  This might be good for stability, though.
3171          *
3172          *      FIXME: Do we really want to do this whenever we
3173          *      receive a packet?  Setting this here means that we
3174          *      mark it alive on *any* packet, even if it's lost all
3175          *      of the *other* packets in the last 10s.
3176          */
3177         if (request->proxy->code != PW_STATUS_SERVER) {
3178                 request->home_server->state = HOME_STATE_ALIVE;
3179         }
3180         
3181 #ifdef WITH_COA
3182         /*
3183          *      When originating CoA, the "proxy" reply is the reply
3184          *      to the CoA request that we originated.  At this point,
3185          *      the original request is finished, and it has a reply.
3186          *
3187          *      However, if we haven't separated the two requests, do
3188          *      so now.  This is done so that cleaning up the original
3189          *      request won't cause the CoA request to be free'd.  See
3190          *      util.c, request_free()
3191          */
3192         if (request->parent && (request->parent->coa == request)) {
3193                 request->parent->coa = NULL;
3194                 request->parent = NULL;
3195
3196                 /*
3197                  *      The proxied packet was different from the
3198                  *      original packet, AND the proxied packet was
3199                  *      a CoA: allow it.
3200                  */
3201         } else if ((request->packet->code != request->proxy->code) &&
3202                    ((request->proxy->code == PW_COA_REQUEST) ||
3203                     (request->proxy->code == PW_DISCONNECT_REQUEST))) {
3204           /*
3205            *    It's already divorced: do nothing.
3206            */
3207           
3208         } else
3209                 /*
3210                  *      Skip the next set of checks, as the original
3211                  *      reply is cached.  We want to be able to still
3212                  *      process the CoA reply, AND to reference the
3213                  *      original request/reply.
3214                  *
3215                  *      This is getting to be really quite a bit of a
3216                  *      hack.
3217                  */
3218 #endif
3219
3220         /*
3221          *      If there's a reply to the NAS, ignore everything
3222          *      related to proxy responses
3223          */
3224         if (request->reply && request->reply->code != 0) {
3225                 RDEBUG2("Ignoring proxy reply that arrived after we sent a reply to the NAS");
3226                 return NULL;
3227         }
3228         
3229 #ifdef WITH_STATS
3230         /*
3231          *      The average includes our time to receive packets and
3232          *      look them up in the hashes, which should be the same
3233          *      for all packets.
3234          *
3235          *      We update the response time only for the FIRST packet
3236          *      we receive.
3237          */
3238         if (request->home_server->ema.window > 0) {
3239                 radius_stats_ema(&request->home_server->ema,
3240                                  &now, &request->proxy_when);
3241         }
3242 #endif
3243
3244         switch (request->child_state) {
3245         case REQUEST_QUEUED:
3246         case REQUEST_RUNNING:
3247                 radlog(L_ERR, "Internal sanity check failed for child state");
3248                 /* FALL-THROUGH */
3249
3250         case REQUEST_REJECT_DELAY:
3251         case REQUEST_CLEANUP_DELAY:
3252         case REQUEST_DONE:
3253                 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'",
3254                        inet_ntop(packet->src_ipaddr.af,
3255                                  &packet->src_ipaddr.ipaddr,
3256                                  buffer, sizeof(buffer)),
3257                        packet->src_port, packet->id,
3258                        request->number);
3259                 /* assert that there's an event queued for request? */
3260                 return NULL;
3261
3262         case REQUEST_PROXIED:
3263                 break;
3264         }
3265
3266         request->proxy_reply = packet;
3267
3268 #if 0
3269         /*
3270          *      Perform RTT calculations, as per RFC 2988 (for TCP).
3271          *      Note that we only do so on the first response.
3272          */
3273         if ((request->num_proxied_responses == 1)
3274                 int rtt;
3275                 home_server *home = request->home_server;
3276
3277                 rtt = now.tv_sec - request->proxy_when.tv_sec;
3278                 rtt *= USEC;
3279                 rtt += now.tv_usec;
3280                 rtt -= request->proxy_when.tv_usec;
3281
3282                 if (!home->has_rtt) {
3283                         home->has_rtt = TRUE;
3284
3285                         home->srtt = rtt;
3286                         home->rttvar = rtt / 2;
3287
3288                 } else {
3289                         home->rttvar -= home->rttvar >> 2;
3290                         home->rttvar += (home->srtt - rtt);
3291                         home->srtt -= home->srtt >> 3;
3292                         home->srtt += rtt >> 3;
3293                 }
3294
3295                 home->rto = home->srtt;
3296                 if (home->rttvar > (USEC / 4)) {
3297                         home->rto += home->rttvar * 4;
3298                 } else {
3299                         home->rto += USEC;
3300                 }
3301         }
3302 #endif
3303
3304         /*
3305          *      There's no incoming request, so it's a proxied packet
3306          *      we originated.
3307          */
3308         if (!request->packet) {
3309                 received_response_to_ping(request);
3310                 request->proxy_reply = NULL; /* caller will free it */
3311                 ev_request_free(&request);
3312                 return NULL;
3313         }
3314
3315         request->child_state = REQUEST_QUEUED;
3316         request->when = now;
3317         request->delay = USEC;
3318         request->priority = RAD_LISTEN_PROXY;
3319         tv_add(&request->when, request->delay);
3320
3321         /*
3322          *      Wait a bit will take care of max_request_time
3323          */
3324         INSERT_EVENT(wait_a_bit, request);
3325
3326         return request;
3327 }
3328
3329 #endif /* WITH_PROXY */
3330
3331 #ifdef WITH_TCP
3332 static void tcp_socket_lifetime(void *ctx)
3333 {
3334         rad_listen_t *listener = ctx;
3335         char buffer[256];
3336
3337         listener->print(listener, buffer, sizeof(buffer));
3338
3339         DEBUG("Reached maximum lifetime on socket %s", buffer);
3340
3341         listener->status = RAD_LISTEN_STATUS_CLOSED;
3342         event_new_fd(listener);
3343 }
3344
3345 static void tcp_socket_idle_timeout(void *ctx)
3346 {
3347         rad_listen_t *listener = ctx;
3348         listen_socket_t *sock = listener->data;
3349         char buffer[256];
3350
3351         fr_event_now(el, &now); /* should always succeed... */
3352
3353         rad_assert(sock->home != NULL);
3354
3355         /*
3356          *      We implement idle timeout by polling, because it's
3357          *      cheaper than resetting the idle timeout every time
3358          *      we send / receive a packet.
3359          */
3360         if ((sock->last_packet + sock->home->idle_timeout) > now.tv_sec) {
3361                 struct timeval when;
3362                 void *fun = tcp_socket_idle_timeout;
3363                 
3364                 when.tv_sec = sock->last_packet;
3365                 when.tv_sec += sock->home->idle_timeout;
3366                 when.tv_usec = 0;
3367
3368                 if (sock->home->lifetime &&
3369                     (sock->opened + sock->home->lifetime < when.tv_sec)) {
3370                         when.tv_sec = sock->opened + sock->home->lifetime;
3371                         fun = tcp_socket_lifetime;
3372                 }
3373                 
3374                 if (!fr_event_insert(el, fun, listener, &when, &sock->ev)) {
3375                         rad_panic("Failed to insert event");
3376                 }
3377
3378                 return;
3379         }
3380
3381         listener->print(listener, buffer, sizeof(buffer));
3382         
3383         DEBUG("Reached idle timeout on socket %s", buffer);
3384
3385         listener->status = RAD_LISTEN_STATUS_CLOSED;
3386         event_new_fd(listener);
3387 }
3388 #endif
3389
3390 int event_new_fd(rad_listen_t *this)
3391 {
3392         char buffer[1024];
3393
3394         if (this->status == RAD_LISTEN_STATUS_KNOWN) return 1;
3395
3396         this->print(this, buffer, sizeof(buffer));
3397
3398         if (this->status == RAD_LISTEN_STATUS_INIT) {
3399                 if (just_started) {
3400                         DEBUG("Listening on %s", buffer);
3401                 } else {
3402                         radlog(L_INFO, " ... adding new socket %s", buffer);
3403                 }
3404
3405 #ifdef WITH_PROXY
3406                 /*
3407                  *      Add it to the list of sockets we can use.
3408                  *      Server sockets (i.e. auth/acct) are never
3409                  *      added to the packet list.
3410                  */
3411                 if (this->type == RAD_LISTEN_PROXY) {
3412                         listen_socket_t *sock = this->data;
3413
3414                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3415                         if (!fr_packet_list_socket_add(proxy_list, this->fd,
3416                                                        sock->proto,
3417                                                        &sock->other_ipaddr, sock->other_port,
3418                                                        this)) {
3419
3420                                 proxy_no_new_sockets = TRUE;
3421                                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3422
3423                                 /*
3424                                  *      This is bad.  However, the
3425                                  *      packet list now supports 256
3426                                  *      open sockets, which should
3427                                  *      minimize this problem.
3428                                  */
3429                                 radlog(L_ERR, "Failed adding proxy socket: %s",
3430                                        fr_strerror());
3431                                 return 0;
3432                         }
3433
3434                         if (sock->home) {
3435                                 sock->home->num_connections++;
3436                                 
3437                                 /*
3438                                  *      If necessary, add it to the list of
3439                                  *      new proxy listeners.
3440                                  */
3441                                 if (sock->home->lifetime || sock->home->idle_timeout) {
3442                                         this->next = proxy_listener_list;
3443                                         proxy_listener_list = this;
3444                                 }
3445                         }
3446                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3447
3448                         /*
3449                          *      Tell the main thread that we've added
3450                          *      a proxy listener, but only if we need
3451                          *      to update the event list.  Do this
3452                          *      with the mutex unlocked, to reduce
3453                          *      contention.
3454                          */
3455                         if (sock->home) {
3456                                 if (sock->home->lifetime || sock->home->idle_timeout) {
3457                                         radius_signal_self(RADIUS_SIGNAL_SELF_NEW_FD);
3458                                 }
3459                         }
3460                 }
3461 #endif          
3462
3463 #ifdef WITH_DETAIL
3464                 /*
3465                  *      Detail files are always known, and aren't
3466                  *      put into the socket event loop.
3467                  */
3468                 if (this->type == RAD_LISTEN_DETAIL) {
3469                         this->status = RAD_LISTEN_STATUS_KNOWN;
3470                         
3471                         /*
3472                          *      Set up the first poll interval.
3473                          */
3474                         event_poll_detail(this);
3475                         return 1;
3476                 }
3477 #endif
3478
3479                 FD_MUTEX_LOCK(&fd_mutex);
3480                 if (!fr_event_fd_insert(el, 0, this->fd,
3481                                         event_socket_handler, this)) {
3482                         radlog(L_ERR, "Failed adding event handler for proxy socket!");
3483                         exit(1);
3484                 }
3485                 FD_MUTEX_UNLOCK(&fd_mutex);
3486                 
3487                 this->status = RAD_LISTEN_STATUS_KNOWN;
3488                 return 1;
3489         }
3490
3491         /*
3492          *      Something went wrong with the socket: make it harmless.
3493          */
3494         if (this->status == RAD_LISTEN_STATUS_REMOVE_FD) {
3495                 int devnull;
3496
3497                 /*
3498                  *      Remove it from the list of live FD's.
3499                  */
3500                 FD_MUTEX_LOCK(&fd_mutex);
3501                 fr_event_fd_delete(el, 0, this->fd);
3502                 FD_MUTEX_UNLOCK(&fd_mutex);
3503
3504 #ifdef WITH_TCP
3505                 /*
3506                  *      We track requests using this socket only for
3507                  *      TCP.  For UDP, we don't currently close
3508                  *      sockets.
3509                  */
3510 #ifdef WITH_PROXY
3511                 if (this->type != RAD_LISTEN_PROXY)
3512 #endif
3513                 {
3514                         if (this->count != 0) {
3515                                 fr_packet_list_walk(pl, this,
3516                                                     remove_all_requests);
3517                         }
3518
3519                         if (this->count == 0) {
3520                                 this->status = RAD_LISTEN_STATUS_FINISH;
3521                                 goto finish;
3522                         }
3523                 }               
3524 #ifdef WITH_PROXY
3525                 else {
3526                         int count = this->count;
3527
3528                         /*
3529                          *      Duplicate code
3530                          */
3531                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3532                         if (!fr_packet_list_socket_freeze(proxy_list,
3533                                                           this->fd)) {
3534                                 radlog(L_ERR, "Fatal error freezing socket: %s",
3535                                        fr_strerror());
3536                                 exit(1);
3537                         }
3538
3539                         /*
3540                          *      Doing this with the proxy mutex held
3541                          *      is a Bad Thing.  We should move to
3542                          *      finer-grained mutexes.
3543                          */
3544                         count = this->count;
3545                         if (count > 0) {
3546                                 fr_packet_list_walk(proxy_list, this,
3547                                                     remove_all_proxied_requests);
3548                         }
3549                         count = this->count; /* protected by mutex */
3550                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3551
3552                         if (count == 0) {
3553                                 this->status = RAD_LISTEN_STATUS_FINISH;
3554                                 goto finish;
3555                         }
3556                 }
3557 #endif  /* WITH_PROXY */
3558 #endif  /* WITH_TCP */
3559
3560                 /*
3561                  *      Re-open the socket, pointing it to /dev/null.
3562                  *      This means that all writes proceed without
3563                  *      blocking, and all reads return "no data".
3564                  *
3565                  *      This leaves the socket active, so any child
3566                  *      threads won't go insane.  But it means that
3567                  *      they cannot send or receive any packets.
3568                  *
3569                  *      This is EXTRA work in the normal case, when
3570                  *      sockets are closed without error.  But it lets
3571                  *      us have one simple processing method for all
3572                  *      sockets.
3573                  */
3574                 devnull = open("/dev/null", O_RDWR);
3575                 if (devnull < 0) {
3576                         radlog(L_ERR, "FATAL failure opening /dev/null: %s",
3577                                strerror(errno));
3578                         exit(1);
3579                 }
3580                 if (dup2(devnull, this->fd) < 0) {
3581                         radlog(L_ERR, "FATAL failure closing socket: %s",
3582                                strerror(errno));
3583                         exit(1);
3584                 }
3585                 close(devnull);
3586
3587                 this->status = RAD_LISTEN_STATUS_CLOSED;
3588
3589                 /*
3590                  *      Fall through to the next section.
3591                  */
3592         }
3593
3594 #ifdef WITH_TCP
3595         /*
3596          *      Called ONLY from the main thread.  On the following
3597          *      conditions:
3598          *
3599          *      idle timeout
3600          *      max lifetime
3601          *
3602          *      (and falling through from "forcibly close FD" above)
3603          *      client closed connection on us
3604          *      client sent us a bad packet.
3605          */
3606         if (this->status == RAD_LISTEN_STATUS_CLOSED) {
3607                 int count = this->count;
3608                 rad_assert(this->type != RAD_LISTEN_DETAIL);
3609
3610 #ifdef WITH_PROXY
3611                 /*
3612                  *      Remove it from the list of active sockets, so
3613                  *      that it isn't used when proxying new packets.
3614                  */
3615                 if (this->type == RAD_LISTEN_PROXY) {
3616                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3617                         if (!fr_packet_list_socket_freeze(proxy_list,
3618                                                           this->fd)) {
3619                                 radlog(L_ERR, "Fatal error freezing socket: %s",
3620                                        fr_strerror());
3621                                 exit(1);
3622                         }
3623                         count = this->count; /* protected by mutex */
3624                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3625                 }
3626 #endif
3627
3628                 /*
3629                  *      Requests are still using the socket.  Wait for
3630                  *      them to finish.
3631                  */
3632                 if (count != 0) {
3633                         struct timeval when;
3634                         listen_socket_t *sock = this->data;
3635
3636                         /*
3637                          *      Try again to clean up the socket in 30
3638                          *      seconds.
3639                          */
3640                         gettimeofday(&when, NULL);
3641                         when.tv_sec += 30;
3642                         
3643                         if (!fr_event_insert(el,
3644                                              (fr_event_callback_t) event_new_fd,
3645                                              this, &when, &sock->ev)) {
3646                                 rad_panic("Failed to insert event");
3647                         }
3648                        
3649                         return 1;
3650                 }
3651
3652                 /*
3653                  *      No one is using this socket: we can delete it
3654                  *      immediately.
3655                  */
3656                 this->status = RAD_LISTEN_STATUS_FINISH;
3657         }
3658         
3659 finish:
3660         if (this->status == RAD_LISTEN_STATUS_FINISH) {
3661                 listen_socket_t *sock = this->data;
3662
3663                 rad_assert(this->count == 0);
3664                 radlog(L_INFO, " ... closing socket %s", buffer);
3665
3666                 /*
3667                  *      Remove it from the list of live FD's.  Note
3668                  *      that it MAY also have been removed above.  We
3669                  *      do it again here, to catch the case of sockets
3670                  *      closing on idle timeout, or max
3671                  *      lifetime... AFTER all requests have finished
3672                  *      using it.
3673                  */
3674                 FD_MUTEX_LOCK(&fd_mutex);
3675                 fr_event_fd_delete(el, 0, this->fd);
3676                 FD_MUTEX_UNLOCK(&fd_mutex);
3677                 
3678 #ifdef WITH_PROXY
3679                 /*
3680                  *      Remove it from the list of sockets to be used
3681                  *      when proxying.
3682                  */
3683                 if (this->type == RAD_LISTEN_PROXY) {
3684                         PTHREAD_MUTEX_LOCK(&proxy_mutex);
3685                         if (!fr_packet_list_socket_remove(proxy_list,
3686                                                           this->fd, NULL)) {
3687                                 radlog(L_ERR, "Fatal error removing socket: %s",
3688                                        fr_strerror());
3689                                 exit(1);
3690                         }
3691                         if (sock->home) sock->home->num_connections--;
3692                         PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3693                 }
3694 #endif
3695
3696                 /*
3697                  *      Remove any pending cleanups.
3698                  */
3699                 if (sock->ev) fr_event_delete(el, &sock->ev);
3700
3701                 /*
3702                  *      And finally, close the socket.
3703                  */
3704                 listen_free(&this);
3705         }
3706 #endif  /* WITH_TCP */
3707
3708         return 1;
3709 }
3710
3711 static void handle_signal_self(int flag)
3712 {
3713         if ((flag & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
3714                 if ((flag & RADIUS_SIGNAL_SELF_EXIT) != 0) {
3715                         radlog(L_INFO, "Received TERM signal");
3716                         fr_event_loop_exit(el, 1);
3717                 } else {
3718                         fr_event_loop_exit(el, 2);
3719                 }
3720
3721                 return;
3722         } /* else exit/term flags weren't set */
3723
3724         /*
3725          *      Tell the even loop to stop processing.
3726          */
3727         if ((flag & RADIUS_SIGNAL_SELF_HUP) != 0) {
3728                 time_t when;
3729                 static time_t last_hup = 0;
3730
3731                 when = time(NULL);
3732                 if ((int) (when - last_hup) < 5) {
3733                         radlog(L_INFO, "Ignoring HUP (less than 5s since last one)");
3734                         return;
3735                 }
3736
3737                 radlog(L_INFO, "Received HUP signal.");
3738
3739                 last_hup = when;
3740
3741                 fr_event_loop_exit(el, 0x80);
3742         }
3743
3744 #ifdef WITH_DETAIL
3745         if ((flag & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
3746                 rad_listen_t *this;
3747                 
3748                 /*
3749                  *      FIXME: O(N) loops suck.
3750                  */
3751                 for (this = mainconfig.listen;
3752                      this != NULL;
3753                      this = this->next) {
3754                         if (this->type != RAD_LISTEN_DETAIL) continue;
3755
3756                         /*
3757                          *      This one didn't send the signal, skip
3758                          *      it.
3759                          */
3760                         if (!this->decode(this, NULL)) continue;
3761
3762                         /*
3763                          *      Go service the interrupt.
3764                          */
3765                         event_poll_detail(this);
3766                 }
3767         }
3768 #endif
3769
3770 #ifdef WITH_TCP
3771 #ifdef WITH_PROXY
3772         /*
3773          *      Add event handlers for idle timeouts && maximum lifetime.
3774          */
3775         if ((flag & RADIUS_SIGNAL_SELF_NEW_FD) != 0) {
3776                 struct timeval when;
3777                 void *fun = NULL;
3778
3779                 fr_event_now(el, &now);
3780
3781                 PTHREAD_MUTEX_LOCK(&proxy_mutex);
3782
3783                 while (proxy_listener_list) {
3784                         rad_listen_t *this = proxy_listener_list;
3785                         listen_socket_t *sock = this->data;
3786
3787                         proxy_listener_list = this->next;
3788                         this->next = NULL;
3789
3790                         if (!sock->home) continue; /* skip UDP sockets */
3791
3792                         when = now;
3793
3794                         if (!sock->home->idle_timeout) {
3795                                 rad_assert(sock->home->lifetime != 0);
3796
3797                                 when.tv_sec += sock->home->lifetime;
3798                                 fun = tcp_socket_lifetime;
3799                         } else {
3800                                 rad_assert(sock->home->idle_timeout != 0);
3801
3802                                 when.tv_sec += sock->home->idle_timeout;
3803                                 fun = tcp_socket_idle_timeout;
3804                         }
3805
3806                         if (!fr_event_insert(el, fun, this, &when,
3807                                              &(sock->ev))) {
3808                                 rad_panic("Failed to insert event");
3809                         }
3810                 }
3811
3812                 PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
3813         }
3814 #endif  /* WITH_PROXY */
3815 #endif  /* WITH_TCP */
3816 }
3817
3818 #ifndef WITH_SELF_PIPE
3819 void radius_signal_self(int flag)
3820 {
3821         handle_signal_self(flag);
3822 }
3823 #else
3824 /*
3825  *      Inform ourselves that we received a signal.
3826  */
3827 void radius_signal_self(int flag)
3828 {
3829         ssize_t rcode;
3830         uint8_t buffer[16];
3831
3832         /*
3833          *      The read MUST be non-blocking for this to work.
3834          */
3835         rcode = read(self_pipe[0], buffer, sizeof(buffer));
3836         if (rcode > 0) {
3837                 ssize_t i;
3838
3839                 for (i = 0; i < rcode; i++) {
3840                         buffer[0] |= buffer[i];
3841                 }
3842         } else {
3843                 buffer[0] = 0;
3844         }
3845
3846         buffer[0] |= flag;
3847
3848         write(self_pipe[1], buffer, 1);
3849 }
3850
3851
3852 static void event_signal_handler(UNUSED fr_event_list_t *xel,
3853                                  UNUSED int fd, UNUSED void *ctx)
3854 {
3855         ssize_t i, rcode;
3856         uint8_t buffer[32];
3857
3858         rcode = read(self_pipe[0], buffer, sizeof(buffer));
3859         if (rcode <= 0) return;
3860
3861         /*
3862          *      Merge pending signals.
3863          */
3864         for (i = 0; i < rcode; i++) {
3865                 buffer[0] |= buffer[i];
3866         }
3867
3868         handle_signal_self(buffer[0]);
3869 }
3870 #endif
3871
3872
3873 static void event_socket_handler(fr_event_list_t *xel, UNUSED int fd,
3874                                  void *ctx)
3875 {
3876         rad_listen_t *listener = ctx;
3877         RAD_REQUEST_FUNP fun;
3878         REQUEST *request;
3879
3880         rad_assert(xel == el);
3881
3882         xel = xel;
3883
3884         if (listener->fd < 0) rad_panic("Socket was closed on us!");
3885         
3886         if (!listener->recv(listener, &fun, &request)) return;
3887
3888         rad_assert(fun != NULL);
3889         rad_assert(request != NULL);
3890
3891         thread_pool_addrequest(request, fun);
3892 }
3893
3894
3895 /*
3896  *      This function is called periodically to see if this detail
3897  *      file is available for reading.
3898  */
3899 static void event_poll_detail(void *ctx)
3900 {
3901         int delay;
3902         rad_listen_t *this = ctx;
3903         struct timeval when;
3904         listen_detail_t *detail = this->data;
3905
3906         rad_assert(this->type == RAD_LISTEN_DETAIL);
3907
3908         event_socket_handler(el, this->fd, this);
3909
3910         fr_event_now(el, &now);
3911         when = now;
3912
3913         /*
3914          *      Backdoor API to get the delay until the next poll
3915          *      time.
3916          */
3917         delay = this->encode(this, NULL);
3918         tv_add(&when, delay);
3919
3920         if (!fr_event_insert(el, event_poll_detail, this,
3921                              &when, &detail->ev)) {
3922                 radlog(L_ERR, "Failed creating handler");
3923                 exit(1);
3924         }
3925 }
3926
3927
3928 static void event_status(struct timeval *wake)
3929 {
3930 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
3931         int argval;
3932 #endif
3933
3934         if (debug_flag == 0) {
3935                 if (just_started) {
3936                         radlog(L_INFO, "Ready to process requests.");
3937                         just_started = FALSE;
3938                 }
3939                 return;
3940         }
3941
3942         if (!wake) {
3943                 radlog(L_INFO, "Ready to process requests.");
3944
3945         } else if ((wake->tv_sec != 0) ||
3946                    (wake->tv_usec >= 100000)) {
3947                 DEBUG("Waking up in %d.%01u seconds.",
3948                       (int) wake->tv_sec, (unsigned int) wake->tv_usec / 100000);
3949         }
3950
3951
3952         /*
3953          *      FIXME: Put this somewhere else, where it isn't called
3954          *      all of the time...
3955          */
3956
3957 #if !defined(HAVE_PTHREAD_H) && defined(WNOHANG)
3958         /*
3959          *      If there are no child threads, then there may
3960          *      be child processes.  In that case, wait for
3961          *      their exit status, and throw that exit status
3962          *      away.  This helps get rid of zxombie children.
3963          */
3964         while (waitpid(-1, &argval, WNOHANG) > 0) {
3965                 /* do nothing */
3966         }
3967 #endif
3968
3969 }
3970
3971 /*
3972  *      Externally-visibly functions.
3973  */
3974 int radius_event_init(CONF_SECTION *cs, int spawn_flag)
3975 {
3976         rad_listen_t *head = NULL;
3977
3978         if (el) return 0;
3979
3980         time(&fr_start_time);
3981
3982         el = fr_event_list_create(event_status);
3983         if (!el) return 0;
3984
3985         pl = fr_packet_list_create(0);
3986         if (!pl) return 0;      /* leak el */
3987
3988         request_num_counter = 0;
3989
3990 #ifdef WITH_PROXY
3991         if (mainconfig.proxy_requests) {
3992                 /*
3993                  *      Create the tree for managing proxied requests and
3994                  *      responses.
3995                  */
3996                 proxy_list = fr_packet_list_create(1);
3997                 if (!proxy_list) return 0;
3998
3999 #ifdef HAVE_PTHREAD_H
4000                 if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
4001                         radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
4002                                strerror(errno));
4003                         exit(1);
4004                 }
4005 #endif
4006         }
4007 #endif
4008
4009 #ifdef HAVE_PTHREAD_H
4010 #ifndef __MINGW32__
4011         NO_SUCH_CHILD_PID = (pthread_t ) (0);
4012 #else
4013         NO_SUCH_CHILD_PID = pthread_self(); /* not a child thread */
4014 #endif
4015         /*
4016          *      Initialize the threads ONLY if we're spawning, AND
4017          *      we're running normally.
4018          */
4019         if (spawn_flag && !check_config &&
4020             (thread_pool_init(cs, &spawn_flag) < 0)) {
4021                 exit(1);
4022         }
4023 #endif
4024
4025         /*
4026          *      Move all of the thread calls to this file?
4027          *
4028          *      It may be best for the mutexes to be in this file...
4029          */
4030         have_children = spawn_flag;
4031
4032         if (check_config) {
4033                 DEBUG("%s: #### Skipping IP addresses and Ports ####",
4034                        mainconfig.name);
4035                 return 1;
4036         }
4037
4038 #ifdef WITH_SELF_PIPE
4039         /*
4040          *      Child threads need a pipe to signal us, as do the
4041          *      signal handlers.
4042          */
4043         if (pipe(self_pipe) < 0) {
4044                 radlog(L_ERR, "radiusd: Error opening internal pipe: %s",
4045                        strerror(errno));
4046                 exit(1);
4047         }
4048         if (fcntl(self_pipe[0], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
4049                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
4050                        strerror(errno));
4051                 exit(1);
4052         }
4053         if (fcntl(self_pipe[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
4054                 radlog(L_ERR, "radiusd: Error setting internal flags: %s",
4055                        strerror(errno));
4056                 exit(1);
4057         }
4058
4059         if (!fr_event_fd_insert(el, 0, self_pipe[0],
4060                                   event_signal_handler, el)) {
4061                 radlog(L_ERR, "Failed creating handler for signals");
4062                 exit(1);
4063         }
4064 #endif  /* WITH_SELF_PIPE */
4065
4066        DEBUG("%s: #### Opening IP addresses and Ports ####",
4067                mainconfig.name);
4068
4069        /*
4070         *       The server temporarily switches to an unprivileged
4071         *       user very early in the bootstrapping process.
4072         *       However, some sockets MAY require privileged access
4073         *       (bind to device, or to port < 1024, or to raw
4074         *       sockets).  Those sockets need to call suid up/down
4075         *       themselves around the functions that need a privileged
4076         *       uid.
4077         */
4078         if (listen_init(cs, &head) < 0) {
4079                 _exit(1);
4080         }
4081         
4082         mainconfig.listen = head;
4083
4084         /*
4085          *      At this point, no one has any business *ever* going
4086          *      back to root uid.
4087          */
4088         fr_suid_down_permanent();
4089
4090         return 1;
4091 }
4092
4093
4094 static int request_hash_cb(UNUSED void *ctx, void *data)
4095 {
4096         REQUEST *request = fr_packet2myptr(REQUEST, packet, data);
4097
4098 #ifdef WITH_PROXY
4099         rad_assert(request->in_proxy_hash == FALSE);
4100 #endif
4101
4102         ev_request_free(&request);
4103
4104         return 0;
4105 }
4106
4107
4108 #ifdef WITH_PROXY
4109 static int proxy_hash_cb(UNUSED void *ctx, void *data)
4110 {
4111         REQUEST *request = fr_packet2myptr(REQUEST, proxy, data);
4112
4113         ev_request_free(&request);
4114
4115         return 0;
4116 }
4117 #endif
4118
4119 void radius_event_free(void)
4120 {
4121         /*
4122          *      FIXME: Stop all threads, or at least check that
4123          *      they're all waiting on the semaphore, and the queues
4124          *      are empty.
4125          */
4126
4127 #ifdef WITH_PROXY
4128         /*
4129          *      There are requests in the proxy hash that aren't
4130          *      referenced from anywhere else.  Remove them first.
4131          */
4132         if (proxy_list) {
4133                 fr_packet_list_walk(proxy_list, NULL, proxy_hash_cb);
4134                 fr_packet_list_free(proxy_list);
4135                 proxy_list = NULL;
4136         }
4137 #endif
4138
4139         fr_packet_list_walk(pl, NULL, request_hash_cb);
4140
4141         fr_packet_list_free(pl);
4142         pl = NULL;
4143
4144         fr_event_list_free(el);
4145 }
4146
4147 int radius_event_process(void)
4148 {
4149         if (!el) return 0;
4150
4151         return fr_event_loop(el);
4152 }
4153
4154 void radius_handle_request(REQUEST *request, RAD_REQUEST_FUNP fun)
4155 {
4156         request->options = RAD_REQUEST_OPTION_DEBUG2;
4157
4158         if (request_pre_handler(request)) {
4159                 rad_assert(fun != NULL);
4160                 rad_assert(request != NULL);
4161                 
4162                 if (request->server) RDEBUG("server %s {",
4163                                             request->server != NULL ?
4164                                             request->server : ""); 
4165                 fun(request);
4166
4167                 if (request->server) RDEBUG("} # server %s",
4168                                              request->server != NULL ?
4169                                             request->server : "");
4170
4171                 request_post_handler(request);
4172         }
4173
4174         DEBUG2("Going to the next request");
4175         return;
4176 }