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