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