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