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