Cleaned up detail file reader. It should now be much more
[freeradius.git] / src / main / listen.c
1 /*
2  * listen.c     Handle socket stuff
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2005,2006  The FreeRADIUS server project
21  * Copyright 2005  Alan DeKok <aland@ox.org>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/radius_snmp.h>
29 #include <freeradius-devel/modules.h>
30 #include <freeradius-devel/rad_assert.h>
31 #include <freeradius-devel/vqp.h>
32
33 #include <sys/resource.h>
34
35 #ifdef HAVE_NET_IF_H
36 #include <net/if.h>
37 #endif
38
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42
43 #include <fcntl.h>
44
45 #define USEC (1000000)
46
47 /*
48  *      We'll use this below.
49  */
50 typedef int (*rad_listen_parse_t)(const char *, int, CONF_SECTION *, rad_listen_t *);
51 typedef void (*rad_listen_free_t)(rad_listen_t *);
52
53 typedef struct rad_listen_master_t {
54         rad_listen_parse_t      parse;
55         rad_listen_free_t       free;
56         rad_listen_recv_t       recv;
57         rad_listen_send_t       send;
58         rad_listen_print_t      print;
59         rad_listen_encode_t     encode;
60         rad_listen_decode_t     decode;
61 } rad_listen_master_t;
62
63 typedef struct listen_socket_t {
64         /*
65          *      For normal sockets.
66          */
67         lrad_ipaddr_t   ipaddr;
68         int             port;
69         RADCLIENT_LIST  *clients;
70 } listen_socket_t;
71
72 typedef struct listen_detail_t {
73         const char      *filename;
74         VALUE_PAIR      *vps;
75         FILE            *fp;
76         int             state;
77         time_t          timestamp;
78         lrad_ipaddr_t   client_ip;
79         int             load_factor; /* 1..100 */
80
81         int             has_rtt;
82         int             srtt;
83         int             rttvar;
84         int             delay_time;
85         struct timeval  last_packet;
86 } listen_detail_t;
87
88
89 /*
90  *      Find a per-socket client.
91  */
92 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
93                                        const lrad_ipaddr_t *ipaddr)
94 {
95         const RADCLIENT_LIST *clients;
96
97         rad_assert(listener != NULL);
98         rad_assert(ipaddr != NULL);
99
100         rad_assert((listener->type == RAD_LISTEN_AUTH) ||
101                    (listener->type == RAD_LISTEN_ACCT) ||
102                    (listener->type == RAD_LISTEN_VQP));
103
104         clients = ((listen_socket_t *)listener->data)->clients;
105         if (!clients) clients = mainconfig.clients;
106
107         rad_assert(clients != NULL);
108
109         return client_find(clients, ipaddr);
110 }
111
112 static int listen_bind(rad_listen_t *this);
113
114 /*
115  *      Process and reply to a server-status request.
116  *      Like rad_authenticate and rad_accounting this should
117  *      live in it's own file but it's so small we don't bother.
118  */
119 static int rad_status_server(REQUEST *request)
120 {
121         int rcode = RLM_MODULE_OK;
122         DICT_VALUE *dval;
123
124         switch (request->listener->type) {
125         case RAD_LISTEN_AUTH:
126                 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
127                 if (dval) {
128                         rcode = module_authorize(dval->value, request);
129                 } else {
130                         rcode = RLM_MODULE_OK;
131                 }
132
133                 switch (rcode) {
134                 case RLM_MODULE_OK:
135                 case RLM_MODULE_UPDATED:
136                         request->reply->code = PW_AUTHENTICATION_ACK;
137                         break;
138
139                 case RLM_MODULE_FAIL:
140                 case RLM_MODULE_HANDLED:
141                         request->reply->code = 0; /* don't reply */
142                         break;
143
144                 default:
145                 case RLM_MODULE_REJECT:
146                         request->reply->code = PW_AUTHENTICATION_REJECT;
147                         break;
148                 }
149                 break;
150
151         case RAD_LISTEN_ACCT:
152                 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
153                 if (dval) {
154                         rcode = module_accounting(dval->value, request);
155                 } else {
156                         rcode = RLM_MODULE_OK;
157                 }
158
159                 switch (rcode) {
160                 case RLM_MODULE_OK:
161                 case RLM_MODULE_UPDATED:
162                         request->reply->code = PW_ACCOUNTING_RESPONSE;
163                         break;
164
165                 default:
166                         request->reply->code = 0; /* don't reply */
167                         break;
168                 }
169                 break;
170
171         default:
172                 return 0;
173         }
174
175         return 0;
176 }
177
178
179 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
180 {
181         size_t len;
182         listen_socket_t *sock = this->data;
183
184         if ((sock->ipaddr.af == AF_INET) &&
185             (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
186                 strcpy(buffer, "*");
187         } else {
188                 ip_ntoh(&sock->ipaddr, buffer, bufsize);
189         }
190
191         len = strlen(buffer);
192
193         return len + snprintf(buffer + len, bufsize - len, " port %d",
194                               sock->port);
195 }
196
197
198 /*
199  *      Parse an authentication or accounting socket.
200  */
201 static int common_socket_parse(const char *filename, int lineno,
202                              CONF_SECTION *cs, rad_listen_t *this)
203 {
204         int             rcode;
205         int             listen_port;
206         lrad_ipaddr_t   ipaddr;
207         listen_socket_t *sock = this->data;
208         const char      *section_name = NULL;
209         CONF_SECTION    *client_cs;
210
211         /*
212          *      Try IPv4 first
213          */
214         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
215         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
216                               &ipaddr.ipaddr.ip4addr, NULL);
217         if (rcode < 0) return -1;
218
219         if (rcode == 0) { /* successfully parsed IPv4 */
220                 ipaddr.af = AF_INET;
221
222         } else {        /* maybe IPv6? */
223                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
224                                       &ipaddr.ipaddr.ip6addr, NULL);
225                 if (rcode < 0) return -1;
226
227                 if (rcode == 1) {
228                         radlog(L_ERR, "%s[%d]: No address specified in listen section",
229                                filename, lineno);
230                         return -1;
231                 }
232                 ipaddr.af = AF_INET6;
233         }
234
235         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
236                               &listen_port, "0");
237         if (rcode < 0) return -1;
238
239         sock->ipaddr = ipaddr;
240         sock->port = listen_port;
241
242         /*
243          *      And bind it to the port.
244          */
245         if (listen_bind(this) < 0) {
246                 char buffer[128];
247                 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
248                        filename, cf_section_lineno(cs),
249                        ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
250                        sock->port);
251                 return -1;
252         }
253
254         /*
255          *      If we can bind to interfaces, do so,
256          *      else don't.
257          */
258         if (cf_pair_find(cs, "interface")) {
259 #ifndef SO_BINDTODEVICE
260                 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
261                        filename, cf_section_lineno(cs));
262                 return -1;
263 #else
264                 const char *value;
265                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
266                 struct ifreq ifreq;
267
268                 rad_assert(cp != NULL);
269                 value = cf_pair_value(cp);
270                 rad_assert(value != NULL);
271
272                 strcpy(ifreq.ifr_name, value);
273
274                 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
275                                (char *)&ifreq, sizeof(ifreq)) < 0) {
276                         radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
277                                filename, cf_section_lineno(cs),
278                                value, strerror(errno));
279                         return -1;
280                 } /* else it worked. */
281 #endif
282         }
283         
284         /*
285          *      Look for the name of a section that holds a list
286          *      of clients.
287          */
288         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
289                               &section_name, NULL);
290         if (rcode < 0) return -1; /* bad string */
291         if (rcode == 0) {
292                 /*
293                  *      Explicit list given: use it.
294                  */
295                 client_cs = cf_section_find(section_name);
296                 free(section_name);
297                 if (!client_cs) {
298                         radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
299                                filename, cf_section_lineno(cs), section_name);
300                         return -1;
301                 }
302
303         } else if (this->identity) { /* no "clients = ", try using identity */
304                 /*
305                  *      Else base it off of the identity.
306                  */
307                 client_cs = cf_section_sub_find_name2(mainconfig.config,
308                                                       "identity",
309                                                       this->identity);
310                 if (!client_cs ||
311                     (cf_section_sub_find(client_cs, "client") == NULL)) {
312                         client_cs = mainconfig.config;
313                 }
314
315         } else {
316                 client_cs = mainconfig.config;
317         }
318
319         sock->clients = clients_parse_section(filename, client_cs);
320         if (!sock->clients) {
321                 return -1;
322         }
323
324         return 0;
325 }
326
327 /*
328  *      Send an authentication response packet
329  */
330 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
331 {
332         rad_assert(request->listener == listener);
333         rad_assert(listener->send == auth_socket_send);
334
335         return rad_send(request->reply, request->packet,
336                         request->client->secret);
337 }
338
339
340 /*
341  *      Send an accounting response packet (or not)
342  */
343 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
344 {
345         rad_assert(request->listener == listener);
346         rad_assert(listener->send == acct_socket_send);
347
348         /*
349          *      Accounting reject's are silently dropped.
350          *
351          *      We do it here to avoid polluting the rest of the
352          *      code with this knowledge
353          */
354         if (request->reply->code == 0) return 0;
355
356         return rad_send(request->reply, request->packet,
357                         request->client->secret);
358 }
359
360
361 /*
362  *      Send a packet to a home server.
363  *
364  *      FIXME: have different code for proxy auth & acct!
365  */
366 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
367 {
368         listen_socket_t *sock = listener->data;
369
370         rad_assert(request->proxy_listener == listener);
371         rad_assert(listener->send == proxy_socket_send);
372
373         request->proxy->src_ipaddr = sock->ipaddr;
374         request->proxy->src_port = sock->port;
375
376         return rad_send(request->proxy, request->packet,
377                         request->home_server->secret);
378 }
379
380
381 /*
382  *      Check if an incoming request is "ok"
383  *
384  *      It takes packets, not requests.  It sees if the packet looks
385  *      OK.  If so, it does a number of sanity checks on it.
386   */
387 static int auth_socket_recv(rad_listen_t *listener,
388                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
389 {
390         ssize_t         rcode;
391         int             code, src_port;
392         RADIUS_PACKET   *packet;
393         RAD_REQUEST_FUNP fun = NULL;
394         char            buffer[128];
395         RADCLIENT       *client;
396         lrad_ipaddr_t   src_ipaddr;
397
398         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
399         if (rcode < 0) return 0;
400
401         RAD_SNMP_TYPE_INC(listener, total_requests);
402
403         if (rcode < 20) {       /* AUTH_HDR_LEN */
404                 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
405                 return 0;
406         }
407
408         if ((client = client_listener_find(listener,
409                                            &src_ipaddr)) == NULL) {
410                 rad_recv_discard(listener->fd);
411                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
412
413                 /*
414                  *      This is debugging rather than logging, so that
415                  *      DoS attacks don't affect us.
416                  */
417                 DEBUG("Ignoring request from unknown client %s port %d",
418                       inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
419                                 buffer, sizeof(buffer)), src_port);
420                 return 0;
421         }
422
423         /*
424          *      Some sanity checks, based on the packet code.
425          */
426         switch(code) {
427         case PW_AUTHENTICATION_REQUEST:
428                 RAD_SNMP_CLIENT_INC(listener, client, requests);
429                 fun = rad_authenticate;
430                 break;
431
432         case PW_STATUS_SERVER:
433                 if (!mainconfig.status_server) {
434                         rad_recv_discard(listener->fd);
435                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
436                         RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
437                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
438                         return 0;
439                 }
440                 fun = rad_status_server;
441                 break;
442
443         default:
444                 rad_recv_discard(listener->fd);
445                 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
446                 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
447
448                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
449                       code, client->shortname, src_port);
450                 return 0;
451                 break;
452         } /* switch over packet types */
453
454         /*
455          *      Now that we've sanity checked everything, receive the
456          *      packet.
457          */
458         packet = rad_recv(listener->fd);
459         if (!packet) {
460                 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
461                 radlog(L_ERR, "%s", librad_errstr);
462                 return 0;
463         }
464
465         if (!received_request(listener, packet, prequest, client)) {
466                 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
467                 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
468                 rad_free(&packet);
469                 return 0;
470         }
471
472         *pfun = fun;
473         return 1;
474 }
475
476
477 /*
478  *      Receive packets from an accounting socket
479  */
480 static int acct_socket_recv(rad_listen_t *listener,
481                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
482 {
483         ssize_t         rcode;
484         int             code, src_port;
485         RADIUS_PACKET   *packet;
486         RAD_REQUEST_FUNP fun = NULL;
487         char            buffer[128];
488         RADCLIENT       *client;
489         lrad_ipaddr_t   src_ipaddr;
490
491         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
492         if (rcode < 0) return 0;
493
494         RAD_SNMP_TYPE_INC(listener, total_requests);
495
496         if (rcode < 20) {       /* AUTH_HDR_LEN */
497                 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
498                 return 0;
499         }
500
501         if ((client = client_listener_find(listener,
502                                            &src_ipaddr)) == NULL) {
503                 rad_recv_discard(listener->fd);
504                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
505
506                 /*
507                  *      This is debugging rather than logging, so that
508                  *      DoS attacks don't affect us.
509                  */
510                 DEBUG("Ignoring request from unknown client %s port %d",
511                       inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
512                                 buffer, sizeof(buffer)), src_port);
513                 return 0;
514         }
515
516         /*
517          *      Some sanity checks, based on the packet code.
518          */
519         switch(code) {
520         case PW_ACCOUNTING_REQUEST:
521                 RAD_SNMP_CLIENT_INC(listener, client, requests);
522                 fun = rad_accounting;
523                 break;
524
525         case PW_STATUS_SERVER:
526                 if (!mainconfig.status_server) {
527                         rad_recv_discard(listener->fd);
528                         RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
529                         RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
530
531                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
532                         return 0;
533                 }
534                 fun = rad_status_server;
535                 break;
536
537         default:
538                 rad_recv_discard(listener->fd);
539                 RAD_SNMP_TYPE_INC(listener, total_unknown_types);
540                 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
541
542                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
543                       code, client->shortname, src_port);
544                 return 0;
545         } /* switch over packet types */
546
547         /*
548          *      Now that we've sanity checked everything, receive the
549          *      packet.
550          */
551         packet = rad_recv(listener->fd);
552         if (!packet) {
553                 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
554                 radlog(L_ERR, "%s", librad_errstr);
555                 return 0;
556         }
557
558         /*
559          *      There can be no duplicate accounting packets.
560          */
561         if (!received_request(listener, packet, prequest, client)) {
562                 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
563                 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
564                 rad_free(&packet);
565                 return 0;
566         }
567
568         *pfun = fun;
569         return 1;
570 }
571
572
573 /*
574  *      Recieve packets from a proxy socket.
575  */
576 static int proxy_socket_recv(rad_listen_t *listener,
577                               RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
578 {
579         REQUEST         *request;
580         RADIUS_PACKET   *packet;
581         RAD_REQUEST_FUNP fun = NULL;
582         char            buffer[128];
583
584         packet = rad_recv(listener->fd);
585         if (!packet) {
586                 radlog(L_ERR, "%s", librad_errstr);
587                 return 0;
588         }
589
590         /*
591          *      FIXME: Client MIB updates?
592          */
593         switch(packet->code) {
594         case PW_AUTHENTICATION_ACK:
595         case PW_ACCESS_CHALLENGE:
596         case PW_AUTHENTICATION_REJECT:
597                 fun = rad_authenticate;
598                 break;
599
600         case PW_ACCOUNTING_RESPONSE:
601                 fun = rad_accounting;
602                 break;
603
604         default:
605                 /*
606                  *      FIXME: Update MIB for packet types?
607                  */
608                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
609                        "from home server %s port %d - ID %d : IGNORED",
610                        packet->code,
611                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
612                        packet->src_port, packet->id);
613                 rad_free(&packet);
614                 return 0;
615         }
616
617         request = received_proxy_response(packet);
618         if (!request) {
619                 return 0;
620         }
621
622         rad_assert(fun != NULL);
623         *pfun = fun;
624         *prequest = request;
625
626         return 1;
627 }
628
629
630 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
631 {
632         if (!request->reply->code) return 0;
633
634         rad_encode(request->reply, request->packet,
635                    request->client->secret);
636         rad_sign(request->reply, request->packet,
637                  request->client->secret);
638
639         return 0;
640 }
641
642
643 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
644 {
645         if (rad_verify(request->packet, NULL,
646                        request->client->secret) < 0) {
647                 return -1;
648         }
649
650         return rad_decode(request->packet, NULL,
651                           request->client->secret);
652 }
653
654 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
655 {
656         rad_encode(request->proxy, NULL, request->home_server->secret);
657         rad_sign(request->proxy, NULL, request->home_server->secret);
658
659         return 0;
660 }
661
662
663 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
664 {
665         if (rad_verify(request->proxy_reply, request->proxy,
666                        request->home_server->secret) < 0) {
667                 return -1;
668         }
669
670         return rad_decode(request->proxy_reply, request->proxy,
671                            request->home_server->secret);
672 }
673
674
675 #define STATE_UNOPENED  (0)
676 #define STATE_UNLOCKED  (1)
677 #define STATE_HEADER    (2)
678 #define STATE_READING   (3)
679 #define STATE_QUEUED    (4)
680 #define STATE_RUNNING   (5)
681 #define STATE_NO_REPLY  (6)
682 #define STATE_REPLIED   (7)
683
684 /*
685  *      If we're limiting outstanding packets, then mark the response
686  *      as being sent.
687  */
688 static int detail_send(rad_listen_t *listener, REQUEST *request)
689 {
690         int rtt;
691         struct timeval now;
692         listen_detail_t *data = listener->data;
693
694         rad_assert(request->listener == listener);
695         rad_assert(listener->send == detail_send);
696
697         /*
698          *      This request timed out.  Remember that, and tell the
699          *      caller it's OK to read more "detail" file stuff.
700          */
701         if (request->reply->code == 0) {
702                 radius_signal_self(RADIUS_SIGNAL_SELF_DETAIL);
703                 data->state = STATE_NO_REPLY;
704                 return 0;
705         }
706
707         /*
708          *      We call gettimeofday a lot.  But here it should be OK,
709          *      because there's nothing else to do.
710          */
711         gettimeofday(&now, NULL);
712
713         /*
714          *      If we haven't sent a packet in the last second, reset
715          *      the RTT.
716          */
717         now.tv_sec -= 1;
718         if (timercmp(&data->last_packet, &now, <)) {
719                 data->has_rtt = FALSE;
720         }
721         now.tv_sec += 1;
722
723         /*
724          *      Only one detail packet may be outstanding at a time,
725          *      so it's safe to update some entries in the detail
726          *      structure.
727          *
728          *      We keep smoothed round trip time (SRTT), but not round
729          *      trip timeout (RTO).  We use SRTT to calculate a rough
730          *      load factor.
731          */
732         rtt = now.tv_sec - request->received.tv_sec;
733         rtt *= USEC;
734         rtt += now.tv_usec;
735         rtt -= request->received.tv_usec;
736
737         /*
738          *      If we're proxying, the RTT is our processing time,
739          *      plus the network delay there and back, plus the time
740          *      on the other end to process the packet.  Ideally, we
741          *      should remove the network delays from the RTT, but we
742          *      don't know what they are.
743          *
744          *      So, to be safe, we over-estimate the total cost of
745          *      processing the packet.
746          */
747         if (!data->has_rtt) {
748                 data->has_rtt = TRUE;
749                 data->srtt = rtt;
750                 data->rttvar = rtt / 2;
751
752         } else {
753                 data->rttvar -= data->rttvar >> 2;
754                 data->rttvar += (data->srtt - rtt);
755                 data->srtt -= data->srtt >> 3;
756                 data->srtt += rtt >> 3;
757         }
758
759         /*
760          *      Calculate the time we wait before sending the next
761          *      packet.
762          *
763          *      rtt / (rtt + delay) = load_factor / 100
764          */
765         data->delay_time = (data->srtt * (100 - data->load_factor)) / (data->load_factor);
766
767         /*
768          *      FIXME: Push this delay to the event handler!
769          */
770         DEBUG2("RTT %d\tdelay %d", data->srtt, data->delay_time);
771
772         usleep(data->delay_time);
773         data->last_packet = now;
774         data->state = STATE_REPLIED;
775
776         return 0;
777 }
778
779
780 /*
781  *      Open the detail file..
782  *
783  *      FIXME: create it, if it's not already there, so that the main
784  *      server select() will wake us up if there's anything to read.
785  */
786 static int detail_open(rad_listen_t *this)
787 {
788         struct stat st;
789         char buffer[2048];
790         listen_detail_t *data = this->data;
791
792         rad_assert(data->state == STATE_UNOPENED);
793         snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
794
795         /*
796          *      Open detail.work first, so we don't lose
797          *      accounting packets.  It's probably better to
798          *      duplicate them than to lose them.
799          *
800          *      Note that we're not writing to the file, but
801          *      we've got to open it for writing in order to
802          *      establish the lock, to prevent rlm_detail from
803          *      writing to it.
804          */
805         this->fd = open(buffer, O_RDWR);
806         if (this->fd < 0) {
807                 /*
808                  *      Try reading the detail file.  If it
809                  *      doesn't exist, we can't do anything.
810                  *
811                  *      Doing the stat will tell us if the file
812                  *      exists, even if we don't have permissions
813                  *      to read it.
814                  */
815                 if (stat(data->filename, &st) < 0) {
816                         return 0;
817                 }
818
819                 /*
820                  *      Open it BEFORE we rename it, just to
821                  *      be safe...
822                  */
823                 this->fd = open(data->filename, O_RDWR);
824                 if (this->fd < 0) {
825                         radlog(L_ERR, "Failed to open %s: %s",
826                                data->filename, strerror(errno));
827                         return 0;
828                 }
829
830                 /*
831                  *      Rename detail to detail.work
832                  */
833                 if (rename(data->filename, buffer) < 0) {
834                         close(this->fd);
835                         this->fd = -1;
836                         return 0;
837                 }
838         } /* else detail.work existed, and we opened it */
839
840         rad_assert(data->vps == NULL);
841
842         rad_assert(data->fp == NULL);
843         data->fp = fdopen(this->fd, "r");
844         if (!data->fp) {
845                 radlog(L_ERR, "Failed to re-open %s: %s",
846                        data->filename, strerror(errno));
847                 return 0;
848         }
849
850         data->state = STATE_UNLOCKED;
851
852         data->client_ip.af = AF_UNSPEC;
853         data->timestamp = 0;
854
855         return 1;
856 }
857
858 /*
859  *      FIXME: this should be dynamically allocated.
860  */
861 static const RADCLIENT detail_client = {
862         {               /* ipaddr */
863                 AF_INET,
864                 {{ INADDR_NONE }}
865         },
866         32,
867         "<detail-file>",
868         "secret",
869         "UNKNOWN-CLIENT",
870         "other",
871         "",
872         "",
873         -1
874 #ifdef WITH_SNMP
875         , NULL, NULL
876 #endif
877 };
878
879 /*
880  *      FIXME: add a configuration "exit when done" so that the detail
881  *      file reader can be used as a one-off tool to update stuff.
882  *
883  *      The time sequence for reading from the detail file is:
884  *
885  *      t_0             signalled that the server is idle, and we
886  *                      can read from the detail file.
887  *
888  *      t_rtt           the packet has been processed successfully,
889  *                      wait for t_delay to enforce load factor.
890  *                      
891  *      t_rtt + t_delay wait for signal that the server is idle.
892  *      
893  */
894 static int detail_recv(rad_listen_t *listener,
895                        RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
896 {
897         char            key[256], value[1024];
898         VALUE_PAIR      *vp, **tail;
899         RADIUS_PACKET   *packet;
900         char            buffer[2048];
901         listen_detail_t *data = listener->data;
902
903         switch (data->state) {
904                 case STATE_UNOPENED:
905                         rad_assert(listener->fd < 0);
906                         
907                         /*
908                          *      FIXME: If the file doesn't exist, then
909                          *      return "sleep for 1s", to avoid busy
910                          *      looping.
911                          */
912                         if (!detail_open(listener)) return 0;
913
914                         rad_assert(data->state == STATE_UNLOCKED);
915                         rad_assert(listener->fd >= 0);
916
917                         /* FALL-THROUGH */
918
919                         /*
920                          *      Try to lock fd.  If we can't, return.
921                          *      If we can, continue.  This means that
922                          *      the server doesn't block while waiting
923                          *      for the lock to open...
924                          */
925                 case STATE_UNLOCKED:
926                         /*
927                          *      Note that we do NOT block waiting for
928                          *      the lock.  We've re-named the file
929                          *      above, so we've already guaranteed
930                          *      that any *new* detail writer will not
931                          *      be opening this file.  The only
932                          *      purpose of the lock is to catch a race
933                          *      condition where the execution
934                          *      "ping-pongs" between radiusd &
935                          *      radrelay.
936                          */
937                         if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
938                                 return 0;
939                         }
940                         /*
941                          *      Look for the header
942                          */
943                         data->state = STATE_HEADER;
944                         data->vps = NULL;
945
946                         /* FALL-THROUGH */
947
948                 case STATE_HEADER:
949                 do_header:
950                         /*
951                          *      End of file.  Delete it, and re-set
952                          *      everything.
953                          */
954                         if (feof(data->fp)) {
955                         cleanup:
956                                 snprintf(buffer, sizeof(buffer),
957                                          "%s.work", data->filename);
958                                 unlink(buffer);
959                                 fclose(data->fp); /* closes listener->fd */
960                                 data->fp = NULL;
961                                 listener->fd = -1;
962                                 data->state = STATE_UNOPENED;
963                                 rad_assert(data->vps == NULL);
964                                 return 0;
965                         }
966
967                         /*
968                          *      Else go read something.
969                          */
970                         break;
971
972                         /*
973                          *      Read more value-pair's, unless we're
974                          *      at EOF.  In that case, queue whatever
975                          *      we have.
976                          */
977                 case STATE_READING:
978                         if (!feof(data->fp)) break;
979                         data->state = STATE_QUEUED;
980
981                         /* FALL-THROUGH */
982
983                 case STATE_QUEUED:
984                         goto alloc_packet;
985
986                         /*
987                          *      We still have an outstanding packet.
988                          *      Don't read any more.
989                          */
990                 case STATE_RUNNING:
991                         return 0;
992
993                         /*
994                          *      If there's no reply, keep
995                          *      retransmitting the current packet
996                          *      forever.
997                          */
998                 case STATE_NO_REPLY:
999                         data->state = STATE_QUEUED;
1000                         goto alloc_packet;
1001                                 
1002                         /*
1003                          *      We have a reply.  Clean up the old
1004                          *      request, and go read another one.
1005                          */
1006                 case STATE_REPLIED:
1007                         pairfree(&data->vps);
1008                         data->state = STATE_HEADER;
1009                         goto do_header;
1010         }
1011         
1012         tail = &data->vps;
1013         while (*tail) tail = &(*tail)->next;
1014
1015         /*
1016          *      Read a header, OR a value-pair.
1017          */
1018         while (fgets(buffer, sizeof(buffer), data->fp)) {
1019                 /*
1020                  *      Badly formatted file: delete it.
1021                  *
1022                  *      FIXME: Maybe flag an error?
1023                  */
1024                 if (!strchr(buffer, '\n')) {
1025                         pairfree(&data->vps);
1026                         goto cleanup;
1027                 }
1028
1029                 /*
1030                  *      We're reading VP's, and got a blank line.
1031                  *      Queue the packet.
1032                  */
1033                 if ((data->state == STATE_READING) &&
1034                     (buffer[0] == '\n')) {
1035                         data->state = STATE_QUEUED;
1036                         break;
1037                 }
1038
1039                 /*
1040                  *      Look for date/time header, and read VP's if
1041                  *      found.  If not, keep reading lines until we
1042                  *      find one.
1043                  */
1044                 if (data->state == STATE_HEADER) {
1045                         int y;
1046
1047                         if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1048                                 data->state = STATE_READING;
1049                         }
1050                         continue;
1051                 }
1052
1053                 /*
1054                  *      We have a full "attribute = value" line.
1055                  *      If it doesn't look reasonable, skip it.
1056                  *
1057                  *      FIXME: print an error for badly formatted attributes?
1058                  */
1059                 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1060                         continue;
1061                 }
1062
1063                 /*
1064                  *      Skip non-protocol attributes.
1065                  */
1066                 if (!strcasecmp(key, "Request-Authenticator")) continue;
1067
1068                 /*
1069                  *      Set the original client IP address, based on
1070                  *      what's in the detail file.
1071                  *
1072                  *      Hmm... we don't set the server IP address.
1073                  *      or port.  Oh well.
1074                  */
1075                 if (!strcasecmp(key, "Client-IP-Address")) {
1076                         data->client_ip.af = AF_INET;
1077                         ip_hton(value, AF_INET, &data->client_ip);
1078                         continue;
1079                 }
1080
1081                 /*
1082                  *      The original time at which we received the
1083                  *      packet.  We need this to properly calculate
1084                  *      Acct-Delay-Time.
1085                  */
1086                 if (!strcasecmp(key, "Timestamp")) {
1087                         data->timestamp = atoi(value);
1088                         continue;
1089                 }
1090
1091                 /*
1092                  *      Read one VP.
1093                  *
1094                  *      FIXME: do we want to check for non-protocol
1095                  *      attributes like radsqlrelay does?
1096                  */
1097                 vp = NULL;
1098                 if ((userparse(buffer, &vp) > 0) &&
1099                     (vp != NULL)) {
1100                         *tail = vp;
1101                         tail = &(vp->next);
1102                 }
1103         }
1104
1105         /*
1106          *      Some kind of error.
1107          *
1108          *      FIXME: Leave the file in-place, and warn the
1109          *      administrator?
1110          */
1111         if (ferror(data->fp)) goto cleanup;
1112
1113         /*
1114          *      Process the packet.
1115          */
1116  alloc_packet:
1117         rad_assert(data->state == STATE_QUEUED);
1118
1119         /*
1120          *      We're done reading the file, but we didn't read
1121          *      anything.  Clean up, and don't return anything.
1122          */
1123         if (!data->vps) {
1124                 data->state = STATE_HEADER;
1125                 return 0;
1126         }
1127
1128         /*
1129          *      Allocate the packet.  If we fail, it's a serious
1130          *      problem.
1131          */
1132         packet = rad_alloc(1);
1133         if (!packet) {
1134                 data->state = STATE_NO_REPLY;   /* try again later */
1135                 return 0;       /* maybe memory will magically free up... */
1136         }
1137
1138         memset(packet, 0, sizeof(*packet));
1139         packet->sockfd = -1;
1140         packet->src_ipaddr.af = AF_INET;
1141         packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1142         packet->code = PW_ACCOUNTING_REQUEST;
1143         packet->timestamp = time(NULL);
1144
1145         /*
1146          *      Remember where it came from, so that we don't
1147          *      proxy it to the place it came from...
1148          */
1149         if (data->client_ip.af != AF_UNSPEC) {
1150                 packet->src_ipaddr = data->client_ip;
1151         }
1152
1153         vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1154         if (vp) {
1155                 packet->src_ipaddr.af = AF_INET;
1156                 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1157         } else {
1158                 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1159                 if (vp) {
1160                         packet->src_ipaddr.af = AF_INET6;
1161                         memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1162                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1163                 }
1164         }
1165
1166         vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1167         if (vp) {
1168                 packet->dst_ipaddr.af = AF_INET;
1169                 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1170         } else {
1171                 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1172                 if (vp) {
1173                         packet->dst_ipaddr.af = AF_INET6;
1174                         memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1175                                &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1176                 }
1177         }
1178
1179         /*
1180          *      We've got to give SOME value for Id & ports, so that
1181          *      the packets can be added to the request queue.
1182          *      However, we don't want to keep track of used/unused
1183          *      id's and ports, as that's a lot of work.  This hack
1184          *      ensures that (if we have real random numbers), that
1185          *      there will be a collision on every 2^(16+15+15+24 - 1)
1186          *      packets, on average.  That means we can read 2^37
1187          *      packets before having a collision, which means it's
1188          *      effectively impossible.
1189          */
1190         packet->id = lrad_rand() & 0xffff;
1191         packet->src_port = 1024 + (lrad_rand() & 0x7fff);
1192         packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
1193
1194         packet->dst_ipaddr.af = AF_INET;
1195         packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1196
1197         /*
1198          *      If everything's OK, this is a waste of memory.
1199          *      Otherwise, it lets us re-send the original packet
1200          *      contents, unmolested.
1201          */
1202         packet->vps = paircopy(data->vps);
1203
1204         /*
1205          *      Look for Acct-Delay-Time, and update
1206          *      based on Acct-Delay-Time += (time(NULL) - timestamp)
1207          */
1208         vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1209         if (!vp) {
1210                 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1211                 rad_assert(vp != NULL);
1212                 pairadd(&packet->vps, vp);
1213         }
1214         if (data->timestamp != 0) {
1215                 vp->vp_integer += time(NULL) - data->timestamp;
1216         }
1217
1218         *pfun = rad_accounting;
1219
1220         if (debug_flag) {
1221                 printf("detail_recv: Read packet from %s\n", data->filename);
1222                 for (vp = packet->vps; vp; vp = vp->next) {
1223                         putchar('\t');
1224                         vp_print(stdout, vp);
1225                         putchar('\n');
1226                 }
1227         }
1228
1229         /*
1230          *      FIXME: many of these checks may not be necessary when
1231          *      reading from the detail file.
1232          *
1233          *      Try again later...
1234          */
1235         if (!received_request(listener, packet, prequest, &detail_client)) {
1236                 rad_free(&packet);
1237                 data->state = STATE_NO_REPLY;   /* try again later */
1238                 return 0;
1239         }
1240
1241         data->state = STATE_RUNNING;
1242
1243         return 1;
1244 }
1245
1246
1247 /*
1248  *      Free detail-specific stuff.
1249  */
1250 static void detail_free(rad_listen_t *this)
1251 {
1252         listen_detail_t *data = this->data;
1253
1254         free(data->filename);
1255         pairfree(&data->vps);
1256
1257         if (data->fp != NULL) fclose(data->fp);
1258 }
1259
1260
1261 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1262 {
1263         return snprintf(buffer, bufsize, "%s",
1264                         ((listen_detail_t *)(this->data))->filename);
1265 }
1266
1267 static int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1268 {
1269         /*
1270          *      We never encode responses "sent to" the detail file.
1271          */
1272         return 0;
1273 }
1274
1275 static int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1276 {
1277         /*
1278          *      We never decode responses read from the detail file.
1279          */
1280         return 0;
1281 }
1282
1283
1284 static const CONF_PARSER detail_config[] = {
1285         { "filename",   PW_TYPE_STRING_PTR,
1286           offsetof(listen_detail_t, filename), NULL,  NULL },
1287         { "load_factor",   PW_TYPE_INTEGER,
1288           offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},
1289
1290         { NULL, -1, 0, NULL, NULL }             /* end the list */
1291 };
1292
1293
1294 /*
1295  *      Parse a detail section.
1296  */
1297 static int detail_parse(const char *filename, int lineno,
1298                         CONF_SECTION *cs, rad_listen_t *this)
1299 {
1300         int             rcode;
1301         listen_detail_t *data;
1302
1303         data = this->data;
1304
1305         rcode = cf_section_parse(cs, data, detail_config);
1306         if (rcode < 0) {
1307                 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1308                        filename, lineno);
1309                 return -1;
1310         }
1311
1312         if (!data->filename) {
1313                 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1314                        filename, lineno);
1315                 return -1;
1316         }
1317
1318         if ((data->load_factor < 1) || (data->load_factor > 100)) {
1319                 radlog(L_ERR, "%s[%d]: Load factor must be between 1 and 100",
1320                        filename, lineno);
1321                 return -1;
1322         }
1323
1324         data->vps = NULL;
1325         data->fp = NULL;
1326         data->state = STATE_UNOPENED;
1327         detail_open(this);
1328
1329         return 0;
1330 }
1331
1332
1333 #ifdef WITH_SNMP
1334 static int radius_snmp_recv(rad_listen_t *listener,
1335                             UNUSED RAD_REQUEST_FUNP *pfun,
1336                             UNUSED REQUEST **prequest)
1337 {
1338         if (!mainconfig.do_snmp) return 0;
1339
1340         if ((rad_snmp.smux_fd >= 0) &&
1341             (rad_snmp.smux_event == SMUX_READ)) {
1342                 smux_read();
1343         }
1344
1345         /*
1346          *  If we've got to re-connect, then do so now,
1347          *  before calling select again.
1348          */
1349         if (rad_snmp.smux_event == SMUX_CONNECT) {
1350                 smux_connect();
1351         }
1352
1353         /*
1354          *      Reset this every time, as the smux connect may have
1355          *      opened a new socket.
1356          */
1357         listener->fd = rad_snmp.smux_fd;
1358
1359         return 0;
1360 }
1361
1362
1363 static int radius_snmp_print(UNUSED rad_listen_t *this, char *buffer, size_t bufsize)
1364 {
1365         return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");
1366 }
1367
1368 #endif
1369
1370 #ifdef WITH_VMPS
1371 /*
1372  *      Check if an incoming request is "ok"
1373  *
1374  *      It takes packets, not requests.  It sees if the packet looks
1375  *      OK.  If so, it does a number of sanity checks on it.
1376  */
1377 static int vqp_socket_recv(rad_listen_t *listener,
1378                            RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1379 {
1380         RADIUS_PACKET   *packet;
1381         RAD_REQUEST_FUNP fun = NULL;
1382         char            buffer[128];
1383         RADCLIENT       *client;
1384
1385         packet = vqp_recv(listener->fd);
1386         if (!packet) {
1387                 radlog(L_ERR, "%s", librad_errstr);
1388                 return 0;
1389         }
1390
1391         if ((client = client_listener_find(listener,
1392                                            &packet->src_ipaddr)) == NULL) {
1393                 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
1394                 
1395                 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
1396                        inet_ntop(packet->src_ipaddr.af,
1397                                  &packet->src_ipaddr.ipaddr,
1398                                  buffer, sizeof(buffer)),
1399                        packet->src_port);
1400                 rad_free(&packet);
1401                 return 0;
1402         }
1403
1404         /*
1405          *      Do new stuff.
1406          */
1407         fun = vmps_process;
1408
1409         if (!received_request(listener, packet, prequest, client)) {
1410                 rad_free(&packet);
1411                 return 0;
1412         }
1413
1414         *pfun = fun;
1415
1416         return 1;
1417 }
1418
1419
1420 /*
1421  *      Send an authentication response packet
1422  */
1423 static int vqp_socket_send(rad_listen_t *listener, REQUEST *request)
1424 {
1425         rad_assert(request->listener == listener);
1426         rad_assert(listener->send == vqp_socket_send);
1427
1428         if (vqp_encode(request->reply, request->packet) < 0) {
1429                 DEBUG2("Failed encoding packet: %s\n", librad_errstr);
1430                 return -1;
1431         }
1432
1433         return vqp_send(request->reply);
1434 }
1435
1436
1437 static int vqp_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1438 {
1439         return vqp_encode(request->reply, request->packet);
1440 }
1441
1442
1443 static int vqp_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1444 {
1445         return vqp_decode(request->packet);
1446 }
1447 #endif /* WITH_VMPS */
1448
1449
1450 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1451         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1452
1453         /* proxying */
1454         { NULL, NULL,
1455           proxy_socket_recv, proxy_socket_send,
1456           socket_print, proxy_socket_encode, proxy_socket_decode },
1457
1458         /* authentication */
1459         { common_socket_parse, NULL,
1460           auth_socket_recv, auth_socket_send,
1461           socket_print, client_socket_encode, client_socket_decode },
1462
1463         /* accounting */
1464         { common_socket_parse, NULL,
1465           acct_socket_recv, acct_socket_send,
1466           socket_print, client_socket_encode, client_socket_decode},
1467
1468         /* detail */
1469         { detail_parse, detail_free,
1470           detail_recv, detail_send,
1471           detail_print, detail_encode, detail_decode },
1472
1473 #ifdef WITH_VMPS
1474         /* vlan query protocol */
1475         { common_socket_parse, NULL,
1476           vqp_socket_recv, vqp_socket_send,
1477           socket_print, vqp_socket_encode, vqp_socket_decode },
1478 #else
1479         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1480 #endif
1481
1482         { NULL, NULL, NULL, NULL, NULL, NULL, NULL}     /* RAD_LISTEN_SNMP */
1483 };
1484
1485
1486
1487 /*
1488  *      Binds a listener to a socket.
1489  */
1490 static int listen_bind(rad_listen_t *this)
1491 {
1492         rad_listen_t    **last;
1493         listen_socket_t *sock = this->data;
1494
1495         /*
1496          *      If the port is zero, then it means the appropriate
1497          *      thing from /etc/services.
1498          */
1499         if (sock->port == 0) {
1500                 struct servent  *svp;
1501
1502                 switch (this->type) {
1503                 case RAD_LISTEN_AUTH:
1504                         svp = getservbyname ("radius", "udp");
1505                         if (svp != NULL) {
1506                                 sock->port = ntohs(svp->s_port);
1507                         } else {
1508                                 sock->port = PW_AUTH_UDP_PORT;
1509                         }
1510                         break;
1511
1512                 case RAD_LISTEN_ACCT:
1513                         svp = getservbyname ("radacct", "udp");
1514                         if (svp != NULL) {
1515                                 sock->port = ntohs(svp->s_port);
1516                         } else {
1517                                 sock->port = PW_ACCT_UDP_PORT;
1518                         }
1519                         break;
1520
1521                 default:
1522                         radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1523                         return -1;
1524                 }
1525         }
1526
1527         /*
1528          *      Find it in the old list, AFTER updating the port.  If
1529          *      it's there, use that, rather than creating a new
1530          *      socket.  This allows HUP's to re-use the old sockets,
1531          *      which means that packets waiting in the socket queue
1532          *      don't get lost.
1533          */
1534         for (last = &mainconfig.listen;
1535              *last != NULL;
1536              last = &((*last)->next)) {
1537                 listen_socket_t *other;
1538
1539                 if (this->type != (*last)->type) continue;
1540
1541                 if ((this->type == RAD_LISTEN_DETAIL) ||
1542                     (this->type == RAD_LISTEN_SNMP)) continue;
1543
1544                 other = (listen_socket_t *)((*last)->data);
1545
1546                 if ((sock->port == other->port) &&
1547                     (sock->ipaddr.af == other->ipaddr.af) &&
1548                     (lrad_ipaddr_cmp(&sock->ipaddr, &other->ipaddr) == 0)) {
1549                         this->fd = (*last)->fd;
1550                         (*last)->fd = -1;
1551                         return 0;
1552                 }
1553         }
1554
1555         this->fd = lrad_socket(&sock->ipaddr, sock->port);
1556         if (this->fd < 0) {
1557                 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1558                        librad_errstr);
1559                 return -1;
1560         }
1561
1562 #if 0
1563 #ifdef O_NONBLOCK
1564         if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0)  {
1565                 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1566                 return -1;
1567         }
1568
1569         flags |= O_NONBLOCK;
1570         if( fcntl(this->fd, F_SETFL, flags) < 0) {
1571                 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1572                 return -1;
1573         }
1574 #endif
1575 #endif
1576
1577         return 0;
1578 }
1579
1580
1581 /*
1582  *      Allocate & initialize a new listener.
1583  */
1584 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1585 {
1586         rad_listen_t *this;
1587
1588         this = rad_malloc(sizeof(*this));
1589         memset(this, 0, sizeof(*this));
1590
1591         this->type = type;
1592         this->recv = master_listen[this->type].recv;
1593         this->send = master_listen[this->type].send;
1594         this->print = master_listen[this->type].print;
1595         this->encode = master_listen[this->type].encode;
1596         this->decode = master_listen[this->type].decode;
1597
1598         switch (type) {
1599         case RAD_LISTEN_AUTH:
1600         case RAD_LISTEN_ACCT:
1601         case RAD_LISTEN_PROXY:
1602         case RAD_LISTEN_VQP:
1603                 this->data = rad_malloc(sizeof(listen_socket_t));
1604                 memset(this->data, 0, sizeof(listen_socket_t));
1605                 break;
1606
1607         case RAD_LISTEN_DETAIL:
1608                 this->data = rad_malloc(sizeof(listen_detail_t));
1609                 memset(this->data, 0, sizeof(listen_detail_t));
1610
1611         default:
1612                 rad_assert("Unsupported option!" == NULL);
1613                 break;
1614         }
1615
1616         return this;
1617 }
1618
1619
1620 /*
1621  *      Externally visible function for creating a new proxy LISTENER.
1622  *
1623  *      For now, don't take ipaddr or port.
1624  *
1625  *      Not thread-safe, but all calls to it are protected by the
1626  *      proxy mutex in request_list.c
1627  */
1628 rad_listen_t *proxy_new_listener()
1629 {
1630         int last_proxy_port, port;
1631         rad_listen_t *this, *tmp, **last;
1632         listen_socket_t *sock, *old;
1633
1634         this = listen_alloc(RAD_LISTEN_PROXY);
1635
1636         /*
1637          *      Find an existing proxy socket to copy.
1638          *
1639          *      FIXME: Make it per-realm, or per-home server!
1640          */
1641         last_proxy_port = 0;
1642         old = NULL;
1643         last = &mainconfig.listen;
1644         for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1645                 if (tmp->type == RAD_LISTEN_PROXY) {
1646                         sock = tmp->data;
1647                         if (sock->port > last_proxy_port) {
1648                                 last_proxy_port = sock->port + 1;
1649                         }
1650                         if (!old) old = sock;
1651                 }
1652
1653                 last = &(tmp->next);
1654         }
1655
1656         if (!old) return NULL;  /* This is a serious error. */
1657
1658         /*
1659          *      FIXME: find a new IP address to listen on?
1660          *
1661          *      This could likely be done in the "home server"
1662          *      configuration, to have per-home-server source IP's.
1663          */
1664         sock = this->data;
1665         memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1666
1667         /*
1668          *      Keep going until we find an unused port.
1669          */
1670         for (port = last_proxy_port; port < 64000; port++) {
1671                 sock->port = port;
1672                 if (listen_bind(this) == 0) {
1673                         /*
1674                          *      Add the new listener to the list of
1675                          *      listeners.
1676                          */
1677                         *last = this;
1678                         return this;
1679                 }
1680         }
1681
1682         return NULL;
1683 }
1684
1685
1686 static const LRAD_NAME_NUMBER listen_compare[] = {
1687         { "auth",       RAD_LISTEN_AUTH },
1688         { "acct",       RAD_LISTEN_ACCT },
1689         { "detail",     RAD_LISTEN_DETAIL },
1690 #ifdef WITH_VMPS
1691         { "vmps",       RAD_LISTEN_VQP },
1692 #endif
1693         { NULL, 0 },
1694 };
1695
1696
1697 /*
1698  *      Generate a list of listeners.  Takes an input list of
1699  *      listeners, too, so we don't close sockets with waiting packets.
1700  */
1701 int listen_init(const char *filename, rad_listen_t **head)
1702 {
1703         int             rcode;
1704         CONF_SECTION    *cs;
1705         rad_listen_t    **last;
1706         rad_listen_t    *this;
1707         lrad_ipaddr_t   server_ipaddr;
1708         int             auth_port = 0;
1709
1710         /*
1711          *      We shouldn't be called with a pre-existing list.
1712          */
1713         rad_assert(head && (*head == NULL));
1714
1715         last = head;
1716         server_ipaddr.af = AF_UNSPEC;
1717
1718         /*
1719          *      If the port is specified on the command-line,
1720          *      it over-rides the configuration file.
1721          *
1722          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1723          */
1724         if (mainconfig.port >= 0) auth_port = mainconfig.port;
1725
1726         /*
1727          *      If the IP address was configured on the command-line,
1728          *      use that as the "bind_address"
1729          */
1730         if (mainconfig.myip.af != AF_UNSPEC) {
1731                 memcpy(&server_ipaddr, &mainconfig.myip,
1732                        sizeof(server_ipaddr));
1733                 goto bind_it;
1734         }
1735
1736         /*
1737          *      Else look for bind_address and/or listen sections.
1738          */
1739         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1740         rcode = cf_item_parse(mainconfig.config, "bind_address",
1741                               PW_TYPE_IPADDR,
1742                               &server_ipaddr.ipaddr.ip4addr, NULL);
1743         if (rcode < 0) return -1; /* error parsing it */
1744
1745         if (rcode == 0) { /* successfully parsed IPv4 */
1746                 listen_socket_t *sock;
1747                 server_ipaddr.af = AF_INET;
1748
1749                 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1750
1751         bind_it:
1752 #ifdef WITH_VMPS
1753                 if (strcmp(progname, "vmpsd") == 0) {
1754                         this = listen_alloc(RAD_LISTEN_VQP);
1755                         if (!auth_port) auth_port = 1589;
1756                 } else
1757 #endif
1758                         this = listen_alloc(RAD_LISTEN_AUTH);
1759
1760                 sock = this->data;
1761
1762                 sock->ipaddr = server_ipaddr;
1763                 sock->port = auth_port;
1764
1765                 if (listen_bind(this) < 0) {
1766                         listen_free(&this);
1767                         listen_free(head);
1768                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1769                         return -1;
1770                 }
1771                 auth_port = sock->port; /* may have been updated in listen_bind */
1772                 *last = this;
1773                 last = &(this->next);
1774
1775 #ifdef WITH_VMPS
1776                 /*
1777                  *      No acct for vmpsd
1778                  */
1779                 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1780 #endif
1781
1782                 /*
1783                  *      Open Accounting Socket.
1784                  *
1785                  *      If we haven't already gotten acct_port from
1786                  *      /etc/services, then make it auth_port + 1.
1787                  */
1788                 this = listen_alloc(RAD_LISTEN_ACCT);
1789                 sock = this->data;
1790
1791                 /*
1792                  *      Create the accounting socket.
1793                  *
1794                  *      The accounting port is always the
1795                  *      authentication port + 1
1796                  */
1797                 sock->ipaddr = server_ipaddr;
1798                 sock->port = auth_port + 1;
1799
1800                 if (listen_bind(this) < 0) {
1801                         listen_free(&this);
1802                         listen_free(head);
1803                         radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1804                         return -1;
1805                 }
1806
1807                 *last = this;
1808                 last = &(this->next);
1809
1810         } else if (mainconfig.port > 0) { /* no bind address, but a port */
1811                 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1812                        mainconfig.port);
1813                 return -1;
1814         }
1815
1816         /*
1817          *      They specified an IP on the command-line, ignore
1818          *      all listen sections.
1819          */
1820         if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1821
1822         /*
1823          *      Walk through the "listen" sections, if they exist.
1824          */
1825         for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
1826              cs != NULL;
1827              cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
1828                 int             type;
1829                 char            *listen_type, *identity;
1830                 int             lineno = cf_section_lineno(cs);
1831
1832                 listen_type = identity = NULL;
1833
1834                 DEBUG2(" listen {");
1835
1836                 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1837                                       &listen_type, "");
1838                 if (rcode < 0) return -1;
1839                 if (rcode == 1) {
1840                         listen_free(head);
1841                         free(listen_type);
1842                         radlog(L_ERR, "%s[%d]: No type specified in listen section",
1843                                filename, lineno);
1844                         return -1;
1845                 }
1846
1847                 /*
1848                  *      See if there's an identity.
1849                  */
1850                 rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
1851                                       &identity, NULL);
1852                 if (rcode < 0) {
1853                         listen_free(head);
1854                         free(identity);
1855                         return -1;
1856                 }
1857
1858                 type = lrad_str2int(listen_compare, listen_type,
1859                                     RAD_LISTEN_NONE);
1860                 free(listen_type);
1861                 if (type == RAD_LISTEN_NONE) {
1862                         listen_free(head);
1863                         radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1864                                filename, lineno);
1865                         return -1;
1866                 }
1867
1868                 /*
1869                  *      Set up cross-type data.
1870                  */
1871                 this = listen_alloc(type);
1872                 this->identity = identity;
1873                 this->fd = -1;
1874
1875                 /*
1876                  *      Call per-type parser.
1877                  */
1878                 if (master_listen[type].parse(filename, lineno,
1879                                               cs, this) < 0) {
1880                         listen_free(&this);
1881                         listen_free(head);
1882                         return -1;
1883                 }
1884
1885                 DEBUG2(" }");
1886
1887                 *last = this;
1888                 last = &(this->next);
1889         }
1890
1891         /*
1892          *      If we're proxying requests, open the proxy FD.
1893          *      Otherwise, don't do anything.
1894          */
1895  do_proxy:
1896         if (mainconfig.proxy_requests == TRUE) {
1897                 int             port = -1;
1898                 listen_socket_t *sock = NULL;
1899
1900                 /*
1901                  *      No sockets to receive packets, therefore
1902                  *      proxying is pointless.
1903                  */
1904                 if (!*head) return -1;
1905
1906                 /*
1907                  *      If we previously had proxy sockets, copy them
1908                  *      to the new config.
1909                  */
1910                 if (mainconfig.listen != NULL) {
1911                         rad_listen_t *old, *next, **tail;
1912
1913                         tail = &mainconfig.listen;
1914                         for (old = mainconfig.listen;
1915                              old != NULL;
1916                              old = next) {
1917                                 next = old->next;
1918
1919                                 if (old->type != RAD_LISTEN_PROXY) {
1920                                         tail = &((*tail)->next);
1921                                         continue;
1922                                 }
1923
1924                                 *last = old;
1925                                 *tail = next;
1926                                 old->next = NULL;
1927                                 last = &(old->next);
1928                         }
1929
1930                         goto do_snmp;
1931                 }
1932
1933                 /*
1934                  *      Find the first authentication port,
1935                  *      and use it
1936                  */
1937                 for (this = *head; this != NULL; this = this->next) {
1938                         if (this->type == RAD_LISTEN_AUTH) {
1939                                 sock = this->data;
1940                                 if (server_ipaddr.af == AF_UNSPEC) {
1941                                         server_ipaddr = sock->ipaddr;
1942                                 }
1943                                 port = sock->port + 2; /* skip acct port */
1944                                 break;
1945                         }
1946                         if (this->type == RAD_LISTEN_VQP) {
1947                                 sock = this->data;
1948                                 if (server_ipaddr.af == AF_UNSPEC) {
1949                                         server_ipaddr = sock->ipaddr;
1950                                 }
1951                                 port = sock->port + 1;
1952                                 break;
1953                         }
1954                 }
1955
1956                 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
1957
1958                 /*
1959                  *      Address is still unspecified, use IPv4.
1960                  */
1961                 if (server_ipaddr.af == AF_UNSPEC) {
1962                         server_ipaddr.af = AF_INET;
1963                         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
1964                 }
1965
1966                 this = listen_alloc(RAD_LISTEN_PROXY);
1967                 sock = this->data;
1968
1969                 /*
1970                  *      Create the first proxy socket.
1971                  */
1972                 sock->ipaddr = server_ipaddr;
1973
1974                 /*
1975                  *      Try to find a proxy port (value doesn't matter)
1976                  */
1977                 for (sock->port = port;
1978                      sock->port < 64000;
1979                      sock->port++) {
1980                         if (listen_bind(this) == 0) {
1981                                 *last = this;
1982                                 last = &(this->next); /* just in case */
1983                                 break;
1984                         }
1985                 }
1986
1987                 if (sock->port >= 64000) {
1988                         listen_free(head);
1989                         listen_free(&this);
1990                         radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
1991                         return -1;
1992                 }
1993         }
1994
1995  do_snmp:
1996 #ifdef WITH_SNMP
1997         if (mainconfig.do_snmp) {
1998                 radius_snmp_init();
1999
2000                 /*
2001                  *      Forget about the old one.
2002                  */
2003                 for (this = mainconfig.listen;
2004                      this != NULL;
2005                      this = this->next) {
2006                         if (this->type != RAD_LISTEN_SNMP) continue;
2007                         this->fd = -1;
2008                 }
2009
2010                 this = rad_malloc(sizeof(*this));
2011                 memset(this, 0, sizeof(*this));
2012
2013                 this->type = RAD_LISTEN_SNMP;
2014                 this->fd = rad_snmp.smux_fd;
2015
2016                 this->recv = radius_snmp_recv;
2017                 this->print = radius_snmp_print;
2018
2019                 *last = this;
2020                 last = &(this->next);
2021         }
2022 #endif
2023
2024         return 0;
2025 }
2026
2027 /*
2028  *      Free a linked list of listeners;
2029  */
2030 void listen_free(rad_listen_t **head)
2031 {
2032         rad_listen_t *this;
2033
2034         if (!head || !*head) return;
2035
2036         this = *head;
2037         while (this) {
2038                 rad_listen_t *next = this->next;
2039
2040                 free(this->identity);
2041
2042                 /*
2043                  *      Other code may have eaten the FD.
2044                  */
2045                 if (this->fd >= 0) close(this->fd);
2046
2047                 if (master_listen[this->type].free) {
2048                         master_listen[this->type].free(this);
2049                 }
2050                 free(this->data);
2051                 free(this);
2052
2053                 this = next;
2054         }
2055
2056         *head = NULL;
2057 }