Ensure struct is initialized
[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                 if (errno == EWOULDBLOCK) {
565                         return 0;
566                 }
567
568                 DEBUG2(" ... failed to accept connection.");
569                 return -1;
570         }
571
572         if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
573                 DEBUG2(" ... unknown address family.");
574                 return 0;
575         }
576
577         /*
578          *      Enforce client IP address checks on accept, not on
579          *      every packet.
580          */
581         if ((client = client_listener_find(listener,
582                                            &src_ipaddr, src_port)) == NULL) {
583                 close(newfd);
584                 FR_STATS_INC(auth, total_invalid_requests);
585                 return 0;
586         }
587
588         /*
589          *      Enforce max_connectionsx on client && listen section.
590          */
591         if ((client->max_connections != 0) &&
592             (client->max_connections == client->num_connections)) {
593                 /*
594                  *      FIXME: Print client IP/port, and server IP/port.
595                  */
596                 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->max_connections);
597                 close(newfd);
598                 return 0;
599         }
600
601         sock = listener->data;
602         if ((sock->max_connections != 0) &&
603             (sock->max_connections == sock->num_connections)) {
604                 /*
605                  *      FIXME: Print client IP/port, and server IP/port.
606                  */
607                 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
608                 close(newfd);
609                 return 0;
610         }
611         client->num_connections++;
612         sock->num_connections++;
613
614         /*
615          *      Add the new listener.
616          */
617         this = listen_alloc(listener->type);
618         if (!this) return -1;
619
620         /*
621          *      Copy everything, including the pointer to the socket
622          *      information.
623          */
624         sock = this->data;
625         memcpy(this->data, listener->data, sizeof(*sock));
626         memcpy(this, listener, sizeof(*this));
627         this->next = NULL;
628         this->data = sock;      /* fix it back */
629
630         sock->parent = listener->data;
631         sock->other_ipaddr = src_ipaddr;
632         sock->other_port = src_port;
633         sock->client = client;
634         sock->opened = sock->last_packet = time(NULL);
635
636         this->fd = newfd;
637         this->status = RAD_LISTEN_STATUS_INIT;
638         this->recv = dual_tcp_recv;
639
640 #ifdef WITH_TLS
641         if (this->tls) {
642                 this->recv = dual_tls_recv;
643                 this->send = dual_tls_send;
644         }
645 #endif
646
647         /*
648          *      FIXME: set O_NONBLOCK on the accept'd fd.
649          *      See djb's portability rants for details.
650          */
651
652         /*
653          *      Tell the event loop that we have a new FD.
654          *      This can be called from a child thread...
655          */
656         event_new_fd(this);
657
658         return 0;
659 }
660 #endif
661
662
663 /*
664  *      This function is stupid and complicated.
665  */
666 static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
667 {
668         size_t len;
669         listen_socket_t *sock = this->data;
670         const char *name;
671
672         switch (this->type) {
673 #ifdef WITH_STATS
674         case RAD_LISTEN_NONE:   /* what a hack... */
675                 name = "status";
676                 break;
677 #endif
678
679         case RAD_LISTEN_AUTH:
680                 name = "authentication";
681                 break;
682
683 #ifdef WITH_ACCOUNTING
684         case RAD_LISTEN_ACCT:
685                 name = "accounting";
686                 break;
687 #endif
688
689 #ifdef WITH_PROXY
690         case RAD_LISTEN_PROXY:
691                 name = "proxy";
692                 break;
693 #endif
694
695 #ifdef WITH_VMPS
696         case RAD_LISTEN_VQP:
697                 name = "vmps";
698                 break;
699 #endif
700
701 #ifdef WITH_DHCP
702         case RAD_LISTEN_DHCP:
703                 name = "dhcp";
704                 break;
705 #endif
706
707 #ifdef WITH_COA
708         case RAD_LISTEN_COA:
709                 name = "coa";
710                 break;
711 #endif
712
713         default:
714                 name = "??";
715                 break;
716         }
717
718 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
719 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
720
721         ADDSTRING(name);
722
723         if (sock->interface) {
724                 ADDSTRING(" interface ");
725                 ADDSTRING(sock->interface);
726         }
727
728 #ifdef WITH_TCP
729         if (this->recv == dual_tcp_accept) {
730                 ADDSTRING(" proto tcp");
731         }
732 #endif
733
734 #ifdef WITH_TCP
735         /*
736          *      TCP sockets get printed a little differently, to make
737          *      it clear what's going on.
738          */
739         if (sock->client) {
740                 ADDSTRING(" from client (");
741                 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
742                 FORWARD;
743
744                 ADDSTRING(", ");
745                 snprintf(buffer, bufsize, "%d", sock->other_port);
746                 FORWARD;
747                 ADDSTRING(") -> (");
748
749                 if ((sock->my_ipaddr.af == AF_INET) &&
750                     (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
751                         strlcpy(buffer, "*", bufsize);
752                 } else {
753                         ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
754                 }
755                 FORWARD;
756                 
757                 ADDSTRING(", ");
758                 snprintf(buffer, bufsize, "%d", sock->my_port);
759                 FORWARD;
760
761                 if (this->server) {
762                         ADDSTRING(", virtual-server=");
763                         ADDSTRING(this->server);
764                 }
765
766                 ADDSTRING(")");
767
768                 return 1;
769         }
770
771 #ifdef WITH_PROXY
772         /*
773          *      Maybe it's a socket that we opened to a home server.
774          */
775         if ((sock->proto == IPPROTO_TCP) &&
776             (this->type == RAD_LISTEN_PROXY)) {
777                 ADDSTRING(" (");
778                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
779                 FORWARD;
780
781                 ADDSTRING(", ");
782                 snprintf(buffer, bufsize, "%d", sock->my_port);
783                 FORWARD;
784                 ADDSTRING(") -> home_server (");
785
786                 if ((sock->other_ipaddr.af == AF_INET) &&
787                     (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
788                         strlcpy(buffer, "*", bufsize);
789                 } else {
790                         ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
791                 }
792                 FORWARD;
793                 
794                 ADDSTRING(", ");
795                 snprintf(buffer, bufsize, "%d", sock->other_port);
796                 FORWARD;
797
798                 ADDSTRING(")");
799
800                 return 1;
801         }
802 #endif  /* WITH_PROXY */
803 #endif  /* WITH_TCP */
804
805         ADDSTRING(" address ");
806         
807         if ((sock->my_ipaddr.af == AF_INET) &&
808             (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
809                 strlcpy(buffer, "*", bufsize);
810         } else {
811                 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
812         }
813         FORWARD;
814
815         ADDSTRING(" port ");
816         snprintf(buffer, bufsize, "%d", sock->my_port);
817         FORWARD;
818
819 #ifdef WITH_TLS
820         if (this->tls) {
821                 ADDSTRING(" (TLS)");
822                 FORWARD;
823         }
824 #endif
825
826         if (this->server) {
827                 ADDSTRING(" as server ");
828                 ADDSTRING(this->server);
829         }
830
831 #undef ADDSTRING
832 #undef FORWARD
833
834         return 1;
835 }
836
837 extern int check_config;        /* radiusd.c */
838
839
840 /*
841  *      Parse an authentication or accounting socket.
842  */
843 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
844 {
845         int             rcode;
846         int             listen_port;
847         fr_ipaddr_t     ipaddr;
848         listen_socket_t *sock = this->data;
849         char            *section_name = NULL;
850         CONF_SECTION    *client_cs, *parentcs;
851
852         this->cs = cs;
853
854         /*
855          *      Try IPv4 first
856          */
857         memset(&ipaddr, 0, sizeof(ipaddr));
858         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
859         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
860                               &ipaddr.ipaddr.ip4addr, NULL);
861         if (rcode < 0) return -1;
862
863         if (rcode == 0) { /* successfully parsed IPv4 */
864                 ipaddr.af = AF_INET;
865
866         } else {        /* maybe IPv6? */
867                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
868                                       &ipaddr.ipaddr.ip6addr, NULL);
869                 if (rcode < 0) return -1;
870
871                 if (rcode == 1) {
872                         cf_log_err(cf_sectiontoitem(cs),
873                                    "No address specified in listen section");
874                         return -1;
875                 }
876                 ipaddr.af = AF_INET6;
877         }
878
879         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
880                               &listen_port, "0");
881         if (rcode < 0) return -1;
882
883         if ((listen_port < 0) || (listen_port > 65535)) {
884                         cf_log_err(cf_sectiontoitem(cs),
885                                    "Invalid value for \"port\"");
886                         return -1;
887         }
888
889         sock->proto = IPPROTO_UDP;
890
891         if (cf_pair_find(cs, "proto")) {
892 #ifndef WITH_TCP
893                 cf_log_err(cf_sectiontoitem(cs),
894                            "System does not support the TCP protocol.  Delete this line from the configuration file.");
895                 return -1;
896 #else
897                 char *proto = NULL;
898 #ifdef WITH_TLS
899                 CONF_SECTION *tls;
900 #endif
901
902                 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
903                                       &proto, "udp");
904                 if (rcode < 0) return -1;
905
906                 if (strcmp(proto, "udp") == 0) {
907                         sock->proto = IPPROTO_UDP;
908
909                 } else if (strcmp(proto, "tcp") == 0) {
910                         sock->proto = IPPROTO_TCP;
911
912                         rcode = cf_item_parse(cs, "max_connections", PW_TYPE_INTEGER,
913                                               &sock->max_connections, "64");
914                         if (rcode < 0) return -1;
915
916                 } else {
917                         cf_log_err(cf_sectiontoitem(cs),
918                                    "Unknown proto name \"%s\"", proto);
919                         free(proto);
920                         return -1;
921                 }
922                 free(proto);
923
924                 /*
925                  *      TCP requires a destination IP for sockets.
926                  *      UDP doesn't, so it's allowed.
927                  */
928 #ifdef WITH_PROXY
929                 if ((this->type == RAD_LISTEN_PROXY) &&
930                     (sock->proto != IPPROTO_UDP)) {
931                         cf_log_err(cf_sectiontoitem(cs),
932                                    "Proxy listeners can only listen on proto = udp");
933                         return -1;
934                 }
935 #endif  /* WITH_PROXY */
936
937 #ifdef WITH_TLS
938                 tls = cf_section_sub_find(cs, "tls");
939
940                 /*
941                  *      Don't allow TLS configurations for UDP sockets.
942                  */
943                 if (sock->proto != IPPROTO_TCP) {
944                         cf_log_err(cf_sectiontoitem(cs),
945                                    "TLS transport is not available for UDP sockets.");
946                         return -1;
947                 }
948
949                 if (tls) {
950                         /*
951                          *      FIXME: Make this better.
952                          */
953                         if (listen_port == 0) listen_port = 2083;
954
955                         this->tls = tls_server_conf_parse(tls);
956                         if (!this->tls) {
957                                 return -1;
958                         }
959
960 #ifdef HAVE_PTRHEAD_H
961                         if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
962                                 rad_assert(0 == 1);
963                                 listen_free(&this);
964                                 return 0;
965                         }
966 #endif
967
968                 }               
969 #else  /* WITH_TLS */
970                 /*
971                  *      Built without TLS.  Disallow it.
972                  */
973                 if (cf_section_sub_find(cs, "tls")) {
974                         cf_log_err(cf_sectiontoitem(cs),
975                                    "TLS transport is not available in this executable.");
976                         return -1;
977                 }
978 #endif  /* WITH_TLS */
979
980 #endif  /* WITH_TCP */
981
982                 /*
983                  *      No "proto" field.  Disallow TLS.
984                  */
985         } else if (cf_section_sub_find(cs, "tls")) {
986                 cf_log_err(cf_sectiontoitem(cs),
987                            "TLS transport is not available in this \"listen\" section.");
988                 return -1;
989         }
990
991         sock->my_ipaddr = ipaddr;
992         sock->my_port = listen_port;
993
994 #ifdef WITH_PROXY
995         if (check_config) {
996                 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
997                                 char buffer[128];
998                                 
999                                 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.",
1000                                       ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1001                                       sock->my_port);
1002                                 return -1;
1003                 }
1004
1005                 return 0;       /* don't do anything */
1006         }
1007 #endif
1008
1009         /*
1010          *      If we can bind to interfaces, do so,
1011          *      else don't.
1012          */
1013         if (cf_pair_find(cs, "interface")) {
1014                 const char *value;
1015                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
1016
1017                 rad_assert(cp != NULL);
1018                 value = cf_pair_value(cp);
1019                 if (!value) {
1020                         cf_log_err(cf_sectiontoitem(cs),
1021                                    "No interface name given");
1022                         return -1;
1023                 }
1024                 sock->interface = value;
1025         }
1026
1027 #ifdef WITH_DHCP
1028         /*
1029          *      If we can do broadcasts..
1030          */
1031         if (cf_pair_find(cs, "broadcast")) {
1032 #ifndef SO_BROADCAST
1033                 cf_log_err(cf_sectiontoitem(cs),
1034                            "System does not support broadcast sockets.  Delete this line from the configuration file.");
1035                 return -1;
1036 #else
1037                 const char *value;
1038                 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
1039
1040                 if (this->type != RAD_LISTEN_DHCP) {
1041                         cf_log_err(cf_pairtoitem(cp),
1042                                    "Broadcast can only be set for DHCP listeners.  Delete this line from the configuration file.");
1043                         return -1;
1044                 }
1045                 
1046                 rad_assert(cp != NULL);
1047                 value = cf_pair_value(cp);
1048                 if (!value) {
1049                         cf_log_err(cf_sectiontoitem(cs),
1050                                    "No broadcast value given");
1051                         return -1;
1052                 }
1053
1054                 /*
1055                  *      Hack... whatever happened to cf_section_parse?
1056                  */
1057                 sock->broadcast = (strcmp(value, "yes") == 0);
1058 #endif
1059         }
1060 #endif
1061
1062         /*
1063          *      And bind it to the port.
1064          */
1065         if (listen_bind(this) < 0) {
1066                 char buffer[128];
1067                 cf_log_err(cf_sectiontoitem(cs),
1068                            "Error binding to port for %s port %d",
1069                            ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1070                            sock->my_port);
1071                 return -1;
1072         }
1073
1074 #ifdef WITH_PROXY
1075         /*
1076          *      Proxy sockets don't have clients.
1077          */
1078         if (this->type == RAD_LISTEN_PROXY) return 0;
1079 #endif
1080         
1081         /*
1082          *      The more specific configurations are preferred to more
1083          *      generic ones.
1084          */
1085         client_cs = NULL;
1086         parentcs = cf_top_section(cs);
1087         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
1088                               &section_name, NULL);
1089         if (rcode < 0) return -1; /* bad string */
1090         if (rcode == 0) {
1091                 /*
1092                  *      Explicit list given: use it.
1093                  */
1094                 client_cs = cf_section_sub_find_name2(parentcs,
1095                                                       "clients",
1096                                                       section_name);
1097                 if (!client_cs) {
1098                         client_cs = cf_section_find(section_name);
1099                 }
1100                 if (!client_cs) {
1101                         cf_log_err(cf_sectiontoitem(cs),
1102                                    "Failed to find clients %s {...}",
1103                                    section_name);
1104                         free(section_name);
1105                         return -1;
1106                 }
1107                 free(section_name);
1108         } /* else there was no "clients = " entry. */
1109
1110         if (!client_cs) {
1111                 CONF_SECTION *server_cs;
1112
1113                 server_cs = cf_section_sub_find_name2(parentcs,
1114                                                       "server",
1115                                                       this->server);
1116                 /*
1117                  *      Found a "server foo" section.  If there are clients
1118                  *      in it, use them.
1119                  */
1120                 if (server_cs &&
1121                     (cf_section_sub_find(server_cs, "client") != NULL)) {
1122                         client_cs = server_cs;
1123                 }
1124         }
1125
1126         /*
1127          *      Still nothing.  Look for global clients.
1128          */
1129         if (!client_cs) client_cs = parentcs;
1130
1131         sock->clients = clients_parse_section(client_cs);
1132         if (!sock->clients) {
1133                 cf_log_err(cf_sectiontoitem(cs),
1134                            "Failed to load clients for this listen section");
1135                 return -1;
1136         }
1137
1138 #ifdef WITH_TCP
1139         if (sock->proto == IPPROTO_TCP) {
1140                 /*
1141                  *      Re-write the listener receive function to
1142                  *      allow us to accept the socket.
1143                  */
1144                 this->recv = dual_tcp_accept;
1145         }
1146 #endif
1147
1148         return 0;
1149 }
1150
1151 /*
1152  *      Send an authentication response packet
1153  */
1154 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1155 {
1156         rad_assert(request->listener == listener);
1157         rad_assert(listener->send == auth_socket_send);
1158
1159         if (rad_send(request->reply, request->packet,
1160                      request->client->secret) < 0) {
1161                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1162                                fr_strerror());
1163                 return -1;
1164         }
1165
1166         return 0;
1167 }
1168
1169
1170 #ifdef WITH_ACCOUNTING
1171 /*
1172  *      Send an accounting response packet (or not)
1173  */
1174 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1175 {
1176         rad_assert(request->listener == listener);
1177         rad_assert(listener->send == acct_socket_send);
1178
1179         /*
1180          *      Accounting reject's are silently dropped.
1181          *
1182          *      We do it here to avoid polluting the rest of the
1183          *      code with this knowledge
1184          */
1185         if (request->reply->code == 0) return 0;
1186
1187         if (rad_send(request->reply, request->packet,
1188                      request->client->secret) < 0) {
1189                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1190                                fr_strerror());
1191                 return -1;
1192         }
1193
1194         return 0;
1195 }
1196 #endif
1197
1198 #ifdef WITH_PROXY
1199 /*
1200  *      Send a packet to a home server.
1201  *
1202  *      FIXME: have different code for proxy auth & acct!
1203  */
1204 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1205 {
1206         rad_assert(request->proxy_listener == listener);
1207         rad_assert(listener->send == proxy_socket_send);
1208
1209         if (rad_send(request->proxy, NULL,
1210                      request->home_server->secret) < 0) {
1211                 radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
1212                                fr_strerror());
1213                 return -1;
1214         }
1215
1216         return 0;
1217 }
1218 #endif
1219
1220 #ifdef WITH_STATS
1221 /*
1222  *      Check if an incoming request is "ok"
1223  *
1224  *      It takes packets, not requests.  It sees if the packet looks
1225  *      OK.  If so, it does a number of sanity checks on it.
1226   */
1227 static int stats_socket_recv(rad_listen_t *listener)
1228 {
1229         ssize_t         rcode;
1230         int             code, src_port;
1231         RADIUS_PACKET   *packet;
1232         RADCLIENT       *client = NULL;
1233         fr_ipaddr_t     src_ipaddr;
1234
1235         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1236         if (rcode < 0) return 0;
1237
1238         FR_STATS_INC(auth, total_requests);
1239
1240         if (rcode < 20) {       /* AUTH_HDR_LEN */
1241                 FR_STATS_INC(auth, total_malformed_requests);
1242                 return 0;
1243         }
1244
1245         if ((client = client_listener_find(listener,
1246                                            &src_ipaddr, src_port)) == NULL) {
1247                 rad_recv_discard(listener->fd);
1248                 FR_STATS_INC(auth, total_invalid_requests);
1249                 return 0;
1250         }
1251
1252         FR_STATS_TYPE_INC(client->auth.total_requests);
1253
1254         /*
1255          *      We only understand Status-Server on this socket.
1256          */
1257         if (code != PW_STATUS_SERVER) {
1258                 DEBUG("Ignoring packet code %d sent to Status-Server port",
1259                       code);
1260                 rad_recv_discard(listener->fd);
1261                 FR_STATS_INC(auth, total_unknown_types);
1262                 return 0;
1263         }
1264
1265         /*
1266          *      Now that we've sanity checked everything, receive the
1267          *      packet.
1268          */
1269         packet = rad_recv(listener->fd, 1); /* require message authenticator */
1270         if (!packet) {
1271                 FR_STATS_INC(auth, total_malformed_requests);
1272                 DEBUG("%s", fr_strerror());
1273                 return 0;
1274         }
1275
1276         if (!request_receive(listener, packet, client, rad_status_server)) {
1277                 FR_STATS_INC(auth, total_packets_dropped);
1278                 rad_free(&packet);
1279                 return 0;
1280         }
1281
1282         return 1;
1283 }
1284 #endif
1285
1286
1287 /*
1288  *      Check if an incoming request is "ok"
1289  *
1290  *      It takes packets, not requests.  It sees if the packet looks
1291  *      OK.  If so, it does a number of sanity checks on it.
1292   */
1293 static int auth_socket_recv(rad_listen_t *listener)
1294 {
1295         ssize_t         rcode;
1296         int             code, src_port;
1297         RADIUS_PACKET   *packet;
1298         RAD_REQUEST_FUNP fun = NULL;
1299         RADCLIENT       *client = NULL;
1300         fr_ipaddr_t     src_ipaddr;
1301
1302         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1303         if (rcode < 0) return 0;
1304
1305         FR_STATS_INC(auth, total_requests);
1306
1307         if (rcode < 20) {       /* AUTH_HDR_LEN */
1308                 FR_STATS_INC(auth, total_malformed_requests);
1309                 return 0;
1310         }
1311
1312         if ((client = client_listener_find(listener,
1313                                            &src_ipaddr, src_port)) == NULL) {
1314                 rad_recv_discard(listener->fd);
1315                 FR_STATS_INC(auth, total_invalid_requests);
1316                 return 0;
1317         }
1318
1319         FR_STATS_TYPE_INC(client->auth.total_requests);
1320
1321         /*
1322          *      Some sanity checks, based on the packet code.
1323          */
1324         switch(code) {
1325         case PW_AUTHENTICATION_REQUEST:
1326                 fun = rad_authenticate;
1327                 break;
1328
1329         case PW_STATUS_SERVER:
1330                 if (!mainconfig.status_server) {
1331                         rad_recv_discard(listener->fd);
1332                         FR_STATS_INC(auth, total_unknown_types);
1333                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1334                         return 0;
1335                 }
1336                 fun = rad_status_server;
1337                 break;
1338
1339         default:
1340                 rad_recv_discard(listener->fd);
1341                 FR_STATS_INC(auth,total_unknown_types);
1342
1343                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1344                       code, client->shortname, src_port);
1345                 return 0;
1346                 break;
1347         } /* switch over packet types */
1348
1349         /*
1350          *      Now that we've sanity checked everything, receive the
1351          *      packet.
1352          */
1353         packet = rad_recv(listener->fd, client->message_authenticator);
1354         if (!packet) {
1355                 FR_STATS_INC(auth, total_malformed_requests);
1356                 DEBUG("%s", fr_strerror());
1357                 return 0;
1358         }
1359
1360         if (!request_receive(listener, packet, client, fun)) {
1361                 FR_STATS_INC(auth, total_packets_dropped);
1362                 rad_free(&packet);
1363                 return 0;
1364         }
1365
1366         return 1;
1367 }
1368
1369
1370 #ifdef WITH_ACCOUNTING
1371 /*
1372  *      Receive packets from an accounting socket
1373  */
1374 static int acct_socket_recv(rad_listen_t *listener)
1375 {
1376         ssize_t         rcode;
1377         int             code, src_port;
1378         RADIUS_PACKET   *packet;
1379         RAD_REQUEST_FUNP fun = NULL;
1380         RADCLIENT       *client = NULL;
1381         fr_ipaddr_t     src_ipaddr;
1382
1383         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1384         if (rcode < 0) return 0;
1385
1386         FR_STATS_INC(acct, total_requests);
1387
1388         if (rcode < 20) {       /* AUTH_HDR_LEN */
1389                 FR_STATS_INC(acct, total_malformed_requests);
1390                 return 0;
1391         }
1392
1393         if ((client = client_listener_find(listener,
1394                                            &src_ipaddr, src_port)) == NULL) {
1395                 rad_recv_discard(listener->fd);
1396                 FR_STATS_INC(acct, total_invalid_requests);
1397                 return 0;
1398         }
1399
1400         FR_STATS_TYPE_INC(client->acct.total_requests);
1401
1402         /*
1403          *      Some sanity checks, based on the packet code.
1404          */
1405         switch(code) {
1406         case PW_ACCOUNTING_REQUEST:
1407                 fun = rad_accounting;
1408                 break;
1409
1410         case PW_STATUS_SERVER:
1411                 if (!mainconfig.status_server) {
1412                         rad_recv_discard(listener->fd);
1413                         FR_STATS_INC(acct, total_unknown_types);
1414
1415                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1416                         return 0;
1417                 }
1418                 fun = rad_status_server;
1419                 break;
1420
1421         default:
1422                 rad_recv_discard(listener->fd);
1423                 FR_STATS_INC(acct, total_unknown_types);
1424
1425                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1426                       code, client->shortname, src_port);
1427                 return 0;
1428         } /* switch over packet types */
1429
1430         /*
1431          *      Now that we've sanity checked everything, receive the
1432          *      packet.
1433          */
1434         packet = rad_recv(listener->fd, 0);
1435         if (!packet) {
1436                 FR_STATS_INC(acct, total_malformed_requests);
1437                 radlog(L_ERR, "%s", fr_strerror());
1438                 return 0;
1439         }
1440
1441         /*
1442          *      There can be no duplicate accounting packets.
1443          */
1444         if (!request_receive(listener, packet, client, fun)) {
1445                 FR_STATS_INC(acct, total_packets_dropped);
1446                 rad_free(&packet);
1447                 return 0;
1448         }
1449
1450         return 1;
1451 }
1452 #endif
1453
1454
1455 #ifdef WITH_COA
1456 static int do_proxy(REQUEST *request)
1457 {
1458         VALUE_PAIR *vp;
1459
1460         if (request->in_proxy_hash ||
1461             (request->proxy_reply && (request->proxy_reply->code != 0))) {
1462                 return 0;
1463         }
1464
1465         vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0);
1466         if (!vp) return 0;
1467         
1468         if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
1469                 RDEBUG2("ERROR: Cannot proxy to unknown pool %s",
1470                         vp->vp_strvalue);
1471                 return 0;
1472         }
1473
1474         return 1;
1475 }
1476
1477 /*
1478  *      Receive a CoA packet.
1479  */
1480 static int rad_coa_recv(REQUEST *request)
1481 {
1482         int rcode = RLM_MODULE_OK;
1483         int ack, nak;
1484         VALUE_PAIR *vp;
1485
1486         /*
1487          *      Get the correct response
1488          */
1489         switch (request->packet->code) {
1490         case PW_COA_REQUEST:
1491                 ack = PW_COA_ACK;
1492                 nak = PW_COA_NAK;
1493                 break;
1494
1495         case PW_DISCONNECT_REQUEST:
1496                 ack = PW_DISCONNECT_ACK;
1497                 nak = PW_DISCONNECT_NAK;
1498                 break;
1499
1500         default:                /* shouldn't happen */
1501                 return RLM_MODULE_FAIL;
1502         }
1503
1504 #ifdef WITH_PROXY
1505 #define WAS_PROXIED (request->proxy)
1506 #else
1507 #define WAS_PROXIED (0)
1508 #endif
1509
1510         if (!WAS_PROXIED) {
1511                 /*
1512                  *      RFC 5176 Section 3.3.  If we have a CoA-Request
1513                  *      with Service-Type = Authorize-Only, it MUST
1514                  *      have a State attribute in it.
1515                  */
1516                 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0);
1517                 if (request->packet->code == PW_COA_REQUEST) {
1518                         if (vp && (vp->vp_integer == 17)) {
1519                                 vp = pairfind(request->packet->vps, PW_STATE, 0);
1520                                 if (!vp || (vp->length == 0)) {
1521                                         RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1522                                         request->reply->code = PW_COA_NAK;
1523                                         return RLM_MODULE_FAIL;
1524                                 }
1525                         }
1526                 } else if (vp) {
1527                         /*
1528                          *      RFC 5176, Section 3.2.
1529                          */
1530                         RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1531                         request->reply->code = PW_DISCONNECT_NAK;
1532                         return RLM_MODULE_FAIL;
1533                 }
1534
1535                 rcode = module_recv_coa(0, request);
1536                 switch (rcode) {
1537                 case RLM_MODULE_FAIL:
1538                 case RLM_MODULE_INVALID:
1539                 case RLM_MODULE_REJECT:
1540                 case RLM_MODULE_USERLOCK:
1541                 default:
1542                         request->reply->code = nak;
1543                         break;
1544                         
1545                 case RLM_MODULE_HANDLED:
1546                         return rcode;
1547                         
1548                 case RLM_MODULE_NOOP:
1549                 case RLM_MODULE_NOTFOUND:
1550                 case RLM_MODULE_OK:
1551                 case RLM_MODULE_UPDATED:
1552                         if (do_proxy(request)) return RLM_MODULE_OK;
1553                         request->reply->code = ack;
1554                         break;
1555                 }
1556         } else if (request->proxy_reply) {
1557                 /*
1558                  *      Start the reply code with the proxy reply
1559                  *      code.
1560                  */
1561                 request->reply->code = request->proxy_reply->code;
1562         }
1563
1564         /*
1565          *      Copy State from the request to the reply.
1566          *      See RFC 5176 Section 3.3.
1567          */
1568         vp = paircopy2(request->packet->vps, PW_STATE, 0);
1569         if (vp) pairadd(&request->reply->vps, vp);
1570
1571         /*
1572          *      We may want to over-ride the reply.
1573          */
1574         if (request->reply->code) {
1575                 rcode = module_send_coa(0, request);
1576                 switch (rcode) {
1577                         /*
1578                          *      We need to send CoA-NAK back if Service-Type
1579                          *      is Authorize-Only.  Rely on the user's policy
1580                          *      to do that.  We're not a real NAS, so this
1581                          *      restriction doesn't (ahem) apply to us.
1582                          */
1583                 case RLM_MODULE_FAIL:
1584                 case RLM_MODULE_INVALID:
1585                 case RLM_MODULE_REJECT:
1586                 case RLM_MODULE_USERLOCK:
1587                 default:
1588                         /*
1589                          *      Over-ride an ACK with a NAK
1590                          */
1591                         request->reply->code = nak;
1592                         break;
1593                         
1594                 case RLM_MODULE_HANDLED:
1595                         return rcode;
1596                         
1597                 case RLM_MODULE_NOOP:
1598                 case RLM_MODULE_NOTFOUND:
1599                 case RLM_MODULE_OK:
1600                 case RLM_MODULE_UPDATED:
1601                         /*
1602                          *      Do NOT over-ride a previously set value.
1603                          *      Otherwise an "ok" here will re-write a
1604                          *      NAK to an ACK.
1605                          */
1606                         if (request->reply->code == 0) {
1607                                 request->reply->code = ack;
1608                         }
1609                         break;
1610                 }
1611         }
1612
1613         return RLM_MODULE_OK;
1614 }
1615
1616
1617 /*
1618  *      Check if an incoming request is "ok"
1619  *
1620  *      It takes packets, not requests.  It sees if the packet looks
1621  *      OK.  If so, it does a number of sanity checks on it.
1622   */
1623 static int coa_socket_recv(rad_listen_t *listener)
1624 {
1625         ssize_t         rcode;
1626         int             code, src_port;
1627         RADIUS_PACKET   *packet;
1628         RAD_REQUEST_FUNP fun = NULL;
1629         RADCLIENT       *client = NULL;
1630         fr_ipaddr_t     src_ipaddr;
1631
1632         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1633         if (rcode < 0) return 0;
1634
1635         if (rcode < 20) {       /* AUTH_HDR_LEN */
1636                 FR_STATS_INC(coa, total_requests);
1637                 FR_STATS_INC(coa, total_malformed_requests);
1638                 return 0;
1639         }
1640
1641         if ((client = client_listener_find(listener,
1642                                            &src_ipaddr, src_port)) == NULL) {
1643                 rad_recv_discard(listener->fd);
1644                 FR_STATS_INC(coa, total_requests);
1645                 FR_STATS_INC(coa, total_invalid_requests);
1646                 return 0;
1647         }
1648
1649         /*
1650          *      Some sanity checks, based on the packet code.
1651          */
1652         switch(code) {
1653         case PW_COA_REQUEST:
1654                 FR_STATS_INC(coa, total_requests);
1655                 fun = rad_coa_recv;
1656                 break;
1657
1658         case PW_DISCONNECT_REQUEST:
1659                 FR_STATS_INC(dsc, total_requests);
1660                 fun = rad_coa_recv;
1661                 break;
1662
1663         default:
1664                 rad_recv_discard(listener->fd);
1665                 FR_STATS_INC(coa, total_unknown_types);
1666                 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1667                       code, client->shortname, src_port);
1668                 return 0;
1669         } /* switch over packet types */
1670
1671         /*
1672          *      Now that we've sanity checked everything, receive the
1673          *      packet.
1674          */
1675         packet = rad_recv(listener->fd, client->message_authenticator);
1676         if (!packet) {
1677                 FR_STATS_INC(coa, total_malformed_requests);
1678                 DEBUG("%s", fr_strerror());
1679                 return 0;
1680         }
1681
1682         if (!request_receive(listener, packet, client, fun)) {
1683                 FR_STATS_INC(coa, total_packets_dropped);
1684                 rad_free(&packet);
1685                 return 0;
1686         }
1687
1688         return 1;
1689 }
1690 #endif
1691
1692 #ifdef WITH_PROXY
1693 /*
1694  *      Recieve packets from a proxy socket.
1695  */
1696 static int proxy_socket_recv(rad_listen_t *listener)
1697 {
1698         RADIUS_PACKET   *packet;
1699         char            buffer[128];
1700
1701         packet = rad_recv(listener->fd, 0);
1702         if (!packet) {
1703                 radlog(L_ERR, "%s", fr_strerror());
1704                 return 0;
1705         }
1706
1707         /*
1708          *      FIXME: Client MIB updates?
1709          */
1710         switch(packet->code) {
1711         case PW_AUTHENTICATION_ACK:
1712         case PW_ACCESS_CHALLENGE:
1713         case PW_AUTHENTICATION_REJECT:
1714                 break;
1715
1716 #ifdef WITH_ACCOUNTING
1717         case PW_ACCOUNTING_RESPONSE:
1718                 break;
1719 #endif
1720
1721 #ifdef WITH_COA
1722         case PW_DISCONNECT_ACK:
1723         case PW_DISCONNECT_NAK:
1724         case PW_COA_ACK:
1725         case PW_COA_NAK:
1726                 break;
1727 #endif
1728
1729         default:
1730                 /*
1731                  *      FIXME: Update MIB for packet types?
1732                  */
1733                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1734                        "from home server %s port %d - ID %d : IGNORED",
1735                        packet->code,
1736                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1737                        packet->src_port, packet->id);
1738                 rad_free(&packet);
1739                 return 0;
1740         }
1741
1742         if (!request_proxy_reply(packet)) {
1743                 rad_free(&packet);
1744                 return 0;
1745         }
1746
1747         return 1;
1748 }
1749
1750 #ifdef WITH_TCP
1751 /*
1752  *      Recieve packets from a proxy socket.
1753  */
1754 static int proxy_socket_tcp_recv(rad_listen_t *listener)
1755 {
1756         RADIUS_PACKET   *packet;
1757         listen_socket_t *sock = listener->data;
1758         char            buffer[128];
1759
1760         packet = fr_tcp_recv(listener->fd, 0);
1761         if (!packet) {
1762                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1763                 event_new_fd(listener);
1764                 return 0;
1765         }
1766
1767         /*
1768          *      FIXME: Client MIB updates?
1769          */
1770         switch(packet->code) {
1771         case PW_AUTHENTICATION_ACK:
1772         case PW_ACCESS_CHALLENGE:
1773         case PW_AUTHENTICATION_REJECT:
1774                 break;
1775
1776 #ifdef WITH_ACCOUNTING
1777         case PW_ACCOUNTING_RESPONSE:
1778                 break;
1779 #endif
1780
1781         default:
1782                 /*
1783                  *      FIXME: Update MIB for packet types?
1784                  */
1785                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1786                        "from home server %s port %d - ID %d : IGNORED",
1787                        packet->code,
1788                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1789                        packet->src_port, packet->id);
1790                 rad_free(&packet);
1791                 return 0;
1792         }
1793
1794         packet->src_ipaddr = sock->other_ipaddr;
1795         packet->src_port = sock->other_port;
1796         packet->dst_ipaddr = sock->my_ipaddr;
1797         packet->dst_port = sock->my_port;
1798
1799         /*
1800          *      FIXME: Have it return an indication of packets that
1801          *      are OK to ignore (dups, too late), versus ones that
1802          *      aren't OK to ignore (unknown response, spoofed, etc.)
1803          *
1804          *      Close the socket on bad packets...
1805          */
1806         if (!request_proxy_reply(packet)) {
1807                 rad_free(&packet);
1808                 return 0;
1809         }
1810
1811         sock->opened = sock->last_packet = time(NULL);
1812
1813         return 1;
1814 }
1815 #endif
1816 #endif
1817
1818
1819 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1820 {
1821         if (!request->reply->code) return 0;
1822
1823         if (rad_encode(request->reply, request->packet,
1824                        request->client->secret) < 0) {
1825                 radlog_request(L_ERR, 0, request, "Failed encoding packet: %s",
1826                                fr_strerror());
1827                 return -1;
1828         }
1829
1830         if (rad_sign(request->reply, request->packet,
1831                      request->client->secret) < 0) {
1832                 radlog_request(L_ERR, 0, request, "Failed signing packet: %s",
1833                                fr_strerror());
1834                 return -1;
1835         }
1836
1837         return 0;
1838 }
1839
1840
1841 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1842 {
1843         if (rad_verify(request->packet, NULL,
1844                        request->client->secret) < 0) {
1845                 return -1;
1846         }
1847
1848         return rad_decode(request->packet, NULL,
1849                           request->client->secret);
1850 }
1851
1852 #ifdef WITH_PROXY
1853 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1854 {
1855         if (rad_encode(request->proxy, NULL, request->home_server->secret) < 0) {
1856                 radlog_request(L_ERR, 0, request, "Failed encoding proxied packet: %s",
1857                                fr_strerror());
1858                 return -1;
1859         }
1860
1861         if (rad_sign(request->proxy, NULL, request->home_server->secret) < 0) {
1862                 radlog_request(L_ERR, 0, request, "Failed signing proxied packet: %s",
1863                                fr_strerror());
1864                 return -1;
1865         }
1866
1867         return 0;
1868 }
1869
1870
1871 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1872 {
1873         /*
1874          *      rad_verify is run in event.c, received_proxy_response()
1875          */
1876
1877         return rad_decode(request->proxy_reply, request->proxy,
1878                            request->home_server->secret);
1879 }
1880 #endif
1881
1882 #include "dhcpd.c"
1883
1884 #include "command.c"
1885
1886 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1887 #ifdef WITH_STATS
1888         { common_socket_parse, NULL,
1889           stats_socket_recv, auth_socket_send,
1890           socket_print, client_socket_encode, client_socket_decode },
1891 #else
1892         /*
1893          *      This always gets defined.
1894          */
1895         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1896 #endif
1897
1898 #ifdef WITH_PROXY
1899         /* proxying */
1900         { common_socket_parse, NULL,
1901           proxy_socket_recv, proxy_socket_send,
1902           socket_print, proxy_socket_encode, proxy_socket_decode },
1903 #endif
1904
1905         /* authentication */
1906         { common_socket_parse, NULL,
1907           auth_socket_recv, auth_socket_send,
1908           socket_print, client_socket_encode, client_socket_decode },
1909
1910 #ifdef WITH_ACCOUNTING
1911         /* accounting */
1912         { common_socket_parse, NULL,
1913           acct_socket_recv, acct_socket_send,
1914           socket_print, client_socket_encode, client_socket_decode},
1915 #endif
1916
1917 #ifdef WITH_DETAIL
1918         /* detail */
1919         { detail_parse, detail_free,
1920           detail_recv, detail_send,
1921           detail_print, detail_encode, detail_decode },
1922 #endif
1923
1924 #ifdef WITH_VMPS
1925         /* vlan query protocol */
1926         { common_socket_parse, NULL,
1927           vqp_socket_recv, vqp_socket_send,
1928           socket_print, vqp_socket_encode, vqp_socket_decode },
1929 #endif
1930
1931 #ifdef WITH_DHCP
1932         /* dhcp query protocol */
1933         { dhcp_socket_parse, NULL,
1934           dhcp_socket_recv, dhcp_socket_send,
1935           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1936 #endif
1937
1938 #ifdef WITH_COMMAND_SOCKET
1939         /* TCP command socket */
1940         { command_socket_parse, command_socket_free,
1941           command_domain_accept, command_domain_send,
1942           command_socket_print, command_socket_encode, command_socket_decode },
1943 #endif
1944
1945 #ifdef WITH_COA
1946         /* Change of Authorization */
1947         { common_socket_parse, NULL,
1948           coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1949           socket_print, client_socket_encode, client_socket_decode },
1950 #endif
1951
1952 };
1953
1954
1955
1956 /*
1957  *      Binds a listener to a socket.
1958  */
1959 static int listen_bind(rad_listen_t *this)
1960 {
1961         int rcode;
1962         struct sockaddr_storage salocal;
1963         socklen_t       salen;
1964         listen_socket_t *sock = this->data;
1965 #ifndef WITH_TCP
1966 #define proto_for_port "udp"
1967 #define sock_type SOCK_DGRAM
1968 #else
1969         const char *proto_for_port = "udp";
1970         int sock_type = SOCK_DGRAM;
1971         
1972         if (sock->proto == IPPROTO_TCP) {
1973 #ifdef WITH_VMPS
1974                 if (this->type == RAD_LISTEN_VQP) {
1975                         radlog(L_ERR, "VQP does not support TCP transport");
1976                         return -1;
1977                 }
1978 #endif
1979
1980                 proto_for_port = "tcp";
1981                 sock_type = SOCK_STREAM;        
1982         }
1983 #endif
1984
1985         /*
1986          *      If the port is zero, then it means the appropriate
1987          *      thing from /etc/services.
1988          */
1989         if (sock->my_port == 0) {
1990                 struct servent  *svp;
1991
1992                 switch (this->type) {
1993                 case RAD_LISTEN_AUTH:
1994                         svp = getservbyname ("radius", proto_for_port);
1995                         if (svp != NULL) {
1996                                 sock->my_port = ntohs(svp->s_port);
1997                         } else {
1998                                 sock->my_port = PW_AUTH_UDP_PORT;
1999                         }
2000                         break;
2001
2002 #ifdef WITH_ACCOUNTING
2003                 case RAD_LISTEN_ACCT:
2004                         svp = getservbyname ("radacct", proto_for_port);
2005                         if (svp != NULL) {
2006                                 sock->my_port = ntohs(svp->s_port);
2007                         } else {
2008                                 sock->my_port = PW_ACCT_UDP_PORT;
2009                         }
2010                         break;
2011 #endif
2012
2013 #ifdef WITH_PROXY
2014                 case RAD_LISTEN_PROXY:
2015                         /* leave it at zero */
2016                         break;
2017 #endif
2018
2019 #ifdef WITH_VMPS
2020                 case RAD_LISTEN_VQP:
2021                         sock->my_port = 1589;
2022                         break;
2023 #endif
2024
2025 #ifdef WITH_COA
2026                 case RAD_LISTEN_COA:
2027                         svp = getservbyname ("radius-dynauth", "udp");
2028                         if (svp != NULL) {
2029                                 sock->my_port = ntohs(svp->s_port);
2030                         } else {
2031                                 sock->my_port = PW_COA_UDP_PORT;
2032                         }
2033                         break;
2034 #endif
2035
2036                 default:
2037                         DEBUG("WARNING: Internal sanity check failed in binding to socket.  Ignoring problem.");
2038                         return -1;
2039                 }
2040         }
2041
2042         /*
2043          *      Don't open sockets if we're checking the config.
2044          */
2045         if (check_config) {
2046                 this->fd = -1;
2047                 return 0;
2048         }
2049
2050         /*
2051          *      Copy fr_socket() here, as we may need to bind to a device.
2052          */
2053         this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
2054         if (this->fd < 0) {
2055                 char buffer[256];
2056
2057                 this->print(this, buffer, sizeof(buffer));
2058
2059                 radlog(L_ERR, "Failed opening %s: %s", buffer, strerror(errno));
2060                 return -1;
2061         }
2062                 
2063         /*
2064          *      Bind to a device BEFORE touching IP addresses.
2065          */
2066         if (sock->interface) {
2067 #ifdef SO_BINDTODEVICE
2068                 struct ifreq ifreq;
2069
2070                 memcset(&ifreq, 0, sizeof(ifreq));
2071                 strlcpy(ifreq.ifr_name, sock->interface, sizeof(ifreq.ifr_name));
2072
2073                 fr_suid_up();
2074                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
2075                                    (char *)&ifreq, sizeof(ifreq));
2076                 fr_suid_down();
2077                 if (rcode < 0) {
2078                         close(this->fd);
2079                         radlog(L_ERR, "Failed binding to interface %s: %s",
2080                                sock->interface, strerror(errno));
2081                         return -1;
2082                 } /* else it worked. */
2083 #else
2084 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2085 #ifdef HAVE_NET_IF_H
2086                 /*
2087                  *      Odds are that any system supporting "bind to
2088                  *      device" also supports IPv6, so this next bit
2089                  *      isn't necessary.  But it's here for
2090                  *      completeness.
2091                  *
2092                  *      If we're doing IPv6, and the scope hasn't yet
2093                  *      been defined, set the scope to the scope of
2094                  *      the interface.
2095                  */
2096                 if (sock->my_ipaddr.af == AF_INET6) {
2097                         if (sock->my_ipaddr.scope == 0) {
2098                                 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
2099                                 if (sock->my_ipaddr.scope == 0) {
2100                                         close(this->fd);
2101                                         radlog(L_ERR, "Failed finding interface %s: %s",
2102                                                sock->interface, strerror(errno));
2103                                         return -1;
2104                                 }
2105                         } /* else scope was defined: we're OK. */
2106                 } else
2107 #endif
2108 #endif
2109                                 /*
2110                                  *      IPv4: no link local addresses,
2111                                  *      and no bind to device.
2112                                  */
2113                 {
2114                         close(this->fd);
2115                         radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
2116                         return -1;
2117                 }
2118 #endif
2119         }
2120
2121 #ifdef WITH_TCP
2122         if (sock->proto == IPPROTO_TCP) {
2123                 int on = 1;
2124
2125                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2126                         close(this->fd);
2127                         radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2128                         return -1;
2129                 }
2130         }
2131 #endif
2132
2133 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2134         else                    /* UDP sockets get UDPfromto */
2135 #endif
2136
2137 #ifdef WITH_UDPFROMTO
2138         /*
2139          *      Initialize udpfromto for all sockets.
2140          */
2141         if (udpfromto_init(this->fd) != 0) {
2142                 radlog(L_ERR, "Failed initializing udpfromto: %s",
2143                        strerror(errno));
2144                 close(this->fd);
2145                 return -1;
2146         }
2147 #endif
2148
2149         /*
2150          *      Set up sockaddr stuff.
2151          */
2152         if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2153                 close(this->fd);
2154                 return -1;
2155         }
2156                 
2157 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2158         if (sock->my_ipaddr.af == AF_INET6) {
2159                 /*
2160                  *      Listening on '::' does NOT get you IPv4 to
2161                  *      IPv6 mapping.  You've got to listen on an IPv4
2162                  *      address, too.  This makes the rest of the server
2163                  *      design a little simpler.
2164                  */
2165 #ifdef IPV6_V6ONLY
2166                 
2167                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2168                         int on = 1;
2169                         
2170                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2171                                    (char *)&on, sizeof(on));
2172                 }
2173 #endif /* IPV6_V6ONLY */
2174         }
2175 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2176
2177         if (sock->my_ipaddr.af == AF_INET) {
2178                 UNUSED int flag;
2179                 
2180 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2181                 /*
2182                  *      Disable PMTU discovery.  On Linux, this
2183                  *      also makes sure that the "don't fragment"
2184                  *      flag is zero.
2185                  */
2186                 flag = IP_PMTUDISC_DONT;
2187                 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2188                            &flag, sizeof(flag));
2189 #endif
2190
2191 #if defined(IP_DONTFRAG)
2192                 /*
2193                  *      Ensure that the "don't fragment" flag is zero.
2194                  */
2195                 flag = 0;
2196                 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2197                            &flag, sizeof(flag));
2198 #endif
2199         }
2200
2201 #ifdef WITH_DHCP
2202 #ifdef SO_BROADCAST
2203         if (sock->broadcast) {
2204                 int on = 1;
2205                 
2206                 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2207                         radlog(L_ERR, "Can't set broadcast option: %s\n",
2208                                strerror(errno));
2209                         return -1;
2210                 }
2211         }
2212 #endif
2213 #endif
2214
2215         /*
2216          *      May be binding to priviledged ports.
2217          */
2218         if (sock->my_port != 0) {
2219 #ifdef SO_REUSEADDR
2220                 int on = 1;
2221
2222                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2223                         radlog(L_ERR, "Can't set re-use address option: %s\n",
2224                                strerror(errno));
2225                         return -1;
2226                 }
2227 #endif
2228
2229                 fr_suid_up();
2230                 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2231                 fr_suid_down();
2232                 if (rcode < 0) {
2233                         char buffer[256];
2234                         close(this->fd);
2235                         
2236                         this->print(this, buffer, sizeof(buffer));
2237                         radlog(L_ERR, "Failed binding to %s: %s\n",
2238                                buffer, strerror(errno));
2239                         return -1;
2240                 }
2241         
2242                 /*
2243                  *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
2244                  *      kernel instead binds us to a 1.2.3.4.  If this
2245                  *      happens, notice, and remember our real IP.
2246                  */
2247                 {
2248                         struct sockaddr_storage src;
2249                         socklen_t               sizeof_src = sizeof(src);
2250                         
2251                         memset(&src, 0, sizeof_src);
2252                         if (getsockname(this->fd, (struct sockaddr *) &src,
2253                                         &sizeof_src) < 0) {
2254                                 radlog(L_ERR, "Failed getting socket name: %s",
2255                                        strerror(errno));
2256                                 return -1;
2257                         }
2258                         
2259                         if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2260                                                 &sock->my_ipaddr, &sock->my_port)) {
2261                                 radlog(L_ERR, "Socket has unsupported address family");
2262                                 return -1;
2263                         }
2264                 }
2265         }
2266
2267 #ifdef WITH_TCP
2268         if (sock->proto == IPPROTO_TCP) {
2269                 if (listen(this->fd, 8) < 0) {
2270                         close(this->fd);
2271                         radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2272                         return -1;
2273                 }
2274         } else
2275 #endif
2276
2277           if (fr_nonblock(this->fd) < 0) {
2278                   close(this->fd);
2279                   radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2280                          strerror(errno));
2281                   return -1;
2282           }
2283
2284         /*
2285          *      Mostly for proxy sockets.
2286          */
2287         sock->other_ipaddr.af = sock->my_ipaddr.af;
2288
2289 /*
2290  *      Don't screw up other people.
2291  */
2292 #undef proto_for_port
2293 #undef sock_type
2294
2295         return 0;
2296 }
2297
2298
2299 /*
2300  *      Allocate & initialize a new listener.
2301  */
2302 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2303 {
2304         rad_listen_t *this;
2305
2306         this = rad_malloc(sizeof(*this));
2307         memset(this, 0, sizeof(*this));
2308
2309         this->type = type;
2310         this->recv = master_listen[this->type].recv;
2311         this->send = master_listen[this->type].send;
2312         this->print = master_listen[this->type].print;
2313         this->encode = master_listen[this->type].encode;
2314         this->decode = master_listen[this->type].decode;
2315
2316         switch (type) {
2317 #ifdef WITH_STATS
2318         case RAD_LISTEN_NONE:
2319 #endif
2320         case RAD_LISTEN_AUTH:
2321 #ifdef WITH_ACCOUNTING
2322         case RAD_LISTEN_ACCT:
2323 #endif
2324 #ifdef WITH_PROXY
2325         case RAD_LISTEN_PROXY:
2326 #endif
2327 #ifdef WITH_VMPS
2328         case RAD_LISTEN_VQP:
2329 #endif
2330 #ifdef WITH_COA
2331         case RAD_LISTEN_COA:
2332 #endif
2333                 this->data = rad_malloc(sizeof(listen_socket_t));
2334                 memset(this->data, 0, sizeof(listen_socket_t));
2335                 break;
2336
2337 #ifdef WITH_DHCP
2338         case RAD_LISTEN_DHCP:
2339                 this->data = rad_malloc(sizeof(dhcp_socket_t));
2340                 memset(this->data, 0, sizeof(dhcp_socket_t));
2341                 break;
2342 #endif
2343
2344 #ifdef WITH_DETAIL
2345         case RAD_LISTEN_DETAIL:
2346                 this->data = NULL;
2347                 break;
2348 #endif
2349
2350 #ifdef WITH_COMMAND_SOCKET
2351         case RAD_LISTEN_COMMAND:
2352                 this->data = rad_malloc(sizeof(fr_command_socket_t));
2353                 memset(this->data, 0, sizeof(fr_command_socket_t));
2354                 break;
2355 #endif
2356
2357         default:
2358                 rad_assert("Unsupported option!" == NULL);
2359                 break;
2360         }
2361
2362         return this;
2363 }
2364
2365 #ifdef WITH_PROXY
2366 /*
2367  *      Externally visible function for creating a new proxy LISTENER.
2368  *
2369  *      Not thread-safe, but all calls to it are protected by the
2370  *      proxy mutex in event.c
2371  */
2372 int proxy_new_listener(home_server *home, int src_port)
2373 {
2374         rad_listen_t *this;
2375         listen_socket_t *sock;
2376 #ifndef NDEBUG
2377         char buffer[256];
2378 #endif
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 }