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