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