2 * listen.c Handle socket stuff
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.
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.
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
20 * Copyright 2005,2006 The FreeRADIUS server project
21 * Copyright 2005 Alan DeKok <aland@ox.org>
24 #include <freeradius-devel/ident.h>
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>
33 #include <freeradius-devel/vmps.h>
34 #include <freeradius-devel/detail.h>
37 #include <freeradius-devel/udpfromto.h>
40 #ifdef HAVE_SYS_RESOURCE_H
41 #include <sys/resource.h>
54 * We'll use this below.
56 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
57 typedef void (*rad_listen_free_t)(rad_listen_t *);
59 typedef struct rad_listen_master_t {
60 rad_listen_parse_t parse;
61 rad_listen_free_t free;
62 rad_listen_recv_t recv;
63 rad_listen_send_t send;
64 rad_listen_print_t print;
65 rad_listen_encode_t encode;
66 rad_listen_decode_t decode;
67 } rad_listen_master_t;
69 typedef struct listen_socket_t {
75 #ifdef SO_BINDTODEVICE
76 const char *interface;
78 RADCLIENT_LIST *clients;
81 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
84 * Find a per-socket client.
86 RADCLIENT *client_listener_find(const rad_listen_t *listener,
87 const fr_ipaddr_t *ipaddr, int src_port)
89 #ifdef WITH_DYNAMIC_CLIENTS
96 RADCLIENT_LIST *clients;
98 rad_assert(listener != NULL);
99 rad_assert(ipaddr != NULL);
101 clients = ((listen_socket_t *)listener->data)->clients;
104 * This HAS to have been initialized previously.
106 rad_assert(clients != NULL);
108 client = client_find(clients, ipaddr
114 static time_t last_printed = 0;
115 char name[256], buffer[128];
117 #ifdef WITH_DYNAMIC_CLIENTS
118 unknown: /* used only for dynamic clients */
122 * DoS attack quenching, but only in debug mode.
123 * If they're running in debug mode, show them
126 if (debug_flag == 0) {
128 if (last_printed == now) return NULL;
133 listener->print(listener, name, sizeof(name));
135 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d",
136 name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
137 buffer, sizeof(buffer)),
142 #ifndef WITH_DYNAMIC_CLIENTS
143 return client; /* return the found client. */
147 * No server defined, and it's not dynamic. Return it.
149 if (!client->client_server && !client->dynamic) return client;
154 * It's a dynamically generated client, check it.
156 if (client->dynamic && (src_port != 0)) {
158 * Lives forever. Return it.
160 if (client->lifetime == 0) return client;
163 * Rate-limit the deletion of known clients.
164 * This makes them last a little longer, but
165 * prevents the server from melting down if (say)
166 * 10k clients all expire at once.
168 if (now == client->last_new_client) return client;
171 * It's not dead yet. Return it.
173 if ((client->created + client->lifetime) > now) return client;
176 * This really puts them onto a queue for later
179 client_delete(clients, client);
182 * Go find the enclosing network again.
184 client = client_find(clients, ipaddr
193 if (!client) goto unknown;
194 if (!client->client_server) goto unknown;
197 * At this point, 'client' is the enclosing
198 * network that configures where dynamic clients
201 rad_assert(client->dynamic == 0);
204 * The IP is unknown, so we've found an enclosing
205 * network. Enable DoS protection. We only
206 * allow one new client per second. Known
207 * clients aren't subject to this restriction.
209 if (now == client->last_new_client) goto unknown;
212 client->last_new_client = now;
214 request = request_alloc();
215 if (!request) goto unknown;
217 request->listener = listener;
218 request->client = client;
219 request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
220 if (!request->packet) { /* badly formed, etc */
221 request_free(&request);
224 request->reply = rad_alloc_reply(request->packet);
225 if (!request->reply) {
226 request_free(&request);
229 request->packet->timestamp = request->timestamp;
231 request->priority = listener->type;
232 request->server = client->client_server;
233 request->root = &mainconfig;
236 * Run a fake request through the given virtual server.
237 * Look for FreeRADIUS-Client-IP-Address
238 * FreeRADIUS-Client-Secret
241 * and create the RADCLIENT structure from that.
243 DEBUG("server %s {", request->server);
245 rcode = module_authorize(0, request);
247 DEBUG("} # server %s", request->server);
249 if (rcode != RLM_MODULE_OK) {
250 request_free(&request);
255 * If the client was updated by rlm_dynamic_clients,
256 * don't create the client from attribute-value pairs.
258 if (request->client == client) {
259 created = client_create(clients, request);
261 created = request->client;
264 * This frees the client if it isn't valid.
266 if (!client_validate(clients, client, created)) goto unknown;
268 request_free(&request);
270 if (!created) goto unknown;
276 static int listen_bind(rad_listen_t *this);
280 * Process and reply to a server-status request.
281 * Like rad_authenticate and rad_accounting this should
282 * live in it's own file but it's so small we don't bother.
284 static int rad_status_server(REQUEST *request)
286 int rcode = RLM_MODULE_OK;
289 switch (request->listener->type) {
291 case RAD_LISTEN_NONE:
293 case RAD_LISTEN_AUTH:
294 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
296 rcode = module_authorize(dval->value, request);
298 rcode = RLM_MODULE_OK;
303 case RLM_MODULE_UPDATED:
304 request->reply->code = PW_AUTHENTICATION_ACK;
307 case RLM_MODULE_FAIL:
308 case RLM_MODULE_HANDLED:
309 request->reply->code = 0; /* don't reply */
313 case RLM_MODULE_REJECT:
314 request->reply->code = PW_AUTHENTICATION_REJECT;
319 #ifdef WITH_ACCOUNTING
320 case RAD_LISTEN_ACCT:
321 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
323 rcode = module_accounting(dval->value, request);
325 rcode = RLM_MODULE_OK;
330 case RLM_MODULE_UPDATED:
331 request->reply->code = PW_ACCOUNTING_RESPONSE;
335 request->reply->code = 0; /* don't reply */
343 * This is a vendor extension. Suggested by Glen
344 * Zorn in IETF 72, and rejected by the rest of
345 * the WG. We like it, so it goes in here.
348 dval = dict_valbyname(PW_RECV_COA_TYPE, "Status-Server");
350 rcode = module_recv_coa(dval->value, request);
352 rcode = RLM_MODULE_OK;
357 case RLM_MODULE_UPDATED:
358 request->reply->code = PW_COA_ACK;
362 request->reply->code = 0; /* don't reply */
374 * Full statistics are available only on a statistics
377 if (request->listener->type == RAD_LISTEN_NONE) {
378 request_stats_reply(request);
386 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
389 listen_socket_t *sock = this->data;
392 switch (this->type) {
394 case RAD_LISTEN_NONE: /* what a hack... */
399 case RAD_LISTEN_AUTH:
400 name = "authentication";
403 #ifdef WITH_ACCOUNTING
404 case RAD_LISTEN_ACCT:
410 case RAD_LISTEN_PROXY:
422 case RAD_LISTEN_DHCP:
438 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
439 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
443 #ifdef SO_BINDTODEVICE
444 if (sock->interface) {
445 ADDSTRING(" interface ");
446 ADDSTRING(sock->interface);
450 ADDSTRING(" address ");
452 if ((sock->ipaddr.af == AF_INET) &&
453 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
454 strlcpy(buffer, "*", bufsize);
456 ip_ntoh(&sock->ipaddr, buffer, bufsize);
461 snprintf(buffer, bufsize, "%d", sock->port);
465 ADDSTRING(" as server ");
466 ADDSTRING(this->server);
477 * Parse an authentication or accounting socket.
479 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
484 listen_socket_t *sock = this->data;
485 char *section_name = NULL;
486 CONF_SECTION *client_cs, *parentcs;
491 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
492 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
493 &ipaddr.ipaddr.ip4addr, NULL);
494 if (rcode < 0) return -1;
496 if (rcode == 0) { /* successfully parsed IPv4 */
499 } else { /* maybe IPv6? */
500 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
501 &ipaddr.ipaddr.ip6addr, NULL);
502 if (rcode < 0) return -1;
505 cf_log_err(cf_sectiontoitem(cs),
506 "No address specified in listen section");
509 ipaddr.af = AF_INET6;
512 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
514 if (rcode < 0) return -1;
516 if ((listen_port < 0) || (listen_port > 65535)) {
517 cf_log_err(cf_sectiontoitem(cs),
518 "Invalid value for \"port\"");
522 sock->ipaddr = ipaddr;
523 sock->port = listen_port;
526 * If we can bind to interfaces, do so,
529 if (cf_pair_find(cs, "interface")) {
530 #ifndef SO_BINDTODEVICE
531 cf_log_err(cf_sectiontoitem(cs),
532 "System does not support binding to interfaces. Delete this line from the configuration file.");
536 CONF_PAIR *cp = cf_pair_find(cs, "interface");
538 rad_assert(cp != NULL);
539 value = cf_pair_value(cp);
541 cf_log_err(cf_sectiontoitem(cs),
542 "No interface name given");
545 sock->interface = value;
550 * And bind it to the port.
552 if (listen_bind(this) < 0) {
554 cf_log_err(cf_sectiontoitem(cs),
555 "Error binding to port for %s port %d",
556 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
563 * Proxy sockets don't have clients.
565 if (this->type == RAD_LISTEN_PROXY) return 0;
569 * The more specific configurations are preferred to more
573 parentcs = cf_top_section(cs);
574 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
575 §ion_name, NULL);
576 if (rcode < 0) return -1; /* bad string */
579 * Explicit list given: use it.
581 client_cs = cf_section_sub_find_name2(parentcs,
585 client_cs = cf_section_find(section_name);
588 cf_log_err(cf_sectiontoitem(cs),
589 "Failed to find clients %s {...}",
595 } /* else there was no "clients = " entry. */
598 CONF_SECTION *server_cs;
600 server_cs = cf_section_sub_find_name2(parentcs,
604 * Found a "server foo" section. If there are clients
608 (cf_section_sub_find(server_cs, "client") != NULL)) {
609 client_cs = server_cs;
614 * Still nothing. Look for global clients.
616 if (!client_cs) client_cs = parentcs;
618 sock->clients = clients_parse_section(client_cs);
619 if (!sock->clients) {
620 cf_log_err(cf_sectiontoitem(cs),
621 "Failed to load clients for this listen section");
629 * Send an authentication response packet
631 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
633 rad_assert(request->listener == listener);
634 rad_assert(listener->send == auth_socket_send);
636 return rad_send(request->reply, request->packet,
637 request->client->secret);
641 #ifdef WITH_ACCOUNTING
643 * Send an accounting response packet (or not)
645 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
647 rad_assert(request->listener == listener);
648 rad_assert(listener->send == acct_socket_send);
651 * Accounting reject's are silently dropped.
653 * We do it here to avoid polluting the rest of the
654 * code with this knowledge
656 if (request->reply->code == 0) return 0;
658 return rad_send(request->reply, request->packet,
659 request->client->secret);
665 * Send a packet to a home server.
667 * FIXME: have different code for proxy auth & acct!
669 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
671 listen_socket_t *sock = listener->data;
673 rad_assert(request->proxy_listener == listener);
674 rad_assert(listener->send == proxy_socket_send);
676 request->proxy->src_ipaddr = sock->ipaddr;
677 request->proxy->src_port = sock->port;
679 return rad_send(request->proxy, request->packet,
680 request->home_server->secret);
686 * Check if an incoming request is "ok"
688 * It takes packets, not requests. It sees if the packet looks
689 * OK. If so, it does a number of sanity checks on it.
691 static int stats_socket_recv(rad_listen_t *listener,
692 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
696 RADIUS_PACKET *packet;
698 fr_ipaddr_t src_ipaddr;
700 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
701 if (rcode < 0) return 0;
703 RAD_STATS_TYPE_INC(listener, total_requests);
705 if (rcode < 20) { /* AUTH_HDR_LEN */
706 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
710 if ((client = client_listener_find(listener,
711 &src_ipaddr, src_port)) == NULL) {
712 rad_recv_discard(listener->fd);
713 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
718 * We only understand Status-Server on this socket.
720 if (code != PW_STATUS_SERVER) {
721 DEBUG("Ignoring packet code %d sent to Status-Server port",
723 rad_recv_discard(listener->fd);
724 RAD_STATS_TYPE_INC(listener, total_unknown_types);
725 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
730 * Now that we've sanity checked everything, receive the
733 packet = rad_recv(listener->fd, 1); /* require message authenticator */
735 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
736 DEBUG("%s", fr_strerror());
740 if (!received_request(listener, packet, prequest, client)) {
741 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
742 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
747 *pfun = rad_status_server;
754 * Check if an incoming request is "ok"
756 * It takes packets, not requests. It sees if the packet looks
757 * OK. If so, it does a number of sanity checks on it.
759 static int auth_socket_recv(rad_listen_t *listener,
760 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
764 RADIUS_PACKET *packet;
765 RAD_REQUEST_FUNP fun = NULL;
767 fr_ipaddr_t src_ipaddr;
769 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
770 if (rcode < 0) return 0;
772 RAD_STATS_TYPE_INC(listener, total_requests);
774 if (rcode < 20) { /* AUTH_HDR_LEN */
775 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
779 if ((client = client_listener_find(listener,
780 &src_ipaddr, src_port)) == NULL) {
781 rad_recv_discard(listener->fd);
782 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
787 * Some sanity checks, based on the packet code.
790 case PW_AUTHENTICATION_REQUEST:
791 RAD_STATS_CLIENT_INC(listener, client, total_requests);
792 fun = rad_authenticate;
795 case PW_STATUS_SERVER:
796 if (!mainconfig.status_server) {
797 rad_recv_discard(listener->fd);
798 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
799 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
800 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
803 fun = rad_status_server;
807 rad_recv_discard(listener->fd);
808 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
809 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
811 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
812 code, client->shortname, src_port);
815 } /* switch over packet types */
818 * Now that we've sanity checked everything, receive the
821 packet = rad_recv(listener->fd, client->message_authenticator);
823 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
824 DEBUG("%s", fr_strerror());
828 if (!received_request(listener, packet, prequest, client)) {
829 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
830 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
840 #ifdef WITH_ACCOUNTING
842 * Receive packets from an accounting socket
844 static int acct_socket_recv(rad_listen_t *listener,
845 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
849 RADIUS_PACKET *packet;
850 RAD_REQUEST_FUNP fun = NULL;
852 fr_ipaddr_t src_ipaddr;
854 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
855 if (rcode < 0) return 0;
857 RAD_STATS_TYPE_INC(listener, total_requests);
859 if (rcode < 20) { /* AUTH_HDR_LEN */
860 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
864 if ((client = client_listener_find(listener,
865 &src_ipaddr, src_port)) == NULL) {
866 rad_recv_discard(listener->fd);
867 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
872 * Some sanity checks, based on the packet code.
875 case PW_ACCOUNTING_REQUEST:
876 RAD_STATS_CLIENT_INC(listener, client, total_requests);
877 fun = rad_accounting;
880 case PW_STATUS_SERVER:
881 if (!mainconfig.status_server) {
882 rad_recv_discard(listener->fd);
883 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
884 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
886 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
889 fun = rad_status_server;
893 rad_recv_discard(listener->fd);
894 RAD_STATS_TYPE_INC(listener, total_unknown_types);
895 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
897 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
898 code, client->shortname, src_port);
900 } /* switch over packet types */
903 * Now that we've sanity checked everything, receive the
906 packet = rad_recv(listener->fd, 0);
908 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
909 radlog(L_ERR, "%s", fr_strerror());
914 * There can be no duplicate accounting packets.
916 if (!received_request(listener, packet, prequest, client)) {
917 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
918 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
931 * For now, all CoA requests are *only* originated, and not
932 * proxied. So all of the necessary work is done in the
933 * post-proxy section, which is automatically handled by event.c.
934 * As a result, we don't have to do anything here.
936 static int rad_coa_reply(REQUEST *request)
941 * Inform the user about RFC requirements.
943 s1 = pairfind(request->proxy->vps, PW_STATE);
945 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
948 DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
950 } else if ((s1->length != s2->length) ||
951 (memcmp(s1->vp_octets, s2->vp_octets,
953 DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
957 return RLM_MODULE_OK;
961 * Receive a CoA packet.
963 static int rad_coa_recv(REQUEST *request)
965 int rcode = RLM_MODULE_OK;
970 * Get the correct response
972 switch (request->packet->code) {
978 case PW_DISCONNECT_REQUEST:
979 ack = PW_DISCONNECT_ACK;
980 nak = PW_DISCONNECT_NAK;
983 default: /* shouldn't happen */
984 return RLM_MODULE_FAIL;
988 #define WAS_PROXIED (request->proxy)
990 #define WAS_PROXIED (0)
995 * RFC 5176 Section 3.3. If we have a CoA-Request
996 * with Service-Type = Authorize-Only, it MUST
997 * have a State attribute in it.
999 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE);
1000 if (request->packet->code == PW_COA_REQUEST) {
1001 if (vp && (vp->vp_integer == 17)) {
1002 vp = pairfind(request->packet->vps, PW_STATE);
1003 if (!vp || (vp->length == 0)) {
1004 RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1005 request->reply->code = PW_COA_NAK;
1006 return RLM_MODULE_FAIL;
1011 * RFC 5176, Section 3.2.
1013 RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
1014 request->reply->code = PW_DISCONNECT_NAK;
1015 return RLM_MODULE_FAIL;
1018 rcode = module_recv_coa(0, request);
1020 case RLM_MODULE_FAIL:
1021 case RLM_MODULE_INVALID:
1022 case RLM_MODULE_REJECT:
1023 case RLM_MODULE_USERLOCK:
1025 request->reply->code = nak;
1028 case RLM_MODULE_HANDLED:
1031 case RLM_MODULE_NOOP:
1032 case RLM_MODULE_NOTFOUND:
1034 case RLM_MODULE_UPDATED:
1035 request->reply->code = ack;
1040 * Start the reply code with the proxy reply
1043 request->reply->code = request->proxy_reply->code;
1047 * Copy State from the request to the reply.
1048 * See RFC 5176 Section 3.3.
1050 vp = paircopy2(request->packet->vps, PW_STATE);
1051 if (vp) pairadd(&request->reply->vps, vp);
1054 * We may want to over-ride the reply.
1056 rcode = module_send_coa(0, request);
1059 * We need to send CoA-NAK back if Service-Type
1060 * is Authorize-Only. Rely on the user's policy
1061 * to do that. We're not a real NAS, so this
1062 * restriction doesn't (ahem) apply to us.
1064 case RLM_MODULE_FAIL:
1065 case RLM_MODULE_INVALID:
1066 case RLM_MODULE_REJECT:
1067 case RLM_MODULE_USERLOCK:
1070 * Over-ride an ACK with a NAK
1072 request->reply->code = nak;
1075 case RLM_MODULE_HANDLED:
1078 case RLM_MODULE_NOOP:
1079 case RLM_MODULE_NOTFOUND:
1081 case RLM_MODULE_UPDATED:
1083 * Do NOT over-ride a previously set value.
1084 * Otherwise an "ok" here will re-write a
1087 if (request->reply->code == 0) {
1088 request->reply->code = ack;
1094 return RLM_MODULE_OK;
1099 * Check if an incoming request is "ok"
1101 * It takes packets, not requests. It sees if the packet looks
1102 * OK. If so, it does a number of sanity checks on it.
1104 static int coa_socket_recv(rad_listen_t *listener,
1105 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1109 RADIUS_PACKET *packet;
1110 RAD_REQUEST_FUNP fun = NULL;
1113 fr_ipaddr_t src_ipaddr;
1115 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1116 if (rcode < 0) return 0;
1118 RAD_STATS_TYPE_INC(listener, total_requests);
1120 if (rcode < 20) { /* AUTH_HDR_LEN */
1121 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1125 if ((client = client_listener_find(listener,
1126 &src_ipaddr, src_port)) == NULL) {
1127 rad_recv_discard(listener->fd);
1128 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1130 if (debug_flag > 0) {
1133 listener->print(listener, name, sizeof(name));
1136 * This is debugging rather than logging, so that
1137 * DoS attacks don't affect us.
1139 DEBUG("Ignoring request to %s from unknown client %s port %d",
1141 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
1142 buffer, sizeof(buffer)), src_port);
1149 * Some sanity checks, based on the packet code.
1152 case PW_COA_REQUEST:
1153 case PW_DISCONNECT_REQUEST:
1158 rad_recv_discard(listener->fd);
1159 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1160 code, client->shortname, src_port);
1163 } /* switch over packet types */
1166 * Now that we've sanity checked everything, receive the
1169 packet = rad_recv(listener->fd, client->message_authenticator);
1171 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1172 DEBUG("%s", fr_strerror());
1176 if (!received_request(listener, packet, prequest, client)) {
1188 * Recieve packets from a proxy socket.
1190 static int proxy_socket_recv(rad_listen_t *listener,
1191 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1194 RADIUS_PACKET *packet;
1195 RAD_REQUEST_FUNP fun = NULL;
1198 packet = rad_recv(listener->fd, 0);
1200 radlog(L_ERR, "%s", fr_strerror());
1205 * FIXME: Client MIB updates?
1207 switch(packet->code) {
1208 case PW_AUTHENTICATION_ACK:
1209 case PW_ACCESS_CHALLENGE:
1210 case PW_AUTHENTICATION_REJECT:
1211 fun = rad_authenticate;
1214 #ifdef WITH_ACCOUNTING
1215 case PW_ACCOUNTING_RESPONSE:
1216 fun = rad_accounting;
1221 case PW_DISCONNECT_ACK:
1222 case PW_DISCONNECT_NAK:
1225 fun = rad_coa_reply;
1231 * FIXME: Update MIB for packet types?
1233 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1234 "from home server %s port %d - ID %d : IGNORED",
1236 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1237 packet->src_port, packet->id);
1242 request = received_proxy_response(packet);
1250 * Distinguish proxied CoA requests from ones we
1253 if ((fun == rad_coa_reply) &&
1254 (request->packet->code == request->proxy->code)) {
1259 rad_assert(fun != NULL);
1261 *prequest = request;
1268 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1270 if (!request->reply->code) return 0;
1272 rad_encode(request->reply, request->packet,
1273 request->client->secret);
1274 rad_sign(request->reply, request->packet,
1275 request->client->secret);
1281 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1283 if (rad_verify(request->packet, NULL,
1284 request->client->secret) < 0) {
1288 return rad_decode(request->packet, NULL,
1289 request->client->secret);
1293 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1295 rad_encode(request->proxy, NULL, request->home_server->secret);
1296 rad_sign(request->proxy, NULL, request->home_server->secret);
1302 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1305 * rad_verify is run in event.c, received_proxy_response()
1308 return rad_decode(request->proxy_reply, request->proxy,
1309 request->home_server->secret);
1315 #include "command.c"
1317 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1319 { common_socket_parse, NULL,
1320 stats_socket_recv, auth_socket_send,
1321 socket_print, client_socket_encode, client_socket_decode },
1324 * This always gets defined.
1326 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1331 { common_socket_parse, NULL,
1332 proxy_socket_recv, proxy_socket_send,
1333 socket_print, proxy_socket_encode, proxy_socket_decode },
1336 /* authentication */
1337 { common_socket_parse, NULL,
1338 auth_socket_recv, auth_socket_send,
1339 socket_print, client_socket_encode, client_socket_decode },
1341 #ifdef WITH_ACCOUNTING
1343 { common_socket_parse, NULL,
1344 acct_socket_recv, acct_socket_send,
1345 socket_print, client_socket_encode, client_socket_decode},
1350 { detail_parse, detail_free,
1351 detail_recv, detail_send,
1352 detail_print, detail_encode, detail_decode },
1356 /* vlan query protocol */
1357 { common_socket_parse, NULL,
1358 vqp_socket_recv, vqp_socket_send,
1359 socket_print, vqp_socket_encode, vqp_socket_decode },
1363 /* dhcp query protocol */
1364 { dhcp_socket_parse, NULL,
1365 dhcp_socket_recv, dhcp_socket_send,
1366 socket_print, dhcp_socket_encode, dhcp_socket_decode },
1369 #ifdef WITH_COMMAND_SOCKET
1370 /* TCP command socket */
1371 { command_socket_parse, NULL,
1372 command_domain_accept, command_domain_send,
1373 command_socket_print, command_socket_encode, command_socket_decode },
1377 /* Change of Authorization */
1378 { common_socket_parse, NULL,
1379 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1380 socket_print, client_socket_encode, client_socket_decode },
1388 * Binds a listener to a socket.
1390 static int listen_bind(rad_listen_t *this)
1393 struct sockaddr_storage salocal;
1395 listen_socket_t *sock = this->data;
1398 * If the port is zero, then it means the appropriate
1399 * thing from /etc/services.
1401 if (sock->port == 0) {
1402 struct servent *svp;
1404 switch (this->type) {
1405 case RAD_LISTEN_AUTH:
1406 svp = getservbyname ("radius", "udp");
1408 sock->port = ntohs(svp->s_port);
1410 sock->port = PW_AUTH_UDP_PORT;
1414 #ifdef WITH_ACCOUNTING
1415 case RAD_LISTEN_ACCT:
1416 svp = getservbyname ("radacct", "udp");
1418 sock->port = ntohs(svp->s_port);
1420 sock->port = PW_ACCT_UDP_PORT;
1426 case RAD_LISTEN_PROXY:
1432 case RAD_LISTEN_VQP:
1438 case RAD_LISTEN_COA:
1439 sock->port = PW_COA_UDP_PORT;
1444 radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");
1450 * Copy fr_socket() here, as we may need to bind to a device.
1452 this->fd = socket(sock->ipaddr.af, SOCK_DGRAM, 0);
1454 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1458 #ifdef SO_BINDTODEVICE
1460 * Bind to a device BEFORE touching IP addresses.
1462 if (sock->interface) {
1464 strcpy(ifreq.ifr_name, sock->interface);
1467 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1468 (char *)&ifreq, sizeof(ifreq));
1472 radlog(L_ERR, "Failed binding to interface %s: %s",
1473 sock->interface, strerror(errno));
1475 } /* else it worked. */
1479 #ifdef WITH_UDPFROMTO
1481 * Initialize udpfromto for all sockets.
1483 if (udpfromto_init(this->fd) != 0) {
1490 * Set up sockaddr stuff.
1492 if (!fr_ipaddr2sockaddr(&sock->ipaddr, sock->port, &salocal, &salen)) {
1497 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1498 if (sock->ipaddr.af == AF_INET6) {
1500 * Listening on '::' does NOT get you IPv4 to
1501 * IPv6 mapping. You've got to listen on an IPv4
1502 * address, too. This makes the rest of the server
1503 * design a little simpler.
1507 if (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr)) {
1510 setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
1511 (char *)&on, sizeof(on));
1513 #endif /* IPV6_V6ONLY */
1515 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
1518 if (sock->ipaddr.af == AF_INET) {
1521 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1523 * Disable PMTU discovery. On Linux, this
1524 * also makes sure that the "don't fragment"
1527 flag = IP_PMTUDISC_DONT;
1528 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
1529 &flag, sizeof(flag));
1532 #if defined(IP_DONTFRAG)
1534 * Ensure that the "don't fragment" flag is zero.
1537 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
1538 &flag, sizeof(flag));
1543 * May be binding to priviledged ports.
1546 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
1552 this->print(this, buffer, sizeof(buffer));
1553 radlog(L_ERR, "Failed binding to %s: %s\n",
1554 buffer, strerror(errno));
1559 * FreeBSD jail issues. We bind to 0.0.0.0, but the
1560 * kernel instead binds us to a 1.2.3.4. If this
1561 * happens, notice, and remember our real IP.
1564 struct sockaddr_storage src;
1565 socklen_t sizeof_src = sizeof(src);
1567 memset(&src, 0, sizeof_src);
1568 if (getsockname(this->fd, (struct sockaddr *) &src,
1570 radlog(L_ERR, "Failed getting socket name: %s",
1575 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
1576 &sock->ipaddr, &sock->port)) {
1577 radlog(L_ERR, "Socket has unsupported address family");
1586 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1587 radlog(L_ERR, "Failure getting socket flags: %s)\n",
1592 flags |= O_NONBLOCK;
1593 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1594 radlog(L_ERR, "Failure setting socket flags: %s)\n",
1606 * Allocate & initialize a new listener.
1608 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1612 this = rad_malloc(sizeof(*this));
1613 memset(this, 0, sizeof(*this));
1616 this->recv = master_listen[this->type].recv;
1617 this->send = master_listen[this->type].send;
1618 this->print = master_listen[this->type].print;
1619 this->encode = master_listen[this->type].encode;
1620 this->decode = master_listen[this->type].decode;
1624 case RAD_LISTEN_NONE:
1626 case RAD_LISTEN_AUTH:
1627 #ifdef WITH_ACCOUNTING
1628 case RAD_LISTEN_ACCT:
1631 case RAD_LISTEN_PROXY:
1634 case RAD_LISTEN_VQP:
1637 case RAD_LISTEN_COA:
1639 this->data = rad_malloc(sizeof(listen_socket_t));
1640 memset(this->data, 0, sizeof(listen_socket_t));
1644 case RAD_LISTEN_DHCP:
1645 this->data = rad_malloc(sizeof(dhcp_socket_t));
1646 memset(this->data, 0, sizeof(dhcp_socket_t));
1651 case RAD_LISTEN_DETAIL:
1656 #ifdef WITH_COMMAND_SOCKET
1657 case RAD_LISTEN_COMMAND:
1658 this->data = rad_malloc(sizeof(fr_command_socket_t));
1659 memset(this->data, 0, sizeof(fr_command_socket_t));
1664 rad_assert("Unsupported option!" == NULL);
1674 * Externally visible function for creating a new proxy LISTENER.
1676 * Not thread-safe, but all calls to it are protected by the
1677 * proxy mutex in event.c
1679 rad_listen_t *proxy_new_listener(fr_ipaddr_t *ipaddr, int exists)
1681 int last_proxy_port, port;
1682 rad_listen_t *this, *tmp, **last;
1683 listen_socket_t *sock, *old;
1686 * Find an existing proxy socket to copy.
1688 last_proxy_port = 0;
1690 last = &mainconfig.listen;
1691 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1693 * Not proxy, ignore it.
1695 if (tmp->type != RAD_LISTEN_PROXY) continue;
1700 * If we were asked to copy a specific one, do
1701 * so. If we're just finding one that already
1702 * exists, return a pointer to it. Otherwise,
1703 * create ANOTHER one with the same IP address.
1705 if ((ipaddr->af != AF_UNSPEC) &&
1706 (fr_ipaddr_cmp(&sock->ipaddr, ipaddr) != 0)) {
1707 if (exists) return tmp;
1711 if (sock->port > last_proxy_port) {
1712 last_proxy_port = sock->port + 1;
1714 if (!old) old = sock;
1716 last = &(tmp->next);
1721 * The socket MUST already exist if we're binding
1722 * to an address while proxying.
1724 * If we're initializing the server, it's OK for the
1725 * socket to NOT exist.
1727 if (!exists) return NULL;
1729 this = listen_alloc(RAD_LISTEN_PROXY);
1732 sock->ipaddr = *ipaddr;
1735 this = listen_alloc(RAD_LISTEN_PROXY);
1738 sock->ipaddr = old->ipaddr;
1742 * Keep going until we find an unused port.
1744 for (port = last_proxy_port; port < 64000; port++) {
1749 rcode = listen_bind(this);
1756 * Add the new listener to the list of
1768 static const FR_NAME_NUMBER listen_compare[] = {
1770 { "status", RAD_LISTEN_NONE },
1772 { "auth", RAD_LISTEN_AUTH },
1773 #ifdef WITH_ACCOUNTING
1774 { "acct", RAD_LISTEN_ACCT },
1777 { "detail", RAD_LISTEN_DETAIL },
1780 { "proxy", RAD_LISTEN_PROXY },
1783 { "vmps", RAD_LISTEN_VQP },
1786 { "dhcp", RAD_LISTEN_DHCP },
1788 #ifdef WITH_COMMAND_SOCKET
1789 { "control", RAD_LISTEN_COMMAND },
1792 { "coa", RAD_LISTEN_COA },
1798 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1806 cf_log_info(cs, "listen {");
1808 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1810 if (rcode < 0) return NULL;
1813 cf_log_err(cf_sectiontoitem(cs),
1814 "No type specified in listen section");
1818 type = fr_str2int(listen_compare, listen_type, -1);
1820 cf_log_err(cf_sectiontoitem(cs),
1821 "Invalid type \"%s\" in listen section.",
1829 * Allow listen sections in the default config to
1830 * refer to a server.
1833 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
1835 if (rcode == 1) { /* compatiblity with 2.0-pre */
1836 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1839 if (rcode < 0) return NULL;
1843 * Set up cross-type data.
1845 this = listen_alloc(type);
1846 this->server = server;
1850 * Call per-type parser.
1852 if (master_listen[type].parse(cs, this) < 0) {
1857 cf_log_info(cs, "}");
1863 * Generate a list of listeners. Takes an input list of
1864 * listeners, too, so we don't close sockets with waiting packets.
1866 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1868 int override = FALSE;
1870 CONF_SECTION *cs = NULL;
1871 rad_listen_t **last;
1873 fr_ipaddr_t server_ipaddr;
1876 int defined_proxy = 0;
1880 * We shouldn't be called with a pre-existing list.
1882 rad_assert(head && (*head == NULL));
1885 server_ipaddr.af = AF_UNSPEC;
1888 * If the port is specified on the command-line,
1889 * it over-rides the configuration file.
1891 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1893 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1896 * If the IP address was configured on the command-line,
1897 * use that as the "bind_address"
1899 if (mainconfig.myip.af != AF_UNSPEC) {
1900 memcpy(&server_ipaddr, &mainconfig.myip,
1901 sizeof(server_ipaddr));
1907 * Else look for bind_address and/or listen sections.
1909 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1910 rcode = cf_item_parse(config, "bind_address",
1912 &server_ipaddr.ipaddr.ip4addr, NULL);
1913 if (rcode < 0) return -1; /* error parsing it */
1915 if (rcode == 0) { /* successfully parsed IPv4 */
1916 listen_socket_t *sock;
1917 server_ipaddr.af = AF_INET;
1919 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1923 if (strcmp(progname, "vmpsd") == 0) {
1924 this = listen_alloc(RAD_LISTEN_VQP);
1925 if (!auth_port) auth_port = 1589;
1928 this = listen_alloc(RAD_LISTEN_AUTH);
1932 sock->ipaddr = server_ipaddr;
1933 sock->port = auth_port;
1935 sock->clients = clients_parse_section(config);
1936 if (!sock->clients) {
1937 cf_log_err(cf_sectiontoitem(config),
1938 "Failed to find any clients for this listen section");
1943 if (listen_bind(this) < 0) {
1945 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1949 auth_port = sock->port; /* may have been updated in listen_bind */
1951 cs = cf_section_sub_find_name2(config, "server",
1953 if (cs) this->server = mainconfig.name;
1957 last = &(this->next);
1963 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1966 #ifdef WITH_ACCOUNTING
1968 * Open Accounting Socket.
1970 * If we haven't already gotten acct_port from
1971 * /etc/services, then make it auth_port + 1.
1973 this = listen_alloc(RAD_LISTEN_ACCT);
1977 * Create the accounting socket.
1979 * The accounting port is always the
1980 * authentication port + 1
1982 sock->ipaddr = server_ipaddr;
1983 sock->port = auth_port + 1;
1985 sock->clients = clients_parse_section(config);
1986 if (!sock->clients) {
1987 cf_log_err(cf_sectiontoitem(config),
1988 "Failed to find any clients for this listen section");
1992 if (listen_bind(this) < 0) {
1995 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
2000 cs = cf_section_sub_find_name2(config, "server",
2002 if (cs) this->server = mainconfig.name;
2006 last = &(this->next);
2008 } else if (mainconfig.port > 0) { /* no bind address, but a port */
2009 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2015 * They specified an IP on the command-line, ignore
2016 * all listen sections except the one in '-n'.
2018 if (mainconfig.myip.af != AF_UNSPEC) {
2019 CONF_SECTION *subcs;
2020 const char *name2 = cf_section_name2(cs);
2022 cs = cf_section_sub_find_name2(config, "server",
2024 if (!cs) goto do_proxy;
2027 * Should really abstract this code...
2029 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2031 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2032 this = listen_parse(subcs, name2);
2039 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2043 last = &(this->next);
2044 } /* loop over "listen" directives in server <foo> */
2050 * Walk through the "listen" sections, if they exist.
2052 for (cs = cf_subsection_find_next(config, NULL, "listen");
2054 cs = cf_subsection_find_next(config, cs, "listen")) {
2055 this = listen_parse(cs, NULL);
2062 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2066 last = &(this->next);
2070 * Check virtual servers for "listen" sections, too.
2072 * FIXME: Move to virtual server init?
2074 for (cs = cf_subsection_find_next(config, NULL, "server");
2076 cs = cf_subsection_find_next(config, cs, "server")) {
2077 CONF_SECTION *subcs;
2078 const char *name2 = cf_section_name2(cs);
2080 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2082 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2083 this = listen_parse(subcs, name2);
2090 if (this->type == RAD_LISTEN_PROXY) {
2091 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2098 last = &(this->next);
2099 } /* loop over "listen" directives in virtual servers */
2100 } /* loop over virtual servers */
2103 * If we're proxying requests, open the proxy FD.
2104 * Otherwise, don't do anything.
2108 if (mainconfig.proxy_requests == TRUE) {
2110 listen_socket_t *sock = NULL;
2113 * No sockets to receive packets, therefore
2114 * proxying is pointless.
2116 if (!*head) return -1;
2118 if (defined_proxy) goto check_home_servers;
2121 * Find the first authentication port,
2124 for (this = *head; this != NULL; this = this->next) {
2125 if (this->type == RAD_LISTEN_AUTH) {
2127 if (server_ipaddr.af == AF_UNSPEC) {
2128 server_ipaddr = sock->ipaddr;
2130 port = sock->port + 2; /* skip acct port */
2134 if (this->type == RAD_LISTEN_VQP) {
2136 if (server_ipaddr.af == AF_UNSPEC) {
2137 server_ipaddr = sock->ipaddr;
2139 port = sock->port + 1;
2145 if (port < 0) port = 1024 + (fr_rand() & 0x1ff);
2148 * Address is still unspecified, use IPv4.
2150 if (server_ipaddr.af == AF_UNSPEC) {
2151 server_ipaddr.af = AF_INET;
2152 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2155 this = listen_alloc(RAD_LISTEN_PROXY);
2159 * Create the first proxy socket.
2161 sock->ipaddr = server_ipaddr;
2164 * Try to find a proxy port (value doesn't matter)
2166 for (sock->port = port;
2169 if (listen_bind(this) == 0) {
2171 last = &(this->next); /* just in case */
2176 if (sock->port >= 64000) {
2179 radlog(L_ERR, "Failed to open socket for proxying");
2184 * Create *additional* proxy listeners, based
2185 * on their src_ipaddr.
2188 if (home_server_create_listeners(*head) != 0) return -1;
2196 * Free a linked list of listeners;
2198 void listen_free(rad_listen_t **head)
2202 if (!head || !*head) return;
2206 rad_listen_t *next = this->next;
2209 * Other code may have eaten the FD.
2211 if (this->fd >= 0) close(this->fd);
2213 if (master_listen[this->type].free) {
2214 master_listen[this->type].free(this);
2226 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2231 for (this = mainconfig.listen; this != NULL; this = this->next) {
2232 listen_socket_t *sock;
2234 if ((this->type != RAD_LISTEN_AUTH) &&
2235 (this->type != RAD_LISTEN_ACCT)) continue;
2239 if ((sock->port == port) &&
2240 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2241 return sock->clients;
2249 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2253 for (this = mainconfig.listen; this != NULL; this = this->next) {
2254 listen_socket_t *sock;
2257 * FIXME: For TCP, ignore the *secondary*
2258 * listeners associated with the main socket.
2260 if ((this->type != RAD_LISTEN_AUTH) &&
2261 (this->type != RAD_LISTEN_ACCT)) continue;
2265 if ((sock->port == port) &&
2266 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2270 if ((sock->port == port) &&
2271 ((sock->ipaddr.af == AF_INET) &&
2272 (sock->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY))) {
2276 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2277 if ((sock->port == port) &&
2278 (sock->ipaddr.af == AF_INET6) &&
2279 (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr))) {