Set "last packet" entry for all sockets
[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         if (this->tls) {
820                 ADDSTRING(" (TLS)");
821                 FORWARD;
822         }
823
824         if (this->server) {
825                 ADDSTRING(" as server ");
826                 ADDSTRING(this->server);
827         }
828
829 #undef ADDSTRING
830 #undef FORWARD
831
832         return 1;
833 }
834
835 extern int check_config;        /* radiusd.c */
836
837
838 /*
839  *      Parse an authentication or accounting socket.
840  */
841 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
842 {
843         int             rcode;
844         int             listen_port;
845         fr_ipaddr_t     ipaddr;
846         listen_socket_t *sock = this->data;
847         char            *section_name = NULL;
848         CONF_SECTION    *client_cs, *parentcs;
849
850         this->cs = cs;
851
852         /*
853          *      Try IPv4 first
854          */
855         ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
856         rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
857                               &ipaddr.ipaddr.ip4addr, NULL);
858         if (rcode < 0) return -1;
859
860         if (rcode == 0) { /* successfully parsed IPv4 */
861                 ipaddr.af = AF_INET;
862
863         } else {        /* maybe IPv6? */
864                 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
865                                       &ipaddr.ipaddr.ip6addr, NULL);
866                 if (rcode < 0) return -1;
867
868                 if (rcode == 1) {
869                         cf_log_err(cf_sectiontoitem(cs),
870                                    "No address specified in listen section");
871                         return -1;
872                 }
873                 ipaddr.af = AF_INET6;
874         }
875
876         rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
877                               &listen_port, "0");
878         if (rcode < 0) return -1;
879
880         if ((listen_port < 0) || (listen_port > 65535)) {
881                         cf_log_err(cf_sectiontoitem(cs),
882                                    "Invalid value for \"port\"");
883                         return -1;
884         }
885
886         sock->proto = IPPROTO_UDP;
887
888         if (cf_pair_find(cs, "proto")) {
889 #ifndef WITH_TCP
890                 cf_log_err(cf_sectiontoitem(cs),
891                            "System does not support the TCP protocol.  Delete this line from the configuration file.");
892                 return -1;
893 #else
894                 char *proto = NULL;
895 #ifdef WITH_TLS
896                 CONF_SECTION *tls;
897 #endif
898
899                 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
900                                       &proto, "udp");
901                 if (rcode < 0) return -1;
902
903                 if (strcmp(proto, "udp") == 0) {
904                         sock->proto = IPPROTO_UDP;
905
906                 } else if (strcmp(proto, "tcp") == 0) {
907                         sock->proto = IPPROTO_TCP;
908
909                         rcode = cf_item_parse(cs, "max_connections", PW_TYPE_INTEGER,
910                                               &sock->max_connections, "64");
911                         if (rcode < 0) return -1;
912
913                 } else {
914                         cf_log_err(cf_sectiontoitem(cs),
915                                    "Unknown proto name \"%s\"", proto);
916                         free(proto);
917                         return -1;
918                 }
919                 free(proto);
920
921                 /*
922                  *      TCP requires a destination IP for sockets.
923                  *      UDP doesn't, so it's allowed.
924                  */
925 #ifdef WITH_PROXY
926                 if ((this->type == RAD_LISTEN_PROXY) &&
927                     (sock->proto != IPPROTO_UDP)) {
928                         cf_log_err(cf_sectiontoitem(cs),
929                                    "Proxy listeners can only listen on proto = udp");
930                         return -1;
931                 }
932 #endif  /* WITH_PROXY */
933
934 #ifdef WITH_TLS
935                 tls = cf_section_sub_find(cs, "tls");
936
937                 /*
938                  *      Don't allow TLS configurations for UDP sockets.
939                  */
940                 if (sock->proto != IPPROTO_TCP) {
941                         cf_log_err(cf_sectiontoitem(cs),
942                                    "TLS transport is not available for UDP sockets.");
943                         return -1;
944                 }
945
946                 if (tls) {
947                         /*
948                          *      FIXME: Make this better.
949                          */
950                         if (listen_port == 0) listen_port = 2083;
951
952                         this->tls = tls_server_conf_parse(tls);
953                         if (!this->tls) {
954                                 return -1;
955                         }
956
957 #ifdef HAVE_PTRHEAD_H
958                         if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
959                                 rad_assert(0 == 1);
960                                 listen_free(&this);
961                                 return 0;
962                         }
963 #endif
964
965                 }               
966 #else  /* WITH_TLS */
967                 /*
968                  *      Built without TLS.  Disallow it.
969                  */
970                 if (cf_section_sub_find(cs, "tls")) {
971                         cf_log_err(cf_sectiontoitem(cs),
972                                    "TLS transport is not available in this executable.");
973                         return -1;
974                 }
975 #endif  /* WITH_TLS */
976
977 #endif  /* WITH_TCP */
978
979                 /*
980                  *      No "proto" field.  Disallow TLS.
981                  */
982         } else if (cf_section_sub_find(cs, "tls")) {
983                 cf_log_err(cf_sectiontoitem(cs),
984                            "TLS transport is not available in this \"listen\" section.");
985                 return -1;
986         }
987
988         sock->my_ipaddr = ipaddr;
989         sock->my_port = listen_port;
990
991 #ifdef WITH_PROXY
992         if (check_config) {
993                 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
994                                 char buffer[128];
995                                 
996                                 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.",
997                                       ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
998                                       sock->my_port);
999                                 return -1;
1000                 }
1001
1002                 return 0;       /* don't do anything */
1003         }
1004 #endif
1005
1006         /*
1007          *      If we can bind to interfaces, do so,
1008          *      else don't.
1009          */
1010         if (cf_pair_find(cs, "interface")) {
1011                 const char *value;
1012                 CONF_PAIR *cp = cf_pair_find(cs, "interface");
1013
1014                 rad_assert(cp != NULL);
1015                 value = cf_pair_value(cp);
1016                 if (!value) {
1017                         cf_log_err(cf_sectiontoitem(cs),
1018                                    "No interface name given");
1019                         return -1;
1020                 }
1021                 sock->interface = value;
1022         }
1023
1024 #ifdef WITH_DHCP
1025         /*
1026          *      If we can do broadcasts..
1027          */
1028         if (cf_pair_find(cs, "broadcast")) {
1029 #ifndef SO_BROADCAST
1030                 cf_log_err(cf_sectiontoitem(cs),
1031                            "System does not support broadcast sockets.  Delete this line from the configuration file.");
1032                 return -1;
1033 #else
1034                 const char *value;
1035                 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
1036
1037                 if (this->type != RAD_LISTEN_DHCP) {
1038                         cf_log_err(cf_pairtoitem(cp),
1039                                    "Broadcast can only be set for DHCP listeners.  Delete this line from the configuration file.");
1040                         return -1;
1041                 }
1042                 
1043                 rad_assert(cp != NULL);
1044                 value = cf_pair_value(cp);
1045                 if (!value) {
1046                         cf_log_err(cf_sectiontoitem(cs),
1047                                    "No broadcast value given");
1048                         return -1;
1049                 }
1050
1051                 /*
1052                  *      Hack... whatever happened to cf_section_parse?
1053                  */
1054                 sock->broadcast = (strcmp(value, "yes") == 0);
1055 #endif
1056         }
1057 #endif
1058
1059         /*
1060          *      And bind it to the port.
1061          */
1062         if (listen_bind(this) < 0) {
1063                 char buffer[128];
1064                 cf_log_err(cf_sectiontoitem(cs),
1065                            "Error binding to port for %s port %d",
1066                            ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1067                            sock->my_port);
1068                 return -1;
1069         }
1070
1071 #ifdef WITH_PROXY
1072         /*
1073          *      Proxy sockets don't have clients.
1074          */
1075         if (this->type == RAD_LISTEN_PROXY) return 0;
1076 #endif
1077         
1078         /*
1079          *      The more specific configurations are preferred to more
1080          *      generic ones.
1081          */
1082         client_cs = NULL;
1083         parentcs = cf_top_section(cs);
1084         rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
1085                               &section_name, NULL);
1086         if (rcode < 0) return -1; /* bad string */
1087         if (rcode == 0) {
1088                 /*
1089                  *      Explicit list given: use it.
1090                  */
1091                 client_cs = cf_section_sub_find_name2(parentcs,
1092                                                       "clients",
1093                                                       section_name);
1094                 if (!client_cs) {
1095                         client_cs = cf_section_find(section_name);
1096                 }
1097                 if (!client_cs) {
1098                         cf_log_err(cf_sectiontoitem(cs),
1099                                    "Failed to find clients %s {...}",
1100                                    section_name);
1101                         free(section_name);
1102                         return -1;
1103                 }
1104                 free(section_name);
1105         } /* else there was no "clients = " entry. */
1106
1107         if (!client_cs) {
1108                 CONF_SECTION *server_cs;
1109
1110                 server_cs = cf_section_sub_find_name2(parentcs,
1111                                                       "server",
1112                                                       this->server);
1113                 /*
1114                  *      Found a "server foo" section.  If there are clients
1115                  *      in it, use them.
1116                  */
1117                 if (server_cs &&
1118                     (cf_section_sub_find(server_cs, "client") != NULL)) {
1119                         client_cs = server_cs;
1120                 }
1121         }
1122
1123         /*
1124          *      Still nothing.  Look for global clients.
1125          */
1126         if (!client_cs) client_cs = parentcs;
1127
1128         sock->clients = clients_parse_section(client_cs);
1129         if (!sock->clients) {
1130                 cf_log_err(cf_sectiontoitem(cs),
1131                            "Failed to load clients for this listen section");
1132                 return -1;
1133         }
1134
1135 #ifdef WITH_TCP
1136         if (sock->proto == IPPROTO_TCP) {
1137                 /*
1138                  *      Re-write the listener receive function to
1139                  *      allow us to accept the socket.
1140                  */
1141                 this->recv = dual_tcp_accept;
1142         }
1143 #endif
1144
1145         return 0;
1146 }
1147
1148 /*
1149  *      Send an authentication response packet
1150  */
1151 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1152 {
1153         rad_assert(request->listener == listener);
1154         rad_assert(listener->send == auth_socket_send);
1155
1156         if (rad_send(request->reply, request->packet,
1157                      request->client->secret) < 0) {
1158                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1159                                fr_strerror());
1160                 return -1;
1161         }
1162
1163         return 0;
1164 }
1165
1166
1167 #ifdef WITH_ACCOUNTING
1168 /*
1169  *      Send an accounting response packet (or not)
1170  */
1171 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1172 {
1173         rad_assert(request->listener == listener);
1174         rad_assert(listener->send == acct_socket_send);
1175
1176         /*
1177          *      Accounting reject's are silently dropped.
1178          *
1179          *      We do it here to avoid polluting the rest of the
1180          *      code with this knowledge
1181          */
1182         if (request->reply->code == 0) return 0;
1183
1184         if (rad_send(request->reply, request->packet,
1185                      request->client->secret) < 0) {
1186                 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1187                                fr_strerror());
1188                 return -1;
1189         }
1190
1191         return 0;
1192 }
1193 #endif
1194
1195 #ifdef WITH_PROXY
1196 /*
1197  *      Send a packet to a home server.
1198  *
1199  *      FIXME: have different code for proxy auth & acct!
1200  */
1201 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1202 {
1203         rad_assert(request->proxy_listener == listener);
1204         rad_assert(listener->send == proxy_socket_send);
1205
1206         if (rad_send(request->proxy, request->packet,
1207                      request->home_server->secret) < 0) {
1208                 radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
1209                                fr_strerror());
1210                 return -1;
1211         }
1212
1213         return 0;
1214 }
1215 #endif
1216
1217 #ifdef WITH_STATS
1218 /*
1219  *      Check if an incoming request is "ok"
1220  *
1221  *      It takes packets, not requests.  It sees if the packet looks
1222  *      OK.  If so, it does a number of sanity checks on it.
1223   */
1224 static int stats_socket_recv(rad_listen_t *listener)
1225 {
1226         ssize_t         rcode;
1227         int             code, src_port;
1228         RADIUS_PACKET   *packet;
1229         RADCLIENT       *client = NULL;
1230         fr_ipaddr_t     src_ipaddr;
1231
1232         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1233         if (rcode < 0) return 0;
1234
1235         FR_STATS_INC(auth, total_requests);
1236
1237         if (rcode < 20) {       /* AUTH_HDR_LEN */
1238                 FR_STATS_INC(auth, total_malformed_requests);
1239                 return 0;
1240         }
1241
1242         if ((client = client_listener_find(listener,
1243                                            &src_ipaddr, src_port)) == NULL) {
1244                 rad_recv_discard(listener->fd);
1245                 FR_STATS_INC(auth, total_invalid_requests);
1246                 return 0;
1247         }
1248
1249         FR_STATS_TYPE_INC(client->auth->total_requests);
1250
1251         /*
1252          *      We only understand Status-Server on this socket.
1253          */
1254         if (code != PW_STATUS_SERVER) {
1255                 DEBUG("Ignoring packet code %d sent to Status-Server port",
1256                       code);
1257                 rad_recv_discard(listener->fd);
1258                 FR_STATS_INC(auth, total_unknown_types);
1259                 return 0;
1260         }
1261
1262         /*
1263          *      Now that we've sanity checked everything, receive the
1264          *      packet.
1265          */
1266         packet = rad_recv(listener->fd, 1); /* require message authenticator */
1267         if (!packet) {
1268                 FR_STATS_INC(auth, total_malformed_requests);
1269                 DEBUG("%s", fr_strerror());
1270                 return 0;
1271         }
1272
1273         if (!request_receive(listener, packet, client, rad_status_server)) {
1274                 FR_STATS_INC(auth, total_packets_dropped);
1275                 rad_free(&packet);
1276                 return 0;
1277         }
1278
1279         return 1;
1280 }
1281 #endif
1282
1283
1284 /*
1285  *      Check if an incoming request is "ok"
1286  *
1287  *      It takes packets, not requests.  It sees if the packet looks
1288  *      OK.  If so, it does a number of sanity checks on it.
1289   */
1290 static int auth_socket_recv(rad_listen_t *listener)
1291 {
1292         ssize_t         rcode;
1293         int             code, src_port;
1294         RADIUS_PACKET   *packet;
1295         RAD_REQUEST_FUNP fun = NULL;
1296         RADCLIENT       *client = NULL;
1297         fr_ipaddr_t     src_ipaddr;
1298
1299         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1300         if (rcode < 0) return 0;
1301
1302         FR_STATS_INC(auth, total_requests);
1303
1304         if (rcode < 20) {       /* AUTH_HDR_LEN */
1305                 FR_STATS_INC(auth, total_malformed_requests);
1306                 return 0;
1307         }
1308
1309         if ((client = client_listener_find(listener,
1310                                            &src_ipaddr, src_port)) == NULL) {
1311                 rad_recv_discard(listener->fd);
1312                 FR_STATS_INC(auth, total_invalid_requests);
1313                 return 0;
1314         }
1315
1316         FR_STATS_TYPE_INC(client->auth->total_requests);
1317
1318         /*
1319          *      Some sanity checks, based on the packet code.
1320          */
1321         switch(code) {
1322         case PW_AUTHENTICATION_REQUEST:
1323                 fun = rad_authenticate;
1324                 break;
1325
1326         case PW_STATUS_SERVER:
1327                 if (!mainconfig.status_server) {
1328                         rad_recv_discard(listener->fd);
1329                         FR_STATS_INC(auth, total_unknown_types);
1330                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1331                         return 0;
1332                 }
1333                 fun = rad_status_server;
1334                 break;
1335
1336         default:
1337                 rad_recv_discard(listener->fd);
1338                 FR_STATS_INC(auth,total_unknown_types);
1339
1340                 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1341                       code, client->shortname, src_port);
1342                 return 0;
1343                 break;
1344         } /* switch over packet types */
1345
1346         /*
1347          *      Now that we've sanity checked everything, receive the
1348          *      packet.
1349          */
1350         packet = rad_recv(listener->fd, client->message_authenticator);
1351         if (!packet) {
1352                 FR_STATS_INC(auth, total_malformed_requests);
1353                 DEBUG("%s", fr_strerror());
1354                 return 0;
1355         }
1356
1357         if (!request_receive(listener, packet, client, fun)) {
1358                 FR_STATS_INC(auth, total_packets_dropped);
1359                 rad_free(&packet);
1360                 return 0;
1361         }
1362
1363         return 1;
1364 }
1365
1366
1367 #ifdef WITH_ACCOUNTING
1368 /*
1369  *      Receive packets from an accounting socket
1370  */
1371 static int acct_socket_recv(rad_listen_t *listener)
1372 {
1373         ssize_t         rcode;
1374         int             code, src_port;
1375         RADIUS_PACKET   *packet;
1376         RAD_REQUEST_FUNP fun = NULL;
1377         RADCLIENT       *client = NULL;
1378         fr_ipaddr_t     src_ipaddr;
1379
1380         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1381         if (rcode < 0) return 0;
1382
1383         FR_STATS_INC(acct, total_requests);
1384
1385         if (rcode < 20) {       /* AUTH_HDR_LEN */
1386                 FR_STATS_INC(acct, total_malformed_requests);
1387                 return 0;
1388         }
1389
1390         if ((client = client_listener_find(listener,
1391                                            &src_ipaddr, src_port)) == NULL) {
1392                 rad_recv_discard(listener->fd);
1393                 FR_STATS_INC(acct, total_invalid_requests);
1394                 return 0;
1395         }
1396
1397         FR_STATS_TYPE_INC(client->acct->total_requests);
1398
1399         /*
1400          *      Some sanity checks, based on the packet code.
1401          */
1402         switch(code) {
1403         case PW_ACCOUNTING_REQUEST:
1404                 fun = rad_accounting;
1405                 break;
1406
1407         case PW_STATUS_SERVER:
1408                 if (!mainconfig.status_server) {
1409                         rad_recv_discard(listener->fd);
1410                         FR_STATS_INC(acct, total_unknown_types);
1411
1412                         DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
1413                         return 0;
1414                 }
1415                 fun = rad_status_server;
1416                 break;
1417
1418         default:
1419                 rad_recv_discard(listener->fd);
1420                 FR_STATS_INC(acct, total_unknown_types);
1421
1422                 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1423                       code, client->shortname, src_port);
1424                 return 0;
1425         } /* switch over packet types */
1426
1427         /*
1428          *      Now that we've sanity checked everything, receive the
1429          *      packet.
1430          */
1431         packet = rad_recv(listener->fd, 0);
1432         if (!packet) {
1433                 FR_STATS_INC(acct, total_malformed_requests);
1434                 radlog(L_ERR, "%s", fr_strerror());
1435                 return 0;
1436         }
1437
1438         /*
1439          *      There can be no duplicate accounting packets.
1440          */
1441         if (!request_receive(listener, packet, client, fun)) {
1442                 FR_STATS_INC(acct, total_packets_dropped);
1443                 rad_free(&packet);
1444                 return 0;
1445         }
1446
1447         return 1;
1448 }
1449 #endif
1450
1451
1452 #ifdef WITH_COA
1453 static int do_proxy(REQUEST *request)
1454 {
1455         VALUE_PAIR *vp;
1456
1457         if (request->in_proxy_hash ||
1458             (request->proxy_reply && (request->proxy_reply->code != 0))) {
1459                 return 0;
1460         }
1461
1462         vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0);
1463         if (!vp) return 0;
1464         
1465         if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
1466                 RDEBUG2("ERROR: Cannot proxy to unknown pool %s",
1467                         vp->vp_strvalue);
1468                 return 0;
1469         }
1470
1471         return 1;
1472 }
1473
1474 /*
1475  *      Receive a CoA packet.
1476  */
1477 static int rad_coa_recv(REQUEST *request)
1478 {
1479         int rcode = RLM_MODULE_OK;
1480         int ack, nak;
1481         VALUE_PAIR *vp;
1482
1483         /*
1484          *      Get the correct response
1485          */
1486         switch (request->packet->code) {
1487         case PW_COA_REQUEST:
1488                 ack = PW_COA_ACK;
1489                 nak = PW_COA_NAK;
1490                 break;
1491
1492         case PW_DISCONNECT_REQUEST:
1493                 ack = PW_DISCONNECT_ACK;
1494                 nak = PW_DISCONNECT_NAK;
1495                 break;
1496
1497         default:                /* shouldn't happen */
1498                 return RLM_MODULE_FAIL;
1499         }
1500
1501 #ifdef WITH_PROXY
1502 #define WAS_PROXIED (request->proxy)
1503 #else
1504 #define WAS_PROXIED (0)
1505 #endif
1506
1507         if (!WAS_PROXIED) {
1508                 /*
1509                  *      RFC 5176 Section 3.3.  If we have a CoA-Request
1510                  *      with Service-Type = Authorize-Only, it MUST
1511                  *      have a State attribute in it.
1512                  */
1513                 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0);
1514                 if (request->packet->code == PW_COA_REQUEST) {
1515                         if (vp && (vp->vp_integer == 17)) {
1516                                 vp = pairfind(request->packet->vps, PW_STATE, 0);
1517                                 if (!vp || (vp->length == 0)) {
1518                                         RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1519                                         request->reply->code = PW_COA_NAK;
1520                                         return RLM_MODULE_FAIL;
1521                                 }
1522                         }
1523                 } else if (vp) {
1524                         /*
1525                          *      RFC 5176, Section 3.2.
1526                          */
1527                         RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1528                         request->reply->code = PW_DISCONNECT_NAK;
1529                         return RLM_MODULE_FAIL;
1530                 }
1531
1532                 rcode = module_recv_coa(0, request);
1533                 switch (rcode) {
1534                 case RLM_MODULE_FAIL:
1535                 case RLM_MODULE_INVALID:
1536                 case RLM_MODULE_REJECT:
1537                 case RLM_MODULE_USERLOCK:
1538                 default:
1539                         request->reply->code = nak;
1540                         break;
1541                         
1542                 case RLM_MODULE_HANDLED:
1543                         return rcode;
1544                         
1545                 case RLM_MODULE_NOOP:
1546                 case RLM_MODULE_NOTFOUND:
1547                 case RLM_MODULE_OK:
1548                 case RLM_MODULE_UPDATED:
1549                         if (do_proxy(request)) return RLM_MODULE_OK;
1550                         request->reply->code = ack;
1551                         break;
1552                 }
1553         } else if (request->proxy_reply) {
1554                 /*
1555                  *      Start the reply code with the proxy reply
1556                  *      code.
1557                  */
1558                 request->reply->code = request->proxy_reply->code;
1559         }
1560
1561         /*
1562          *      Copy State from the request to the reply.
1563          *      See RFC 5176 Section 3.3.
1564          */
1565         vp = paircopy2(request->packet->vps, PW_STATE, 0);
1566         if (vp) pairadd(&request->reply->vps, vp);
1567
1568         /*
1569          *      We may want to over-ride the reply.
1570          */
1571         if (request->reply->code) {
1572                 rcode = module_send_coa(0, request);
1573                 switch (rcode) {
1574                         /*
1575                          *      We need to send CoA-NAK back if Service-Type
1576                          *      is Authorize-Only.  Rely on the user's policy
1577                          *      to do that.  We're not a real NAS, so this
1578                          *      restriction doesn't (ahem) apply to us.
1579                          */
1580                 case RLM_MODULE_FAIL:
1581                 case RLM_MODULE_INVALID:
1582                 case RLM_MODULE_REJECT:
1583                 case RLM_MODULE_USERLOCK:
1584                 default:
1585                         /*
1586                          *      Over-ride an ACK with a NAK
1587                          */
1588                         request->reply->code = nak;
1589                         break;
1590                         
1591                 case RLM_MODULE_HANDLED:
1592                         return rcode;
1593                         
1594                 case RLM_MODULE_NOOP:
1595                 case RLM_MODULE_NOTFOUND:
1596                 case RLM_MODULE_OK:
1597                 case RLM_MODULE_UPDATED:
1598                         /*
1599                          *      Do NOT over-ride a previously set value.
1600                          *      Otherwise an "ok" here will re-write a
1601                          *      NAK to an ACK.
1602                          */
1603                         if (request->reply->code == 0) {
1604                                 request->reply->code = ack;
1605                         }
1606                         break;
1607                 }
1608         }
1609
1610         return RLM_MODULE_OK;
1611 }
1612
1613
1614 /*
1615  *      Check if an incoming request is "ok"
1616  *
1617  *      It takes packets, not requests.  It sees if the packet looks
1618  *      OK.  If so, it does a number of sanity checks on it.
1619   */
1620 static int coa_socket_recv(rad_listen_t *listener)
1621 {
1622         ssize_t         rcode;
1623         int             code, src_port;
1624         RADIUS_PACKET   *packet;
1625         RAD_REQUEST_FUNP fun = NULL;
1626         RADCLIENT       *client = NULL;
1627         fr_ipaddr_t     src_ipaddr;
1628
1629         rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1630         if (rcode < 0) return 0;
1631
1632         if (rcode < 20) {       /* AUTH_HDR_LEN */
1633                 FR_STATS_INC(coa, total_requests);
1634                 FR_STATS_INC(coa, total_malformed_requests);
1635                 return 0;
1636         }
1637
1638         if ((client = client_listener_find(listener,
1639                                            &src_ipaddr, src_port)) == NULL) {
1640                 rad_recv_discard(listener->fd);
1641                 FR_STATS_INC(coa, total_requests);
1642                 FR_STATS_INC(coa, total_invalid_requests);
1643                 return 0;
1644         }
1645
1646         /*
1647          *      Some sanity checks, based on the packet code.
1648          */
1649         switch(code) {
1650         case PW_COA_REQUEST:
1651                 FR_STATS_INC(coa, total_requests);
1652                 fun = rad_coa_recv;
1653                 break;
1654
1655         case PW_DISCONNECT_REQUEST:
1656                 FR_STATS_INC(dsc, total_requests);
1657                 fun = rad_coa_recv;
1658                 break;
1659
1660         default:
1661                 rad_recv_discard(listener->fd);
1662                 FR_STATS_INC(coa, total_unknown_types);
1663                 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1664                       code, client->shortname, src_port);
1665                 return 0;
1666         } /* switch over packet types */
1667
1668         /*
1669          *      Now that we've sanity checked everything, receive the
1670          *      packet.
1671          */
1672         packet = rad_recv(listener->fd, client->message_authenticator);
1673         if (!packet) {
1674                 FR_STATS_INC(coa, total_malformed_requests);
1675                 DEBUG("%s", fr_strerror());
1676                 return 0;
1677         }
1678
1679         if (!request_receive(listener, packet, client, fun)) {
1680                 FR_STATS_INC(coa, total_packets_dropped);
1681                 rad_free(&packet);
1682                 return 0;
1683         }
1684
1685         return 1;
1686 }
1687 #endif
1688
1689 #ifdef WITH_PROXY
1690 /*
1691  *      Recieve packets from a proxy socket.
1692  */
1693 static int proxy_socket_recv(rad_listen_t *listener)
1694 {
1695         RADIUS_PACKET   *packet;
1696         char            buffer[128];
1697
1698         packet = rad_recv(listener->fd, 0);
1699         if (!packet) {
1700                 radlog(L_ERR, "%s", fr_strerror());
1701                 return 0;
1702         }
1703
1704         /*
1705          *      FIXME: Client MIB updates?
1706          */
1707         switch(packet->code) {
1708         case PW_AUTHENTICATION_ACK:
1709         case PW_ACCESS_CHALLENGE:
1710         case PW_AUTHENTICATION_REJECT:
1711                 break;
1712
1713 #ifdef WITH_ACCOUNTING
1714         case PW_ACCOUNTING_RESPONSE:
1715                 break;
1716 #endif
1717
1718 #ifdef WITH_COA
1719         case PW_DISCONNECT_ACK:
1720         case PW_DISCONNECT_NAK:
1721         case PW_COA_ACK:
1722         case PW_COA_NAK:
1723                 break;
1724 #endif
1725
1726         default:
1727                 /*
1728                  *      FIXME: Update MIB for packet types?
1729                  */
1730                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1731                        "from home server %s port %d - ID %d : IGNORED",
1732                        packet->code,
1733                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1734                        packet->src_port, packet->id);
1735                 rad_free(&packet);
1736                 return 0;
1737         }
1738
1739         if (!request_proxy_reply(packet)) {
1740                 rad_free(&packet);
1741                 return 0;
1742         }
1743
1744         return 1;
1745 }
1746
1747 #ifdef WITH_TCP
1748 /*
1749  *      Recieve packets from a proxy socket.
1750  */
1751 static int proxy_socket_tcp_recv(rad_listen_t *listener)
1752 {
1753         RADIUS_PACKET   *packet;
1754         listen_socket_t *sock = listener->data;
1755         char            buffer[128];
1756
1757         packet = fr_tcp_recv(listener->fd, 0);
1758         if (!packet) {
1759                 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1760                 event_new_fd(listener);
1761                 return 0;
1762         }
1763
1764         /*
1765          *      FIXME: Client MIB updates?
1766          */
1767         switch(packet->code) {
1768         case PW_AUTHENTICATION_ACK:
1769         case PW_ACCESS_CHALLENGE:
1770         case PW_AUTHENTICATION_REJECT:
1771                 break;
1772
1773 #ifdef WITH_ACCOUNTING
1774         case PW_ACCOUNTING_RESPONSE:
1775                 break;
1776 #endif
1777
1778         default:
1779                 /*
1780                  *      FIXME: Update MIB for packet types?
1781                  */
1782                 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1783                        "from home server %s port %d - ID %d : IGNORED",
1784                        packet->code,
1785                        ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1786                        packet->src_port, packet->id);
1787                 rad_free(&packet);
1788                 return 0;
1789         }
1790
1791         packet->src_ipaddr = sock->other_ipaddr;
1792         packet->src_port = sock->other_port;
1793         packet->dst_ipaddr = sock->my_ipaddr;
1794         packet->dst_port = sock->my_port;
1795
1796         /*
1797          *      FIXME: Have it return an indication of packets that
1798          *      are OK to ignore (dups, too late), versus ones that
1799          *      aren't OK to ignore (unknown response, spoofed, etc.)
1800          *
1801          *      Close the socket on bad packets...
1802          */
1803         if (!request_proxy_reply(packet)) {
1804                 rad_free(&packet);
1805                 return 0;
1806         }
1807
1808         sock->opened = sock->last_packet = time(NULL);
1809
1810         return 1;
1811 }
1812 #endif
1813 #endif
1814
1815
1816 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1817 {
1818         if (!request->reply->code) return 0;
1819
1820         if (rad_encode(request->reply, request->packet,
1821                        request->client->secret) < 0) {
1822                 radlog_request(L_ERR, 0, request, "Failed encoding packet: %s",
1823                                fr_strerror());
1824                 return -1;
1825         }
1826
1827         if (rad_sign(request->reply, request->packet,
1828                      request->client->secret) < 0) {
1829                 radlog_request(L_ERR, 0, request, "Failed signing packet: %s",
1830                                fr_strerror());
1831                 return -1;
1832         }
1833
1834         return 0;
1835 }
1836
1837
1838 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1839 {
1840         if (rad_verify(request->packet, NULL,
1841                        request->client->secret) < 0) {
1842                 return -1;
1843         }
1844
1845         return rad_decode(request->packet, NULL,
1846                           request->client->secret);
1847 }
1848
1849 #ifdef WITH_PROXY
1850 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1851 {
1852         if (rad_encode(request->proxy, NULL, request->home_server->secret) < 0) {
1853                 radlog_request(L_ERR, 0, request, "Failed encoding proxied packet: %s",
1854                                fr_strerror());
1855                 return -1;
1856         }
1857
1858         if (rad_sign(request->proxy, NULL, request->home_server->secret) < 0) {
1859                 radlog_request(L_ERR, 0, request, "Failed signing proxied packet: %s",
1860                                fr_strerror());
1861                 return -1;
1862         }
1863
1864         return 0;
1865 }
1866
1867
1868 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1869 {
1870         /*
1871          *      rad_verify is run in event.c, received_proxy_response()
1872          */
1873
1874         return rad_decode(request->proxy_reply, request->proxy,
1875                            request->home_server->secret);
1876 }
1877 #endif
1878
1879 #include "dhcpd.c"
1880
1881 #include "command.c"
1882
1883 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1884 #ifdef WITH_STATS
1885         { common_socket_parse, NULL,
1886           stats_socket_recv, auth_socket_send,
1887           socket_print, client_socket_encode, client_socket_decode },
1888 #else
1889         /*
1890          *      This always gets defined.
1891          */
1892         { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
1893 #endif
1894
1895 #ifdef WITH_PROXY
1896         /* proxying */
1897         { common_socket_parse, NULL,
1898           proxy_socket_recv, proxy_socket_send,
1899           socket_print, proxy_socket_encode, proxy_socket_decode },
1900 #endif
1901
1902         /* authentication */
1903         { common_socket_parse, NULL,
1904           auth_socket_recv, auth_socket_send,
1905           socket_print, client_socket_encode, client_socket_decode },
1906
1907 #ifdef WITH_ACCOUNTING
1908         /* accounting */
1909         { common_socket_parse, NULL,
1910           acct_socket_recv, acct_socket_send,
1911           socket_print, client_socket_encode, client_socket_decode},
1912 #endif
1913
1914 #ifdef WITH_DETAIL
1915         /* detail */
1916         { detail_parse, detail_free,
1917           detail_recv, detail_send,
1918           detail_print, detail_encode, detail_decode },
1919 #endif
1920
1921 #ifdef WITH_VMPS
1922         /* vlan query protocol */
1923         { common_socket_parse, NULL,
1924           vqp_socket_recv, vqp_socket_send,
1925           socket_print, vqp_socket_encode, vqp_socket_decode },
1926 #endif
1927
1928 #ifdef WITH_DHCP
1929         /* dhcp query protocol */
1930         { dhcp_socket_parse, NULL,
1931           dhcp_socket_recv, dhcp_socket_send,
1932           socket_print, dhcp_socket_encode, dhcp_socket_decode },
1933 #endif
1934
1935 #ifdef WITH_COMMAND_SOCKET
1936         /* TCP command socket */
1937         { command_socket_parse, command_socket_free,
1938           command_domain_accept, command_domain_send,
1939           command_socket_print, command_socket_encode, command_socket_decode },
1940 #endif
1941
1942 #ifdef WITH_COA
1943         /* Change of Authorization */
1944         { common_socket_parse, NULL,
1945           coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1946           socket_print, client_socket_encode, client_socket_decode },
1947 #endif
1948
1949 };
1950
1951
1952
1953 /*
1954  *      Binds a listener to a socket.
1955  */
1956 static int listen_bind(rad_listen_t *this)
1957 {
1958         int rcode;
1959         struct sockaddr_storage salocal;
1960         socklen_t       salen;
1961         listen_socket_t *sock = this->data;
1962 #ifndef WITH_TCP
1963 #define proto_for_port "udp"
1964 #define sock_type SOCK_DGRAM
1965 #else
1966         const char *proto_for_port = "udp";
1967         int sock_type = SOCK_DGRAM;
1968         
1969         if (sock->proto == IPPROTO_TCP) {
1970 #ifdef WITH_VMPS
1971                 if (this->type == RAD_LISTEN_VQP) {
1972                         radlog(L_ERR, "VQP does not support TCP transport");
1973                         return -1;
1974                 }
1975 #endif
1976
1977                 proto_for_port = "tcp";
1978                 sock_type = SOCK_STREAM;        
1979         }
1980 #endif
1981
1982         /*
1983          *      If the port is zero, then it means the appropriate
1984          *      thing from /etc/services.
1985          */
1986         if (sock->my_port == 0) {
1987                 struct servent  *svp;
1988
1989                 switch (this->type) {
1990                 case RAD_LISTEN_AUTH:
1991                         svp = getservbyname ("radius", proto_for_port);
1992                         if (svp != NULL) {
1993                                 sock->my_port = ntohs(svp->s_port);
1994                         } else {
1995                                 sock->my_port = PW_AUTH_UDP_PORT;
1996                         }
1997                         break;
1998
1999 #ifdef WITH_ACCOUNTING
2000                 case RAD_LISTEN_ACCT:
2001                         svp = getservbyname ("radacct", proto_for_port);
2002                         if (svp != NULL) {
2003                                 sock->my_port = ntohs(svp->s_port);
2004                         } else {
2005                                 sock->my_port = PW_ACCT_UDP_PORT;
2006                         }
2007                         break;
2008 #endif
2009
2010 #ifdef WITH_PROXY
2011                 case RAD_LISTEN_PROXY:
2012                         /* leave it at zero */
2013                         break;
2014 #endif
2015
2016 #ifdef WITH_VMPS
2017                 case RAD_LISTEN_VQP:
2018                         sock->my_port = 1589;
2019                         break;
2020 #endif
2021
2022 #ifdef WITH_COA
2023                 case RAD_LISTEN_COA:
2024                         svp = getservbyname ("radius-dynauth", "udp");
2025                         if (svp != NULL) {
2026                                 sock->my_port = ntohs(svp->s_port);
2027                         } else {
2028                                 sock->my_port = PW_COA_UDP_PORT;
2029                         }
2030                         break;
2031 #endif
2032
2033                 default:
2034                         DEBUG("WARNING: Internal sanity check failed in binding to socket.  Ignoring problem.");
2035                         return -1;
2036                 }
2037         }
2038
2039         /*
2040          *      Copy fr_socket() here, as we may need to bind to a device.
2041          */
2042         this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
2043         if (this->fd < 0) {
2044                 char buffer[256];
2045
2046                 this->print(this, buffer, sizeof(buffer));
2047
2048                 radlog(L_ERR, "Failed opening %s: %s", buffer, strerror(errno));
2049                 return -1;
2050         }
2051                 
2052         /*
2053          *      Bind to a device BEFORE touching IP addresses.
2054          */
2055         if (sock->interface) {
2056 #ifdef SO_BINDTODEVICE
2057                 struct ifreq ifreq;
2058                 strcpy(ifreq.ifr_name, sock->interface);
2059
2060                 fr_suid_up();
2061                 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
2062                                    (char *)&ifreq, sizeof(ifreq));
2063                 fr_suid_down();
2064                 if (rcode < 0) {
2065                         close(this->fd);
2066                         radlog(L_ERR, "Failed binding to interface %s: %s",
2067                                sock->interface, strerror(errno));
2068                         return -1;
2069                 } /* else it worked. */
2070 #else
2071 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2072 #ifdef HAVE_NET_IF_H
2073                 /*
2074                  *      Odds are that any system supporting "bind to
2075                  *      device" also supports IPv6, so this next bit
2076                  *      isn't necessary.  But it's here for
2077                  *      completeness.
2078                  *
2079                  *      If we're doing IPv6, and the scope hasn't yet
2080                  *      been defined, set the scope to the scope of
2081                  *      the interface.
2082                  */
2083                 if (sock->my_ipaddr.af == AF_INET6) {
2084                         if (sock->my_ipaddr.scope == 0) {
2085                                 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
2086                                 if (sock->my_ipaddr.scope == 0) {
2087                                         close(this->fd);
2088                                         radlog(L_ERR, "Failed finding interface %s: %s",
2089                                                sock->interface, strerror(errno));
2090                                         return -1;
2091                                 }
2092                         } /* else scope was defined: we're OK. */
2093                 } else
2094 #endif
2095 #endif
2096                                 /*
2097                                  *      IPv4: no link local addresses,
2098                                  *      and no bind to device.
2099                                  */
2100                 {
2101                         close(this->fd);
2102                         radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
2103                         return -1;
2104                 }
2105 #endif
2106         }
2107
2108 #ifdef WITH_TCP
2109         if (sock->proto == IPPROTO_TCP) {
2110                 int on = 1;
2111
2112                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2113                         close(this->fd);
2114                         radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2115                         return -1;
2116                 }
2117         }
2118 #endif
2119
2120 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2121         else                    /* UDP sockets get UDPfromto */
2122 #endif
2123
2124 #ifdef WITH_UDPFROMTO
2125         /*
2126          *      Initialize udpfromto for all sockets.
2127          */
2128         if (udpfromto_init(this->fd) != 0) {
2129                 radlog(L_ERR, "Failed initializing udpfromto: %s",
2130                        strerror(errno));
2131                 close(this->fd);
2132                 return -1;
2133         }
2134 #endif
2135
2136         /*
2137          *      Set up sockaddr stuff.
2138          */
2139         if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2140                 close(this->fd);
2141                 return -1;
2142         }
2143                 
2144 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2145         if (sock->my_ipaddr.af == AF_INET6) {
2146                 /*
2147                  *      Listening on '::' does NOT get you IPv4 to
2148                  *      IPv6 mapping.  You've got to listen on an IPv4
2149                  *      address, too.  This makes the rest of the server
2150                  *      design a little simpler.
2151                  */
2152 #ifdef IPV6_V6ONLY
2153                 
2154                 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2155                         int on = 1;
2156                         
2157                         setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2158                                    (char *)&on, sizeof(on));
2159                 }
2160 #endif /* IPV6_V6ONLY */
2161         }
2162 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2163
2164         if (sock->my_ipaddr.af == AF_INET) {
2165                 UNUSED int flag;
2166                 
2167 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2168                 /*
2169                  *      Disable PMTU discovery.  On Linux, this
2170                  *      also makes sure that the "don't fragment"
2171                  *      flag is zero.
2172                  */
2173                 flag = IP_PMTUDISC_DONT;
2174                 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2175                            &flag, sizeof(flag));
2176 #endif
2177
2178 #if defined(IP_DONTFRAG)
2179                 /*
2180                  *      Ensure that the "don't fragment" flag is zero.
2181                  */
2182                 flag = 0;
2183                 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2184                            &flag, sizeof(flag));
2185 #endif
2186         }
2187
2188 #ifdef WITH_DHCP
2189 #ifdef SO_BROADCAST
2190         if (sock->broadcast) {
2191                 int on = 1;
2192                 
2193                 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2194                         radlog(L_ERR, "Can't set broadcast option: %s\n",
2195                                strerror(errno));
2196                         return -1;
2197                 }
2198         }
2199 #endif
2200 #endif
2201
2202         /*
2203          *      May be binding to priviledged ports.
2204          */
2205         if (sock->my_port != 0) {
2206 #ifdef SO_REUSEADDR
2207                 int on = 1;
2208
2209                 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2210                         radlog(L_ERR, "Can't set re-use address option: %s\n",
2211                                strerror(errno));
2212                         return -1;
2213                 }
2214 #endif
2215
2216                 fr_suid_up();
2217                 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2218                 fr_suid_down();
2219                 if (rcode < 0) {
2220                         char buffer[256];
2221                         close(this->fd);
2222                         
2223                         this->print(this, buffer, sizeof(buffer));
2224                         radlog(L_ERR, "Failed binding to %s: %s\n",
2225                                buffer, strerror(errno));
2226                         return -1;
2227                 }
2228         
2229                 /*
2230                  *      FreeBSD jail issues.  We bind to 0.0.0.0, but the
2231                  *      kernel instead binds us to a 1.2.3.4.  If this
2232                  *      happens, notice, and remember our real IP.
2233                  */
2234                 {
2235                         struct sockaddr_storage src;
2236                         socklen_t               sizeof_src = sizeof(src);
2237                         
2238                         memset(&src, 0, sizeof_src);
2239                         if (getsockname(this->fd, (struct sockaddr *) &src,
2240                                         &sizeof_src) < 0) {
2241                                 radlog(L_ERR, "Failed getting socket name: %s",
2242                                        strerror(errno));
2243                                 return -1;
2244                         }
2245                         
2246                         if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2247                                                 &sock->my_ipaddr, &sock->my_port)) {
2248                                 radlog(L_ERR, "Socket has unsupported address family");
2249                                 return -1;
2250                         }
2251                 }
2252         }
2253
2254 #ifdef WITH_TCP
2255         if (sock->proto == IPPROTO_TCP) {
2256                 if (listen(this->fd, 8) < 0) {
2257                         close(this->fd);
2258                         radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2259                         return -1;
2260                 }
2261         } else
2262 #endif
2263
2264           if (fr_nonblock(this->fd) < 0) {
2265                   close(this->fd);
2266                   radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2267                          strerror(errno));
2268                   return -1;
2269           }
2270
2271         /*
2272          *      Mostly for proxy sockets.
2273          */
2274         sock->other_ipaddr.af = sock->my_ipaddr.af;
2275
2276 /*
2277  *      Don't screw up other people.
2278  */
2279 #undef proto_for_port
2280 #undef sock_type
2281
2282         return 0;
2283 }
2284
2285
2286 /*
2287  *      Allocate & initialize a new listener.
2288  */
2289 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
2290 {
2291         rad_listen_t *this;
2292
2293         this = rad_malloc(sizeof(*this));
2294         memset(this, 0, sizeof(*this));
2295
2296         this->type = type;
2297         this->recv = master_listen[this->type].recv;
2298         this->send = master_listen[this->type].send;
2299         this->print = master_listen[this->type].print;
2300         this->encode = master_listen[this->type].encode;
2301         this->decode = master_listen[this->type].decode;
2302
2303         switch (type) {
2304 #ifdef WITH_STATS
2305         case RAD_LISTEN_NONE:
2306 #endif
2307         case RAD_LISTEN_AUTH:
2308 #ifdef WITH_ACCOUNTING
2309         case RAD_LISTEN_ACCT:
2310 #endif
2311 #ifdef WITH_PROXY
2312         case RAD_LISTEN_PROXY:
2313 #endif
2314 #ifdef WITH_VMPS
2315         case RAD_LISTEN_VQP:
2316 #endif
2317 #ifdef WITH_COA
2318         case RAD_LISTEN_COA:
2319 #endif
2320                 this->data = rad_malloc(sizeof(listen_socket_t));
2321                 memset(this->data, 0, sizeof(listen_socket_t));
2322                 break;
2323
2324 #ifdef WITH_DHCP
2325         case RAD_LISTEN_DHCP:
2326                 this->data = rad_malloc(sizeof(dhcp_socket_t));
2327                 memset(this->data, 0, sizeof(dhcp_socket_t));
2328                 break;
2329 #endif
2330
2331 #ifdef WITH_DETAIL
2332         case RAD_LISTEN_DETAIL:
2333                 this->data = NULL;
2334                 break;
2335 #endif
2336
2337 #ifdef WITH_COMMAND_SOCKET
2338         case RAD_LISTEN_COMMAND:
2339                 this->data = rad_malloc(sizeof(fr_command_socket_t));
2340                 memset(this->data, 0, sizeof(fr_command_socket_t));
2341                 break;
2342 #endif
2343
2344         default:
2345                 rad_assert("Unsupported option!" == NULL);
2346                 break;
2347         }
2348
2349         return this;
2350 }
2351
2352 #ifdef WITH_PROXY
2353 /*
2354  *      Externally visible function for creating a new proxy LISTENER.
2355  *
2356  *      Not thread-safe, but all calls to it are protected by the
2357  *      proxy mutex in event.c
2358  */
2359 int proxy_new_listener(home_server *home, int src_port)
2360 {
2361         rad_listen_t *this;
2362         listen_socket_t *sock;
2363 #ifndef NDEBUG
2364         char buffer[256];
2365 #endif
2366
2367         if (!home) return 0;
2368
2369         if ((home->max_connections > 0) &&
2370             (home->num_connections >= home->max_connections)) {
2371                 DEBUG("WARNING: Home server has too many open connections (%d)",
2372                       home->max_connections);
2373                 return 0;
2374         }
2375
2376         this = listen_alloc(RAD_LISTEN_PROXY);
2377
2378         sock = this->data;
2379         sock->other_ipaddr = home->ipaddr;
2380         sock->other_port = home->port;
2381         sock->home = home;
2382
2383         sock->my_ipaddr = home->src_ipaddr;
2384         sock->my_port = src_port;
2385         sock->proto = home->proto;
2386
2387         if (debug_flag >= 2) {
2388                 this->print(this, buffer, sizeof(buffer));
2389                 DEBUG("Opening new %s", buffer);
2390         }
2391
2392 #ifdef WITH_TCP
2393         sock->opened = sock->last_packet = time(NULL);
2394
2395         if (home->proto == IPPROTO_TCP) {
2396                 this->recv = proxy_socket_tcp_recv;
2397
2398                 /*
2399                  *      FIXME: connect() is blocking!
2400                  *      We do this with the proxy mutex locked, which may
2401                  *      cause large delays!
2402                  *
2403                  *      http://www.developerweb.net/forum/showthread.php?p=13486
2404                  */
2405                 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2406                                                 &home->ipaddr, home->port);
2407 #ifdef WITH_TLS
2408                 if (home->tls) {
2409                         DEBUG("Trying SSL to port %d\n", home->port);
2410                         sock->ssn = tls_new_client_session(home->tls, this->fd);
2411                         if (!sock->ssn) {
2412                                 listen_free(&this);
2413                                 return 0;
2414                         }
2415
2416                         this->recv = proxy_tls_recv;
2417                         this->send = proxy_tls_send;
2418                 }
2419 #endif
2420         } else
2421 #endif
2422                 this->fd = fr_socket(&home->src_ipaddr, src_port);
2423
2424         if (this->fd < 0) {
2425                 this->print(this, buffer,sizeof(buffer));
2426                 DEBUG("Failed opening client socket ::%s:: : %s",
2427                       buffer, fr_strerror());
2428                 listen_free(&this);
2429                 return 0;
2430         }
2431
2432         /*
2433          *      Figure out which port we were bound to.
2434          */
2435         if (sock->my_port == 0) {
2436                 struct sockaddr_storage src;
2437                 socklen_t               sizeof_src = sizeof(src);
2438                 
2439                 memset(&src, 0, sizeof_src);
2440                 if (getsockname(this->fd, (struct sockaddr *) &src,
2441                                 &sizeof_src) < 0) {
2442                         radlog(L_ERR, "Failed getting socket name: %s",
2443                                strerror(errno));
2444                         listen_free(&this);
2445                         return 0;
2446                 }
2447                 
2448                 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2449                                         &sock->my_ipaddr, &sock->my_port)) {
2450                         radlog(L_ERR, "Socket has unsupported address family");
2451                         listen_free(&this);
2452                         return 0;
2453                 }
2454         }
2455
2456         /*
2457          *      Tell the event loop that we have a new FD
2458          */
2459         if (!event_new_fd(this)) {
2460                 listen_free(&this);
2461                 return 0;
2462         }
2463         
2464         return 1;
2465 }
2466 #endif
2467
2468
2469 static const FR_NAME_NUMBER listen_compare[] = {
2470 #ifdef WITH_STATS
2471         { "status",     RAD_LISTEN_NONE },
2472 #endif
2473         { "auth",       RAD_LISTEN_AUTH },
2474 #ifdef WITH_ACCOUNTING
2475         { "acct",       RAD_LISTEN_ACCT },
2476 #endif
2477 #ifdef WITH_DETAIL
2478         { "detail",     RAD_LISTEN_DETAIL },
2479 #endif
2480 #ifdef WITH_PROXY
2481         { "proxy",      RAD_LISTEN_PROXY },
2482 #endif
2483 #ifdef WITH_VMPS
2484         { "vmps",       RAD_LISTEN_VQP },
2485 #endif
2486 #ifdef WITH_DHCP
2487         { "dhcp",       RAD_LISTEN_DHCP },
2488 #endif
2489 #ifdef WITH_COMMAND_SOCKET
2490         { "control",    RAD_LISTEN_COMMAND },
2491 #endif
2492 #ifdef WITH_COA
2493         { "coa",        RAD_LISTEN_COA },
2494 #endif
2495         { NULL, 0 },
2496 };
2497
2498
2499 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2500 {
2501         int             type, rcode;
2502         char            *listen_type;
2503         rad_listen_t    *this;
2504
2505         listen_type = NULL;
2506         
2507         cf_log_info(cs, "listen {");
2508
2509         rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2510                               &listen_type, "");
2511         if (rcode < 0) return NULL;
2512         if (rcode == 1) {
2513                 free(listen_type);
2514                 cf_log_err(cf_sectiontoitem(cs),
2515                            "No type specified in listen section");
2516                 return NULL;
2517         }
2518
2519         type = fr_str2int(listen_compare, listen_type, -1);
2520         if (type < 0) {
2521                 cf_log_err(cf_sectiontoitem(cs),
2522                            "Invalid type \"%s\" in listen section.",
2523                            listen_type);
2524                 free(listen_type);
2525                 return NULL;
2526         }
2527         free(listen_type);
2528
2529         /*
2530          *      Allow listen sections in the default config to
2531          *      refer to a server.
2532          */
2533         if (!server) {
2534                 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2535                                       &server, NULL);
2536                 if (rcode == 1) { /* compatiblity with 2.0-pre */
2537                         rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2538                                               &server, NULL);
2539                 }
2540                 if (rcode < 0) return NULL;
2541         }
2542
2543 #ifdef WITH_PROXY
2544         /*
2545          *      We were passed a virtual server, so the caller is
2546          *      defining a proxy listener inside of a virtual server.
2547          *      This isn't allowed right now.
2548          */
2549         else if (type == RAD_LISTEN_PROXY) {
2550                 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2551                 return NULL;
2552         }
2553 #endif
2554
2555         /*
2556          *      Set up cross-type data.
2557          */
2558         this = listen_alloc(type);
2559         this->server = server;
2560         this->fd = -1;
2561
2562         /*
2563          *      Call per-type parser.
2564          */
2565         if (master_listen[type].parse(cs, this) < 0) {
2566                 listen_free(&this);
2567                 return NULL;
2568         }
2569
2570         cf_log_info(cs, "}");
2571
2572         return this;
2573 }
2574
2575 #ifdef WITH_PROXY
2576 static int is_loopback(const fr_ipaddr_t *ipaddr)
2577 {
2578         /*
2579          *      We shouldn't proxy on loopback.
2580          */
2581         if ((ipaddr->af == AF_INET) &&
2582             (ipaddr->ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) {
2583                 return 1;
2584         }
2585         
2586 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2587         if ((ipaddr->af == AF_INET6) &&
2588             (IN6_IS_ADDR_LINKLOCAL(&ipaddr->ipaddr.ip6addr))) {
2589                 return 1;
2590         }
2591 #endif
2592
2593         return 0;
2594 }
2595 #endif
2596
2597 /*
2598  *      Generate a list of listeners.  Takes an input list of
2599  *      listeners, too, so we don't close sockets with waiting packets.
2600  */
2601 int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
2602 {
2603         int             override = FALSE;
2604         int             rcode;
2605         CONF_SECTION    *cs = NULL;
2606         rad_listen_t    **last;
2607         rad_listen_t    *this;
2608         fr_ipaddr_t     server_ipaddr;
2609         int             auth_port = 0;
2610 #ifdef WITH_PROXY
2611         int             defined_proxy = 0;
2612 #endif
2613
2614         /*
2615          *      We shouldn't be called with a pre-existing list.
2616          */
2617         rad_assert(head && (*head == NULL));
2618
2619         last = head;
2620         server_ipaddr.af = AF_UNSPEC;
2621
2622         /*
2623          *      If the port is specified on the command-line,
2624          *      it over-rides the configuration file.
2625          *
2626          *      FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2627          */
2628         if (mainconfig.port >= 0) auth_port = mainconfig.port;
2629
2630         /*
2631          *      If the IP address was configured on the command-line,
2632          *      use that as the "bind_address"
2633          */
2634         if (mainconfig.myip.af != AF_UNSPEC) {
2635                 memcpy(&server_ipaddr, &mainconfig.myip,
2636                        sizeof(server_ipaddr));
2637                 override = TRUE;
2638                 goto bind_it;
2639         }
2640
2641         /*
2642          *      Else look for bind_address and/or listen sections.
2643          */
2644         server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
2645         rcode = cf_item_parse(config, "bind_address",
2646                               PW_TYPE_IPADDR,
2647                               &server_ipaddr.ipaddr.ip4addr, NULL);
2648         if (rcode < 0) return -1; /* error parsing it */
2649
2650         if (rcode == 0) { /* successfully parsed IPv4 */
2651                 listen_socket_t *sock;
2652                 server_ipaddr.af = AF_INET;
2653
2654                 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'.");
2655
2656         bind_it:
2657 #ifdef WITH_VMPS
2658                 if (strcmp(progname, "vmpsd") == 0) {
2659                         this = listen_alloc(RAD_LISTEN_VQP);
2660                         if (!auth_port) auth_port = 1589;
2661                 } else
2662 #endif
2663                         this = listen_alloc(RAD_LISTEN_AUTH);
2664
2665                 sock = this->data;
2666
2667                 sock->my_ipaddr = server_ipaddr;
2668                 sock->my_port = auth_port;
2669
2670                 sock->clients = clients_parse_section(config);
2671                 if (!sock->clients) {
2672                         cf_log_err(cf_sectiontoitem(config),
2673                                    "Failed to find any clients for this listen section");
2674                         listen_free(&this);
2675                         return -1;
2676                 }
2677
2678                 if (listen_bind(this) < 0) {
2679                         listen_free(head);
2680                         radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2681                         listen_free(&this);
2682                         return -1;
2683                 }
2684                 auth_port = sock->my_port;      /* may have been updated in listen_bind */
2685                 if (override) {
2686                         cs = cf_section_sub_find_name2(config, "server",
2687                                                        mainconfig.name);
2688                         if (cs) this->server = mainconfig.name;
2689                 }
2690
2691                 *last = this;
2692                 last = &(this->next);
2693
2694 #ifdef WITH_VMPS
2695                 /*
2696                  *      No acct for vmpsd
2697                  */
2698                 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2699 #endif
2700
2701 #ifdef WITH_ACCOUNTING
2702                 /*
2703                  *      Open Accounting Socket.
2704                  *
2705                  *      If we haven't already gotten acct_port from
2706                  *      /etc/services, then make it auth_port + 1.
2707                  */
2708                 this = listen_alloc(RAD_LISTEN_ACCT);
2709                 sock = this->data;
2710
2711                 /*
2712                  *      Create the accounting socket.
2713                  *
2714                  *      The accounting port is always the
2715                  *      authentication port + 1
2716                  */
2717                 sock->my_ipaddr = server_ipaddr;
2718                 sock->my_port = auth_port + 1;
2719
2720                 sock->clients = clients_parse_section(config);
2721                 if (!sock->clients) {
2722                         cf_log_err(cf_sectiontoitem(config),
2723                                    "Failed to find any clients for this listen section");
2724                         return -1;
2725                 }
2726
2727                 if (listen_bind(this) < 0) {
2728                         listen_free(&this);
2729                         listen_free(head);
2730                         radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2731                         return -1;
2732                 }
2733
2734                 if (override) {
2735                         cs = cf_section_sub_find_name2(config, "server",
2736                                                        mainconfig.name);
2737                         if (cs) this->server = mainconfig.name;
2738                 }
2739
2740                 *last = this;
2741                 last = &(this->next);
2742 #endif
2743         } else if (mainconfig.port > 0) { /* no bind address, but a port */
2744                 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2745                        mainconfig.port);
2746                 return -1;
2747         }
2748
2749         /*
2750          *      They specified an IP on the command-line, ignore
2751          *      all listen sections except the one in '-n'.
2752          */
2753         if (mainconfig.myip.af != AF_UNSPEC) {
2754                 CONF_SECTION *subcs;
2755                 const char *name2 = cf_section_name2(cs);
2756
2757                 cs = cf_section_sub_find_name2(config, "server",
2758                                                mainconfig.name);
2759                 if (!cs) goto add_sockets;
2760
2761                 /*
2762                  *      Should really abstract this code...
2763                  */
2764                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2765                      subcs != NULL;
2766                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2767                         this = listen_parse(subcs, name2);
2768                         if (!this) {
2769                                 listen_free(head);
2770                                 return -1;
2771                         }
2772
2773                         *last = this;
2774                         last = &(this->next);
2775                 } /* loop over "listen" directives in server <foo> */
2776
2777                 goto add_sockets;
2778         }
2779
2780         /*
2781          *      Walk through the "listen" sections, if they exist.
2782          */
2783         for (cs = cf_subsection_find_next(config, NULL, "listen");
2784              cs != NULL;
2785              cs = cf_subsection_find_next(config, cs, "listen")) {
2786                 this = listen_parse(cs, NULL);
2787                 if (!this) {
2788                         listen_free(head);
2789                         return -1;
2790                 }
2791
2792                 *last = this;
2793                 last = &(this->next);
2794         }
2795
2796         /*
2797          *      Check virtual servers for "listen" sections, too.
2798          *
2799          *      FIXME: Move to virtual server init?
2800          */
2801         for (cs = cf_subsection_find_next(config, NULL, "server");
2802              cs != NULL;
2803              cs = cf_subsection_find_next(config, cs, "server")) {
2804                 CONF_SECTION *subcs;
2805                 const char *name2 = cf_section_name2(cs);
2806                 
2807                 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2808                      subcs != NULL;
2809                      subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2810                         this = listen_parse(subcs, name2);
2811                         if (!this) {
2812                                 listen_free(head);
2813                                 return -1;
2814                         }
2815                         
2816                         *last = this;
2817                         last = &(this->next);
2818                 } /* loop over "listen" directives in virtual servers */
2819         } /* loop over virtual servers */
2820
2821 add_sockets:
2822         /*
2823          *      No sockets to receive packets, this is an error.
2824          *      proxying is pointless.
2825          */
2826         if (!*head) {
2827                 radlog(L_ERR, "The server is not configured to listen on any ports.  Cannot start.");
2828                 return -1;
2829         }
2830
2831         /*
2832          *      Print out which sockets we're listening on, and
2833          *      add them to the event list.
2834          */
2835         for (this = *head; this != NULL; this = this->next) {
2836 #ifdef WITH_PROXY
2837                 if (this->type == RAD_LISTEN_PROXY) {
2838                         defined_proxy = 1;
2839                 }
2840
2841 #endif
2842
2843 #ifdef WITH_TLS
2844                 if (!spawn_flag && this->tls) {
2845                         cf_log_err(cf_sectiontoitem(this->cs), "Threading must be enabled for TLS sockets to function properly.");
2846                         cf_log_err(cf_sectiontoitem(this->cs), "You probably need to do 'radiusd -fxx -l stdout' for debugging");
2847                         return -1;
2848                 }
2849 #endif
2850                 event_new_fd(this);
2851         }
2852
2853         /*
2854          *      If we're proxying requests, open the proxy FD.
2855          *      Otherwise, don't do anything.
2856          */
2857 #ifdef WITH_PROXY
2858         if ((mainconfig.proxy_requests == TRUE) &&
2859             (*head != NULL) && !defined_proxy) {
2860                 listen_socket_t *sock = NULL;
2861                 int             port = 0;
2862                 home_server     home;
2863
2864                 memset(&home, 0, sizeof(home));
2865
2866                 /*
2867                  *      
2868                  */
2869                 home.proto = IPPROTO_UDP;
2870                 home.src_ipaddr = server_ipaddr;
2871
2872                 /*
2873                  *      Find the first authentication port,
2874                  *      and use it
2875                  */
2876                 for (this = *head; this != NULL; this = this->next) {
2877                         if (this->type == RAD_LISTEN_AUTH) {
2878                                 sock = this->data;
2879
2880                                 if (is_loopback(&sock->my_ipaddr)) continue;
2881
2882                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2883                                         home.src_ipaddr = sock->my_ipaddr;
2884                                 }
2885                                 port = sock->my_port + 2;
2886                                 break;
2887                         }
2888 #ifdef WITH_ACCT
2889                         if (this->type == RAD_LISTEN_ACCT) {
2890                                 sock = this->data;
2891
2892                                 if (is_loopback(&sock->my_ipaddr)) continue;
2893
2894                                 if (home.src_ipaddr.af == AF_UNSPEC) {
2895                                         home.src_ipaddr = sock->my_ipaddr;
2896                                 }
2897                                 port = sock->my_port + 1;
2898                                 break;
2899                         }
2900 #endif
2901                 }
2902
2903                 /*
2904                  *      Address is still unspecified, use IPv4.
2905                  */
2906                 if (home.src_ipaddr.af == AF_UNSPEC) {
2907                         home.src_ipaddr.af = AF_INET;
2908                         /* everything else is already set to zero */
2909                 }
2910
2911                 home.ipaddr.af = home.src_ipaddr.af;
2912                 /* everything else is already set to zero */
2913
2914                 if (!proxy_new_listener(&home, port)) {
2915                         listen_free(head);
2916                         return -1;
2917                 }
2918         }
2919 #endif
2920
2921         /*
2922          *      Haven't defined any sockets.  Die.
2923          */
2924         if (!*head) return -1;
2925
2926         xlat_register("listen", xlat_listen, NULL);
2927
2928         return 0;
2929 }
2930
2931 /*
2932  *      Free a linked list of listeners;
2933  */
2934 void listen_free(rad_listen_t **head)
2935 {
2936         rad_listen_t *this;
2937
2938         if (!head || !*head) return;
2939
2940         this = *head;
2941         while (this) {
2942                 rad_listen_t *next = this->next;
2943
2944                 /*
2945                  *      Other code may have eaten the FD.
2946                  */
2947                 if (this->fd >= 0) close(this->fd);
2948
2949                 if (master_listen[this->type].free) {
2950                         master_listen[this->type].free(this);
2951                 }
2952
2953 #ifdef WITH_TLS
2954                 if (this->tls) tls_server_conf_free(this->tls);         
2955 #endif
2956
2957 #ifdef WITH_TCP
2958                 if ((this->type == RAD_LISTEN_AUTH)
2959 #ifdef WITH_ACCT
2960                     || (this->type == RAD_LISTEN_ACCT)
2961 #endif
2962 #ifdef WITH_PROXY
2963                     || (this->type == RAD_LISTEN_PROXY)
2964 #endif
2965                         ) {
2966                         listen_socket_t *sock = this->data;
2967
2968 #ifdef WITH_TLS
2969                         if (sock->request) {
2970                                 pthread_mutex_destroy(&(sock->mutex));
2971                                 request_free(&sock->request);
2972                                 sock->packet = NULL;
2973
2974                                 if (sock->ssn) session_free(sock->ssn);
2975                                 request_free(&sock->request);
2976                         } else
2977 #endif
2978                                 rad_free(&sock->packet);
2979
2980                 }
2981 #endif  /* WITH_TCP */
2982
2983                 free(this->data);
2984                 free(this);
2985
2986                 this = next;
2987         }
2988
2989         *head = NULL;
2990 }
2991
2992 #ifdef WITH_STATS
2993 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2994                                           int port)
2995 {
2996         rad_listen_t *this;
2997
2998         for (this = mainconfig.listen; this != NULL; this = this->next) {
2999                 listen_socket_t *sock;
3000
3001                 if ((this->type != RAD_LISTEN_AUTH)
3002 #ifdef WITH_ACCOUNTING
3003                     && (this->type != RAD_LISTEN_ACCT)
3004 #endif
3005                     ) continue;
3006                 
3007                 sock = this->data;
3008
3009                 if ((sock->my_port == port) &&
3010                     (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
3011                         return sock->clients;
3012                 }
3013         }
3014
3015         return NULL;
3016 }
3017 #endif
3018
3019 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port, int proto)
3020 {
3021         rad_listen_t *this;
3022
3023         for (this = mainconfig.listen; this != NULL; this = this->next) {
3024                 listen_socket_t *sock;
3025
3026                 sock = this->data;
3027
3028                 if (sock->my_port != port) continue;
3029                 if (sock->proto != proto) continue;
3030                 if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3031
3032                 return this;
3033         }
3034
3035         /*
3036          *      Failed to find a specific one.  Find INADDR_ANY
3037          */
3038         for (this = mainconfig.listen; this != NULL; this = this->next) {
3039                 listen_socket_t *sock;
3040
3041                 sock = this->data;
3042
3043                 if (sock->my_port != port) continue;
3044                 if (sock->proto != proto) continue;
3045                 if (!fr_inaddr_any(&sock->my_ipaddr)) continue;
3046
3047                 return this;
3048         }
3049
3050         return NULL;
3051 }