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