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