Always use buffer
[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/modules.h>
29 #include <freeradius-devel/rad_assert.h>
30 #include <freeradius-devel/vqp.h>
31 #include <freeradius-devel/dhcp.h>
32 #include <freeradius-devel/process.h>
33
34 #include <freeradius-devel/vmps.h>
35 #include <freeradius-devel/detail.h>
36
37 #ifdef WITH_UDPFROMTO
38 #include <freeradius-devel/udpfromto.h>
39 #endif
40
41 #ifdef HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
43 #endif
44
45 #ifdef HAVE_NET_IF_H
46 #include <net/if.h>
47 #endif
48
49 #ifdef HAVE_FCNTL_H
50 #include <fcntl.h>
51 #endif
52
53
54 static void print_packet(RADIUS_PACKET *packet)
55 {
56         char src[256], dst[256];
57
58         ip_ntoh(&packet->src_ipaddr, src, sizeof(src));
59         ip_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
60
61         fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
62                 src, packet->src_port, dst, packet->dst_port);
63
64 }
65
66
67 /*
68  *      We'll use this below.
69  */
70 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
71 typedef void (*rad_listen_free_t)(rad_listen_t *);
72
73 typedef struct rad_listen_master_t {
74         rad_listen_parse_t      parse;
75         rad_listen_free_t       free;
76         rad_listen_recv_t       recv;
77         rad_listen_send_t       send;
78         rad_listen_print_t      print;
79         rad_listen_encode_t     encode;
80         rad_listen_decode_t     decode;
81 } rad_listen_master_t;
82
83 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
84
85 /*
86  *      Xlat for %{listen:foo}
87  */
88 static size_t xlat_listen(UNUSED void *instance, REQUEST *request,
89                        char *fmt, char *out,
90                        size_t outlen,
91                        UNUSED RADIUS_ESCAPE_STRING func)
92 {
93         const char *value = NULL;
94         CONF_PAIR *cp;
95
96         if (!fmt || !out || (outlen < 1)) return 0;
97
98         if (!request || !request->listener) {
99                 *out = '\0';
100                 return 0;
101         }
102
103         cp = cf_pair_find(request->listener->cs, fmt);
104         if (!cp || !(value = cf_pair_value(cp))) {
105                 *out = '\0';
106                 return 0;
107         }
108         
109         strlcpy(out, value, outlen);
110
111         return strlen(out);
112 }
113
114 /*
115  *      Find a per-socket client.
116  */
117 RADCLIENT *client_listener_find(rad_listen_t *listener,
118                                 const fr_ipaddr_t *ipaddr, int src_port)
119 {
120 #ifdef WITH_DYNAMIC_CLIENTS
121         int rcode;
122         REQUEST *request;
123         RADCLIENT *created;
124 #endif
125         time_t now;
126         RADCLIENT *client;
127         RADCLIENT_LIST *clients;
128         listen_socket_t *sock;
129
130         rad_assert(listener != NULL);
131         rad_assert(ipaddr != NULL);
132
133         sock = listener->data;
134         clients = sock->clients;
135
136         /*
137          *      This HAS to have been initialized previously.
138          */
139         rad_assert(clients != NULL);
140
141         client = client_find(clients, ipaddr,sock->proto);
142         if (!client) {
143                 char name[256], buffer[128];
144                                         
145 #ifdef WITH_DYNAMIC_CLIENTS
146         unknown:                /* used only for dynamic clients */
147 #endif
148
149                 /*
150                  *      DoS attack quenching, but only in daemon mode.
151                  *      If they're running in debug mode, show them
152                  *      every packet.
153                  */
154                 if (debug_flag == 0) {
155                         static time_t last_printed = 0;
156
157                         now = time(NULL);
158                         if (last_printed == now) return NULL;
159                         
160                         last_printed = now;
161                 }
162
163                 listener->print(listener, name, sizeof(name));
164
165                 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
166 #ifdef WITH_TCP
167                        " proto %s"
168 #endif
169                        , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
170                                          buffer, sizeof(buffer)), src_port
171 #ifdef WITH_TCP
172                        , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
173 #endif
174                        );
175                 return NULL;
176         }
177
178 #ifndef WITH_DYNAMIC_CLIENTS
179         return client;          /* return the found client. */
180 #else
181
182         /*
183          *      No server defined, and it's not dynamic.  Return it.
184          */
185         if (!client->client_server && !client->dynamic) return client;
186
187         now = time(NULL);
188         
189         /*
190          *      It's a dynamically generated client, check it.
191          */
192         if (client->dynamic && (src_port != 0)) {
193                 /*
194                  *      Lives forever.  Return it.
195                  */
196                 if (client->lifetime == 0) return client;
197                 
198                 /*
199                  *      Rate-limit the deletion of known clients.
200                  *      This makes them last a little longer, but
201                  *      prevents the server from melting down if (say)
202                  *      10k clients all expire at once.
203                  */
204                 if (now == client->last_new_client) return client;
205
206                 /*
207                  *      It's not dead yet.  Return it.
208                  */
209                 if ((client->created + client->lifetime) > now) return client;
210                 
211                 /*
212                  *      This really puts them onto a queue for later
213                  *      deletion.
214                  */
215                 client_delete(clients, client);
216
217                 /*
218                  *      Go find the enclosing network again.
219                  */
220                 client = client_find(clients, ipaddr, sock->proto);
221
222                 /*
223                  *      WTF?
224                  */
225                 if (!client) goto unknown;
226                 if (!client->client_server) goto unknown;
227
228                 /*
229                  *      At this point, 'client' is the enclosing
230                  *      network that configures where dynamic clients
231                  *      can be defined.
232                  */
233                 rad_assert(client->dynamic == 0);
234
235         } else if (!client->dynamic && client->rate_limit) {
236                 /*
237                  *      The IP is unknown, so we've found an enclosing
238                  *      network.  Enable DoS protection.  We only
239                  *      allow one new client per second.  Known
240                  *      clients aren't subject to this restriction.
241                  */
242                 if (now == client->last_new_client) goto unknown;
243         }
244
245         client->last_new_client = now;
246
247         request = request_alloc();
248         if (!request) goto unknown;
249
250         request->listener = listener;
251         request->client = client;
252         request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
253         if (!request->packet) {                         /* badly formed, etc */
254                 request_free(&request);
255                 goto unknown;
256         }
257         request->reply = rad_alloc_reply(request->packet);
258         if (!request->reply) {
259                 request_free(&request);
260                 goto unknown;
261         }
262         gettimeofday(&request->packet->timestamp, NULL);
263         request->number = 0;
264         request->priority = listener->type;
265         request->server = client->client_server;
266         request->root = &mainconfig;
267
268         /*
269          *      Run a fake request through the given virtual server.
270          *      Look for FreeRADIUS-Client-IP-Address
271          *               FreeRADIUS-Client-Secret
272          *              ...
273          *
274          *      and create the RADCLIENT structure from that.
275          */
276         DEBUG("server %s {", request->server);
277
278         rcode = module_authorize(0, request);
279
280         DEBUG("} # server %s", request->server);
281
282         if (rcode != RLM_MODULE_OK) {
283                 request_free(&request);
284                 goto unknown;
285         }
286
287         /*
288          *      If the client was updated by rlm_dynamic_clients,
289          *      don't create the client from attribute-value pairs.
290          */
291         if (request->client == client) {
292                 created = client_create(clients, request);
293         } else {
294                 created = request->client;
295
296                 /*
297                  *      This frees the client if it isn't valid.
298                  */
299                 if (!client_validate(clients, client, created)) goto unknown;
300         }
301
302         request->server = client->server;
303         exec_trigger(request, NULL, "server.client.add");
304
305         request_free(&request);
306
307         if (!created) goto unknown;
308
309         return created;
310 #endif
311 }
312
313 static int listen_bind(rad_listen_t *this);
314
315
316 /*
317  *      Process and reply to a server-status request.
318  *      Like rad_authenticate and rad_accounting this should
319  *      live in it's own file but it's so small we don't bother.
320  */
321 int rad_status_server(REQUEST *request)
322 {
323         int rcode = RLM_MODULE_OK;
324         DICT_VALUE *dval;
325
326         switch (request->listener->type) {
327 #ifdef WITH_STATS
328         case RAD_LISTEN_NONE:
329 #endif
330         case RAD_LISTEN_AUTH:
331                 dval = dict_valbyname(PW_AUTZ_TYPE, 0, "Status-Server");
332                 if (dval) {
333                         rcode = module_authorize(dval->value, request);
334                 } else {
335                         rcode = RLM_MODULE_OK;
336                 }
337
338                 switch (rcode) {
339                 case RLM_MODULE_OK:
340                 case RLM_MODULE_UPDATED:
341                         request->reply->code = PW_AUTHENTICATION_ACK;
342                         break;
343
344                 case RLM_MODULE_FAIL:
345                 case RLM_MODULE_HANDLED:
346                         request->reply->code = 0; /* don't reply */
347                         break;
348
349                 default:
350                 case RLM_MODULE_REJECT:
351                         request->reply->code = PW_AUTHENTICATION_REJECT;
352                         break;
353                 }
354                 break;
355
356 #ifdef WITH_ACCOUNTING
357         case RAD_LISTEN_ACCT:
358                 dval = dict_valbyname(PW_ACCT_TYPE, 0, "Status-Server");
359                 if (dval) {
360                         rcode = module_accounting(dval->value, request);
361                 } else {
362                         rcode = RLM_MODULE_OK;
363                 }
364
365                 switch (rcode) {
366                 case RLM_MODULE_OK:
367                 case RLM_MODULE_UPDATED:
368                         request->reply->code = PW_ACCOUNTING_RESPONSE;
369                         break;
370
371                 default:
372                         request->reply->code = 0; /* don't reply */
373                         break;
374                 }
375                 break;
376 #endif
377
378 #ifdef WITH_COA
379                 /*
380                  *      This is a vendor extension.  Suggested by Glen
381                  *      Zorn in IETF 72, and rejected by the rest of
382                  *      the WG.  We like it, so it goes in here.
383                  */
384         case RAD_LISTEN_COA:
385                 dval = dict_valbyname(PW_RECV_COA_TYPE, 0, "Status-Server");
386                 if (dval) {
387                         rcode = module_recv_coa(dval->value, request);
388                 } else {
389                         rcode = RLM_MODULE_OK;
390                 }
391
392                 switch (rcode) {
393                 case RLM_MODULE_OK:
394                 case RLM_MODULE_UPDATED:
395                         request->reply->code = PW_COA_ACK;
396                         break;
397
398                 default:
399                         request->reply->code = 0; /* don't reply */
400                         break;
401                 }
402                 break;
403 #endif
404
405         default:
406                 return 0;
407         }
408
409 #ifdef WITH_STATS
410         /*
411          *      Full statistics are available only on a statistics
412          *      socket.
413          */
414         if (request->listener->type == RAD_LISTEN_NONE) {
415                 request_stats_reply(request);
416         }
417 #endif
418
419         return 0;
420 }
421
422 #ifdef WITH_TCP
423 static int dual_tcp_recv(rad_listen_t *listener)
424 {
425         int rcode;
426         RADIUS_PACKET   *packet;
427         RAD_REQUEST_FUNP fun = NULL;
428         listen_socket_t *sock = listener->data;
429         RADCLIENT       *client = sock->client;
430
431         /*
432          *      Allocate a packet for partial reads.
433          */
434         if (!sock->packet) {
435                 sock->packet = rad_alloc(0);
436                 if (!sock->packet) return 0;
437
438                 sock->packet->sockfd = listener->fd;
439                 sock->packet->src_ipaddr = sock->other_ipaddr;
440                 sock->packet->src_port = sock->other_port;
441                 sock->packet->dst_ipaddr = sock->my_ipaddr;
442                 sock->packet->dst_port = sock->my_port;
443         }
444         
445         /*
446          *      Grab the packet currently being processed.
447          */
448         packet = sock->packet;
449
450         rcode = fr_tcp_read_packet(packet, 0);
451
452         /*
453          *      Still only a partial packet.  Put it back, and return,
454          *      so that we'll read more data when it's ready.
455          */
456         if (rcode == 0) {
457                 return 0;
458         }
459
460         if (rcode == -1) {      /* error reading packet */
461                 char buffer[256];
462
463                 radlog(L_ERR, "Invalid packet from %s port %d: closing socket",
464                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
465                        packet->src_port);
466         }
467
468         if (rcode < 0) {        /* error or connection reset */
469                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
470
471                 /*
472                  *      Decrement the number of connections.
473                  */
474                 if (sock->parent->num_connections > 0) {
475                         sock->parent->num_connections--;
476                 }
477                 if (sock->client->num_connections > 0) {
478                         sock->client->num_connections--;
479                 }
480
481                 /*
482                  *      Tell the event handler that an FD has disappeared.
483                  */
484                 DEBUG("Client has closed connection");
485                 event_new_fd(listener);
486
487                 /*
488                  *      Do NOT free the listener here.  It's in use by
489                  *      a request, and will need to hang around until
490                  *      all of the requests are done.
491                  *
492                  *      It is instead free'd in remove_from_request_hash()
493                  */
494                 return 0;
495         }
496
497         /*
498          *      Some sanity checks, based on the packet code.
499          */
500         switch(packet->code) {
501         case PW_AUTHENTICATION_REQUEST:
502                 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
503                 FR_STATS_INC(auth, total_requests);
504                 fun = rad_authenticate;
505                 break;
506
507 #ifdef WITH_ACCOUNTING
508         case PW_ACCOUNTING_REQUEST:
509                 if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
510                 FR_STATS_INC(acct, total_requests);
511                 fun = rad_accounting;
512                 break;
513 #endif
514
515         case PW_STATUS_SERVER:
516                 if (!mainconfig.status_server) {
517                         FR_STATS_INC(auth, total_unknown_types);
518                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
519                         rad_free(&sock->packet);
520                         return 0;
521                 }
522                 fun = rad_status_server;
523                 break;
524
525         default:
526         bad_packet:
527                 FR_STATS_INC(auth, total_unknown_types);
528
529                 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
530                       packet->code, client->shortname, packet->src_port);
531                 rad_free(&sock->packet);
532                 return 0;
533         } /* switch over packet types */
534
535         if (!request_receive(listener, packet, client, fun)) {
536                 FR_STATS_INC(auth, total_packets_dropped);
537                 rad_free(&sock->packet);
538                 return 0;
539         }
540
541         sock->packet = NULL;    /* we have no need for more partial reads */
542         return 1;
543 }
544
545 static int dual_tcp_accept(rad_listen_t *listener)
546 {
547         int newfd, src_port;
548         rad_listen_t *this;
549         socklen_t salen;
550         struct sockaddr_storage src;
551         listen_socket_t *sock;
552         fr_ipaddr_t src_ipaddr;
553         RADCLIENT *client = NULL;
554         
555         salen = sizeof(src);
556
557         DEBUG2(" ... new connection request on TCP socket.");
558         
559         newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
560         if (newfd < 0) {
561                 /*
562                  *      Non-blocking sockets must handle this.
563                  */
564 #ifdef EWOULDBLOCK
565                 if (errno == EWOULDBLOCK) {
566                         return 0;
567                 }
568 #endif
569
570                 DEBUG2(" ... failed to accept connection.");
571                 return -1;
572         }
573
574         if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
575                 DEBUG2(" ... unknown address family.");
576                 return 0;
577         }
578
579         /*
580          *      Enforce client IP address checks on accept, not on
581          *      every packet.
582          */
583         if ((client = client_listener_find(listener,
584                                            &src_ipaddr, src_port)) == NULL) {
585                 close(newfd);
586                 FR_STATS_INC(auth, total_invalid_requests);
587                 return 0;
588         }
589
590         /*
591          *      Enforce max_connectionsx on client && listen section.
592          */
593         if ((client->max_connections != 0) &&
594             (client->max_connections == client->num_connections)) {
595                 /*
596                  *      FIXME: Print client IP/port, and server IP/port.
597                  */
598                 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->max_connections);
599                 close(newfd);
600                 return 0;
601         }
602
603         sock = listener->data;
604         if ((sock->max_connections != 0) &&
605             (sock->max_connections == sock->num_connections)) {
606                 /*
607                  *      FIXME: Print client IP/port, and server IP/port.
608                  */
609                 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
610                 close(newfd);
611                 return 0;
612         }
613         client->num_connections++;
614         sock->num_connections++;
615
616         /*
617          *      Add the new listener.
618          */
619         this = listen_alloc(listener->type);
620         if (!this) return -1;
621
622         /*
623          *      Copy everything, including the pointer to the socket
624          *      information.
625          */
626         sock = this->data;
627         memcpy(this->data, listener->data, sizeof(*sock));
628         memcpy(this, listener, sizeof(*this));
629         this->next = NULL;
630         this->data = sock;      /* fix it back */
631
632         sock->parent = listener->data;
633         sock->other_ipaddr = src_ipaddr;
634         sock->other_port = src_port;
635         sock->client = client;
636         sock->opened = sock->last_packet = time(NULL);
637
638         this->fd = newfd;
639         this->status = RAD_LISTEN_STATUS_INIT;
640         this->recv = dual_tcp_recv;
641
642 #ifdef WITH_TLS
643         if (this->tls) {
644                 this->recv = dual_tls_recv;
645                 this->send = dual_tls_send;
646         }
647 #endif
648
649         /*
650          *      FIXME: set O_NONBLOCK on the accept'd fd.
651          *      See djb's portability rants for details.
652          */
653
654         /*
655          *      Tell the event loop that we have a new FD.
656          *      This can be called from a child thread...
657          */
658         event_new_fd(this);
659
660         return 0;
661 }
662 #endif
663
664
665 /*
666  *      This function is stupid and complicated.
667  */
668 static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
669 {
670         size_t len;
671         listen_socket_t *sock = this->data;
672         const char *name;
673
674         switch (this->type) {
675 #ifdef WITH_STATS
676         case RAD_LISTEN_NONE:   /* what a hack... */
677                 name = "status";
678                 break;
679 #endif
680
681         case RAD_LISTEN_AUTH:
682                 name = "authentication";
683                 break;
684
685 #ifdef WITH_ACCOUNTING
686         case RAD_LISTEN_ACCT:
687                 name = "accounting";
688                 break;
689 #endif
690
691 #ifdef WITH_PROXY
692         case RAD_LISTEN_PROXY:
693                 name = "proxy";
694                 break;
695 #endif
696
697 #ifdef WITH_VMPS
698         case RAD_LISTEN_VQP:
699                 name = "vmps";
700                 break;
701 #endif
702
703 #ifdef WITH_DHCP
704         case RAD_LISTEN_DHCP:
705                 name = "dhcp";
706                 break;
707 #endif
708
709 #ifdef WITH_COA
710         case RAD_LISTEN_COA:
711                 name = "coa";
712                 break;
713 #endif
714
715         default:
716                 name = "??";
717                 break;
718         }
719
720 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
721 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
722
723         ADDSTRING(name);
724
725         if (sock->interface) {
726                 ADDSTRING(" interface ");
727                 ADDSTRING(sock->interface);
728         }
729
730 #ifdef WITH_TCP
731         if (this->recv == dual_tcp_accept) {
732                 ADDSTRING(" proto tcp");
733         }
734 #endif
735
736 #ifdef WITH_TCP
737         /*
738          *      TCP sockets get printed a little differently, to make
739          *      it clear what's going on.
740          */
741         if (sock->client) {
742                 ADDSTRING(" from client (");
743                 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
744                 FORWARD;
745
746                 ADDSTRING(", ");
747                 snprintf(buffer, bufsize, "%d", sock->other_port);
748                 FORWARD;
749                 ADDSTRING(") -> (");
750
751                 if ((sock->my_ipaddr.af == AF_INET) &&
752                     (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
753                         strlcpy(buffer, "*", bufsize);
754                 } else {
755                         ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
756                 }
757                 FORWARD;
758                 
759                 ADDSTRING(", ");
760                 snprintf(buffer, bufsize, "%d", sock->my_port);
761                 FORWARD;
762
763                 if (this->server) {
764                         ADDSTRING(", virtual-server=");
765                         ADDSTRING(this->server);
766                 }
767
768                 ADDSTRING(")");
769
770                 return 1;
771         }
772
773 #ifdef WITH_PROXY
774         /*
775          *      Maybe it's a socket that we opened to a home server.
776          */
777         if ((sock->proto == IPPROTO_TCP) &&
778             (this->type == RAD_LISTEN_PROXY)) {
779                 ADDSTRING(" (");
780                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
781                 FORWARD;
782
783                 ADDSTRING(", ");
784                 snprintf(buffer, bufsize, "%d", sock->my_port);
785                 FORWARD;
786                 ADDSTRING(") -> home_server (");
787
788                 if ((sock->other_ipaddr.af == AF_INET) &&
789                     (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
790                         strlcpy(buffer, "*", bufsize);
791                 } else {
792                         ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
793                 }
794                 FORWARD;
795                 
796                 ADDSTRING(", ");
797                 snprintf(buffer, bufsize, "%d", sock->other_port);
798                 FORWARD;
799
800                 ADDSTRING(")");
801
802                 return 1;
803         }
804 #endif  /* WITH_PROXY */
805 #endif  /* WITH_TCP */
806
807         ADDSTRING(" address ");
808         
809         if ((sock->my_ipaddr.af == AF_INET) &&
810             (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
811                 strlcpy(buffer, "*", bufsize);
812         } else {
813                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
814         }
815         FORWARD;
816
817         ADDSTRING(" port ");
818         snprintf(buffer, bufsize, "%d", sock->my_port);
819         FORWARD;
820
821 #ifdef WITH_TLS
822         if (this->tls) {
823                 ADDSTRING(" (TLS)");
824                 FORWARD;
825         }
826 #endif
827
828         if (this->server) {
829                 ADDSTRING(" as server ");
830                 ADDSTRING(this->server);
831         }
832
833 #undef ADDSTRING
834 #undef FORWARD
835
836         return 1;
837 }
838
839 extern int check_config;        /* radiusd.c */
840
841
842 /*
843  *      Parse an authentication or accounting socket.
844  */
845 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
846 {
847         int             rcode;
848         int             listen_port;
849         fr_ipaddr_t     ipaddr;
850         listen_socket_t *sock = this->data;
851         char            *section_name = NULL;
852         CONF_SECTION    *client_cs, *parentcs;
853
854         this->cs = cs;
855
856         /*
857          *      Try IPv4 first
858          */
859         memset(&ipaddr, 0, sizeof(ipaddr));
860         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
861         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
862                               &ipaddr.ipaddr.ip4addr, NULL);
863         if (rcode < 0) return -1;
864
865         if (rcode == 0) { /* successfully parsed IPv4 */
866                 ipaddr.af = AF_INET;
867
868         } else {        /* maybe IPv6? */
869                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
870                                       &ipaddr.ipaddr.ip6addr, NULL);
871                 if (rcode < 0) return -1;
872
873                 if (rcode == 1) {
874                         cf_log_err(cf_sectiontoitem(cs),
875                                    "No address specified in listen section");
876                         return -1;
877                 }
878                 ipaddr.af = AF_INET6;
879         }
880
881         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
882                               &listen_port, "0");
883         if (rcode < 0) return -1;
884
885         if ((listen_port < 0) || (listen_port > 65535)) {
886                         cf_log_err(cf_sectiontoitem(cs),
887                                    "Invalid value for \"port\"");
888                         return -1;
889         }
890
891         sock->proto = IPPROTO_UDP;
892
893         if (cf_pair_find(cs, "proto")) {
894 #ifndef WITH_TCP
895                 cf_log_err(cf_sectiontoitem(cs),
896                            "System does not support the TCP protocol.  Delete this line from the configuration file.");
897                 return -1;
898 #else
899                 char *proto = NULL;
900 #ifdef WITH_TLS
901                 CONF_SECTION *tls;
902 #endif
903
904                 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
905                                       &proto, "udp");
906                 if (rcode < 0) return -1;
907
908                 if (strcmp(proto, "udp") == 0) {
909                         sock->proto = IPPROTO_UDP;
910
911                 } else if (strcmp(proto, "tcp") == 0) {
912                         sock->proto = IPPROTO_TCP;
913
914                         rcode = cf_item_parse(cs, "max_connections", PW_TYPE_INTEGER,
915                                               &sock->max_connections, "64");
916                         if (rcode < 0) return -1;
917
918                 } else {
919                         cf_log_err(cf_sectiontoitem(cs),
920                                    "Unknown proto name \"%s\"", proto);
921                         free(proto);
922                         return -1;
923                 }
924                 free(proto);
925
926                 /*
927                  *      TCP requires a destination IP for sockets.
928                  *      UDP doesn't, so it's allowed.
929                  */
930 #ifdef WITH_PROXY
931                 if ((this->type == RAD_LISTEN_PROXY) &&
932                     (sock->proto != IPPROTO_UDP)) {
933                         cf_log_err(cf_sectiontoitem(cs),
934                                    "Proxy listeners can only listen on proto = udp");
935                         return -1;
936                 }
937 #endif  /* WITH_PROXY */
938
939 #ifdef WITH_TLS
940                 tls = cf_section_sub_find(cs, "tls");
941
942                 /*
943                  *      Don't allow TLS configurations for UDP sockets.
944                  */
945                 if (sock->proto != IPPROTO_TCP) {
946                         cf_log_err(cf_sectiontoitem(cs),
947                                    "TLS transport is not available for UDP sockets.");
948                         return -1;
949                 }
950
951                 if (tls) {
952                         /*
953                          *      FIXME: Make this better.
954                          */
955                         if (listen_port == 0) listen_port = 2083;
956
957                         this->tls = tls_server_conf_parse(tls);
958                         if (!this->tls) {
959                                 return -1;
960                         }
961
962 #ifdef HAVE_PTRHEAD_H
963                         if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
964                                 rad_assert(0 == 1);
965                                 listen_free(&this);
966                                 return 0;
967                         }
968 #endif
969
970                 }               
971 #else  /* WITH_TLS */
972                 /*
973                  *      Built without TLS.  Disallow it.
974                  */
975                 if (cf_section_sub_find(cs, "tls")) {
976                         cf_log_err(cf_sectiontoitem(cs),
977                                    "TLS transport is not available in this executable.");
978                         return -1;
979                 }
980 #endif  /* WITH_TLS */
981
982 #endif  /* WITH_TCP */
983
984                 /*
985                  *      No "proto" field.  Disallow TLS.
986                  */
987         } else if (cf_section_sub_find(cs, "tls")) {
988                 cf_log_err(cf_sectiontoitem(cs),
989                            "TLS transport is not available in this \"listen\" section.");
990                 return -1;
991         }
992
993         sock->my_ipaddr = ipaddr;
994         sock->my_port = listen_port;
995
996 #ifdef WITH_PROXY
997         if (check_config) {
998                 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
999                                 char buffer[128];
1000                                 
1001                                 DEBUG("ERROR: We have been asked to listen on %s port %d, which is also listed as a home server.  This can create a proxy loop.",
1002                                       ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1003                                       sock->my_port);
1004                                 return -1;
1005                 }
1006
1007                 return 0;       /* don't do anything */
1008         }
1009 #endif
1010
1011         /*
1012          *      If we can bind to interfaces, do so,
1013          *      else don't.
1014          */
1015         if (cf_pair_find(cs, "interface")) {
1016                 const char *value;
1017                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
1018
1019                 rad_assert(cp != NULL);
1020                 value = cf_pair_value(cp);
1021                 if (!value) {
1022                         cf_log_err(cf_sectiontoitem(cs),
1023                                    "No interface name given");
1024                         return -1;
1025                 }
1026                 sock->interface = value;
1027         }
1028
1029 #ifdef WITH_DHCP
1030         /*
1031          *      If we can do broadcasts..
1032          */
1033         if (cf_pair_find(cs, "broadcast")) {
1034 #ifndef SO_BROADCAST
1035                 cf_log_err(cf_sectiontoitem(cs),
1036                            "System does not support broadcast sockets.  Delete this line from the configuration file.");
1037                 return -1;
1038 #else
1039                 const char *value;
1040                 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
1041
1042                 if (this->type != RAD_LISTEN_DHCP) {
1043                         cf_log_err(cf_pairtoitem(cp),
1044                                    "Broadcast can only be set for DHCP listeners.  Delete this line from the configuration file.");
1045                         return -1;
1046                 }
1047                 
1048                 rad_assert(cp != NULL);
1049                 value = cf_pair_value(cp);
1050                 if (!value) {
1051                         cf_log_err(cf_sectiontoitem(cs),
1052                                    "No broadcast value given");
1053                         return -1;
1054                 }
1055
1056                 /*
1057                  *      Hack... whatever happened to cf_section_parse?
1058                  */
1059                 sock->broadcast = (strcmp(value, "yes") == 0);
1060 #endif
1061         }
1062 #endif
1063
1064         /*
1065          *      And bind it to the port.
1066          */
1067         if (listen_bind(this) < 0) {
1068                 char buffer[128];
1069                 cf_log_err(cf_sectiontoitem(cs),
1070                            "Error binding to port for %s port %d",
1071                            ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1072                            sock->my_port);
1073                 return -1;
1074         }
1075
1076 #ifdef WITH_PROXY
1077         /*
1078          *      Proxy sockets don't have clients.
1079          */
1080         if (this->type == RAD_LISTEN_PROXY) return 0;
1081 #endif
1082         
1083         /*
1084          *      The more specific configurations are preferred to more
1085          *      generic ones.
1086          */
1087         client_cs = NULL;
1088         parentcs = cf_top_section(cs);
1089         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
1090                               &section_name, NULL);
1091         if (rcode < 0) return -1; /* bad string */
1092         if (rcode == 0) {
1093                 /*
1094                  *      Explicit list given: use it.
1095                  */
1096                 client_cs = cf_section_sub_find_name2(parentcs,
1097                                                       "clients",
1098                                                       section_name);
1099                 if (!client_cs) {
1100                         client_cs = cf_section_find(section_name);
1101                 }
1102                 if (!client_cs) {
1103                         cf_log_err(cf_sectiontoitem(cs),
1104                                    "Failed to find clients %s {...}",
1105                                    section_name);
1106                         free(section_name);
1107                         return -1;
1108                 }
1109                 free(section_name);
1110         } /* else there was no "clients = " entry. */
1111
1112         if (!client_cs) {
1113                 CONF_SECTION *server_cs;
1114
1115                 server_cs = cf_section_sub_find_name2(parentcs,
1116                                                       "server",
1117                                                       this->server);
1118                 /*
1119                  *      Found a "server foo" section.  If there are clients
1120                  *      in it, use them.
1121                  */
1122                 if (server_cs &&
1123                     (cf_section_sub_find(server_cs, "client") != NULL)) {
1124                         client_cs = server_cs;
1125                 }
1126         }
1127
1128         /*
1129          *      Still nothing.  Look for global clients.
1130          */
1131         if (!client_cs) client_cs = parentcs;
1132
1133         sock->clients = clients_parse_section(client_cs);
1134         if (!sock->clients) {
1135                 cf_log_err(cf_sectiontoitem(cs),
1136                            "Failed to load clients for this listen section");
1137                 return -1;
1138         }
1139
1140 #ifdef WITH_TCP
1141         if (sock->proto == IPPROTO_TCP) {
1142                 /*
1143                  *      Re-write the listener receive function to
1144                  *      allow us to accept the socket.
1145                  */
1146                 this->recv = dual_tcp_accept;
1147         }
1148 #endif
1149
1150         return 0;
1151 }
1152
1153 /*
1154  *      Send an authentication response packet
1155  */
1156 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1157 {
1158         rad_assert(request->listener == listener);
1159         rad_assert(listener->send == auth_socket_send);
1160
1161         if (rad_send(request->reply, request->packet,
1162                      request->client->secret) < 0) {
1163                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1164                                fr_strerror());
1165                 return -1;
1166         }
1167
1168         return 0;
1169 }
1170
1171
1172 #ifdef WITH_ACCOUNTING
1173 /*
1174  *      Send an accounting response packet (or not)
1175  */
1176 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1177 {
1178         rad_assert(request->listener == listener);
1179         rad_assert(listener->send == acct_socket_send);
1180
1181         /*
1182          *      Accounting reject's are silently dropped.
1183          *
1184          *      We do it here to avoid polluting the rest of the
1185          *      code with this knowledge
1186          */
1187         if (request->reply->code == 0) return 0;
1188
1189         if (rad_send(request->reply, request->packet,
1190                      request->client->secret) < 0) {
1191                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1192                                fr_strerror());
1193                 return -1;
1194         }
1195
1196         return 0;
1197 }
1198 #endif
1199
1200 #ifdef WITH_PROXY
1201 /*
1202  *      Send a packet to a home server.
1203  *
1204  *      FIXME: have different code for proxy auth & acct!
1205  */
1206 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1207 {
1208         rad_assert(request->proxy_listener == listener);
1209         rad_assert(listener->send == proxy_socket_send);
1210
1211         if (rad_send(request->proxy, NULL,
1212                      request->home_server->secret) < 0) {
1213                 radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
1214                                fr_strerror());
1215                 return -1;
1216         }
1217
1218         return 0;
1219 }
1220 #endif
1221
1222 #ifdef WITH_STATS
1223 /*
1224  *      Check if an incoming request is "ok"
1225  *
1226  *      It takes packets, not requests.  It sees if the packet looks
1227  *      OK.  If so, it does a number of sanity checks on it.
1228   */
1229 static int stats_socket_recv(rad_listen_t *listener)
1230 {
1231         ssize_t         rcode;
1232         int             code, src_port;
1233         RADIUS_PACKET   *packet;
1234         RADCLIENT       *client = NULL;
1235         fr_ipaddr_t     src_ipaddr;
1236
1237         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1238         if (rcode < 0) return 0;
1239
1240         FR_STATS_INC(auth, total_requests);
1241
1242         if (rcode < 20) {       /* AUTH_HDR_LEN */
1243                 FR_STATS_INC(auth, total_malformed_requests);
1244                 return 0;
1245         }
1246
1247         if ((client = client_listener_find(listener,
1248                                            &src_ipaddr, src_port)) == NULL) {
1249                 rad_recv_discard(listener->fd);
1250                 FR_STATS_INC(auth, total_invalid_requests);
1251                 return 0;
1252         }
1253
1254         FR_STATS_TYPE_INC(client->auth.total_requests);
1255
1256         /*
1257          *      We only understand Status-Server on this socket.
1258          */
1259         if (code != PW_STATUS_SERVER) {
1260                 DEBUG("Ignoring packet code %d sent to Status-Server port",
1261                       code);
1262                 rad_recv_discard(listener->fd);
1263                 FR_STATS_INC(auth, total_unknown_types);
1264                 return 0;
1265         }
1266
1267         /*
1268          *      Now that we've sanity checked everything, receive the
1269          *      packet.
1270          */
1271         packet = rad_recv(listener->fd, 1); /* require message authenticator */
1272         if (!packet) {
1273                 FR_STATS_INC(auth, total_malformed_requests);
1274                 DEBUG("%s", fr_strerror());
1275                 return 0;
1276         }
1277
1278         if (!request_receive(listener, packet, client, rad_status_server)) {
1279                 FR_STATS_INC(auth, total_packets_dropped);
1280                 rad_free(&packet);
1281                 return 0;
1282         }
1283
1284         return 1;
1285 }
1286 #endif
1287
1288
1289 /*
1290  *      Check if an incoming request is "ok"
1291  *
1292  *      It takes packets, not requests.  It sees if the packet looks
1293  *      OK.  If so, it does a number of sanity checks on it.
1294   */
1295 static int auth_socket_recv(rad_listen_t *listener)
1296 {
1297         ssize_t         rcode;
1298         int             code, src_port;
1299         RADIUS_PACKET   *packet;
1300         RAD_REQUEST_FUNP fun = NULL;
1301         RADCLIENT       *client = NULL;
1302         fr_ipaddr_t     src_ipaddr;
1303
1304         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1305         if (rcode < 0) return 0;
1306
1307         FR_STATS_INC(auth, total_requests);
1308
1309         if (rcode < 20) {       /* AUTH_HDR_LEN */
1310                 FR_STATS_INC(auth, total_malformed_requests);
1311                 return 0;
1312         }
1313
1314         if ((client = client_listener_find(listener,
1315                                            &src_ipaddr, src_port)) == NULL) {
1316                 rad_recv_discard(listener->fd);
1317                 FR_STATS_INC(auth, total_invalid_requests);
1318                 return 0;
1319         }
1320
1321         FR_STATS_TYPE_INC(client->auth.total_requests);
1322
1323         /*
1324          *      Some sanity checks, based on the packet code.
1325          */
1326         switch(code) {
1327         case PW_AUTHENTICATION_REQUEST:
1328                 fun = rad_authenticate;
1329                 break;
1330
1331         case PW_STATUS_SERVER:
1332                 if (!mainconfig.status_server) {
1333                         rad_recv_discard(listener->fd);
1334                         FR_STATS_INC(auth, total_unknown_types);
1335                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1336                         return 0;
1337                 }
1338                 fun = rad_status_server;
1339                 break;
1340
1341         default:
1342                 rad_recv_discard(listener->fd);
1343                 FR_STATS_INC(auth,total_unknown_types);
1344
1345                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1346                       code, client->shortname, src_port);
1347                 return 0;
1348                 break;
1349         } /* switch over packet types */
1350
1351         /*
1352          *      Now that we've sanity checked everything, receive the
1353          *      packet.
1354          */
1355         packet = rad_recv(listener->fd, client->message_authenticator);
1356         if (!packet) {
1357                 FR_STATS_INC(auth, total_malformed_requests);
1358                 DEBUG("%s", fr_strerror());
1359                 return 0;
1360         }
1361
1362         if (!request_receive(listener, packet, client, fun)) {
1363                 FR_STATS_INC(auth, total_packets_dropped);
1364                 rad_free(&packet);
1365                 return 0;
1366         }
1367
1368         return 1;
1369 }
1370
1371
1372 #ifdef WITH_ACCOUNTING
1373 /*
1374  *      Receive packets from an accounting socket
1375  */
1376 static int acct_socket_recv(rad_listen_t *listener)
1377 {
1378         ssize_t         rcode;
1379         int             code, src_port;
1380         RADIUS_PACKET   *packet;
1381         RAD_REQUEST_FUNP fun = NULL;
1382         RADCLIENT       *client = NULL;
1383         fr_ipaddr_t     src_ipaddr;
1384
1385         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1386         if (rcode < 0) return 0;
1387
1388         FR_STATS_INC(acct, total_requests);
1389
1390         if (rcode < 20) {       /* AUTH_HDR_LEN */
1391                 FR_STATS_INC(acct, total_malformed_requests);
1392                 return 0;
1393         }
1394
1395         if ((client = client_listener_find(listener,
1396                                            &src_ipaddr, src_port)) == NULL) {
1397                 rad_recv_discard(listener->fd);
1398                 FR_STATS_INC(acct, total_invalid_requests);
1399                 return 0;
1400         }
1401
1402         FR_STATS_TYPE_INC(client->acct.total_requests);
1403
1404         /*
1405          *      Some sanity checks, based on the packet code.
1406          */
1407         switch(code) {
1408         case PW_ACCOUNTING_REQUEST:
1409                 fun = rad_accounting;
1410                 break;
1411
1412         case PW_STATUS_SERVER:
1413                 if (!mainconfig.status_server) {
1414                         rad_recv_discard(listener->fd);
1415                         FR_STATS_INC(acct, total_unknown_types);
1416
1417                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1418                         return 0;
1419                 }
1420                 fun = rad_status_server;
1421                 break;
1422
1423         default:
1424                 rad_recv_discard(listener->fd);
1425                 FR_STATS_INC(acct, total_unknown_types);
1426
1427                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1428                       code, client->shortname, src_port);
1429                 return 0;
1430         } /* switch over packet types */
1431
1432         /*
1433          *      Now that we've sanity checked everything, receive the
1434          *      packet.
1435          */
1436         packet = rad_recv(listener->fd, 0);
1437         if (!packet) {
1438                 FR_STATS_INC(acct, total_malformed_requests);
1439                 radlog(L_ERR, "%s", fr_strerror());
1440                 return 0;
1441         }
1442
1443         /*
1444          *      There can be no duplicate accounting packets.
1445          */
1446         if (!request_receive(listener, packet, client, fun)) {
1447                 FR_STATS_INC(acct, total_packets_dropped);
1448                 rad_free(&packet);
1449                 return 0;
1450         }
1451
1452         return 1;
1453 }
1454 #endif
1455
1456
1457 #ifdef WITH_COA
1458 static int do_proxy(REQUEST *request)
1459 {
1460         VALUE_PAIR *vp;
1461
1462         if (request->in_proxy_hash ||
1463             (request->proxy_reply && (request->proxy_reply->code != 0))) {
1464                 return 0;
1465         }
1466
1467         vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0);
1468         if (!vp) return 0;
1469         
1470         if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
1471                 RDEBUG2("ERROR: Cannot proxy to unknown pool %s",
1472                         vp->vp_strvalue);
1473                 return 0;
1474         }
1475
1476         return 1;
1477 }
1478
1479 /*
1480  *      Receive a CoA packet.
1481  */
1482 static int rad_coa_recv(REQUEST *request)
1483 {
1484         int rcode = RLM_MODULE_OK;
1485         int ack, nak;
1486         VALUE_PAIR *vp;
1487
1488         /*
1489          *      Get the correct response
1490          */
1491         switch (request->packet->code) {
1492         case PW_COA_REQUEST:
1493                 ack = PW_COA_ACK;
1494                 nak = PW_COA_NAK;
1495                 break;
1496
1497         case PW_DISCONNECT_REQUEST:
1498                 ack = PW_DISCONNECT_ACK;
1499                 nak = PW_DISCONNECT_NAK;
1500                 break;
1501
1502         default:                /* shouldn't happen */
1503                 return RLM_MODULE_FAIL;
1504         }
1505
1506 #ifdef WITH_PROXY
1507 #define WAS_PROXIED (request->proxy)
1508 #else
1509 #define WAS_PROXIED (0)
1510 #endif
1511
1512         if (!WAS_PROXIED) {
1513                 /*
1514                  *      RFC 5176 Section 3.3.  If we have a CoA-Request
1515                  *      with Service-Type = Authorize-Only, it MUST
1516                  *      have a State attribute in it.
1517                  */
1518                 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0);
1519                 if (request->packet->code == PW_COA_REQUEST) {
1520                         if (vp && (vp->vp_integer == 17)) {
1521                                 vp = pairfind(request->packet->vps, PW_STATE, 0);
1522                                 if (!vp || (vp->length == 0)) {
1523                                         RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1524                                         request->reply->code = PW_COA_NAK;
1525                                         return RLM_MODULE_FAIL;
1526                                 }
1527                         }
1528                 } else if (vp) {
1529                         /*
1530                          *      RFC 5176, Section 3.2.
1531                          */
1532                         RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1533                         request->reply->code = PW_DISCONNECT_NAK;
1534                         return RLM_MODULE_FAIL;
1535                 }
1536
1537                 rcode = module_recv_coa(0, request);
1538                 switch (rcode) {
1539                 case RLM_MODULE_FAIL:
1540                 case RLM_MODULE_INVALID:
1541                 case RLM_MODULE_REJECT:
1542                 case RLM_MODULE_USERLOCK:
1543                 default:
1544                         request->reply->code = nak;
1545                         break;
1546                         
1547                 case RLM_MODULE_HANDLED:
1548                         return rcode;
1549                         
1550                 case RLM_MODULE_NOOP:
1551                 case RLM_MODULE_NOTFOUND:
1552                 case RLM_MODULE_OK:
1553                 case RLM_MODULE_UPDATED:
1554                         if (do_proxy(request)) return RLM_MODULE_OK;
1555                         request->reply->code = ack;
1556                         break;
1557                 }
1558         } else if (request->proxy_reply) {
1559                 /*
1560                  *      Start the reply code with the proxy reply
1561                  *      code.
1562                  */
1563                 request->reply->code = request->proxy_reply->code;
1564         }
1565
1566         /*
1567          *      Copy State from the request to the reply.
1568          *      See RFC 5176 Section 3.3.
1569          */
1570         vp = paircopy2(request->packet->vps, PW_STATE, 0);
1571         if (vp) pairadd(&request->reply->vps, vp);
1572
1573         /*
1574          *      We may want to over-ride the reply.
1575          */
1576         if (request->reply->code) {
1577                 rcode = module_send_coa(0, request);
1578                 switch (rcode) {
1579                         /*
1580                          *      We need to send CoA-NAK back if Service-Type
1581                          *      is Authorize-Only.  Rely on the user's policy
1582                          *      to do that.  We're not a real NAS, so this
1583                          *      restriction doesn't (ahem) apply to us.
1584                          */
1585                 case RLM_MODULE_FAIL:
1586                 case RLM_MODULE_INVALID:
1587                 case RLM_MODULE_REJECT:
1588                 case RLM_MODULE_USERLOCK:
1589                 default:
1590                         /*
1591                          *      Over-ride an ACK with a NAK
1592                          */
1593                         request->reply->code = nak;
1594                         break;
1595                         
1596                 case RLM_MODULE_HANDLED:
1597                         return rcode;
1598                         
1599                 case RLM_MODULE_NOOP:
1600                 case RLM_MODULE_NOTFOUND:
1601                 case RLM_MODULE_OK:
1602                 case RLM_MODULE_UPDATED:
1603                         /*
1604                          *      Do NOT over-ride a previously set value.
1605                          *      Otherwise an "ok" here will re-write a
1606                          *      NAK to an ACK.
1607                          */
1608                         if (request->reply->code == 0) {
1609                                 request->reply->code = ack;
1610                         }
1611                         break;
1612                 }
1613         }
1614
1615         return RLM_MODULE_OK;
1616 }
1617
1618
1619 /*
1620  *      Check if an incoming request is "ok"
1621  *
1622  *      It takes packets, not requests.  It sees if the packet looks
1623  *      OK.  If so, it does a number of sanity checks on it.
1624   */
1625 static int coa_socket_recv(rad_listen_t *listener)
1626 {
1627         ssize_t         rcode;
1628         int             code, src_port;
1629         RADIUS_PACKET   *packet;
1630         RAD_REQUEST_FUNP fun = NULL;
1631         RADCLIENT       *client = NULL;
1632         fr_ipaddr_t     src_ipaddr;
1633
1634         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1635         if (rcode < 0) return 0;
1636
1637         if (rcode < 20) {       /* AUTH_HDR_LEN */
1638                 FR_STATS_INC(coa, total_requests);
1639                 FR_STATS_INC(coa, total_malformed_requests);
1640                 return 0;
1641         }
1642
1643         if ((client = client_listener_find(listener,
1644                                            &src_ipaddr, src_port)) == NULL) {
1645                 rad_recv_discard(listener->fd);
1646                 FR_STATS_INC(coa, total_requests);
1647                 FR_STATS_INC(coa, total_invalid_requests);
1648                 return 0;
1649         }
1650
1651         /*
1652          *      Some sanity checks, based on the packet code.
1653          */
1654         switch(code) {
1655         case PW_COA_REQUEST:
1656                 FR_STATS_INC(coa, total_requests);
1657                 fun = rad_coa_recv;
1658                 break;
1659
1660         case PW_DISCONNECT_REQUEST:
1661                 FR_STATS_INC(dsc, total_requests);
1662                 fun = rad_coa_recv;
1663                 break;
1664
1665         default:
1666                 rad_recv_discard(listener->fd);
1667                 FR_STATS_INC(coa, total_unknown_types);
1668                 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1669                       code, client->shortname, src_port);
1670                 return 0;
1671         } /* switch over packet types */
1672
1673         /*
1674          *      Now that we've sanity checked everything, receive the
1675          *      packet.
1676          */
1677         packet = rad_recv(listener->fd, client->message_authenticator);
1678         if (!packet) {
1679                 FR_STATS_INC(coa, total_malformed_requests);
1680                 DEBUG("%s", fr_strerror());
1681                 return 0;
1682         }
1683
1684         if (!request_receive(listener, packet, client, fun)) {
1685                 FR_STATS_INC(coa, total_packets_dropped);
1686                 rad_free(&packet);
1687                 return 0;
1688         }
1689
1690         return 1;
1691 }
1692 #endif
1693
1694 #ifdef WITH_PROXY
1695 /*
1696  *      Recieve packets from a proxy socket.
1697  */
1698 static int proxy_socket_recv(rad_listen_t *listener)
1699 {
1700         RADIUS_PACKET   *packet;
1701         char            buffer[128];
1702
1703         packet = rad_recv(listener->fd, 0);
1704         if (!packet) {
1705                 radlog(L_ERR, "%s", fr_strerror());
1706                 return 0;
1707         }
1708
1709         /*
1710          *      FIXME: Client MIB updates?
1711          */
1712         switch(packet->code) {
1713         case PW_AUTHENTICATION_ACK:
1714         case PW_ACCESS_CHALLENGE:
1715         case PW_AUTHENTICATION_REJECT:
1716                 break;
1717
1718 #ifdef WITH_ACCOUNTING
1719         case PW_ACCOUNTING_RESPONSE:
1720                 break;
1721 #endif
1722
1723 #ifdef WITH_COA
1724         case PW_DISCONNECT_ACK:
1725         case PW_DISCONNECT_NAK:
1726         case PW_COA_ACK:
1727         case PW_COA_NAK:
1728                 break;
1729 #endif
1730
1731         default:
1732                 /*
1733                  *      FIXME: Update MIB for packet types?
1734                  */
1735                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1736                        "from home server %s port %d - ID %d : IGNORED",
1737                        packet->code,
1738                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1739                        packet->src_port, packet->id);
1740                 rad_free(&packet);
1741                 return 0;
1742         }
1743
1744         if (!request_proxy_reply(packet)) {
1745                 rad_free(&packet);
1746                 return 0;
1747         }
1748
1749         return 1;
1750 }
1751
1752 #ifdef WITH_TCP
1753 /*
1754  *      Recieve packets from a proxy socket.
1755  */
1756 static int proxy_socket_tcp_recv(rad_listen_t *listener)
1757 {
1758         RADIUS_PACKET   *packet;
1759         listen_socket_t *sock = listener->data;
1760         char            buffer[128];
1761
1762         packet = fr_tcp_recv(listener->fd, 0);
1763         if (!packet) {
1764                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1765                 event_new_fd(listener);
1766                 return 0;
1767         }
1768
1769         /*
1770          *      FIXME: Client MIB updates?
1771          */
1772         switch(packet->code) {
1773         case PW_AUTHENTICATION_ACK:
1774         case PW_ACCESS_CHALLENGE:
1775         case PW_AUTHENTICATION_REJECT:
1776                 break;
1777
1778 #ifdef WITH_ACCOUNTING
1779         case PW_ACCOUNTING_RESPONSE:
1780                 break;
1781 #endif
1782
1783         default:
1784                 /*
1785                  *      FIXME: Update MIB for packet types?
1786                  */
1787                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1788                        "from home server %s port %d - ID %d : IGNORED",
1789                        packet->code,
1790                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1791                        packet->src_port, packet->id);
1792                 rad_free(&packet);
1793                 return 0;
1794         }
1795
1796         packet->src_ipaddr = sock->other_ipaddr;
1797         packet->src_port = sock->other_port;
1798         packet->dst_ipaddr = sock->my_ipaddr;
1799         packet->dst_port = sock->my_port;
1800
1801         /*
1802          *      FIXME: Have it return an indication of packets that
1803          *      are OK to ignore (dups, too late), versus ones that
1804          *      aren't OK to ignore (unknown response, spoofed, etc.)
1805          *
1806          *      Close the socket on bad packets...
1807          */
1808         if (!request_proxy_reply(packet)) {
1809                 rad_free(&packet);
1810                 return 0;
1811         }
1812
1813         sock->opened = sock->last_packet = time(NULL);
1814
1815         return 1;
1816 }
1817 #endif
1818 #endif
1819
1820
1821 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1822 {
1823         if (!request->reply->code) return 0;
1824
1825         if (rad_encode(request->reply, request->packet,
1826                        request->client->secret) < 0) {
1827                 radlog_request(L_ERR, 0, request, "Failed encoding packet: %s",
1828                                fr_strerror());
1829                 return -1;
1830         }
1831
1832         if (rad_sign(request->reply, request->packet,
1833                      request->client->secret) < 0) {
1834                 radlog_request(L_ERR, 0, request, "Failed signing packet: %s",
1835                                fr_strerror());
1836                 return -1;
1837         }
1838
1839         return 0;
1840 }
1841
1842
1843 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1844 {
1845         if (rad_verify(request->packet, NULL,
1846                        request->client->secret) < 0) {
1847                 return -1;
1848         }
1849
1850         return rad_decode(request->packet, NULL,
1851                           request->client->secret);
1852 }
1853
1854 #ifdef WITH_PROXY
1855 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1856 {
1857         if (rad_encode(request->proxy, NULL, request->home_server->secret) < 0) {
1858                 radlog_request(L_ERR, 0, request, "Failed encoding proxied packet: %s",
1859                                fr_strerror());
1860                 return -1;
1861         }
1862
1863         if (rad_sign(request->proxy, NULL, request->home_server->secret) < 0) {
1864                 radlog_request(L_ERR, 0, request, "Failed signing proxied packet: %s",
1865                                fr_strerror());
1866                 return -1;
1867         }
1868
1869         return 0;
1870 }
1871
1872
1873 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1874 {
1875         /*
1876          *      rad_verify is run in event.c, received_proxy_response()
1877          */
1878
1879         return rad_decode(request->proxy_reply, request->proxy,
1880                            request->home_server->secret);
1881 }
1882 #endif
1883
1884 #include "dhcpd.c"
1885
1886 #include "command.c"
1887
1888 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1889 #ifdef WITH_STATS
1890         { common_socket_parse, NULL,
1891           stats_socket_recv, auth_socket_send,
1892           socket_print, client_socket_encode, client_socket_decode },
1893 #else
1894         /*
1895          *      This always gets defined.
1896          */
1897         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1898 #endif
1899
1900 #ifdef WITH_PROXY
1901         /* proxying */
1902         { common_socket_parse, NULL,
1903           proxy_socket_recv, proxy_socket_send,
1904           socket_print, proxy_socket_encode, proxy_socket_decode },
1905 #endif
1906
1907         /* authentication */
1908         { common_socket_parse, NULL,
1909           auth_socket_recv, auth_socket_send,
1910           socket_print, client_socket_encode, client_socket_decode },
1911
1912 #ifdef WITH_ACCOUNTING
1913         /* accounting */
1914         { common_socket_parse, NULL,
1915           acct_socket_recv, acct_socket_send,
1916           socket_print, client_socket_encode, client_socket_decode},
1917 #endif
1918
1919 #ifdef WITH_DETAIL
1920         /* detail */
1921         { detail_parse, detail_free,
1922           detail_recv, detail_send,
1923           detail_print, detail_encode, detail_decode },
1924 #endif
1925
1926 #ifdef WITH_VMPS
1927         /* vlan query protocol */
1928         { common_socket_parse, NULL,
1929           vqp_socket_recv, vqp_socket_send,
1930           socket_print, vqp_socket_encode, vqp_socket_decode },
1931 #endif
1932
1933 #ifdef WITH_DHCP
1934         /* dhcp query protocol */
1935         { dhcp_socket_parse, NULL,
1936           dhcp_socket_recv, dhcp_socket_send,
1937           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1938 #endif
1939
1940 #ifdef WITH_COMMAND_SOCKET
1941         /* TCP command socket */
1942         { command_socket_parse, command_socket_free,
1943           command_domain_accept, command_domain_send,
1944           command_socket_print, command_socket_encode, command_socket_decode },
1945 #endif
1946
1947 #ifdef WITH_COA
1948         /* Change of Authorization */
1949         { common_socket_parse, NULL,
1950           coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1951           socket_print, client_socket_encode, client_socket_decode },
1952 #endif
1953
1954 };
1955
1956
1957
1958 /*
1959  *      Binds a listener to a socket.
1960  */
1961 static int listen_bind(rad_listen_t *this)
1962 {
1963         int rcode;
1964         struct sockaddr_storage salocal;
1965         socklen_t       salen;
1966         listen_socket_t *sock = this->data;
1967 #ifndef WITH_TCP
1968 #define proto_for_port "udp"
1969 #define sock_type SOCK_DGRAM
1970 #else
1971         const char *proto_for_port = "udp";
1972         int sock_type = SOCK_DGRAM;
1973         
1974         if (sock->proto == IPPROTO_TCP) {
1975 #ifdef WITH_VMPS
1976                 if (this->type == RAD_LISTEN_VQP) {
1977                         radlog(L_ERR, "VQP does not support TCP transport");
1978                         return -1;
1979                 }
1980 #endif
1981
1982                 proto_for_port = "tcp";
1983                 sock_type = SOCK_STREAM;        
1984         }
1985 #endif
1986
1987         /*
1988          *      If the port is zero, then it means the appropriate
1989          *      thing from /etc/services.
1990          */
1991         if (sock->my_port == 0) {
1992                 struct servent  *svp;
1993
1994                 switch (this->type) {
1995                 case RAD_LISTEN_AUTH:
1996                         svp = getservbyname ("radius", proto_for_port);
1997                         if (svp != NULL) {
1998                                 sock->my_port = ntohs(svp->s_port);
1999                         } else {
2000                                 sock->my_port = PW_AUTH_UDP_PORT;
2001                         }
2002                         break;
2003
2004 #ifdef WITH_ACCOUNTING
2005                 case RAD_LISTEN_ACCT:
2006                         svp = getservbyname ("radacct", proto_for_port);
2007                         if (svp != NULL) {
2008                                 sock->my_port = ntohs(svp->s_port);
2009                         } else {
2010                                 sock->my_port = PW_ACCT_UDP_PORT;
2011                         }
2012                         break;
2013 #endif
2014
2015 #ifdef WITH_PROXY
2016                 case RAD_LISTEN_PROXY:
2017                         /* leave it at zero */
2018                         break;
2019 #endif
2020
2021 #ifdef WITH_VMPS
2022                 case RAD_LISTEN_VQP:
2023                         sock->my_port = 1589;
2024                         break;
2025 #endif
2026
2027 #ifdef WITH_COA
2028                 case RAD_LISTEN_COA:
2029                         svp = getservbyname ("radius-dynauth", "udp");
2030                         if (svp != NULL) {
2031                                 sock->my_port = ntohs(svp->s_port);
2032                         } else {
2033                                 sock->my_port = PW_COA_UDP_PORT;
2034                         }
2035                         break;
2036 #endif
2037
2038                 default:
2039                         DEBUG("WARNING: Internal sanity check failed in binding to socket.  Ignoring problem.");
2040                         return -1;
2041                 }
2042         }
2043
2044         /*
2045          *      Don't open sockets if we're checking the config.
2046          */
2047         if (check_config) {
2048                 this->fd = -1;
2049                 return 0;
2050         }
2051
2052         /*
2053          *      Copy fr_socket() here, as we may need to bind to a device.
2054          */
2055         this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
2056         if (this->fd < 0) {
2057                 char buffer[256];
2058
2059                 this->print(this, buffer, sizeof(buffer));
2060
2061                 radlog(L_ERR, "Failed opening %s: %s", buffer, strerror(errno));
2062                 return -1;
2063         }
2064                 
2065         /*
2066          *      Bind to a device BEFORE touching IP addresses.
2067          */
2068         if (sock->interface) {
2069 #ifdef SO_BINDTODEVICE
2070                 struct ifreq ifreq;
2071
2072                 memset(&ifreq, 0, sizeof(ifreq));
2073                 strlcpy(ifreq.ifr_name, sock->interface, sizeof(ifreq.ifr_name));
2074
2075                 fr_suid_up();
2076                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
2077                                    (char *)&ifreq, sizeof(ifreq));
2078                 fr_suid_down();
2079                 if (rcode < 0) {
2080                         close(this->fd);
2081                         radlog(L_ERR, "Failed binding to interface %s: %s",
2082                                sock->interface, strerror(errno));
2083                         return -1;
2084                 } /* else it worked. */
2085 #else
2086 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2087 #ifdef HAVE_NET_IF_H
2088                 /*
2089                  *      Odds are that any system supporting "bind to
2090                  *      device" also supports IPv6, so this next bit
2091                  *      isn't necessary.  But it's here for
2092                  *      completeness.
2093                  *
2094                  *      If we're doing IPv6, and the scope hasn't yet
2095                  *      been defined, set the scope to the scope of
2096                  *      the interface.
2097                  */
2098                 if (sock->my_ipaddr.af == AF_INET6) {
2099                         if (sock->my_ipaddr.scope == 0) {
2100                                 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
2101                                 if (sock->my_ipaddr.scope == 0) {
2102                                         close(this->fd);
2103                                         radlog(L_ERR, "Failed finding interface %s: %s",
2104                                                sock->interface, strerror(errno));
2105                                         return -1;
2106                                 }
2107                         } /* else scope was defined: we're OK. */
2108                 } else
2109 #endif
2110 #endif
2111                                 /*
2112                                  *      IPv4: no link local addresses,
2113                                  *      and no bind to device.
2114                                  */
2115                 {
2116                         close(this->fd);
2117                         radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
2118                         return -1;
2119                 }
2120 #endif
2121         }
2122
2123 #ifdef WITH_TCP
2124         if (sock->proto == IPPROTO_TCP) {
2125                 int on = 1;
2126
2127                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2128                         close(this->fd);
2129                         radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2130                         return -1;
2131                 }
2132         }
2133 #endif
2134
2135 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2136         else                    /* UDP sockets get UDPfromto */
2137 #endif
2138
2139 #ifdef WITH_UDPFROMTO
2140         /*
2141          *      Initialize udpfromto for all sockets.
2142          */
2143         if (udpfromto_init(this->fd) != 0) {
2144                 radlog(L_ERR, "Failed initializing udpfromto: %s",
2145                        strerror(errno));
2146                 close(this->fd);
2147                 return -1;
2148         }
2149 #endif
2150
2151         /*
2152          *      Set up sockaddr stuff.
2153          */
2154         if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2155                 close(this->fd);
2156                 return -1;
2157         }
2158                 
2159 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2160         if (sock->my_ipaddr.af == AF_INET6) {
2161                 /*
2162                  *      Listening on '::' does NOT get you IPv4 to
2163                  *      IPv6 mapping.  You've got to listen on an IPv4
2164                  *      address, too.  This makes the rest of the server
2165                  *      design a little simpler.
2166                  */
2167 #ifdef IPV6_V6ONLY
2168                 
2169                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2170                         int on = 1;
2171                         
2172                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2173                                    (char *)&on, sizeof(on));
2174                 }
2175 #endif /* IPV6_V6ONLY */
2176         }
2177 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2178
2179         if (sock->my_ipaddr.af == AF_INET) {
2180                 UNUSED int flag;
2181                 
2182 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2183                 /*
2184                  *      Disable PMTU discovery.  On Linux, this
2185                  *      also makes sure that the "don't fragment"
2186                  *      flag is zero.
2187                  */
2188                 flag = IP_PMTUDISC_DONT;
2189                 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2190                            &flag, sizeof(flag));
2191 #endif
2192
2193 #if defined(IP_DONTFRAG)
2194                 /*
2195                  *      Ensure that the "don't fragment" flag is zero.
2196                  */
2197                 flag = 0;
2198                 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2199                            &flag, sizeof(flag));
2200 #endif
2201         }
2202
2203 #ifdef WITH_DHCP
2204 #ifdef SO_BROADCAST
2205         if (sock->broadcast) {
2206                 int on = 1;
2207                 
2208                 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2209                         radlog(L_ERR, "Can't set broadcast option: %s\n",
2210                                strerror(errno));
2211                         return -1;
2212                 }
2213         }
2214 #endif
2215 #endif
2216
2217         /*
2218          *      May be binding to priviledged ports.
2219          */
2220         if (sock->my_port != 0) {
2221 #ifdef SO_REUSEADDR
2222                 int on = 1;
2223
2224                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2225                         radlog(L_ERR, "Can't set re-use address option: %s\n",
2226                                strerror(errno));
2227                         return -1;
2228                 }
2229 #endif
2230
2231                 fr_suid_up();
2232                 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2233                 fr_suid_down();
2234                 if (rcode < 0) {
2235                         char buffer[256];
2236                         close(this->fd);
2237                         
2238                         this->print(this, buffer, sizeof(buffer));
2239                         radlog(L_ERR, "Failed binding to %s: %s\n",
2240                                buffer, strerror(errno));
2241                         return -1;
2242                 }
2243         
2244                 /*
2245                  *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
2246                  *      kernel instead binds us to a 1.2.3.4.  If this
2247                  *      happens, notice, and remember our real IP.
2248                  */
2249                 {
2250                         struct sockaddr_storage src;
2251                         socklen_t               sizeof_src = sizeof(src);
2252                         
2253                         memset(&src, 0, sizeof_src);
2254                         if (getsockname(this->fd, (struct sockaddr *) &src,
2255                                         &sizeof_src) < 0) {
2256                                 radlog(L_ERR, "Failed getting socket name: %s",
2257                                        strerror(errno));
2258                                 return -1;
2259                         }
2260                         
2261                         if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2262                                                 &sock->my_ipaddr, &sock->my_port)) {
2263                                 radlog(L_ERR, "Socket has unsupported address family");
2264                                 return -1;
2265                         }
2266                 }
2267         }
2268
2269 #ifdef WITH_TCP
2270         if (sock->proto == IPPROTO_TCP) {
2271                 if (listen(this->fd, 8) < 0) {
2272                         close(this->fd);
2273                         radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2274                         return -1;
2275                 }
2276         } else
2277 #endif
2278
2279           if (fr_nonblock(this->fd) < 0) {
2280                   close(this->fd);
2281                   radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2282                          strerror(errno));
2283                   return -1;
2284           }
2285
2286         /*
2287          *      Mostly for proxy sockets.
2288          */
2289         sock->other_ipaddr.af = sock->my_ipaddr.af;
2290
2291 /*
2292  *      Don't screw up other people.
2293  */
2294 #undef proto_for_port
2295 #undef sock_type
2296
2297         return 0;
2298 }
2299
2300
2301 /*
2302  *      Allocate & initialize a new listener.
2303  */
2304 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2305 {
2306         rad_listen_t *this;
2307
2308         this = rad_malloc(sizeof(*this));
2309         memset(this, 0, sizeof(*this));
2310
2311         this->type = type;
2312         this->recv = master_listen[this->type].recv;
2313         this->send = master_listen[this->type].send;
2314         this->print = master_listen[this->type].print;
2315         this->encode = master_listen[this->type].encode;
2316         this->decode = master_listen[this->type].decode;
2317
2318         switch (type) {
2319 #ifdef WITH_STATS
2320         case RAD_LISTEN_NONE:
2321 #endif
2322         case RAD_LISTEN_AUTH:
2323 #ifdef WITH_ACCOUNTING
2324         case RAD_LISTEN_ACCT:
2325 #endif
2326 #ifdef WITH_PROXY
2327         case RAD_LISTEN_PROXY:
2328 #endif
2329 #ifdef WITH_VMPS
2330         case RAD_LISTEN_VQP:
2331 #endif
2332 #ifdef WITH_COA
2333         case RAD_LISTEN_COA:
2334 #endif
2335                 this->data = rad_malloc(sizeof(listen_socket_t));
2336                 memset(this->data, 0, sizeof(listen_socket_t));
2337                 break;
2338
2339 #ifdef WITH_DHCP
2340         case RAD_LISTEN_DHCP:
2341                 this->data = rad_malloc(sizeof(dhcp_socket_t));
2342                 memset(this->data, 0, sizeof(dhcp_socket_t));
2343                 break;
2344 #endif
2345
2346 #ifdef WITH_DETAIL
2347         case RAD_LISTEN_DETAIL:
2348                 this->data = NULL;
2349                 break;
2350 #endif
2351
2352 #ifdef WITH_COMMAND_SOCKET
2353         case RAD_LISTEN_COMMAND:
2354                 this->data = rad_malloc(sizeof(fr_command_socket_t));
2355                 memset(this->data, 0, sizeof(fr_command_socket_t));
2356                 break;
2357 #endif
2358
2359         default:
2360                 rad_assert("Unsupported option!" == NULL);
2361                 break;
2362         }
2363
2364         return this;
2365 }
2366
2367 #ifdef WITH_PROXY
2368 /*
2369  *      Externally visible function for creating a new proxy LISTENER.
2370  *
2371  *      Not thread-safe, but all calls to it are protected by the
2372  *      proxy mutex in event.c
2373  */
2374 int proxy_new_listener(home_server *home, int src_port)
2375 {
2376         rad_listen_t *this;
2377         listen_socket_t *sock;
2378         char buffer[256];
2379
2380         if (!home) return 0;
2381
2382         if ((home->max_connections > 0) &&
2383             (home->num_connections >= home->max_connections)) {
2384                 DEBUG("WARNING: Home server has too many open connections (%d)",
2385                       home->max_connections);
2386                 return 0;
2387         }
2388
2389         this = listen_alloc(RAD_LISTEN_PROXY);
2390
2391         sock = this->data;
2392         sock->other_ipaddr = home->ipaddr;
2393         sock->other_port = home->port;
2394         sock->home = home;
2395
2396         sock->my_ipaddr = home->src_ipaddr;
2397         sock->my_port = src_port;
2398         sock->proto = home->proto;
2399
2400         if (debug_flag >= 2) {
2401                 this->print(this, buffer, sizeof(buffer));
2402                 DEBUG("Opening new %s", buffer);
2403         }
2404
2405 #ifdef WITH_TCP
2406         sock->opened = sock->last_packet = time(NULL);
2407
2408         if (home->proto == IPPROTO_TCP) {
2409                 this->recv = proxy_socket_tcp_recv;
2410
2411                 /*
2412                  *      FIXME: connect() is blocking!
2413                  *      We do this with the proxy mutex locked, which may
2414                  *      cause large delays!
2415                  *
2416                  *      http://www.developerweb.net/forum/showthread.php?p=13486
2417                  */
2418                 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2419                                                 &home->ipaddr, home->port);
2420 #ifdef WITH_TLS
2421                 if (home->tls) {
2422                         DEBUG("Trying SSL to port %d\n", home->port);
2423                         sock->ssn = tls_new_client_session(home->tls, this->fd);
2424                         if (!sock->ssn) {
2425                                 listen_free(&this);
2426                                 return 0;
2427                         }
2428
2429                         this->recv = proxy_tls_recv;
2430                         this->send = proxy_tls_send;
2431                 }
2432 #endif
2433         } else
2434 #endif
2435                 this->fd = fr_socket(&home->src_ipaddr, src_port);
2436
2437         if (this->fd < 0) {
2438                 this->print(this, buffer,sizeof(buffer));
2439                 DEBUG("Failed opening client socket ::%s:: : %s",
2440                       buffer, fr_strerror());
2441                 listen_free(&this);
2442                 return 0;
2443         }
2444
2445         /*
2446          *      Figure out which port we were bound to.
2447          */
2448         if (sock->my_port == 0) {
2449                 struct sockaddr_storage src;
2450                 socklen_t               sizeof_src = sizeof(src);
2451                 
2452                 memset(&src, 0, sizeof_src);
2453                 if (getsockname(this->fd, (struct sockaddr *) &src,
2454                                 &sizeof_src) < 0) {
2455                         radlog(L_ERR, "Failed getting socket name: %s",
2456                                strerror(errno));
2457                         listen_free(&this);
2458                         return 0;
2459                 }
2460                 
2461                 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2462                                         &sock->my_ipaddr, &sock->my_port)) {
2463                         radlog(L_ERR, "Socket has unsupported address family");
2464                         listen_free(&this);
2465                         return 0;
2466                 }
2467         }
2468
2469         /*
2470          *      Tell the event loop that we have a new FD
2471          */
2472         if (!event_new_fd(this)) {
2473                 listen_free(&this);
2474                 return 0;
2475         }
2476         
2477         return 1;
2478 }
2479 #endif
2480
2481
2482 static const FR_NAME_NUMBER listen_compare[] = {
2483 #ifdef WITH_STATS
2484         { "status",     RAD_LISTEN_NONE },
2485 #endif
2486         { "auth",       RAD_LISTEN_AUTH },
2487 #ifdef WITH_ACCOUNTING
2488         { "acct",       RAD_LISTEN_ACCT },
2489 #endif
2490 #ifdef WITH_DETAIL
2491         { "detail",     RAD_LISTEN_DETAIL },
2492 #endif
2493 #ifdef WITH_PROXY
2494         { "proxy",      RAD_LISTEN_PROXY },
2495 #endif
2496 #ifdef WITH_VMPS
2497         { "vmps",       RAD_LISTEN_VQP },
2498 #endif
2499 #ifdef WITH_DHCP
2500         { "dhcp",       RAD_LISTEN_DHCP },
2501 #endif
2502 #ifdef WITH_COMMAND_SOCKET
2503         { "control",    RAD_LISTEN_COMMAND },
2504 #endif
2505 #ifdef WITH_COA
2506         { "coa",        RAD_LISTEN_COA },
2507 #endif
2508         { NULL, 0 },
2509 };
2510
2511
2512 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2513 {
2514         int             type, rcode;
2515         char            *listen_type;
2516         rad_listen_t    *this;
2517
2518         listen_type = NULL;
2519         
2520         cf_log_info(cs, "listen {");
2521
2522         rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2523                               &listen_type, "");
2524         if (rcode < 0) return NULL;
2525         if (rcode == 1) {
2526                 free(listen_type);
2527                 cf_log_err(cf_sectiontoitem(cs),
2528                            "No type specified in listen section");
2529                 return NULL;
2530         }
2531
2532         type = fr_str2int(listen_compare, listen_type, -1);
2533         if (type < 0) {
2534                 cf_log_err(cf_sectiontoitem(cs),
2535                            "Invalid type \"%s\" in listen section.",
2536                            listen_type);
2537                 free(listen_type);
2538                 return NULL;
2539         }
2540         free(listen_type);
2541
2542         /*
2543          *      Allow listen sections in the default config to
2544          *      refer to a server.
2545          */
2546         if (!server) {
2547                 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2548                                       &server, NULL);
2549                 if (rcode == 1) { /* compatiblity with 2.0-pre */
2550                         rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2551                                               &server, NULL);
2552                 }
2553                 if (rcode < 0) return NULL;
2554         }
2555
2556 #ifdef WITH_PROXY
2557         /*
2558          *      We were passed a virtual server, so the caller is
2559          *      defining a proxy listener inside of a virtual server.
2560          *      This isn't allowed right now.
2561          */
2562         else if (type == RAD_LISTEN_PROXY) {
2563                 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2564                 return NULL;
2565         }
2566 #endif
2567
2568         /*
2569          *      Set up cross-type data.
2570          */
2571         this = listen_alloc(type);
2572         this->server = server;
2573         this->fd = -1;
2574
2575         /*
2576          *      Call per-type parser.
2577          */
2578         if (master_listen[type].parse(cs, this) < 0) {
2579                 listen_free(&this);
2580                 return NULL;
2581         }
2582
2583         cf_log_info(cs, "}");
2584
2585         return this;
2586 }
2587
2588 #ifdef WITH_PROXY
2589 static int is_loopback(const fr_ipaddr_t *ipaddr)
2590 {
2591         /*
2592          *      We shouldn't proxy on loopback.
2593          */
2594         if ((ipaddr->af == AF_INET) &&
2595             (ipaddr->ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) {
2596                 return 1;
2597         }
2598         
2599 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2600         if ((ipaddr->af == AF_INET6) &&
2601             (IN6_IS_ADDR_LINKLOCAL(&ipaddr->ipaddr.ip6addr))) {
2602                 return 1;
2603         }
2604 #endif
2605
2606         return 0;
2607 }
2608 #endif
2609
2610 /*
2611  *      Generate a list of listeners.  Takes an input list of
2612  *      listeners, too, so we don't close sockets with waiting packets.
2613  */
2614 int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
2615 {
2616         int             override = FALSE;
2617         int             rcode;
2618         CONF_SECTION    *cs = NULL;
2619         rad_listen_t    **last;
2620         rad_listen_t    *this;
2621         fr_ipaddr_t     server_ipaddr;
2622         int             auth_port = 0;
2623 #ifdef WITH_PROXY
2624         int             defined_proxy = 0;
2625 #endif
2626 #ifndef WITH_TLS
2627         spawn_flag = spawn_flag; /* -Wunused */
2628 #endif
2629
2630         /*
2631          *      We shouldn't be called with a pre-existing list.
2632          */
2633         rad_assert(head && (*head == NULL));
2634
2635         last = head;
2636         server_ipaddr.af = AF_UNSPEC;
2637
2638         /*
2639          *      If the port is specified on the command-line,
2640          *      it over-rides the configuration file.
2641          *
2642          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2643          */
2644         if (mainconfig.port >= 0) auth_port = mainconfig.port;
2645
2646         /*
2647          *      If the IP address was configured on the command-line,
2648          *      use that as the "bind_address"
2649          */
2650         if (mainconfig.myip.af != AF_UNSPEC) {
2651                 memcpy(&server_ipaddr, &mainconfig.myip,
2652                        sizeof(server_ipaddr));
2653                 override = TRUE;
2654                 goto bind_it;
2655         }
2656
2657         /*
2658          *      Else look for bind_address and/or listen sections.
2659          */
2660         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
2661         rcode = cf_item_parse(config, "bind_address",
2662                               PW_TYPE_IPADDR,
2663                               &server_ipaddr.ipaddr.ip4addr, NULL);
2664         if (rcode < 0) return -1; /* error parsing it */
2665
2666         if (rcode == 0) { /* successfully parsed IPv4 */
2667                 listen_socket_t *sock;
2668                 server_ipaddr.af = AF_INET;
2669
2670                 radlog(L_INFO, "WARNING: The directive 'bind_address' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
2671
2672         bind_it:
2673 #ifdef WITH_VMPS
2674                 if (strcmp(progname, "vmpsd") == 0) {
2675                         this = listen_alloc(RAD_LISTEN_VQP);
2676                         if (!auth_port) auth_port = 1589;
2677                 } else
2678 #endif
2679                         this = listen_alloc(RAD_LISTEN_AUTH);
2680
2681                 sock = this->data;
2682
2683                 sock->my_ipaddr = server_ipaddr;
2684                 sock->my_port = auth_port;
2685
2686                 sock->clients = clients_parse_section(config);
2687                 if (!sock->clients) {
2688                         cf_log_err(cf_sectiontoitem(config),
2689                                    "Failed to find any clients for this listen section");
2690                         listen_free(&this);
2691                         return -1;
2692                 }
2693
2694                 if (listen_bind(this) < 0) {
2695                         listen_free(head);
2696                         radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2697                         listen_free(&this);
2698                         return -1;
2699                 }
2700                 auth_port = sock->my_port;      /* may have been updated in listen_bind */
2701                 if (override) {
2702                         cs = cf_section_sub_find_name2(config, "server",
2703                                                        mainconfig.name);
2704                         if (cs) this->server = mainconfig.name;
2705                 }
2706
2707                 *last = this;
2708                 last = &(this->next);
2709
2710 #ifdef WITH_VMPS
2711                 /*
2712                  *      No acct for vmpsd
2713                  */
2714                 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2715 #endif
2716
2717 #ifdef WITH_ACCOUNTING
2718                 /*
2719                  *      Open Accounting Socket.
2720                  *
2721                  *      If we haven't already gotten acct_port from
2722                  *      /etc/services, then make it auth_port + 1.
2723                  */
2724                 this = listen_alloc(RAD_LISTEN_ACCT);
2725                 sock = this->data;
2726
2727                 /*
2728                  *      Create the accounting socket.
2729                  *
2730                  *      The accounting port is always the
2731                  *      authentication port + 1
2732                  */
2733                 sock->my_ipaddr = server_ipaddr;
2734                 sock->my_port = auth_port + 1;
2735
2736                 sock->clients = clients_parse_section(config);
2737                 if (!sock->clients) {
2738                         cf_log_err(cf_sectiontoitem(config),
2739                                    "Failed to find any clients for this listen section");
2740                         return -1;
2741                 }
2742
2743                 if (listen_bind(this) < 0) {
2744                         listen_free(&this);
2745                         listen_free(head);
2746                         radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2747                         return -1;
2748                 }
2749
2750                 if (override) {
2751                         cs = cf_section_sub_find_name2(config, "server",
2752                                                        mainconfig.name);
2753                         if (cs) this->server = mainconfig.name;
2754                 }
2755
2756                 *last = this;
2757                 last = &(this->next);
2758 #endif
2759         } else if (mainconfig.port > 0) { /* no bind address, but a port */
2760                 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2761                        mainconfig.port);
2762                 return -1;
2763         }
2764
2765         /*
2766          *      They specified an IP on the command-line, ignore
2767          *      all listen sections except the one in '-n'.
2768          */
2769         if (mainconfig.myip.af != AF_UNSPEC) {
2770                 CONF_SECTION *subcs;
2771                 const char *name2 = cf_section_name2(cs);
2772
2773                 cs = cf_section_sub_find_name2(config, "server",
2774                                                mainconfig.name);
2775                 if (!cs) goto add_sockets;
2776
2777                 /*
2778                  *      Should really abstract this code...
2779                  */
2780                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2781                      subcs != NULL;
2782                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2783                         this = listen_parse(subcs, name2);
2784                         if (!this) {
2785                                 listen_free(head);
2786                                 return -1;
2787                         }
2788
2789                         *last = this;
2790                         last = &(this->next);
2791                 } /* loop over "listen" directives in server <foo> */
2792
2793                 goto add_sockets;
2794         }
2795
2796         /*
2797          *      Walk through the "listen" sections, if they exist.
2798          */
2799         for (cs = cf_subsection_find_next(config, NULL, "listen");
2800              cs != NULL;
2801              cs = cf_subsection_find_next(config, cs, "listen")) {
2802                 this = listen_parse(cs, NULL);
2803                 if (!this) {
2804                         listen_free(head);
2805                         return -1;
2806                 }
2807
2808                 *last = this;
2809                 last = &(this->next);
2810         }
2811
2812         /*
2813          *      Check virtual servers for "listen" sections, too.
2814          *
2815          *      FIXME: Move to virtual server init?
2816          */
2817         for (cs = cf_subsection_find_next(config, NULL, "server");
2818              cs != NULL;
2819              cs = cf_subsection_find_next(config, cs, "server")) {
2820                 CONF_SECTION *subcs;
2821                 const char *name2 = cf_section_name2(cs);
2822                 
2823                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2824                      subcs != NULL;
2825                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2826                         this = listen_parse(subcs, name2);
2827                         if (!this) {
2828                                 listen_free(head);
2829                                 return -1;
2830                         }
2831                         
2832                         *last = this;
2833                         last = &(this->next);
2834                 } /* loop over "listen" directives in virtual servers */
2835         } /* loop over virtual servers */
2836
2837 add_sockets:
2838         /*
2839          *      No sockets to receive packets, this is an error.
2840          *      proxying is pointless.
2841          */
2842         if (!*head) {
2843                 radlog(L_ERR, "The server is not configured to listen on any ports.  Cannot start.");
2844                 return -1;
2845         }
2846
2847         /*
2848          *      Print out which sockets we're listening on, and
2849          *      add them to the event list.
2850          */
2851         for (this = *head; this != NULL; this = this->next) {
2852 #ifdef WITH_PROXY
2853                 if (this->type == RAD_LISTEN_PROXY) {
2854                         defined_proxy = 1;
2855                 }
2856
2857 #endif
2858
2859 #ifdef WITH_TLS
2860                 if (!spawn_flag && this->tls) {
2861                         cf_log_err(cf_sectiontoitem(this->cs), "Threading must be enabled for TLS sockets to function properly.");
2862                         cf_log_err(cf_sectiontoitem(this->cs), "You probably need to do 'radiusd -fxx -l stdout' for debugging");
2863                         return -1;
2864                 }
2865 #endif
2866                 if (!check_config) event_new_fd(this);
2867         }
2868
2869         /*
2870          *      If we're proxying requests, open the proxy FD.
2871          *      Otherwise, don't do anything.
2872          */
2873 #ifdef WITH_PROXY
2874         if ((mainconfig.proxy_requests == TRUE) &&
2875             !check_config &&
2876             (*head != NULL) && !defined_proxy) {
2877                 listen_socket_t *sock = NULL;
2878                 int             port = 0;
2879                 home_server     home;
2880
2881                 memset(&home, 0, sizeof(home));
2882
2883                 /*
2884                  *      
2885                  */
2886                 home.proto = IPPROTO_UDP;
2887                 home.src_ipaddr = server_ipaddr;
2888
2889                 /*
2890                  *      Find the first authentication port,
2891                  *      and use it
2892                  */
2893                 for (this = *head; this != NULL; this = this->next) {
2894                         if (this->type == RAD_LISTEN_AUTH) {
2895                                 sock = this->data;
2896
2897                                 if (is_loopback(&sock->my_ipaddr)) continue;
2898
2899                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2900                                         home.src_ipaddr = sock->my_ipaddr;
2901                                 }
2902                                 port = sock->my_port + 2;
2903                                 break;
2904                         }
2905 #ifdef WITH_ACCT
2906                         if (this->type == RAD_LISTEN_ACCT) {
2907                                 sock = this->data;
2908
2909                                 if (is_loopback(&sock->my_ipaddr)) continue;
2910
2911                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2912                                         home.src_ipaddr = sock->my_ipaddr;
2913                                 }
2914                                 port = sock->my_port + 1;
2915                                 break;
2916                         }
2917 #endif
2918                 }
2919
2920                 /*
2921                  *      Address is still unspecified, use IPv4.
2922                  */
2923                 if (home.src_ipaddr.af == AF_UNSPEC) {
2924                         home.src_ipaddr.af = AF_INET;
2925                         /* everything else is already set to zero */
2926                 }
2927
2928                 home.ipaddr.af = home.src_ipaddr.af;
2929                 /* everything else is already set to zero */
2930
2931                 if (!proxy_new_listener(&home, port)) {
2932                         listen_free(head);
2933                         return -1;
2934                 }
2935         }
2936 #endif
2937
2938         /*
2939          *      Haven't defined any sockets.  Die.
2940          */
2941         if (!*head) return -1;
2942
2943         xlat_register("listen", xlat_listen, NULL);
2944
2945         return 0;
2946 }
2947
2948 /*
2949  *      Free a linked list of listeners;
2950  */
2951 void listen_free(rad_listen_t **head)
2952 {
2953         rad_listen_t *this;
2954
2955         if (!head || !*head) return;
2956
2957         this = *head;
2958         while (this) {
2959                 rad_listen_t *next = this->next;
2960
2961                 /*
2962                  *      Other code may have eaten the FD.
2963                  */
2964                 if (this->fd >= 0) close(this->fd);
2965
2966                 if (master_listen[this->type].free) {
2967                         master_listen[this->type].free(this);
2968                 }
2969
2970 #ifdef WITH_TLS
2971                 if (this->tls) tls_server_conf_free(this->tls);         
2972 #endif
2973
2974 #ifdef WITH_TCP
2975                 if ((this->type == RAD_LISTEN_AUTH)
2976 #ifdef WITH_ACCT
2977                     || (this->type == RAD_LISTEN_ACCT)
2978 #endif
2979 #ifdef WITH_PROXY
2980                     || (this->type == RAD_LISTEN_PROXY)
2981 #endif
2982                         ) {
2983                         listen_socket_t *sock = this->data;
2984
2985 #ifdef WITH_TLS
2986                         if (sock->request) {
2987                                 pthread_mutex_destroy(&(sock->mutex));
2988                                 request_free(&sock->request);
2989                                 sock->packet = NULL;
2990
2991                                 if (sock->ssn) session_free(sock->ssn);
2992                                 request_free(&sock->request);
2993                         } else
2994 #endif
2995                                 rad_free(&sock->packet);
2996
2997                 }
2998 #endif  /* WITH_TCP */
2999
3000                 free(this->data);
3001                 free(this);
3002
3003                 this = next;
3004         }
3005
3006         *head = NULL;
3007 }
3008
3009 #ifdef WITH_STATS
3010 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
3011                                           int port)
3012 {
3013         rad_listen_t *this;
3014
3015         for (this = mainconfig.listen; this != NULL; this = this->next) {
3016                 listen_socket_t *sock;
3017
3018                 if ((this->type != RAD_LISTEN_AUTH)
3019 #ifdef WITH_ACCOUNTING
3020                     && (this->type != RAD_LISTEN_ACCT)
3021 #endif
3022                     ) continue;
3023                 
3024                 sock = this->data;
3025
3026                 if ((sock->my_port == port) &&
3027                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
3028                         return sock->clients;
3029                 }
3030         }
3031
3032         return NULL;
3033 }
3034 #endif
3035
3036 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port, int proto)
3037 {
3038         rad_listen_t *this;
3039
3040         for (this = mainconfig.listen; this != NULL; this = this->next) {
3041                 listen_socket_t *sock;
3042
3043                 sock = this->data;
3044
3045                 if (sock->my_port != port) continue;
3046                 if (sock->proto != proto) continue;
3047                 if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3048
3049                 return this;
3050         }
3051
3052         /*
3053          *      Failed to find a specific one.  Find INADDR_ANY
3054          */
3055         for (this = mainconfig.listen; this != NULL; this = this->next) {
3056                 listen_socket_t *sock;
3057
3058                 sock = this->data;
3059
3060                 if (sock->my_port != port) continue;
3061                 if (sock->proto != proto) continue;
3062                 if (!fr_inaddr_any(&sock->my_ipaddr)) continue;
3063
3064                 return this;
3065         }
3066
3067         return NULL;
3068 }