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 const char *interface;
76 RADCLIENT_LIST *clients;
79 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type);
82 * Find a per-socket client.
84 RADCLIENT *client_listener_find(const rad_listen_t *listener,
85 const fr_ipaddr_t *ipaddr, int src_port)
87 #ifdef WITH_DYNAMIC_CLIENTS
94 RADCLIENT_LIST *clients;
96 rad_assert(listener != NULL);
97 rad_assert(ipaddr != NULL);
99 clients = ((listen_socket_t *)listener->data)->clients;
102 * This HAS to have been initialized previously.
104 rad_assert(clients != NULL);
106 client = client_find(clients, ipaddr);
108 static time_t last_printed = 0;
109 char name[256], buffer[128];
111 #ifdef WITH_DYNAMIC_CLIENTS
112 unknown: /* used only for dynamic clients */
116 * DoS attack quenching, but only in debug mode.
117 * If they're running in debug mode, show them
120 if (debug_flag == 0) {
122 if (last_printed == now) return NULL;
127 listener->print(listener, name, sizeof(name));
129 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d",
130 name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
131 buffer, sizeof(buffer)),
136 #ifndef WITH_DYNAMIC_CLIENTS
137 return client; /* return the found client. */
141 * No server defined, and it's not dynamic. Return it.
143 if (!client->client_server && !client->dynamic) return client;
148 * It's a dynamically generated client, check it.
150 if (client->dynamic && (src_port != 0)) {
152 * Lives forever. Return it.
154 if (client->lifetime == 0) return client;
157 * Rate-limit the deletion of known clients.
158 * This makes them last a little longer, but
159 * prevents the server from melting down if (say)
160 * 10k clients all expire at once.
162 if (now == client->last_new_client) return client;
165 * It's not dead yet. Return it.
167 if ((client->created + client->lifetime) > now) return client;
170 * This really puts them onto a queue for later
173 client_delete(clients, client);
176 * Go find the enclosing network again.
178 client = client_find(clients, ipaddr);
183 if (!client) goto unknown;
184 if (!client->client_server) goto unknown;
187 * At this point, 'client' is the enclosing
188 * network that configures where dynamic clients
191 rad_assert(client->dynamic == 0);
193 } else if (!client->dynamic && client->rate_limit) {
195 * The IP is unknown, so we've found an enclosing
196 * network. Enable DoS protection. We only
197 * allow one new client per second. Known
198 * clients aren't subject to this restriction.
200 if (now == client->last_new_client) goto unknown;
203 client->last_new_client = now;
205 request = request_alloc();
206 if (!request) goto unknown;
208 request->listener = listener;
209 request->client = client;
210 request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
211 if (!request->packet) { /* badly formed, etc */
212 request_free(&request);
215 request->reply = rad_alloc_reply(request->packet);
216 if (!request->reply) {
217 request_free(&request);
220 request->packet->timestamp = request->timestamp;
222 request->priority = listener->type;
223 request->server = client->client_server;
224 request->root = &mainconfig;
227 * Run a fake request through the given virtual server.
228 * Look for FreeRADIUS-Client-IP-Address
229 * FreeRADIUS-Client-Secret
232 * and create the RADCLIENT structure from that.
234 DEBUG("server %s {", request->server);
236 rcode = module_authorize(0, request);
238 DEBUG("} # server %s", request->server);
240 if (rcode != RLM_MODULE_OK) {
241 request_free(&request);
246 * If the client was updated by rlm_dynamic_clients,
247 * don't create the client from attribute-value pairs.
249 if (request->client == client) {
250 created = client_create(clients, request);
252 created = request->client;
255 * This frees the client if it isn't valid.
257 if (!client_validate(clients, client, created)) goto unknown;
259 request_free(&request);
261 if (!created) goto unknown;
267 static int listen_bind(rad_listen_t *this);
271 * Process and reply to a server-status request.
272 * Like rad_authenticate and rad_accounting this should
273 * live in it's own file but it's so small we don't bother.
275 static int rad_status_server(REQUEST *request)
277 int rcode = RLM_MODULE_OK;
280 switch (request->listener->type) {
282 case RAD_LISTEN_NONE:
284 case RAD_LISTEN_AUTH:
285 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
287 rcode = module_authorize(dval->value, request);
289 rcode = RLM_MODULE_OK;
294 case RLM_MODULE_UPDATED:
295 request->reply->code = PW_AUTHENTICATION_ACK;
298 case RLM_MODULE_FAIL:
299 case RLM_MODULE_HANDLED:
300 request->reply->code = 0; /* don't reply */
304 case RLM_MODULE_REJECT:
305 request->reply->code = PW_AUTHENTICATION_REJECT;
310 #ifdef WITH_ACCOUNTING
311 case RAD_LISTEN_ACCT:
312 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
314 rcode = module_accounting(dval->value, request);
316 rcode = RLM_MODULE_OK;
321 case RLM_MODULE_UPDATED:
322 request->reply->code = PW_ACCOUNTING_RESPONSE;
326 request->reply->code = 0; /* don't reply */
334 * This is a vendor extension. Suggested by Glen
335 * Zorn in IETF 72, and rejected by the rest of
336 * the WG. We like it, so it goes in here.
339 dval = dict_valbyname(PW_RECV_COA_TYPE, "Status-Server");
341 rcode = module_recv_coa(dval->value, request);
343 rcode = RLM_MODULE_OK;
348 case RLM_MODULE_UPDATED:
349 request->reply->code = PW_COA_ACK;
353 request->reply->code = 0; /* don't reply */
365 * Full statistics are available only on a statistics
368 if (request->listener->type == RAD_LISTEN_NONE) {
369 request_stats_reply(request);
377 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
380 listen_socket_t *sock = this->data;
383 switch (this->type) {
385 case RAD_LISTEN_NONE: /* what a hack... */
390 case RAD_LISTEN_AUTH:
391 name = "authentication";
394 #ifdef WITH_ACCOUNTING
395 case RAD_LISTEN_ACCT:
401 case RAD_LISTEN_PROXY:
413 case RAD_LISTEN_DHCP:
429 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
430 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
434 if (sock->interface) {
435 ADDSTRING(" interface ");
436 ADDSTRING(sock->interface);
439 ADDSTRING(" address ");
441 if ((sock->ipaddr.af == AF_INET) &&
442 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
443 strlcpy(buffer, "*", bufsize);
445 ip_ntoh(&sock->ipaddr, buffer, bufsize);
450 snprintf(buffer, bufsize, "%d", sock->port);
454 ADDSTRING(" as server ");
455 ADDSTRING(this->server);
466 * Parse an authentication or accounting socket.
468 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
473 listen_socket_t *sock = this->data;
474 char *section_name = NULL;
475 CONF_SECTION *client_cs, *parentcs;
480 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
481 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
482 &ipaddr.ipaddr.ip4addr, NULL);
483 if (rcode < 0) return -1;
485 if (rcode == 0) { /* successfully parsed IPv4 */
488 } else { /* maybe IPv6? */
489 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
490 &ipaddr.ipaddr.ip6addr, NULL);
491 if (rcode < 0) return -1;
494 cf_log_err(cf_sectiontoitem(cs),
495 "No address specified in listen section");
498 ipaddr.af = AF_INET6;
501 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
503 if (rcode < 0) return -1;
505 if ((listen_port < 0) || (listen_port > 65535)) {
506 cf_log_err(cf_sectiontoitem(cs),
507 "Invalid value for \"port\"");
511 sock->ipaddr = ipaddr;
512 sock->port = listen_port;
515 * If we can bind to interfaces, do so,
518 if (cf_pair_find(cs, "interface")) {
520 CONF_PAIR *cp = cf_pair_find(cs, "interface");
522 rad_assert(cp != NULL);
523 value = cf_pair_value(cp);
525 cf_log_err(cf_sectiontoitem(cs),
526 "No interface name given");
529 sock->interface = value;
533 * And bind it to the port.
535 if (listen_bind(this) < 0) {
537 cf_log_err(cf_sectiontoitem(cs),
538 "Error binding to port for %s port %d",
539 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
546 * Proxy sockets don't have clients.
548 if (this->type == RAD_LISTEN_PROXY) return 0;
552 * The more specific configurations are preferred to more
556 parentcs = cf_top_section(cs);
557 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
558 §ion_name, NULL);
559 if (rcode < 0) return -1; /* bad string */
562 * Explicit list given: use it.
564 client_cs = cf_section_sub_find_name2(parentcs,
568 client_cs = cf_section_find(section_name);
571 cf_log_err(cf_sectiontoitem(cs),
572 "Failed to find clients %s {...}",
578 } /* else there was no "clients = " entry. */
581 CONF_SECTION *server_cs;
583 server_cs = cf_section_sub_find_name2(parentcs,
587 * Found a "server foo" section. If there are clients
591 (cf_section_sub_find(server_cs, "client") != NULL)) {
592 client_cs = server_cs;
597 * Still nothing. Look for global clients.
599 if (!client_cs) client_cs = parentcs;
601 sock->clients = clients_parse_section(client_cs);
602 if (!sock->clients) {
603 cf_log_err(cf_sectiontoitem(cs),
604 "Failed to load clients for this listen section");
612 * Send an authentication response packet
614 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
616 rad_assert(request->listener == listener);
617 rad_assert(listener->send == auth_socket_send);
619 return rad_send(request->reply, request->packet,
620 request->client->secret);
624 #ifdef WITH_ACCOUNTING
626 * Send an accounting response packet (or not)
628 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
630 rad_assert(request->listener == listener);
631 rad_assert(listener->send == acct_socket_send);
634 * Accounting reject's are silently dropped.
636 * We do it here to avoid polluting the rest of the
637 * code with this knowledge
639 if (request->reply->code == 0) return 0;
641 return rad_send(request->reply, request->packet,
642 request->client->secret);
648 * Send a packet to a home server.
650 * FIXME: have different code for proxy auth & acct!
652 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
654 listen_socket_t *sock = listener->data;
656 rad_assert(request->proxy_listener == listener);
657 rad_assert(listener->send == proxy_socket_send);
659 request->proxy->src_ipaddr = sock->ipaddr;
660 request->proxy->src_port = sock->port;
662 return rad_send(request->proxy, request->packet,
663 request->home_server->secret);
669 * Check if an incoming request is "ok"
671 * It takes packets, not requests. It sees if the packet looks
672 * OK. If so, it does a number of sanity checks on it.
674 static int stats_socket_recv(rad_listen_t *listener,
675 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
679 RADIUS_PACKET *packet;
681 fr_ipaddr_t src_ipaddr;
683 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
684 if (rcode < 0) return 0;
686 RAD_STATS_TYPE_INC(listener, total_requests);
688 if (rcode < 20) { /* AUTH_HDR_LEN */
689 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
693 if ((client = client_listener_find(listener,
694 &src_ipaddr, src_port)) == NULL) {
695 rad_recv_discard(listener->fd);
696 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
701 * We only understand Status-Server on this socket.
703 if (code != PW_STATUS_SERVER) {
704 DEBUG("Ignoring packet code %d sent to Status-Server port",
706 rad_recv_discard(listener->fd);
707 RAD_STATS_TYPE_INC(listener, total_unknown_types);
708 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
713 * Now that we've sanity checked everything, receive the
716 packet = rad_recv(listener->fd, 1); /* require message authenticator */
718 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
719 DEBUG("%s", fr_strerror());
723 if (!received_request(listener, packet, prequest, client)) {
724 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
725 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
730 *pfun = rad_status_server;
737 * Check if an incoming request is "ok"
739 * It takes packets, not requests. It sees if the packet looks
740 * OK. If so, it does a number of sanity checks on it.
742 static int auth_socket_recv(rad_listen_t *listener,
743 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
747 RADIUS_PACKET *packet;
748 RAD_REQUEST_FUNP fun = NULL;
750 fr_ipaddr_t src_ipaddr;
752 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
753 if (rcode < 0) return 0;
755 RAD_STATS_TYPE_INC(listener, total_requests);
757 if (rcode < 20) { /* AUTH_HDR_LEN */
758 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
762 if ((client = client_listener_find(listener,
763 &src_ipaddr, src_port)) == NULL) {
764 rad_recv_discard(listener->fd);
765 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
770 * Some sanity checks, based on the packet code.
773 case PW_AUTHENTICATION_REQUEST:
774 RAD_STATS_CLIENT_INC(listener, client, total_requests);
775 fun = rad_authenticate;
778 case PW_STATUS_SERVER:
779 if (!mainconfig.status_server) {
780 rad_recv_discard(listener->fd);
781 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
782 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
783 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
786 fun = rad_status_server;
790 rad_recv_discard(listener->fd);
791 RAD_STATS_INC(radius_auth_stats.total_unknown_types);
792 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
794 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
795 code, client->shortname, src_port);
798 } /* switch over packet types */
801 * Now that we've sanity checked everything, receive the
804 packet = rad_recv(listener->fd, client->message_authenticator);
806 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
807 DEBUG("%s", fr_strerror());
811 if (!received_request(listener, packet, prequest, client)) {
812 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
813 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
823 #ifdef WITH_ACCOUNTING
825 * Receive packets from an accounting socket
827 static int acct_socket_recv(rad_listen_t *listener,
828 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
832 RADIUS_PACKET *packet;
833 RAD_REQUEST_FUNP fun = NULL;
835 fr_ipaddr_t src_ipaddr;
837 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
838 if (rcode < 0) return 0;
840 RAD_STATS_TYPE_INC(listener, total_requests);
842 if (rcode < 20) { /* AUTH_HDR_LEN */
843 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
847 if ((client = client_listener_find(listener,
848 &src_ipaddr, src_port)) == NULL) {
849 rad_recv_discard(listener->fd);
850 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
855 * Some sanity checks, based on the packet code.
858 case PW_ACCOUNTING_REQUEST:
859 RAD_STATS_CLIENT_INC(listener, client, total_requests);
860 fun = rad_accounting;
863 case PW_STATUS_SERVER:
864 if (!mainconfig.status_server) {
865 rad_recv_discard(listener->fd);
866 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
867 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
869 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
872 fun = rad_status_server;
876 rad_recv_discard(listener->fd);
877 RAD_STATS_TYPE_INC(listener, total_unknown_types);
878 RAD_STATS_CLIENT_INC(listener, client, total_unknown_types);
880 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
881 code, client->shortname, src_port);
883 } /* switch over packet types */
886 * Now that we've sanity checked everything, receive the
889 packet = rad_recv(listener->fd, 0);
891 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
892 radlog(L_ERR, "%s", fr_strerror());
897 * There can be no duplicate accounting packets.
899 if (!received_request(listener, packet, prequest, client)) {
900 RAD_STATS_TYPE_INC(listener, total_packets_dropped);
901 RAD_STATS_CLIENT_INC(listener, client, total_packets_dropped);
914 * For now, all CoA requests are *only* originated, and not
915 * proxied. So all of the necessary work is done in the
916 * post-proxy section, which is automatically handled by event.c.
917 * As a result, we don't have to do anything here.
919 static int rad_coa_reply(REQUEST *request)
924 * Inform the user about RFC requirements.
926 s1 = pairfind(request->proxy->vps, PW_STATE);
928 s2 = pairfind(request->proxy_reply->vps, PW_STATE);
931 DEBUG("WARNING: Client was sent State in CoA, and did not respond with State.");
933 } else if ((s1->length != s2->length) ||
934 (memcmp(s1->vp_octets, s2->vp_octets,
936 DEBUG("WARNING: Client was sent State in CoA, and did not respond with the same State.");
940 return RLM_MODULE_OK;
944 * Receive a CoA packet.
946 static int rad_coa_recv(REQUEST *request)
948 int rcode = RLM_MODULE_OK;
953 * Get the correct response
955 switch (request->packet->code) {
961 case PW_DISCONNECT_REQUEST:
962 ack = PW_DISCONNECT_ACK;
963 nak = PW_DISCONNECT_NAK;
966 default: /* shouldn't happen */
967 return RLM_MODULE_FAIL;
971 #define WAS_PROXIED (request->proxy)
973 #define WAS_PROXIED (0)
978 * RFC 5176 Section 3.3. If we have a CoA-Request
979 * with Service-Type = Authorize-Only, it MUST
980 * have a State attribute in it.
982 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE);
983 if (request->packet->code == PW_COA_REQUEST) {
984 if (vp && (vp->vp_integer == 17)) {
985 vp = pairfind(request->packet->vps, PW_STATE);
986 if (!vp || (vp->length == 0)) {
987 RDEBUG("ERROR: CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
988 request->reply->code = PW_COA_NAK;
989 return RLM_MODULE_FAIL;
994 * RFC 5176, Section 3.2.
996 RDEBUG("ERROR: Disconnect-Request MUST NOT contain a Service-Type attribute");
997 request->reply->code = PW_DISCONNECT_NAK;
998 return RLM_MODULE_FAIL;
1001 rcode = module_recv_coa(0, request);
1003 case RLM_MODULE_FAIL:
1004 case RLM_MODULE_INVALID:
1005 case RLM_MODULE_REJECT:
1006 case RLM_MODULE_USERLOCK:
1008 request->reply->code = nak;
1011 case RLM_MODULE_HANDLED:
1014 case RLM_MODULE_NOOP:
1015 case RLM_MODULE_NOTFOUND:
1017 case RLM_MODULE_UPDATED:
1018 request->reply->code = ack;
1023 * Start the reply code with the proxy reply
1026 request->reply->code = request->proxy_reply->code;
1030 * Copy State from the request to the reply.
1031 * See RFC 5176 Section 3.3.
1033 vp = paircopy2(request->packet->vps, PW_STATE);
1034 if (vp) pairadd(&request->reply->vps, vp);
1037 * We may want to over-ride the reply.
1039 rcode = module_send_coa(0, request);
1042 * We need to send CoA-NAK back if Service-Type
1043 * is Authorize-Only. Rely on the user's policy
1044 * to do that. We're not a real NAS, so this
1045 * restriction doesn't (ahem) apply to us.
1047 case RLM_MODULE_FAIL:
1048 case RLM_MODULE_INVALID:
1049 case RLM_MODULE_REJECT:
1050 case RLM_MODULE_USERLOCK:
1053 * Over-ride an ACK with a NAK
1055 request->reply->code = nak;
1058 case RLM_MODULE_HANDLED:
1061 case RLM_MODULE_NOOP:
1062 case RLM_MODULE_NOTFOUND:
1064 case RLM_MODULE_UPDATED:
1066 * Do NOT over-ride a previously set value.
1067 * Otherwise an "ok" here will re-write a
1070 if (request->reply->code == 0) {
1071 request->reply->code = ack;
1077 return RLM_MODULE_OK;
1082 * Check if an incoming request is "ok"
1084 * It takes packets, not requests. It sees if the packet looks
1085 * OK. If so, it does a number of sanity checks on it.
1087 static int coa_socket_recv(rad_listen_t *listener,
1088 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1092 RADIUS_PACKET *packet;
1093 RAD_REQUEST_FUNP fun = NULL;
1096 fr_ipaddr_t src_ipaddr;
1098 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1099 if (rcode < 0) return 0;
1101 RAD_STATS_TYPE_INC(listener, total_requests);
1103 if (rcode < 20) { /* AUTH_HDR_LEN */
1104 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1108 if ((client = client_listener_find(listener,
1109 &src_ipaddr, src_port)) == NULL) {
1110 rad_recv_discard(listener->fd);
1111 RAD_STATS_TYPE_INC(listener, total_invalid_requests);
1113 if (debug_flag > 0) {
1116 listener->print(listener, name, sizeof(name));
1119 * This is debugging rather than logging, so that
1120 * DoS attacks don't affect us.
1122 DEBUG("Ignoring request to %s from unknown client %s port %d",
1124 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
1125 buffer, sizeof(buffer)), src_port);
1132 * Some sanity checks, based on the packet code.
1135 case PW_COA_REQUEST:
1136 case PW_DISCONNECT_REQUEST:
1141 rad_recv_discard(listener->fd);
1142 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1143 code, client->shortname, src_port);
1146 } /* switch over packet types */
1149 * Now that we've sanity checked everything, receive the
1152 packet = rad_recv(listener->fd, client->message_authenticator);
1154 RAD_STATS_TYPE_INC(listener, total_malformed_requests);
1155 DEBUG("%s", fr_strerror());
1159 if (!received_request(listener, packet, prequest, client)) {
1171 * Recieve packets from a proxy socket.
1173 static int proxy_socket_recv(rad_listen_t *listener,
1174 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1177 RADIUS_PACKET *packet;
1178 RAD_REQUEST_FUNP fun = NULL;
1181 packet = rad_recv(listener->fd, 0);
1183 radlog(L_ERR, "%s", fr_strerror());
1188 * FIXME: Client MIB updates?
1190 switch(packet->code) {
1191 case PW_AUTHENTICATION_ACK:
1192 case PW_ACCESS_CHALLENGE:
1193 case PW_AUTHENTICATION_REJECT:
1194 fun = rad_authenticate;
1197 #ifdef WITH_ACCOUNTING
1198 case PW_ACCOUNTING_RESPONSE:
1199 fun = rad_accounting;
1204 case PW_DISCONNECT_ACK:
1205 case PW_DISCONNECT_NAK:
1208 fun = rad_coa_reply;
1214 * FIXME: Update MIB for packet types?
1216 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1217 "from home server %s port %d - ID %d : IGNORED",
1219 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1220 packet->src_port, packet->id);
1225 request = received_proxy_response(packet);
1233 * Distinguish proxied CoA requests from ones we
1236 if ((fun == rad_coa_reply) &&
1237 (request->packet->code == request->proxy->code)) {
1242 rad_assert(fun != NULL);
1244 *prequest = request;
1251 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1253 if (!request->reply->code) return 0;
1255 rad_encode(request->reply, request->packet,
1256 request->client->secret);
1257 rad_sign(request->reply, request->packet,
1258 request->client->secret);
1264 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1266 if (rad_verify(request->packet, NULL,
1267 request->client->secret) < 0) {
1271 return rad_decode(request->packet, NULL,
1272 request->client->secret);
1276 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1278 rad_encode(request->proxy, NULL, request->home_server->secret);
1279 rad_sign(request->proxy, NULL, request->home_server->secret);
1285 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1288 * rad_verify is run in event.c, received_proxy_response()
1291 return rad_decode(request->proxy_reply, request->proxy,
1292 request->home_server->secret);
1298 #include "command.c"
1300 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1302 { common_socket_parse, NULL,
1303 stats_socket_recv, auth_socket_send,
1304 socket_print, client_socket_encode, client_socket_decode },
1307 * This always gets defined.
1309 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1314 { common_socket_parse, NULL,
1315 proxy_socket_recv, proxy_socket_send,
1316 socket_print, proxy_socket_encode, proxy_socket_decode },
1319 /* authentication */
1320 { common_socket_parse, NULL,
1321 auth_socket_recv, auth_socket_send,
1322 socket_print, client_socket_encode, client_socket_decode },
1324 #ifdef WITH_ACCOUNTING
1326 { common_socket_parse, NULL,
1327 acct_socket_recv, acct_socket_send,
1328 socket_print, client_socket_encode, client_socket_decode},
1333 { detail_parse, detail_free,
1334 detail_recv, detail_send,
1335 detail_print, detail_encode, detail_decode },
1339 /* vlan query protocol */
1340 { common_socket_parse, NULL,
1341 vqp_socket_recv, vqp_socket_send,
1342 socket_print, vqp_socket_encode, vqp_socket_decode },
1346 /* dhcp query protocol */
1347 { dhcp_socket_parse, NULL,
1348 dhcp_socket_recv, dhcp_socket_send,
1349 socket_print, dhcp_socket_encode, dhcp_socket_decode },
1352 #ifdef WITH_COMMAND_SOCKET
1353 /* TCP command socket */
1354 { command_socket_parse, NULL,
1355 command_domain_accept, command_domain_send,
1356 command_socket_print, command_socket_encode, command_socket_decode },
1360 /* Change of Authorization */
1361 { common_socket_parse, NULL,
1362 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
1363 socket_print, client_socket_encode, client_socket_decode },
1371 * Binds a listener to a socket.
1373 static int listen_bind(rad_listen_t *this)
1376 struct sockaddr_storage salocal;
1378 listen_socket_t *sock = this->data;
1381 * If the port is zero, then it means the appropriate
1382 * thing from /etc/services.
1384 if (sock->port == 0) {
1385 struct servent *svp;
1387 switch (this->type) {
1388 case RAD_LISTEN_AUTH:
1389 svp = getservbyname ("radius", "udp");
1391 sock->port = ntohs(svp->s_port);
1393 sock->port = PW_AUTH_UDP_PORT;
1397 #ifdef WITH_ACCOUNTING
1398 case RAD_LISTEN_ACCT:
1399 svp = getservbyname ("radacct", "udp");
1401 sock->port = ntohs(svp->s_port);
1403 sock->port = PW_ACCT_UDP_PORT;
1409 case RAD_LISTEN_PROXY:
1415 case RAD_LISTEN_VQP:
1421 case RAD_LISTEN_COA:
1422 svp = getservbyname ("radius-dynauth", "udp");
1424 sock->port = ntohs(svp->s_port);
1426 sock->port = PW_COA_UDP_PORT;
1432 radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");
1438 * Copy fr_socket() here, as we may need to bind to a device.
1440 this->fd = socket(sock->ipaddr.af, SOCK_DGRAM, 0);
1442 radlog(L_ERR, "Failed opening socket: %s", strerror(errno));
1447 * Bind to a device BEFORE touching IP addresses.
1449 if (sock->interface) {
1450 #ifdef SO_BINDTODEVICE
1452 strcpy(ifreq.ifr_name, sock->interface);
1455 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
1456 (char *)&ifreq, sizeof(ifreq));
1460 radlog(L_ERR, "Failed binding to interface %s: %s",
1461 sock->interface, strerror(errno));
1463 } /* else it worked. */
1465 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1466 #ifdef HAVE_NET_IF_H
1468 * Odds are that any system supporting "bind to
1469 * device" also supports IPv6, so this next bit
1470 * isn't necessary. But it's here for
1473 * If we're doing IPv6, and the scope hasn't yet
1474 * been defined, set the scope to the scope of
1477 if (sock->ipaddr.af == AF_INET6) {
1478 if (sock->ipaddr.scope == 0) {
1479 sock->ipaddr.scope = if_nametoindex(sock->interface);
1480 if (sock->ipaddr.scope == 0) {
1482 radlog(L_ERR, "Failed finding interface %s: %s",
1483 sock->interface, strerror(errno));
1486 } /* else scope was defined: we're OK. */
1491 * IPv4: no link local addresses,
1492 * and no bind to device.
1496 radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
1502 #ifdef WITH_UDPFROMTO
1504 * Initialize udpfromto for all sockets.
1506 if (udpfromto_init(this->fd) != 0) {
1513 * Set up sockaddr stuff.
1515 if (!fr_ipaddr2sockaddr(&sock->ipaddr, sock->port, &salocal, &salen)) {
1520 #ifdef HAVE_STRUCT_SOCKADDR_IN6
1521 if (sock->ipaddr.af == AF_INET6) {
1523 * Listening on '::' does NOT get you IPv4 to
1524 * IPv6 mapping. You've got to listen on an IPv4
1525 * address, too. This makes the rest of the server
1526 * design a little simpler.
1530 if (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr)) {
1533 setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
1534 (char *)&on, sizeof(on));
1536 #endif /* IPV6_V6ONLY */
1538 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
1541 if (sock->ipaddr.af == AF_INET) {
1544 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1546 * Disable PMTU discovery. On Linux, this
1547 * also makes sure that the "don't fragment"
1550 flag = IP_PMTUDISC_DONT;
1551 setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
1552 &flag, sizeof(flag));
1555 #if defined(IP_DONTFRAG)
1557 * Ensure that the "don't fragment" flag is zero.
1560 setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
1561 &flag, sizeof(flag));
1566 * May be binding to priviledged ports.
1569 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
1575 this->print(this, buffer, sizeof(buffer));
1576 radlog(L_ERR, "Failed binding to %s: %s\n",
1577 buffer, strerror(errno));
1582 * FreeBSD jail issues. We bind to 0.0.0.0, but the
1583 * kernel instead binds us to a 1.2.3.4. If this
1584 * happens, notice, and remember our real IP.
1587 struct sockaddr_storage src;
1588 socklen_t sizeof_src = sizeof(src);
1590 memset(&src, 0, sizeof_src);
1591 if (getsockname(this->fd, (struct sockaddr *) &src,
1593 radlog(L_ERR, "Failed getting socket name: %s",
1598 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
1599 &sock->ipaddr, &sock->port)) {
1600 radlog(L_ERR, "Socket has unsupported address family");
1609 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1610 radlog(L_ERR, "Failure getting socket flags: %s)\n",
1615 flags |= O_NONBLOCK;
1616 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1617 radlog(L_ERR, "Failure setting socket flags: %s)\n",
1629 * Allocate & initialize a new listener.
1631 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1635 this = rad_malloc(sizeof(*this));
1636 memset(this, 0, sizeof(*this));
1639 this->recv = master_listen[this->type].recv;
1640 this->send = master_listen[this->type].send;
1641 this->print = master_listen[this->type].print;
1642 this->encode = master_listen[this->type].encode;
1643 this->decode = master_listen[this->type].decode;
1647 case RAD_LISTEN_NONE:
1649 case RAD_LISTEN_AUTH:
1650 #ifdef WITH_ACCOUNTING
1651 case RAD_LISTEN_ACCT:
1654 case RAD_LISTEN_PROXY:
1657 case RAD_LISTEN_VQP:
1660 case RAD_LISTEN_COA:
1662 this->data = rad_malloc(sizeof(listen_socket_t));
1663 memset(this->data, 0, sizeof(listen_socket_t));
1667 case RAD_LISTEN_DHCP:
1668 this->data = rad_malloc(sizeof(dhcp_socket_t));
1669 memset(this->data, 0, sizeof(dhcp_socket_t));
1674 case RAD_LISTEN_DETAIL:
1679 #ifdef WITH_COMMAND_SOCKET
1680 case RAD_LISTEN_COMMAND:
1681 this->data = rad_malloc(sizeof(fr_command_socket_t));
1682 memset(this->data, 0, sizeof(fr_command_socket_t));
1687 rad_assert("Unsupported option!" == NULL);
1697 * Externally visible function for creating a new proxy LISTENER.
1699 * Not thread-safe, but all calls to it are protected by the
1700 * proxy mutex in event.c
1702 rad_listen_t *proxy_new_listener(fr_ipaddr_t *ipaddr, int exists)
1704 rad_listen_t *this, *tmp, **last;
1705 listen_socket_t *sock, *old;
1708 * Find an existing proxy socket to copy.
1711 last = &mainconfig.listen;
1712 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1714 * Not proxy, ignore it.
1716 if (tmp->type != RAD_LISTEN_PROXY) continue;
1721 * If we were asked to copy a specific one, do
1722 * so. If we're just finding one that already
1723 * exists, return a pointer to it. Otherwise,
1724 * create ANOTHER one with the same IP address.
1726 if ((ipaddr->af != AF_UNSPEC) &&
1727 (fr_ipaddr_cmp(&sock->ipaddr, ipaddr) != 0)) {
1728 if (exists) return tmp;
1732 if (!old) old = sock;
1734 last = &(tmp->next);
1737 this = listen_alloc(RAD_LISTEN_PROXY);
1742 * The socket MUST already exist if we're binding
1743 * to an address while proxying.
1745 * If we're initializing the server, it's OK for the
1746 * socket to NOT exist.
1749 DEBUG("WARNING: No previous template for proxy socket. Source IP address may be chosen by the OS");
1752 if (ipaddr->af != AF_UNSPEC) {
1753 sock->ipaddr = *ipaddr;
1755 memset(&sock->ipaddr, 0, sizeof(sock->ipaddr));
1756 sock->ipaddr.af = AF_INET; /* Oh well */
1759 sock->ipaddr = old->ipaddr;
1764 if (listen_bind(this) >= 0) {
1766 * Add the new listener to the list of
1773 DEBUG("Failed binding to new proxy socket");
1779 static const FR_NAME_NUMBER listen_compare[] = {
1781 { "status", RAD_LISTEN_NONE },
1783 { "auth", RAD_LISTEN_AUTH },
1784 #ifdef WITH_ACCOUNTING
1785 { "acct", RAD_LISTEN_ACCT },
1788 { "detail", RAD_LISTEN_DETAIL },
1791 { "proxy", RAD_LISTEN_PROXY },
1794 { "vmps", RAD_LISTEN_VQP },
1797 { "dhcp", RAD_LISTEN_DHCP },
1799 #ifdef WITH_COMMAND_SOCKET
1800 { "control", RAD_LISTEN_COMMAND },
1803 { "coa", RAD_LISTEN_COA },
1809 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1817 cf_log_info(cs, "listen {");
1819 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1821 if (rcode < 0) return NULL;
1824 cf_log_err(cf_sectiontoitem(cs),
1825 "No type specified in listen section");
1829 type = fr_str2int(listen_compare, listen_type, -1);
1831 cf_log_err(cf_sectiontoitem(cs),
1832 "Invalid type \"%s\" in listen section.",
1840 * Allow listen sections in the default config to
1841 * refer to a server.
1844 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
1846 if (rcode == 1) { /* compatiblity with 2.0-pre */
1847 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1850 if (rcode < 0) return NULL;
1854 * Set up cross-type data.
1856 this = listen_alloc(type);
1857 this->server = server;
1861 * Call per-type parser.
1863 if (master_listen[type].parse(cs, this) < 0) {
1868 cf_log_info(cs, "}");
1874 * Generate a list of listeners. Takes an input list of
1875 * listeners, too, so we don't close sockets with waiting packets.
1877 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1879 int override = FALSE;
1881 CONF_SECTION *cs = NULL;
1882 rad_listen_t **last;
1884 fr_ipaddr_t server_ipaddr;
1887 int defined_proxy = 0;
1891 * We shouldn't be called with a pre-existing list.
1893 rad_assert(head && (*head == NULL));
1896 server_ipaddr.af = AF_UNSPEC;
1899 * If the port is specified on the command-line,
1900 * it over-rides the configuration file.
1902 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1904 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1907 * If the IP address was configured on the command-line,
1908 * use that as the "bind_address"
1910 if (mainconfig.myip.af != AF_UNSPEC) {
1911 memcpy(&server_ipaddr, &mainconfig.myip,
1912 sizeof(server_ipaddr));
1918 * Else look for bind_address and/or listen sections.
1920 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1921 rcode = cf_item_parse(config, "bind_address",
1923 &server_ipaddr.ipaddr.ip4addr, NULL);
1924 if (rcode < 0) return -1; /* error parsing it */
1926 if (rcode == 0) { /* successfully parsed IPv4 */
1927 listen_socket_t *sock;
1928 server_ipaddr.af = AF_INET;
1930 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'.");
1934 if (strcmp(progname, "vmpsd") == 0) {
1935 this = listen_alloc(RAD_LISTEN_VQP);
1936 if (!auth_port) auth_port = 1589;
1939 this = listen_alloc(RAD_LISTEN_AUTH);
1943 sock->ipaddr = server_ipaddr;
1944 sock->port = auth_port;
1946 sock->clients = clients_parse_section(config);
1947 if (!sock->clients) {
1948 cf_log_err(cf_sectiontoitem(config),
1949 "Failed to find any clients for this listen section");
1954 if (listen_bind(this) < 0) {
1956 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1960 auth_port = sock->port; /* may have been updated in listen_bind */
1962 cs = cf_section_sub_find_name2(config, "server",
1964 if (cs) this->server = mainconfig.name;
1968 last = &(this->next);
1974 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1977 #ifdef WITH_ACCOUNTING
1979 * Open Accounting Socket.
1981 * If we haven't already gotten acct_port from
1982 * /etc/services, then make it auth_port + 1.
1984 this = listen_alloc(RAD_LISTEN_ACCT);
1988 * Create the accounting socket.
1990 * The accounting port is always the
1991 * authentication port + 1
1993 sock->ipaddr = server_ipaddr;
1994 sock->port = auth_port + 1;
1996 sock->clients = clients_parse_section(config);
1997 if (!sock->clients) {
1998 cf_log_err(cf_sectiontoitem(config),
1999 "Failed to find any clients for this listen section");
2003 if (listen_bind(this) < 0) {
2006 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
2011 cs = cf_section_sub_find_name2(config, "server",
2013 if (cs) this->server = mainconfig.name;
2017 last = &(this->next);
2019 } else if (mainconfig.port > 0) { /* no bind address, but a port */
2020 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2026 * They specified an IP on the command-line, ignore
2027 * all listen sections except the one in '-n'.
2029 if (mainconfig.myip.af != AF_UNSPEC) {
2030 CONF_SECTION *subcs;
2031 const char *name2 = cf_section_name2(cs);
2033 cs = cf_section_sub_find_name2(config, "server",
2035 if (!cs) goto do_proxy;
2038 * Should really abstract this code...
2040 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2042 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2043 this = listen_parse(subcs, name2);
2050 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2054 last = &(this->next);
2055 } /* loop over "listen" directives in server <foo> */
2061 * Walk through the "listen" sections, if they exist.
2063 for (cs = cf_subsection_find_next(config, NULL, "listen");
2065 cs = cf_subsection_find_next(config, cs, "listen")) {
2066 this = listen_parse(cs, NULL);
2073 if (this->type == RAD_LISTEN_PROXY) defined_proxy = 1;
2077 last = &(this->next);
2081 * Check virtual servers for "listen" sections, too.
2083 * FIXME: Move to virtual server init?
2085 for (cs = cf_subsection_find_next(config, NULL, "server");
2087 cs = cf_subsection_find_next(config, cs, "server")) {
2088 CONF_SECTION *subcs;
2089 const char *name2 = cf_section_name2(cs);
2091 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2093 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2094 this = listen_parse(subcs, name2);
2101 if (this->type == RAD_LISTEN_PROXY) {
2102 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2109 last = &(this->next);
2110 } /* loop over "listen" directives in virtual servers */
2111 } /* loop over virtual servers */
2114 * If we're proxying requests, open the proxy FD.
2115 * Otherwise, don't do anything.
2119 if (mainconfig.proxy_requests == TRUE) {
2121 listen_socket_t *sock = NULL;
2124 * No sockets to receive packets, therefore
2125 * proxying is pointless.
2127 if (!*head) return -1;
2129 if (defined_proxy) goto check_home_servers;
2132 * Find the first authentication port,
2135 for (this = *head; this != NULL; this = this->next) {
2136 if (this->type == RAD_LISTEN_AUTH) {
2138 if (server_ipaddr.af == AF_UNSPEC) {
2139 server_ipaddr = sock->ipaddr;
2141 port = sock->port + 2; /* skip acct port */
2145 if (this->type == RAD_LISTEN_VQP) {
2147 if (server_ipaddr.af == AF_UNSPEC) {
2148 server_ipaddr = sock->ipaddr;
2150 port = sock->port + 1;
2156 if (port < 0) port = 1024 + (fr_rand() & 0x1ff);
2159 * Address is still unspecified, use IPv4.
2161 if (server_ipaddr.af == AF_UNSPEC) {
2162 server_ipaddr.af = AF_INET;
2163 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2166 this = listen_alloc(RAD_LISTEN_PROXY);
2170 * Create the first proxy socket.
2172 sock->ipaddr = server_ipaddr;
2175 * Try to find a proxy port (value doesn't matter)
2177 for (sock->port = port;
2180 if (listen_bind(this) == 0) {
2182 last = &(this->next); /* just in case */
2187 if (sock->port >= 64000) {
2190 radlog(L_ERR, "Failed to open socket for proxying");
2195 * Create *additional* proxy listeners, based
2196 * on their src_ipaddr.
2199 if (home_server_create_listeners(*head) != 0) return -1;
2207 * Free a linked list of listeners;
2209 void listen_free(rad_listen_t **head)
2213 if (!head || !*head) return;
2217 rad_listen_t *next = this->next;
2220 * Other code may have eaten the FD.
2222 if (this->fd >= 0) close(this->fd);
2224 if (master_listen[this->type].free) {
2225 master_listen[this->type].free(this);
2237 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
2242 for (this = mainconfig.listen; this != NULL; this = this->next) {
2243 listen_socket_t *sock;
2245 if ((this->type != RAD_LISTEN_AUTH) &&
2246 (this->type != RAD_LISTEN_ACCT)) continue;
2250 if ((sock->port == port) &&
2251 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2252 return sock->clients;
2260 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port)
2264 for (this = mainconfig.listen; this != NULL; this = this->next) {
2265 listen_socket_t *sock;
2268 * FIXME: For TCP, ignore the *secondary*
2269 * listeners associated with the main socket.
2271 if ((this->type != RAD_LISTEN_AUTH) &&
2272 (this->type != RAD_LISTEN_ACCT)) continue;
2276 if ((sock->port == port) &&
2277 (fr_ipaddr_cmp(ipaddr, &sock->ipaddr) == 0)) {
2281 if ((sock->port == port) &&
2282 ((sock->ipaddr.af == AF_INET) &&
2283 (sock->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY))) {
2287 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2288 if ((sock->port == port) &&
2289 (sock->ipaddr.af == AF_INET6) &&
2290 (IN6_IS_ADDR_UNSPECIFIED(&sock->ipaddr.ipaddr.ip6addr))) {