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