free another tree
[freeradius.git] / src / main / request_list.c
1 /*
2  * request_list.c       Hide the handling of the REQUEST list from
3  *                      the main server.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * Copyright 2003-2004  The FreeRADIUS server project
22  */
23 static const char rcsid[] = "$Id$";
24
25 #include "autoconf.h"
26 #include "libradius.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "radiusd.h"
32 #include "rad_assert.h"
33 #include "request_list.h"
34 #include "radius_snmp.h"
35
36
37 /*
38  *      We keep the incoming requests in an array, indexed by ID.
39  *
40  *      Each array element contains a linked list of containers of
41  *      active requests, a count of the number of requests, and a time
42  *      at which the first request in the list must be serviced.
43  *
44  *      Note that we ALSO keep a tree view of the same data, below.
45  *      Both views are needed for the server to work optimally.
46  */
47 typedef struct REQNODE {
48         struct REQNODE *prev, *next;
49         REQUEST *req;
50 } REQNODE;
51
52 typedef struct REQUESTINFO {
53         REQNODE *first_request;
54         REQNODE *last_request;
55         int request_count;
56         time_t last_cleaned_list;
57 } REQUESTINFO;
58
59 static REQUESTINFO      request_list[256];
60
61 /*
62  *      Remember the next request at which we start walking
63  *      the list.
64  */
65 static REQUEST *last_request = NULL;
66
67 /*
68  *      It MAY make more sense here to key off of the packet ID, just
69  *      like the request_list.  Then again, saving another 8 lookups
70  *      (on average) isn't much of a problem.
71  *
72  *      The "request_cmp" function keys off of the packet ID first,
73  *      so the first 8 layers of the tree will be the fanned-out
74  *      tree for packet ID's.
75  */
76 static rbtree_t         *request_tree;
77
78 #ifdef HAVE_PTHREAD_H
79 static pthread_mutex_t  proxy_mutex;
80 #else
81 /*
82  *      This is easier than ifdef's throughout the code.
83  */
84 #define pthread_mutex_lock(_x)
85 #define pthread_mutex_unlock(_x)
86 #endif
87
88 /*
89  *      We keep track of packets we're proxying, keyed by
90  *      source socket, and destination ip/port, and Id.
91  */
92 static rbtree_t         *proxy_tree;
93
94 /*
95  *      We keep track of free/used Id's, by destination ip/port.
96  *
97  *      We need a different tree than above, because this one is NOT
98  *      keyed by Id.  Instead, we use this one to allocate Id's.
99  */
100 static rbtree_t         *proxy_id_tree;
101
102 /*
103  *      We keep the proxy FD's here.  The RADIUS Id's are marked
104  *      "allocated" per Id, via a bit per proxy FD.
105  */
106 static int              proxy_fds[32];
107
108 static uint32_t         proxy_ipaddr;
109
110 /*
111  *      We can use 256 RADIUS Id's per dst ipaddr/port, per server
112  *      socket.  So, to allocate them, we key off of dst ipaddr/port,
113  *      and then search the RADIUS Id's, looking for an unused socket.
114  *
115  *      We do NOT key off of socket fd's, here, either.  Instead,
116  *      we look for a free Id from a sockfd, any sockfd.
117  */
118 typedef struct proxy_id_t {
119         uint32_t        dst_ipaddr;
120         int             dst_port;
121
122         /*
123          *      FIXME: Allocate more proxy sockets when this gets full.
124          */
125         int             index;
126         uint32_t        mask;   /* of FD's we know about. */
127         uint32_t        id[1];  /* really id[256] */
128 } proxy_id_t;
129
130
131 /*
132  *      Find a matching entry in the proxy ID tree.
133  */
134 static int proxy_id_cmp(const void *one, const void *two)
135 {
136         const proxy_id_t *a = one;
137         const proxy_id_t *b = two;
138
139         /*
140          *      The following comparisons look weird, but it's
141          *      the only way to make the comparisons work.
142          */
143         if (a->dst_ipaddr < b->dst_ipaddr) return -1;
144         if (a->dst_ipaddr > b->dst_ipaddr) return +1;
145
146         if (a->dst_port < b->dst_port) return -1;
147         if (a->dst_port > b->dst_port) return +1;
148         
149         /*
150          *      Everything's equal.  Say so.
151          */
152         return 0;
153 }
154
155
156 /*
157  *      Compare two REQUEST data structures, based on a number
158  *      of criteria.
159  */
160 static int request_cmp(const void *one, const void *two)
161 {
162         const REQUEST *a = one;
163         const REQUEST *b = two;
164
165         /*
166          *      The following comparisons look weird, but it's
167          *      the only way to make the comparisons work.
168          */
169
170         /*
171          *      If the packets didn't arrive on the same socket,
172          *      they're not identical, no matter what their src/dst
173          *      ip/ports say.
174          */
175         if (a->packet->sockfd < b->packet->sockfd) return -1;
176         if (a->packet->sockfd > b->packet->sockfd) return +1;
177
178         if (a->packet->id < b->packet->id) return -1;
179         if (a->packet->id > b->packet->id) return +1;
180
181         if (a->packet->code < b->packet->code) return -1;
182         if (a->packet->code > b->packet->code) return +1;
183
184         if (a->packet->src_ipaddr < b->packet->src_ipaddr) return -1;
185         if (a->packet->src_ipaddr > b->packet->src_ipaddr) return +1;
186
187         if (a->packet->src_port < b->packet->src_port) return -1;
188         if (a->packet->src_port > b->packet->src_port) return +1;
189
190         /*
191          *      Hmm... we may be listening on IPADDR_ANY, in which case
192          *      the destination IP is important, too.
193          */
194         if (a->packet->dst_ipaddr < b->packet->dst_ipaddr) return -1;
195         if (a->packet->dst_ipaddr > b->packet->dst_ipaddr) return +1;
196
197         if (a->packet->dst_port < b->packet->dst_port) return -1;
198         if (a->packet->dst_port > b->packet->dst_port) return +1;
199
200         /*
201          *      Everything's equal.  Say so.
202          */
203         return 0;
204 }
205
206 /*
207  *      Compare two REQUEST data structures, based on a number
208  *      of criteria, for proxied packets.
209  */
210 static int proxy_cmp(const void *one, const void *two)
211 {
212         const REQUEST *a = one;
213         const REQUEST *b = two;
214
215         rad_assert(a->magic == REQUEST_MAGIC);
216         rad_assert(b->magic == REQUEST_MAGIC);
217
218         rad_assert(a->proxy != NULL);
219         rad_assert(b->proxy != NULL);
220
221         /*
222          *      The following code looks unreasonable, but it's
223          *      the only way to make the comparisons work.
224          */
225         if (a->proxy->sockfd < b->proxy->sockfd) return -1;
226         if (a->proxy->sockfd > b->proxy->sockfd) return +1;
227
228         if (a->proxy->id < b->proxy->id) return -1;
229         if (a->proxy->id > b->proxy->id) return +1;
230
231         /*
232          *      We've got to check packet codes, too.  But
233          *      this should be done later, by someone else...
234          */
235
236         if (a->proxy->dst_ipaddr < b->proxy->dst_ipaddr) return -1;
237         if (a->proxy->dst_ipaddr > b->proxy->dst_ipaddr) return +1;
238
239         if (a->proxy->dst_port < b->proxy->dst_port) return -1;
240         if (a->proxy->dst_port > b->proxy->dst_port) return +1;
241
242         /*
243          *      FIXME: Check the Proxy-State attribute, too.
244          *      This will help cut down on duplicates.
245          */
246
247         /*
248          *      Everything's equal.  Say so.
249          */
250         return 0;
251 }
252
253 void rl_free(void)
254 {
255         rbtree_free(request_tree);
256         rbtree_free(proxy_id_tree);
257         rbtree_free(proxy_tree);
258 }
259
260
261 /*
262  *      Initialize the request list.
263  */
264 int rl_init(void)
265 {
266         /*
267          *      Initialize the request_list[] array.
268          */
269         memset(request_list, 0, sizeof(request_list));
270
271         request_tree = rbtree_create(request_cmp, NULL, 0);
272         if (!request_tree) {
273                 rad_assert("FAIL" == NULL);
274         }
275
276         /*
277          *      Create the tree for managing proxied requests and
278          *      responses.
279          */
280         proxy_tree = rbtree_create(proxy_cmp, NULL, 1);
281         if (!proxy_tree) {
282                 rad_assert("FAIL" == NULL);
283         }
284
285         /*
286          *      Create the tree for allocating proxy ID's.
287          */
288         proxy_id_tree = rbtree_create(proxy_id_cmp, NULL, 0);
289         if (!proxy_id_tree) {
290                 rad_assert("FAIL" == NULL);
291         }
292
293 #ifdef HAVE_PTHREAD_H
294         /*
295          *      For now, always create the mutex.
296          *
297          *      Later, we can only create it if there are multiple threads.
298          */
299         if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
300                 radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
301                        strerror(errno));
302                 exit(1);
303         }
304 #endif
305
306         /*
307          *      The Id allocation table is done by bits, so we have
308          *      32 bits per Id.  These bits indicate which entry
309          *      in the proxy_fds array is used for that Id.
310          *
311          *      This design allows 256*32 = 8k requests to be
312          *      outstanding to a home server, before something goes
313          *      wrong.
314          */
315         {
316                 int i;
317                 rad_listen_t *listener;
318
319                 /*
320                  *      Mark the Fd's as unused.
321                  */
322                 for (i = 0; i < 32; i++) proxy_fds[i] = -1;
323
324                 for (listener = mainconfig.listen;
325                      listener != NULL;
326                      listener = listener->next) {
327                         if (listener->type == RAD_LISTEN_PROXY) {
328                                 proxy_ipaddr = listener->ipaddr;
329                                 proxy_fds[listener->fd & 0x1f] = listener->fd;
330                                 break;
331                         }
332                 }
333         }
334
335         return 1;
336 }
337
338
339 /*
340  *      Delete a request from the proxy trees.
341  */
342 static void rl_delete_proxy(REQUEST *request, rbnode_t *node)
343 {
344         proxy_id_t      myid, *entry;
345
346         rad_assert(node != NULL);
347
348         rbtree_delete(proxy_tree, node);
349         
350         myid.dst_ipaddr = request->proxy->dst_ipaddr;
351         myid.dst_port = request->proxy->dst_port;
352
353         /*
354          *      Find the Id in the array of allocated Id's,
355          *      and delete it.
356          */
357         entry = rbtree_finddata(proxy_id_tree, &myid);
358         if (entry) {
359                 int i;
360
361                 DEBUG3(" proxy: de-allocating %08x:%d %d",
362                        entry->dst_ipaddr,
363                        entry->dst_port,
364                        request->proxy->id);
365
366                 /*
367                  *      Find the proxy socket associated with this
368                  *      Id.  We loop over all 32 proxy fd's, but we
369                  *      partially index by proxy fd's, which means
370                  *      that we almost always break out of the loop
371                  *      quickly.
372                  */
373                 for (i = 0; i < 32; i++) {
374                         int offset;
375
376                         offset = (request->proxy->sockfd + i) & 0x1f;
377                   
378                         if (proxy_fds[offset] == request->proxy->sockfd) {
379                                 
380                                 entry->id[request->proxy->id] &= ~(1 << offset);
381                                 break;
382                         }
383                 } /* else die horribly? */
384         } else {
385                 /*
386                  *      Hmm... not sure what to do here.
387                  */
388                 DEBUG3(" proxy: FAILED TO FIND %08x:%d %d",
389                        myid.dst_ipaddr,
390                        myid.dst_port,
391                        request->proxy->id);
392         }
393 }
394
395
396 /*
397  *      Delete a particular request.
398  */
399 void rl_delete(REQUEST *request)
400 {
401         int id;
402         REQNODE *prev, *next;
403
404         prev = ((REQNODE *) request->container)->prev;
405         next = ((REQNODE *) request->container)->next;
406
407         id = request->packet->id;
408
409         /*
410          *      Update the last request we touched.
411          *
412          *      This is so the periodic "walk & clean list"
413          *      function, below, doesn't walk over all requests
414          *      all of the time.  Rather, it tries to amortize
415          *      the cost...
416          */
417         if (last_request == request) {
418                 last_request = rl_next(last_request);
419         }
420
421
422         if (prev == NULL) {
423                 request_list[id].first_request = next;
424         } else {
425                 prev->next = next;
426         }
427
428         if (next == NULL) {
429                 request_list[id].last_request = prev;
430         } else {
431                 next->prev = prev;
432         }
433
434         free(request->container);
435
436 #ifdef WITH_SNMP
437         /*
438          *      Update the SNMP statistics.
439          *
440          *      Note that we do NOT do this in rad_respond(),
441          *      as that function is called from child threads.
442          *      Instead, we update the stats when a request is
443          *      deleted, because only the main server thread calls
444          *      this function...
445          */
446         if (mainconfig.do_snmp) {
447                 switch (request->reply->code) {
448                 case PW_AUTHENTICATION_ACK:
449                   rad_snmp.auth.total_responses++;
450                   rad_snmp.auth.total_access_accepts++;
451                   break;
452
453                 case PW_AUTHENTICATION_REJECT:
454                   rad_snmp.auth.total_responses++;
455                   rad_snmp.auth.total_access_rejects++;
456                   break;
457
458                 case PW_ACCESS_CHALLENGE:
459                   rad_snmp.auth.total_responses++;
460                   rad_snmp.auth.total_access_challenges++;
461                   break;
462
463                 case PW_ACCOUNTING_RESPONSE:
464                   rad_snmp.acct.total_responses++;
465                   break;
466
467                 default:
468                         break;
469                 }
470         }
471 #endif
472
473         /*
474          *      Delete the request from the tree.
475          */
476         {
477                 rbnode_t *node;
478
479                 node = rbtree_find(request_tree, request);
480                 rad_assert(node != NULL);
481                 rbtree_delete(request_tree, node);
482
483
484                 /*
485                  *      If there's a proxied packet, and we're still
486                  *      waiting for a reply, then delete the packet
487                  *      from the list of outstanding proxied requests.
488                  */
489                 if (request->proxy &&
490                     (request->proxy_outstanding > 0)) {
491                         pthread_mutex_lock(&proxy_mutex);
492                         node = rbtree_find(proxy_tree, request);
493                         rl_delete_proxy(request, node);
494                         pthread_mutex_unlock(&proxy_mutex);
495                 }
496         }
497
498         request_free(&request);
499         request_list[id].request_count--;
500
501 }
502
503 /*
504  *      Add a request to the request list.
505  */
506 void rl_add(REQUEST *request)
507 {
508         int id = request->packet->id;
509         REQNODE *node;
510
511         rad_assert(request->container == NULL);
512
513         request->container = rad_malloc(sizeof(REQNODE));
514         node = (REQNODE *) request->container;
515         node->req = request;
516
517         node->prev = NULL;
518         node->next = NULL;
519
520         if (!request_list[id].first_request) {
521                 rad_assert(request_list[id].request_count == 0);
522
523                 request_list[id].first_request = node;
524                 request_list[id].last_request = node;
525         } else {
526                 rad_assert(request_list[id].request_count != 0);
527
528                 node->prev = request_list[id].last_request;
529                 request_list[id].last_request->next = node;
530                 request_list[id].last_request = node;
531         }
532
533         /*
534          *      Insert the request into the tree.
535          */
536         if (rbtree_insert(request_tree, request) == 0) {
537                 rad_assert("FAIL" == NULL);
538         }
539
540         request_list[id].request_count++;
541 }
542
543 /*
544  *      Look up a particular request, using:
545  *
546  *      Request ID, request code, source IP, source port,
547  *
548  *      Note that we do NOT use the request vector to look up requests.
549  *
550  *      We MUST NOT have two requests with identical (id/code/IP/port), and
551  *      different vectors.  This is a serious error!
552  */
553 REQUEST *rl_find(RADIUS_PACKET *packet)
554 {
555         REQUEST myrequest;
556
557         myrequest.packet = packet;
558
559         return rbtree_finddata(request_tree, &myrequest);
560 }
561
562 /*
563  *      See mainconfig.c
564  */
565 extern int proxy_new_listener(void);
566
567 /*
568  *      Add an entry to the proxy tree.
569  *
570  *      This is the ONLY function in this source file which may be called
571  *      from a child thread.  It therefore needs mutexes...
572  */
573 int rl_add_proxy(REQUEST *request)
574 {
575         int             i, found, proxy;
576         uint32_t        mask;
577         proxy_id_t      myid, *entry;
578
579         myid.dst_ipaddr = request->proxy->dst_ipaddr;
580         myid.dst_port = request->proxy->dst_port;
581
582         /*
583          *      Proxied requests get sent out the proxy FD ONLY.
584          *
585          *      FIXME: Once we allocate multiple proxy FD's, move this
586          *      code to below, so we can have more than 256 requests
587          *      outstanding.
588          */
589         request->proxy_outstanding = 1;
590
591         pthread_mutex_lock(&proxy_mutex);
592
593         /*
594          *      Assign a proxy ID.
595          */
596         entry = rbtree_finddata(proxy_id_tree, &myid);
597         if (!entry) {   /* allocate it */
598                 entry = rad_malloc(sizeof(*entry) + sizeof(entry->id) * 255);
599                 
600                 entry->dst_ipaddr = request->proxy->dst_ipaddr;
601                 entry->dst_port = request->proxy->dst_port;
602                 entry->index = 0;
603
604                 DEBUG3(" proxy: creating %08x:%d",
605                        entry->dst_ipaddr,
606                        entry->dst_port);
607                 
608                 /*
609                  *      Insert the new home server entry into
610                  *      the tree.
611                  *
612                  *      FIXME: We don't (currently) delete the
613                  *      entries, so this is technically a
614                  *      memory leak.
615                  */
616                 if (rbtree_insert(proxy_id_tree, entry) == 0) {
617                         DEBUG2("ERROR: Failed to insert entry into proxy Id tree");
618                         free(entry);
619                         return 0;
620                 }
621
622                 /*
623                  *      Clear out bits in the array which DO have
624                  *      proxy Fd's associated with them.  We do this
625                  *      by getting the mask of bits which have proxy
626                  *      fd's...  */
627                 mask = 0;
628                 for (i = 0; i < 32; i++) {
629                         if (proxy_fds[i] != -1) {
630                                 mask |= (1 << i);
631                         }
632                 }
633                 rad_assert(mask != 0);
634
635                 /*
636                  *      Set bits here indicate that the Fd is in use.
637                  */
638                 entry->mask = mask;
639
640                 mask = ~mask;
641
642                 /*
643                  *      Set the bits which are unused (and therefore
644                  *      allocated).  The clear bits indicate that the Id
645                  *      for that FD is unused.
646                  */
647                 for (i = 0; i < 256; i++) {
648                         entry->id[i] = mask;
649                 }
650         } /* else the entry already existed in the proxy Id tree */
651         
652  retry:
653         /*
654          *      Try to find a free Id.
655          */
656         found = -1;
657         for (i = 0; i < 256; i++) {
658                 /*
659                  *      Some bits are still zero..
660                  */
661                 if (entry->id[(i + entry->index) & 0xff] != (uint32_t) ~0) {
662                         found = (i + entry->index) & 0xff;
663                         break;
664                 }
665
666                 /*
667                  *      Hmm... do we want to re-use Id's, when we
668                  *      haven't seen all of the responses?
669                  */
670         }
671         
672         /*
673          *      No free Id, try to get a new FD.
674          */
675         if (found < 0) {
676                 /*
677                  *      First, see if there were FD's recently allocated,
678                  *      which we don't know about.
679                  */
680                 mask = 0;
681                 for (i = 0; i < 32; i++) {
682                         if (proxy_fds[i] < 0) continue;
683
684                         mask |= (1 << i);
685                 }
686
687                 /*
688                  *      There ARE more FD's than we know about.
689                  *      Update the masks for Id's, and re-try.
690                  */
691                 if (entry->mask != mask) {
692                         /*
693                          *      New mask always has more bits than
694                          *      the old one, but never fewer bits.
695                          */
696                         rad_assert((entry->mask & mask) == entry->mask);
697
698                         /*
699                          *      Clear the bits we already know about,
700                          *      and then or in those bits into the
701                          *      global mask.
702                          */
703                         mask ^= entry->mask;
704                         entry->mask |= mask;
705                         mask = ~mask;
706                         
707                         /*
708                          *      Clear the bits in the Id's for the new
709                          *      FD's.
710                          */
711                         for (i = 0; i < 256; i++) {
712                                 entry->id[i] &= mask;
713                         }
714                         
715                         /*
716                          *      And try again to allocate an Id.
717                          */
718                         goto retry;
719                 } /* else no new Fd's were allocated. */
720
721                 /*
722                  *      If all Fd's are allocated, die.
723                  */
724                 if (~mask == 0) {
725                         radlog(L_ERR|L_CONS, "ERROR: More than 8000 proxied requests outstanding for home server %08x:%d",
726                                ntohs(entry->dst_ipaddr), entry->dst_port);
727                         return 0;
728                 }
729                 
730                 /*
731                  *      Allocate a new proxy Fd.  This function adds it
732                  *      into the list of listeners.
733                  */
734                 proxy = proxy_new_listener();
735                 if (proxy < 0) {
736                         DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
737                         return 0;
738                 }
739
740                 /*
741                  *
742                  */
743                 found = -1;
744                 for (i = 0; i < 32; i++) {
745                         /*
746                          *      Found a free entry.  Save the socket,
747                          *      and remember where we saved it.
748                          */
749                         if (proxy_fds[(proxy + i) & 0x1f] == -1) {
750                                 proxy_fds[(proxy + i) & 0x1f] = proxy;
751                                 found = (proxy + i) & 0x1f;
752                                 break;
753                         }
754                 }
755                 rad_assert(found >= 0); /* i.e. the mask had free bits. */
756
757                 mask = 1 << found;
758                 entry->mask |= mask;
759                 mask = ~mask;
760
761                 /*
762                  *      Clear the relevant bits in the mask.
763                  */
764                 for (i = 0; i < 256; i++) {
765                         entry->id[i] &= mask;
766                 }
767
768                 /*
769                  *      Pick a random Id to start from, as we've
770                  *      just guaranteed that it's free.
771                  */
772                 found = lrad_rand() & 0xff;
773         }
774         
775         /*
776          *      Mark next (hopefully unused) entry.
777          */
778         entry->index = (found + 1) & 0xff;
779         
780         /*
781          *      We now have to find WHICH proxy fd to use.
782          */
783         proxy = -1;
784         for (i = 0; i < 32; i++) {
785                 /*
786                  *      FIXME: pick a random socket to use?
787                  */
788                 if ((entry->id[found] & (1 << i)) == 0) {
789                         proxy = i;
790                         break;
791                 }
792         }
793
794         /*
795          *      There was no bit clear, which we had just checked above...
796          */
797         rad_assert(proxy != -1);
798
799         /*
800          *      Mark the Id as allocated, for thei Fd.
801          */
802         entry->id[found] |= (1 << proxy);
803         request->proxy->id = found;
804         request->proxy->src_ipaddr = proxy_ipaddr;
805
806         rad_assert(proxy_fds[proxy] != -1);
807         request->proxy->sockfd = proxy_fds[proxy];
808
809         DEBUG3(" proxy: allocating %08x:%d %d",
810                entry->dst_ipaddr,
811                entry->dst_port,
812                request->proxy->id);
813         
814         if (!rbtree_insert(proxy_tree, request)) {
815                 DEBUG2("ERROR: Failed to insert entry into proxy tree");
816                 return 0;
817         }
818         
819         pthread_mutex_unlock(&proxy_mutex);
820
821         return 1;
822 }
823
824
825 /*
826  *      Look up a particular request, using:
827  *
828  *      Request Id, request code, source IP, source port,
829  *
830  *      Note that we do NOT use the request vector to look up requests.
831  *
832  *      We MUST NOT have two requests with identical (id/code/IP/port), and
833  *      different vectors.  This is a serious error!
834  */
835 REQUEST *rl_find_proxy(RADIUS_PACKET *packet)
836 {
837         rbnode_t        *node;
838         REQUEST         myrequest, *maybe = NULL;
839         RADIUS_PACKET   myproxy;
840
841         /*
842          *      If we use the socket FD as an indicator,
843          *      then that implicitely contains information
844          *      as to our src ipaddr/port, so we don't need
845          *      to use that in the comparisons.
846          */
847         myproxy.sockfd = packet->sockfd;
848         myproxy.id = packet->id;
849         myproxy.dst_ipaddr = packet->src_ipaddr;
850         myproxy.dst_port = packet->src_port;
851
852 #ifndef NDEBUG
853         myrequest.magic = REQUEST_MAGIC;
854 #endif
855         myrequest.proxy = &myproxy;
856
857         pthread_mutex_lock(&proxy_mutex);
858         node = rbtree_find(proxy_tree, &myrequest);
859
860         if (node) {
861                 maybe = rbtree_node2data(proxy_tree, node);
862                 rad_assert(maybe->proxy_outstanding > 0);
863                 maybe->proxy_outstanding--;
864                 
865                 /*
866                  *      Received all of the replies we expect.
867                  *      delete it from both trees.
868                  */
869                 if (maybe->proxy_outstanding == 0) {
870                         rl_delete_proxy(&myrequest, node);
871                 }
872         }
873         pthread_mutex_unlock(&proxy_mutex);
874
875         return maybe;
876 }
877
878
879 /*
880  *      Walk over all requests, performing a callback for each request.
881  */
882 int rl_walk(RL_WALK_FUNC walker, void *data)
883 {
884         int id, rcode;
885         REQNODE *curreq, *next;
886
887         /*
888          *      Walk over all 256 ID's.
889          */
890         for (id = 0; id < 256; id++) {
891
892                 /*
893                  *      Walk over the request list for each ID.
894                  */
895                 for (curreq = request_list[id].first_request;
896                                 curreq != NULL ;
897                                 curreq = next) {
898                         /*
899                          *      The callback MIGHT delete the current
900                          *      request, so we CANNOT depend on curreq->next
901                          *      to be there, when going to the next element
902                          *      in the 'for' loop.
903                          */
904                         next = curreq->next;
905
906                         rcode = walker(curreq->req, data);
907                         if (rcode != RL_WALK_CONTINUE) {
908                                 return rcode;
909                         }
910                 }
911         }
912
913         return 0;
914 }
915
916
917 /*
918  *      Walk from one request to the next.
919  */
920 REQUEST *rl_next(REQUEST *request)
921 {
922         int id, start_id;
923         int count;
924
925         /*
926          *      If we were passed a request, then go to the "next" one.
927          */
928         if (request != NULL) {
929                 rad_assert(request->magic == REQUEST_MAGIC);
930
931                 /*
932                  *      It has a "next", return it.
933                  */
934                 if (((REQNODE *)request->container)->next != NULL) {
935                         return ((REQNODE *)request->container)->next->req;
936                 } else {
937                         /*
938                          *      No "next", increment the ID, and look
939                          *      at that one.
940                          */
941                         start_id = request->packet->id + 1;
942                         start_id &= 0xff;
943                         count = 255;
944                 }
945         } else {
946                 /*
947                  *      No input request, start looking at ID 0.
948                  */
949                 start_id = 0;
950                 count = 256;
951         }
952
953         /*
954          *      Check all ID's, wrapping around at 255.
955          */
956         for (id = start_id; id < (start_id + count); id++) {
957
958                 /*
959                  *      This ID has a request, return it.
960                  */
961                 if (request_list[id & 0xff].first_request != NULL) {
962                         rad_assert(request_list[id&0xff].first_request->req != request);
963
964                         return request_list[id & 0xff].first_request->req;
965                 }
966         }
967
968         /*
969          *      No requests at all in the list. Nothing to do.
970          */
971         DEBUG3("rl_next:  returning NULL");
972         return NULL;
973 }
974
975
976 /*
977  *      Return the number of requests in the request list.
978  */
979 int rl_num_requests(void)
980 {
981         int id;
982         int request_count = 0;
983
984         for (id = 0; id < 256; id++) {
985                 request_count += request_list[id].request_count;
986         }
987
988         return request_count;
989 }
990
991
992 typedef struct rl_walk_t {
993         time_t  now;
994         time_t  smallest;
995 } rl_walk_t;
996
997
998 /*
999  *  Refresh a request, by using proxy_retry_delay, cleanup_delay,
1000  *  max_request_time, etc.
1001  *
1002  *  When walking over the request list, all of the per-request
1003  *  magic is done here.
1004  */
1005 static int refresh_request(REQUEST *request, void *data)
1006 {
1007         rl_walk_t *info = (rl_walk_t *) data;
1008         time_t difference;
1009         child_pid_t child_pid;
1010
1011         rad_assert(request->magic == REQUEST_MAGIC);
1012
1013         /*
1014          *  If the request is marked as a delayed reject, AND it's
1015          *  time to send the reject, then do so now.
1016          */
1017         if (request->finished &&
1018             ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) != 0)) {
1019                 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
1020
1021                 difference = info->now - request->timestamp;
1022                 if (difference >= (time_t) mainconfig.reject_delay) {
1023
1024                         /*
1025                          *  Clear the 'delayed reject' bit, so that we
1026                          *  don't do this again.
1027                          */
1028                         request->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
1029                         rad_send(request->reply, request->packet,
1030                                  request->secret);
1031                 }
1032         }
1033
1034         /*
1035          *  If the request has finished processing, AND it's child has
1036          *  been cleaned up, AND it's time to clean up the request,
1037          *  OR, it's an accounting request.  THEN, go delete it.
1038          *
1039          *  If this is a request which had the "don't cache" option
1040          *  set, then delete it immediately, as it CANNOT have a
1041          *  duplicate.
1042          */
1043         if (request->finished &&
1044             ((request->timestamp + mainconfig.cleanup_delay <= info->now) ||
1045              ((request->options & RAD_REQUEST_OPTION_DONT_CACHE) != 0))) {
1046                 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
1047
1048                 /*
1049                  *  Request completed, delete it, and unlink it
1050                  *  from the currently 'alive' list of requests.
1051                  */
1052                 DEBUG2("Cleaning up request %d ID %d with timestamp %08lx",
1053                                 request->number, request->packet->id,
1054                                 (unsigned long) request->timestamp);
1055
1056                 /*
1057                  *  Delete the request.
1058                  */
1059                 rl_delete(request);
1060                 return RL_WALK_CONTINUE;
1061         }
1062
1063         /*
1064          *  Maybe the child process handling the request has hung:
1065          *  kill it, and continue.
1066          */
1067         if ((request->timestamp + mainconfig.max_request_time) <= info->now) {
1068                 int number;
1069
1070                 child_pid = request->child_pid;
1071                 number = request->number;
1072
1073                 /*
1074                  *      There MUST be a RAD_PACKET reply.
1075                  */
1076                 rad_assert(request->reply != NULL);
1077
1078                 /*
1079                  *      If we've tried to proxy the request, and
1080                  *      the proxy server hasn't responded, then
1081                  *      we send a REJECT back to the caller.
1082                  *
1083                  *      For safety, we assert that there is no child
1084                  *      handling the request.  If the assertion fails,
1085                  *      it means that we've sent a proxied request to
1086                  *      the home server, and the child thread is still
1087                  *      sitting on the request!
1088                  */
1089                 if (request->proxy && !request->proxy_reply) {
1090                         rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
1091
1092                         radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s:%d",
1093                                request->number,
1094                                client_name(request->packet->src_ipaddr),
1095                                request->packet->src_port);
1096                         request_reject(request);
1097                         request->finished = TRUE;
1098                         return RL_WALK_CONTINUE;
1099                 }
1100
1101                 if (mainconfig.kill_unresponsive_children) {
1102                         if (child_pid != NO_SUCH_CHILD_PID) {
1103                                 /*
1104                                  *  This request seems to have hung
1105                                  *   - kill it
1106                                  */
1107 #ifdef HAVE_PTHREAD_H
1108                                 radlog(L_ERR, "Killing unresponsive thread for request %d",
1109                                        request->number);
1110                                 pthread_cancel(child_pid);
1111 #endif
1112                         } /* else no proxy reply, quietly fail */
1113
1114                         /*
1115                          *      Maybe we haven't killed it.  In that
1116                          *      case, print a warning.
1117                          */
1118                 } else if ((child_pid != NO_SUCH_CHILD_PID) &&
1119                            ((request->options & RAD_REQUEST_OPTION_LOGGED_CHILD) == 0)) {
1120                         radlog(L_ERR, "WARNING: Unresponsive child (id %lu) for request %d",
1121                                (unsigned long)child_pid, number);
1122
1123                         /*
1124                          *  Set the option that we've sent a log message,
1125                          *  so that we don't send more than one message
1126                          *  per request.
1127                          */
1128                         request->options |= RAD_REQUEST_OPTION_LOGGED_CHILD;
1129                 }
1130
1131                 /*
1132                  *  Send a reject message for the request, mark it
1133                  *  finished, and forget about the child.
1134                  */
1135                 request_reject(request);
1136                 request->child_pid = NO_SUCH_CHILD_PID;
1137                 if (mainconfig.kill_unresponsive_children)
1138                         request->finished = TRUE;
1139                 return RL_WALK_CONTINUE;
1140         } /* the request has been in the queue for too long */
1141
1142         /*
1143          *  If the request is still being processed, then due to the
1144          *  above check, it's still within it's time limit.  In that
1145          *  case, don't do anything.
1146          */
1147         if (request->child_pid != NO_SUCH_CHILD_PID) {
1148                 return RL_WALK_CONTINUE;
1149         }
1150
1151         /*
1152          *  The request is finished.
1153          */
1154         if (request->finished) goto setup_timeout;
1155
1156         /*
1157          *  We're not proxying requests at all.
1158          */
1159         if (!mainconfig.proxy_requests) goto setup_timeout;
1160
1161         /*
1162          *  We're proxying synchronously, so we don't retry it here.
1163          *  Some other code takes care of retrying the proxy requests.
1164          */
1165         if (mainconfig.proxy_synchronous) goto setup_timeout;
1166
1167         /*
1168          *  The proxy retry delay is zero, meaning don't retry.
1169          */
1170         if (mainconfig.proxy_retry_delay == 0) goto setup_timeout;
1171
1172         /*
1173          *  There is no proxied request for this packet, so there's
1174          *  no proxy retries.
1175          */
1176         if (!request->proxy) goto setup_timeout;
1177
1178         /*
1179          *  We've already seen the proxy reply, so we don't need
1180          *  to send another proxy request.
1181          */
1182         if (request->proxy_reply) goto setup_timeout;
1183
1184         /*
1185          *  It's not yet time to re-send this proxied request.
1186          */
1187         if (request->proxy_next_try > info->now) goto setup_timeout;
1188
1189         /*
1190          *  If the proxy retry count is zero, then
1191          *  we've sent the last try, and have NOT received
1192          *  a reply from the end server.  In that case,
1193          *  we don't bother trying again, but just mark
1194          *  the request as finished, and go to the next one.
1195          */
1196         if (request->proxy_try_count == 0) {
1197                 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
1198                 request_reject(request);
1199                 realm_disable(request->proxy->dst_ipaddr,request->proxy->dst_port);
1200                 request->finished = TRUE;
1201                 goto setup_timeout;
1202         }
1203
1204         /*
1205          *  We're trying one more time, so count down
1206          *  the tries, and set the next try time.
1207          */
1208         request->proxy_try_count--;
1209         request->proxy_next_try = info->now + mainconfig.proxy_retry_delay;
1210
1211         /* Fix up Acct-Delay-Time */
1212         if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
1213                 VALUE_PAIR *delaypair;
1214                 delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
1215
1216                 if (!delaypair) {
1217                         delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1218                         if (!delaypair) {
1219                                 radlog(L_ERR|L_CONS, "no memory");
1220                                 exit(1);
1221                         }
1222                         pairadd(&request->proxy->vps, delaypair);
1223                 }
1224                 delaypair->lvalue = info->now - request->proxy->timestamp;
1225
1226                 /* Must recompile the valuepairs to wire format */
1227                 free(request->proxy->data);
1228                 request->proxy->data = NULL;
1229         } /* proxy accounting request */
1230
1231         /*
1232          *  Assert that we have NOT seen the proxy reply yet.
1233          *
1234          *  If we HAVE seen it, then we SHOULD NOT be bugging the
1235          *  home server!
1236          */
1237         rad_assert(request->proxy_reply == NULL);
1238
1239         /*
1240          *  Send the proxy packet.
1241          */
1242         request->proxy_outstanding++;
1243         rad_send(request->proxy, NULL, request->proxysecret);
1244
1245 setup_timeout:
1246         /*
1247          *  Don't do more long-term checks, if we've got to wake
1248          *  up now.
1249          */
1250         if (info->smallest == 0) {
1251                 return RL_WALK_CONTINUE;
1252         }
1253
1254         /*
1255          *  The request is finished.  Wake up when it's time to
1256          *  clean it up.
1257          */
1258         if (request->finished) {
1259                 difference = (request->timestamp + mainconfig.cleanup_delay) - info->now;
1260
1261                 /*
1262                  *  If the request is marked up to be rejected later,
1263                  *  then wake up later.
1264                  */
1265                 if ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) != 0) {
1266                         if (difference >= (time_t) mainconfig.reject_delay) {
1267                                 difference = (time_t) mainconfig.reject_delay;
1268                         }
1269                 }
1270
1271         } else if (request->proxy && !request->proxy_reply) {
1272                 /*
1273                  *  The request is NOT finished, but there is an
1274                  *  outstanding proxy request, with no matching
1275                  *  proxy reply.
1276                  *
1277                  *  Wake up when it's time to re-send
1278                  *  the proxy request.
1279                  *
1280                  *  But in synchronous proxy, we don't retry but we update
1281                  *  the next retry time as NAS has not resent the request
1282                  *  in the given retry window.
1283                  */
1284                 if (mainconfig.proxy_synchronous) {
1285                         /*
1286                          *      If the retry_delay * count has passed,
1287                          *      then mark the realm dead.
1288                          */
1289                         if (info->now > (request->timestamp + (mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count))) {
1290                                 rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
1291                                 request_reject(request);
1292                                 
1293                                 realm_disable(request->proxy->dst_ipaddr,
1294                                               request->proxy->dst_port);
1295                                 request->finished = TRUE;
1296                                 goto setup_timeout;
1297                         }
1298                         request->proxy_next_try = info->now + mainconfig.proxy_retry_delay;
1299                 }
1300                 difference = request->proxy_next_try - info->now;
1301         } else {
1302                 /*
1303                  *  The request is NOT finished.
1304                  *
1305                  *  Wake up when it's time to kill the errant
1306                  *  thread/process.
1307                  */
1308                 difference = (request->timestamp + mainconfig.max_request_time) - info->now;
1309         }
1310
1311         /*
1312          *  If the server is CPU starved, then we CAN miss a time
1313          *  for servicing requests.  In which case the 'difference'
1314          *  value will be negative.  select() doesn't like that,
1315          *  so we fix it.
1316          */
1317         if (difference < 0) {
1318                 difference = 0;
1319         }
1320
1321         /*
1322          *  Update the 'smallest' time.
1323          */
1324         if ((info->smallest < 0) ||
1325                 (difference < info->smallest)) {
1326                 info->smallest = difference;
1327         }
1328
1329         return RL_WALK_CONTINUE;
1330 }
1331
1332
1333 /*
1334  *  Clean up the request list, every so often.
1335  *
1336  *  This is done by walking through ALL of the list, and
1337  *  - marking any requests which are finished, and expired
1338  *  - killing any processes which are NOT finished after a delay
1339  *  - deleting any marked requests.
1340  */
1341 struct timeval *rl_clean_list(time_t now)
1342 {
1343         /*
1344          *  Static variables, so that we don't do all of this work
1345          *  more than once per second.
1346          *
1347          *  Note that we have 'tv' and 'last_tv'.  'last_tv' is
1348          *  pointed to by 'last_tv_ptr', and depending on the
1349          *  system implementation of select(), it MAY be modified.
1350          *
1351          *  In that was, we want to use the ORIGINAL value, from
1352          *  'tv', and wipe out the (possibly modified) last_tv.
1353          */
1354         static time_t last_cleaned_list = 0;
1355         static struct timeval tv, *last_tv_ptr = NULL;
1356         static struct timeval last_tv;
1357
1358         rl_walk_t info;
1359
1360         info.now = now;
1361         info.smallest = -1;
1362
1363         /*
1364          *  If we've already set up the timeout or cleaned the
1365          *  request list this second, then don't do it again.  We
1366          *  simply return the sleep delay from last time.
1367          *
1368          *  Note that if we returned NULL last time, there was nothing
1369          *  to do.  BUT we've been woken up since then, which can only
1370          *  happen if we received a packet.  And if we've received a
1371          *  packet, then there's some work to do in the future.
1372          *
1373          *  FIXME: We can probably use gettimeofday() for finer clock
1374          *  resolution, as the current method will cause it to sleep
1375          *  too long...
1376          */
1377         if ((last_tv_ptr != NULL) &&
1378             (last_cleaned_list == now) &&
1379             (tv.tv_sec != 0)) {
1380                 int i;
1381
1382                 /*
1383                  *  If we're NOT walking the entire request list,
1384                  *  then we want to iteratively check the request
1385                  *  list.
1386                  *
1387                  *  If there is NO previous request, go look for one.
1388                  */
1389                 if (!last_request)
1390                         last_request = rl_next(last_request);
1391
1392                 /*
1393                  *  On average, there will be one request per
1394                  *  'cleanup_delay' requests, which needs to be
1395                  *  serviced.
1396                  *
1397                  *  And only do this servicing, if we have a request
1398                  *  to service.
1399                  */
1400                 if (last_request)
1401                         for (i = 0; i < mainconfig.cleanup_delay; i++) {
1402                                 REQUEST *next;
1403
1404                                 /*
1405                                  *  This function call MAY delete the
1406                                  *  request pointed to by 'last_request'.
1407                                  */
1408                                 next = rl_next(last_request);
1409                                 refresh_request(last_request, &info);
1410                                 last_request = next;
1411
1412                                 /*
1413                                  *  Nothing to do any more, exit.
1414                                  */
1415                                 if (!last_request)
1416                                         break;
1417                         }
1418
1419                 last_tv = tv;
1420                 DEBUG2("Waking up in %d seconds...",
1421                                 (int) last_tv_ptr->tv_sec);
1422                 return last_tv_ptr;
1423         }
1424         last_cleaned_list = now;
1425         last_request = NULL;
1426         DEBUG2("--- Walking the entire request list ---");
1427
1428         /*
1429          *  Hmmm... this is Big Magic.  We make it seem like
1430          *  there's an additional second to wait, for a whole
1431          *  host of reasons which I can't explain adequately,
1432          *  but which cause the code to Just Work Right.
1433          */
1434         info.now--;
1435
1436         rl_walk(refresh_request, &info);
1437
1438         /*
1439          *  We haven't found a time at which we need to wake up.
1440          *  Return NULL, so that the select() call will sleep forever.
1441          */
1442         if (info.smallest < 0) {
1443                 /*
1444                  *  If we're not proxying, then there really isn't anything
1445                  *  to do.
1446                  *
1447                  *  If we ARE proxying, then we can safely sleep
1448                  *  forever if we're told to NEVER send proxy retries
1449                  *  ourselves, until the NAS kicks us again.
1450                  *
1451                  *  Otherwise, there are no outstanding requests, then
1452                  *  we can sleep forever.  This happens when we get
1453                  *  woken up with a bad packet.  It's discarded, so if
1454                  *  there are no live requests, we can safely sleep
1455                  *  forever.
1456                  */
1457                 if ((!mainconfig.proxy_requests) ||
1458                     mainconfig.proxy_synchronous ||
1459                     (rl_num_requests() == 0)) {
1460                         DEBUG2("Nothing to do.  Sleeping until we see a request.");
1461                         last_tv_ptr = NULL;
1462                         return NULL;
1463                 }
1464
1465                 /*
1466                  *  We ARE proxying.  In that case, we avoid a race condition
1467                  *  where a child thread handling a request proxies the
1468                  *  packet, and sets the retry delay.  In that case, we're
1469                  *  supposed to wake up in N seconds, but we can't, as
1470                  *  we're sleeping forever.
1471                  *
1472                  *  Instead, we prevent the problem by waking up anyhow
1473                  *  at the 'proxy_retry_delay' time, even if there's
1474                  *  nothing to do.  In the worst case, this will cause
1475                  *  the server to wake up every N seconds, to do a small
1476                  *  amount of unnecessary work.
1477                  */
1478                 info.smallest = mainconfig.proxy_retry_delay;
1479         }
1480         /*
1481          *  Set the time (in seconds) for how long we're
1482          *  supposed to sleep.
1483          */
1484         tv.tv_sec = info.smallest;
1485         tv.tv_usec = 0;
1486         DEBUG2("Waking up in %d seconds...", (int) info.smallest);
1487
1488         /*
1489          *  Remember how long we should sleep for.
1490          */
1491         last_tv = tv;
1492         last_tv_ptr = &last_tv;
1493         return last_tv_ptr;
1494 }