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