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