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