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>
32 #include <freeradius-devel/process.h>
34 #include <freeradius-devel/vmps.h>
35 #include <freeradius-devel/detail.h>
38 #include <freeradius-devel/udpfromto.h>
41 #ifdef HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
54 #ifdef DEBUG_PRINT_PACKET
55 static void print_packet(RADIUS_PACKET *packet)
57 char src[256], dst[256];
59 ip_ntoh(&packet->src_ipaddr, src, sizeof(src));
60 ip_ntoh(&packet->dst_ipaddr, dst, sizeof(dst));
62 fprintf(stderr, "ID %d: %s %d -> %s %d\n", packet->id,
63 src, packet->src_port, dst, packet->dst_port);
69 * We'll use this below.
71 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
72 typedef void (*rad_listen_free_t)(rad_listen_t *);
74 typedef struct rad_listen_master_t {
75 rad_listen_parse_t parse;
76 rad_listen_free_t free;
77 rad_listen_recv_t recv;
78 rad_listen_send_t send;
79 rad_listen_print_t print;
80 rad_listen_encode_t encode;
81 rad_listen_decode_t decode;
82 } rad_listen_master_t;
84 static rad_listen_t *listen_alloc(TALLOC_CTX *ctx, RAD_LISTEN_TYPE type);
86 #ifdef WITH_COMMAND_SOCKET
87 static int command_tcp_recv(rad_listen_t *listener);
88 static int command_tcp_send(rad_listen_t *listener, REQUEST *request);
89 static int command_write_magic(int newfd, listen_socket_t *sock);
93 * Xlat for %{listen:foo}
95 static size_t xlat_listen(UNUSED void *instance, REQUEST *request,
96 const char *fmt, char *out,
99 const char *value = NULL;
102 if (!fmt || !out || (outlen < 1)) return 0;
104 if (!request || !request->listener) {
109 cp = cf_pair_find(request->listener->cs, fmt);
110 if (!cp || !(value = cf_pair_value(cp))) {
115 strlcpy(out, value, outlen);
121 * Find a per-socket client.
123 RADCLIENT *client_listener_find(rad_listen_t *listener,
124 const fr_ipaddr_t *ipaddr, int src_port)
126 #ifdef WITH_DYNAMIC_CLIENTS
133 RADCLIENT_LIST *clients;
134 listen_socket_t *sock;
136 rad_assert(listener != NULL);
137 rad_assert(ipaddr != NULL);
139 sock = listener->data;
140 clients = sock->clients;
143 * This HAS to have been initialized previously.
145 rad_assert(clients != NULL);
147 client = client_find(clients, ipaddr,sock->proto);
149 char name[256], buffer[128];
151 #ifdef WITH_DYNAMIC_CLIENTS
152 unknown: /* used only for dynamic clients */
156 * DoS attack quenching, but only in daemon mode.
157 * If they're running in debug mode, show them
160 if (debug_flag == 0) {
161 static time_t last_printed = 0;
164 if (last_printed == now) return NULL;
169 listener->print(listener, name, sizeof(name));
171 radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
175 , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
176 buffer, sizeof(buffer)), src_port
178 , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
184 #ifndef WITH_DYNAMIC_CLIENTS
185 return client; /* return the found client. */
189 * No server defined, and it's not dynamic. Return it.
191 if (!client->client_server && !client->dynamic) return client;
196 * It's a dynamically generated client, check it.
198 if (client->dynamic && (src_port != 0)) {
200 * Lives forever. Return it.
202 if (client->lifetime == 0) return client;
205 * Rate-limit the deletion of known clients.
206 * This makes them last a little longer, but
207 * prevents the server from melting down if (say)
208 * 10k clients all expire at once.
210 if (now == client->last_new_client) return client;
213 * It's not dead yet. Return it.
215 if ((client->created + client->lifetime) > now) return client;
218 * This really puts them onto a queue for later
221 client_delete(clients, client);
224 * Go find the enclosing network again.
226 client = client_find(clients, ipaddr, sock->proto);
231 if (!client) goto unknown;
232 if (!client->client_server) goto unknown;
235 * At this point, 'client' is the enclosing
236 * network that configures where dynamic clients
239 rad_assert(client->dynamic == 0);
241 } else if (!client->dynamic && client->rate_limit) {
243 * The IP is unknown, so we've found an enclosing
244 * network. Enable DoS protection. We only
245 * allow one new client per second. Known
246 * clients aren't subject to this restriction.
248 if (now == client->last_new_client) goto unknown;
251 client->last_new_client = now;
253 request = request_alloc();
254 if (!request) goto unknown;
256 request->listener = listener;
257 request->client = client;
258 request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
259 if (!request->packet) { /* badly formed, etc */
260 request_free(&request);
263 request->reply = rad_alloc_reply(request, request->packet);
264 if (!request->reply) {
265 request_free(&request);
268 gettimeofday(&request->packet->timestamp, NULL);
270 request->priority = listener->type;
271 request->server = client->client_server;
272 request->root = &mainconfig;
275 * Run a fake request through the given virtual server.
276 * Look for FreeRADIUS-Client-IP-Address
277 * FreeRADIUS-Client-Secret
280 * and create the RADCLIENT structure from that.
282 DEBUG("server %s {", request->server);
284 rcode = module_authorize(0, request);
286 DEBUG("} # server %s", request->server);
288 if (rcode != RLM_MODULE_OK) {
289 request_free(&request);
294 * If the client was updated by rlm_dynamic_clients,
295 * don't create the client from attribute-value pairs.
297 if (request->client == client) {
298 created = client_create(clients, request);
300 created = request->client;
303 * This frees the client if it isn't valid.
305 if (!client_validate(clients, client, created)) goto unknown;
308 request->server = client->server;
309 exec_trigger(request, NULL, "server.client.add", FALSE);
311 request_free(&request);
313 if (!created) goto unknown;
319 static int listen_bind(rad_listen_t *this);
323 * Process and reply to a server-status request.
324 * Like rad_authenticate and rad_accounting this should
325 * live in it's own file but it's so small we don't bother.
327 int rad_status_server(REQUEST *request)
329 int rcode = RLM_MODULE_OK;
332 switch (request->listener->type) {
334 case RAD_LISTEN_NONE:
336 case RAD_LISTEN_AUTH:
337 dval = dict_valbyname(PW_AUTZ_TYPE, 0, "Status-Server");
339 rcode = module_authorize(dval->value, request);
341 rcode = RLM_MODULE_OK;
346 case RLM_MODULE_UPDATED:
347 request->reply->code = PW_AUTHENTICATION_ACK;
350 case RLM_MODULE_FAIL:
351 case RLM_MODULE_HANDLED:
352 request->reply->code = 0; /* don't reply */
356 case RLM_MODULE_REJECT:
357 request->reply->code = PW_AUTHENTICATION_REJECT;
362 #ifdef WITH_ACCOUNTING
363 case RAD_LISTEN_ACCT:
364 dval = dict_valbyname(PW_ACCT_TYPE, 0, "Status-Server");
366 rcode = module_accounting(dval->value, request);
368 rcode = RLM_MODULE_OK;
373 case RLM_MODULE_UPDATED:
374 request->reply->code = PW_ACCOUNTING_RESPONSE;
378 request->reply->code = 0; /* don't reply */
386 * This is a vendor extension. Suggested by Glen
387 * Zorn in IETF 72, and rejected by the rest of
388 * the WG. We like it, so it goes in here.
391 dval = dict_valbyname(PW_RECV_COA_TYPE, 0, "Status-Server");
393 rcode = module_recv_coa(dval->value, request);
395 rcode = RLM_MODULE_OK;
400 case RLM_MODULE_UPDATED:
401 request->reply->code = PW_COA_ACK;
405 request->reply->code = 0; /* don't reply */
417 * Full statistics are available only on a statistics
420 if (request->listener->type == RAD_LISTEN_NONE) {
421 request_stats_reply(request);
429 static int dual_tcp_recv(rad_listen_t *listener)
432 RADIUS_PACKET *packet;
433 RAD_REQUEST_FUNP fun = NULL;
434 listen_socket_t *sock = listener->data;
435 RADCLIENT *client = sock->client;
438 * Allocate a packet for partial reads.
441 sock->packet = rad_alloc(NULL, 0);
442 if (!sock->packet) return 0;
444 sock->packet->sockfd = listener->fd;
445 sock->packet->src_ipaddr = sock->other_ipaddr;
446 sock->packet->src_port = sock->other_port;
447 sock->packet->dst_ipaddr = sock->my_ipaddr;
448 sock->packet->dst_port = sock->my_port;
452 * Grab the packet currently being processed.
454 packet = sock->packet;
456 rcode = fr_tcp_read_packet(packet, 0);
459 * Still only a partial packet. Put it back, and return,
460 * so that we'll read more data when it's ready.
466 if (rcode == -1) { /* error reading packet */
469 radlog(L_ERR, "Invalid packet from %s port %d: closing socket",
470 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
474 if (rcode < 0) { /* error or connection reset */
475 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
478 * Decrement the number of connections.
480 if (sock->parent->limit.num_connections > 0) {
481 sock->parent->limit.num_connections--;
483 if (sock->client->limit.num_connections > 0) {
484 sock->client->limit.num_connections--;
488 * Tell the event handler that an FD has disappeared.
490 DEBUG("Client has closed connection");
491 event_new_fd(listener);
494 * Do NOT free the listener here. It's in use by
495 * a request, and will need to hang around until
496 * all of the requests are done.
498 * It is instead free'd in remove_from_request_hash()
504 * Some sanity checks, based on the packet code.
506 switch(packet->code) {
507 case PW_AUTHENTICATION_REQUEST:
508 if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
509 FR_STATS_INC(auth, total_requests);
510 fun = rad_authenticate;
513 #ifdef WITH_ACCOUNTING
514 case PW_ACCOUNTING_REQUEST:
515 if (listener->type != RAD_LISTEN_ACCT) goto bad_packet;
516 FR_STATS_INC(acct, total_requests);
517 fun = rad_accounting;
521 case PW_STATUS_SERVER:
522 if (!mainconfig.status_server) {
523 FR_STATS_INC(auth, total_unknown_types);
524 DEBUGW("Ignoring Status-Server request due to security configuration");
525 rad_free(&sock->packet);
528 fun = rad_status_server;
533 FR_STATS_INC(auth, total_unknown_types);
535 DEBUG("Invalid packet code %d sent from client %s port %d : IGNORED",
536 packet->code, client->shortname, packet->src_port);
537 rad_free(&sock->packet);
539 } /* switch over packet types */
541 if (!request_receive(listener, packet, client, fun)) {
542 FR_STATS_INC(auth, total_packets_dropped);
543 rad_free(&sock->packet);
547 sock->packet = NULL; /* we have no need for more partial reads */
551 static int dual_tcp_accept(rad_listen_t *listener)
556 struct sockaddr_storage src;
557 listen_socket_t *sock;
558 fr_ipaddr_t src_ipaddr;
559 RADCLIENT *client = NULL;
563 DEBUG2(" ... new connection request on TCP socket.");
565 newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
568 * Non-blocking sockets must handle this.
571 if (errno == EWOULDBLOCK) {
576 DEBUG2(" ... failed to accept connection.");
580 if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
582 DEBUG2(" ... unknown address family.");
587 * Enforce client IP address checks on accept, not on
590 if ((client = client_listener_find(listener,
591 &src_ipaddr, src_port)) == NULL) {
593 FR_STATS_INC(auth, total_invalid_requests);
598 * Enforce max_connections on client && listen section.
600 if ((client->limit.max_connections != 0) &&
601 (client->limit.max_connections == client->limit.num_connections)) {
603 * FIXME: Print client IP/port, and server IP/port.
605 radlog(L_INFO, "Ignoring new connection due to client max_connections (%d)", client->limit.max_connections);
610 sock = listener->data;
611 if ((sock->limit.max_connections != 0) &&
612 (sock->limit.max_connections == sock->limit.num_connections)) {
614 * FIXME: Print client IP/port, and server IP/port.
616 radlog(L_INFO, "Ignoring new connection due to socket max_connections");
620 client->limit.num_connections++;
621 sock->limit.num_connections++;
624 * Add the new listener.
626 this = listen_alloc(listener, listener->type);
627 if (!this) return -1;
630 * Copy everything, including the pointer to the socket
634 memcpy(this->data, listener->data, sizeof(*sock));
635 memcpy(this, listener, sizeof(*this));
637 this->data = sock; /* fix it back */
639 sock->parent = listener->data;
640 sock->other_ipaddr = src_ipaddr;
641 sock->other_port = src_port;
642 sock->client = client;
643 sock->opened = sock->last_packet = time(NULL);
646 * Set the limits. The defaults are the parent limits.
647 * Client limits on max_connections are enforced dynamically.
648 * Set the MINIMUM of client/socket idle timeout or lifetime.
650 memcpy(&sock->limit, &sock->parent->limit, sizeof(sock->limit));
652 if (client->limit.idle_timeout &&
653 ((sock->limit.idle_timeout == 0) ||
654 (client->limit.idle_timeout < sock->limit.idle_timeout))) {
655 sock->limit.idle_timeout = client->limit.idle_timeout;
658 if (client->limit.lifetime &&
659 ((sock->limit.lifetime == 0) ||
660 (client->limit.lifetime < sock->limit.lifetime))) {
661 sock->limit.lifetime = client->limit.lifetime;
665 this->status = RAD_LISTEN_STATUS_INIT;
668 #ifdef WITH_COMMAND_SOCKET
669 if (this->type == RAD_LISTEN_COMMAND) {
670 this->recv = command_tcp_recv;
671 this->send = command_tcp_send;
672 command_write_magic(this->fd, sock);
677 this->recv = dual_tcp_recv;
681 this->recv = dual_tls_recv;
682 this->send = dual_tls_send;
688 * FIXME: set O_NONBLOCK on the accept'd fd.
689 * See djb's portability rants for details.
693 * Tell the event loop that we have a new FD.
694 * This can be called from a child thread...
704 * This function is stupid and complicated.
706 static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
709 listen_socket_t *sock = this->data;
712 switch (this->type) {
714 case RAD_LISTEN_NONE: /* what a hack... */
719 case RAD_LISTEN_AUTH:
720 name = "authentication";
723 #ifdef WITH_ACCOUNTING
724 case RAD_LISTEN_ACCT:
730 case RAD_LISTEN_PROXY:
742 case RAD_LISTEN_DHCP:
753 #ifdef WITH_COMMAND_SOCKET
754 case RAD_LISTEN_COMMAND:
764 #define FORWARD len = strlen(buffer); if (len >= (bufsize + 1)) return 0;buffer += len;bufsize -= len
765 #define ADDSTRING(_x) strlcpy(buffer, _x, bufsize);FORWARD
769 if (sock->interface) {
770 ADDSTRING(" interface ");
771 ADDSTRING(sock->interface);
775 if (this->recv == dual_tcp_accept) {
776 ADDSTRING(" proto tcp");
782 * TCP sockets get printed a little differently, to make
783 * it clear what's going on.
786 ADDSTRING(" from client (");
787 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
791 snprintf(buffer, bufsize, "%d", sock->other_port);
795 if ((sock->my_ipaddr.af == AF_INET) &&
796 (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
797 strlcpy(buffer, "*", bufsize);
799 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
804 snprintf(buffer, bufsize, "%d", sock->my_port);
808 ADDSTRING(", virtual-server=");
809 ADDSTRING(this->server);
819 * Maybe it's a socket that we opened to a home server.
821 if ((sock->proto == IPPROTO_TCP) &&
822 (this->type == RAD_LISTEN_PROXY)) {
824 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
828 snprintf(buffer, bufsize, "%d", sock->my_port);
830 ADDSTRING(") -> home_server (");
832 if ((sock->other_ipaddr.af == AF_INET) &&
833 (sock->other_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
834 strlcpy(buffer, "*", bufsize);
836 ip_ntoh(&sock->other_ipaddr, buffer, bufsize);
841 snprintf(buffer, bufsize, "%d", sock->other_port);
848 #endif /* WITH_PROXY */
849 #endif /* WITH_TCP */
851 ADDSTRING(" address ");
853 if ((sock->my_ipaddr.af == AF_INET) &&
854 (sock->my_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
855 strlcpy(buffer, "*", bufsize);
857 ip_ntoh(&sock->my_ipaddr, buffer, bufsize);
862 snprintf(buffer, bufsize, "%d", sock->my_port);
873 ADDSTRING(" as server ");
874 ADDSTRING(this->server);
883 extern int check_config; /* radiusd.c */
886 static CONF_PARSER limit_config[] = {
887 { "max_connections", PW_TYPE_INTEGER,
888 offsetof(listen_socket_t, limit.max_connections), NULL, "16" },
890 { "lifetime", PW_TYPE_INTEGER,
891 offsetof(listen_socket_t, limit.lifetime), NULL, "0" },
893 { "idle_timeout", PW_TYPE_INTEGER,
894 offsetof(listen_socket_t, limit.idle_timeout), NULL, "30" },
896 { NULL, -1, 0, NULL, NULL } /* end the list */
901 * Parse an authentication or accounting socket.
903 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
906 int listen_port, max_pps;
908 listen_socket_t *sock = this->data;
909 char *section_name = NULL;
910 CONF_SECTION *client_cs, *parentcs;
917 memset(&ipaddr, 0, sizeof(ipaddr));
918 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
919 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
920 &ipaddr.ipaddr.ip4addr, NULL);
921 if (rcode < 0) return -1;
923 if (rcode == 0) { /* successfully parsed IPv4 */
926 } else { /* maybe IPv6? */
927 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
928 &ipaddr.ipaddr.ip6addr, NULL);
929 if (rcode < 0) return -1;
932 cf_log_err(cf_sectiontoitem(cs),
933 "No address specified in listen section");
936 ipaddr.af = AF_INET6;
939 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
941 if (rcode < 0) return -1;
943 if ((listen_port < 0) || (listen_port > 65535)) {
944 cf_log_err(cf_sectiontoitem(cs),
945 "Invalid value for \"port\"");
949 rcode = cf_item_parse(cs, "max_pps", PW_TYPE_INTEGER,
951 if (rcode < 0) return -1;
953 if (max_pps && ((max_pps < 10) || (max_pps > 1000000))) {
954 cf_log_err(cf_sectiontoitem(cs),
955 "Invalid value for \"max_pps\"");
959 sock->proto = IPPROTO_UDP;
961 if (cf_pair_find(cs, "proto")) {
963 cf_log_err(cf_sectiontoitem(cs),
964 "System does not support the TCP protocol. Delete this line from the configuration file.");
972 rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
974 if (rcode < 0) return -1;
976 if (strcmp(proto, "udp") == 0) {
977 sock->proto = IPPROTO_UDP;
979 } else if (strcmp(proto, "tcp") == 0) {
980 sock->proto = IPPROTO_TCP;
983 limit = cf_section_sub_find(cs, "limit");
985 rcode = cf_section_parse(limit, sock,
987 if (rcode < 0) return -1;
989 sock->limit.max_connections = 60;
990 sock->limit.idle_timeout = 30;
991 sock->limit.lifetime = 0;
994 if ((sock->limit.idle_timeout > 0) && (sock->limit.idle_timeout < 5))
995 sock->limit.idle_timeout = 5;
996 if ((sock->limit.lifetime > 0) && (sock->limit.lifetime < 5))
997 sock->limit.lifetime = 5;
998 if ((sock->limit.lifetime > 0) && (sock->limit.idle_timeout > sock->limit.lifetime))
999 sock->limit.idle_timeout = 0;
1001 cf_log_err(cf_sectiontoitem(cs),
1002 "Unknown proto name \"%s\"", proto);
1007 * TCP requires a destination IP for sockets.
1008 * UDP doesn't, so it's allowed.
1011 if ((this->type == RAD_LISTEN_PROXY) &&
1012 (sock->proto != IPPROTO_UDP)) {
1013 cf_log_err(cf_sectiontoitem(cs),
1014 "Proxy listeners can only listen on proto = udp");
1017 #endif /* WITH_PROXY */
1020 tls = cf_section_sub_find(cs, "tls");
1023 * Don't allow TLS configurations for UDP sockets.
1025 if (sock->proto != IPPROTO_TCP) {
1026 cf_log_err(cf_sectiontoitem(cs),
1027 "TLS transport is not available for UDP sockets.");
1033 * FIXME: Make this better.
1035 if (listen_port == 0) listen_port = 2083;
1037 this->tls = tls_server_conf_parse(tls);
1042 #ifdef HAVE_PTRHEAD_H
1043 if (pthread_mutex_init(&sock->mutex, NULL) < 0) {
1051 #else /* WITH_TLS */
1053 * Built without TLS. Disallow it.
1055 if (cf_section_sub_find(cs, "tls")) {
1056 cf_log_err(cf_sectiontoitem(cs),
1057 "TLS transport is not available in this executable.");
1060 #endif /* WITH_TLS */
1062 #endif /* WITH_TCP */
1065 * No "proto" field. Disallow TLS.
1067 } else if (cf_section_sub_find(cs, "tls")) {
1068 cf_log_err(cf_sectiontoitem(cs),
1069 "TLS transport is not available in this \"listen\" section.");
1073 sock->my_ipaddr = ipaddr;
1074 sock->my_port = listen_port;
1075 sock->max_rate = max_pps;
1079 if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
1082 DEBUGE("We have been asked to listen on %s port %d, which is also listed as a home server. This can create a proxy loop.",
1083 ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1088 return 0; /* don't do anything */
1093 * If we can bind to interfaces, do so,
1096 if (cf_pair_find(cs, "interface")) {
1098 CONF_PAIR *cp = cf_pair_find(cs, "interface");
1100 rad_assert(cp != NULL);
1101 value = cf_pair_value(cp);
1103 cf_log_err(cf_sectiontoitem(cs),
1104 "No interface name given");
1107 sock->interface = value;
1112 * If we can do broadcasts..
1114 if (cf_pair_find(cs, "broadcast")) {
1115 #ifndef SO_BROADCAST
1116 cf_log_err(cf_sectiontoitem(cs),
1117 "System does not support broadcast sockets. Delete this line from the configuration file.");
1121 CONF_PAIR *cp = cf_pair_find(cs, "broadcast");
1123 if (this->type != RAD_LISTEN_DHCP) {
1124 cf_log_err(cf_pairtoitem(cp),
1125 "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file.");
1129 rad_assert(cp != NULL);
1130 value = cf_pair_value(cp);
1132 cf_log_err(cf_sectiontoitem(cs),
1133 "No broadcast value given");
1138 * Hack... whatever happened to cf_section_parse?
1140 sock->broadcast = (strcmp(value, "yes") == 0);
1146 * And bind it to the port.
1148 if (listen_bind(this) < 0) {
1150 cf_log_err(cf_sectiontoitem(cs),
1151 "Error binding to port for %s port %d",
1152 ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)),
1159 * Proxy sockets don't have clients.
1161 if (this->type == RAD_LISTEN_PROXY) return 0;
1165 * The more specific configurations are preferred to more
1169 parentcs = cf_top_section(cs);
1170 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
1171 §ion_name, NULL);
1172 if (rcode < 0) return -1; /* bad string */
1175 * Explicit list given: use it.
1177 client_cs = cf_section_sub_find_name2(parentcs,
1181 client_cs = cf_section_find(section_name);
1184 cf_log_err(cf_sectiontoitem(cs),
1185 "Failed to find clients %s {...}",
1189 } /* else there was no "clients = " entry. */
1192 CONF_SECTION *server_cs;
1194 server_cs = cf_section_sub_find_name2(parentcs,
1198 * Found a "server foo" section. If there are clients
1202 (cf_section_sub_find(server_cs, "client") != NULL)) {
1203 client_cs = server_cs;
1208 * Still nothing. Look for global clients.
1210 if (!client_cs) client_cs = parentcs;
1212 sock->clients = clients_parse_section(client_cs);
1213 if (!sock->clients) {
1214 cf_log_err(cf_sectiontoitem(cs),
1215 "Failed to load clients for this listen section");
1220 if (sock->proto == IPPROTO_TCP) {
1222 * Re-write the listener receive function to
1223 * allow us to accept the socket.
1225 this->recv = dual_tcp_accept;
1233 * Send an authentication response packet
1235 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
1237 rad_assert(request->listener == listener);
1238 rad_assert(listener->send == auth_socket_send);
1240 #ifdef WITH_UDPFROMTO
1242 * Overwrite the src ip address on the outbound packet
1243 * with the one specified by the client.
1244 * This is useful to work around broken DSR implementations
1245 * and other routing issues.
1247 if (request->client->src_ipaddr.af != AF_UNSPEC) {
1248 request->reply->src_ipaddr = request->client->src_ipaddr;
1252 if (rad_send(request->reply, request->packet,
1253 request->client->secret) < 0) {
1254 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1263 #ifdef WITH_ACCOUNTING
1265 * Send an accounting response packet (or not)
1267 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
1269 rad_assert(request->listener == listener);
1270 rad_assert(listener->send == acct_socket_send);
1273 * Accounting reject's are silently dropped.
1275 * We do it here to avoid polluting the rest of the
1276 * code with this knowledge
1278 if (request->reply->code == 0) return 0;
1280 #ifdef WITH_UDPFROMTO
1282 * Overwrite the src ip address on the outbound packet
1283 * with the one specified by the client.
1284 * This is useful to work around broken DSR implementations
1285 * and other routing issues.
1287 if (request->client->src_ipaddr.af != AF_UNSPEC) {
1288 request->reply->src_ipaddr = request->client->src_ipaddr;
1292 if (rad_send(request->reply, request->packet,
1293 request->client->secret) < 0) {
1294 radlog_request(L_ERR, 0, request, "Failed sending reply: %s",
1305 * Send a packet to a home server.
1307 * FIXME: have different code for proxy auth & acct!
1309 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
1311 rad_assert(request->proxy_listener == listener);
1312 rad_assert(listener->send == proxy_socket_send);
1314 if (rad_send(request->proxy, NULL,
1315 request->home_server->secret) < 0) {
1316 radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
1327 * Check if an incoming request is "ok"
1329 * It takes packets, not requests. It sees if the packet looks
1330 * OK. If so, it does a number of sanity checks on it.
1332 static int stats_socket_recv(rad_listen_t *listener)
1336 RADIUS_PACKET *packet;
1337 RADCLIENT *client = NULL;
1338 fr_ipaddr_t src_ipaddr;
1340 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1341 if (rcode < 0) return 0;
1343 FR_STATS_INC(auth, total_requests);
1345 if (rcode < 20) { /* AUTH_HDR_LEN */
1346 FR_STATS_INC(auth, total_malformed_requests);
1350 if ((client = client_listener_find(listener,
1351 &src_ipaddr, src_port)) == NULL) {
1352 rad_recv_discard(listener->fd);
1353 FR_STATS_INC(auth, total_invalid_requests);
1357 FR_STATS_TYPE_INC(client->auth.total_requests);
1360 * We only understand Status-Server on this socket.
1362 if (code != PW_STATUS_SERVER) {
1363 DEBUG("Ignoring packet code %d sent to Status-Server port",
1365 rad_recv_discard(listener->fd);
1366 FR_STATS_INC(auth, total_unknown_types);
1371 * Now that we've sanity checked everything, receive the
1374 packet = rad_recv(listener->fd, 1); /* require message authenticator */
1376 FR_STATS_INC(auth, total_malformed_requests);
1377 DEBUG("%s", fr_strerror());
1381 if (!request_receive(listener, packet, client, rad_status_server)) {
1382 FR_STATS_INC(auth, total_packets_dropped);
1393 * Check if an incoming request is "ok"
1395 * It takes packets, not requests. It sees if the packet looks
1396 * OK. If so, it does a number of sanity checks on it.
1398 static int auth_socket_recv(rad_listen_t *listener)
1402 RADIUS_PACKET *packet;
1403 RAD_REQUEST_FUNP fun = NULL;
1404 RADCLIENT *client = NULL;
1405 fr_ipaddr_t src_ipaddr;
1407 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1408 if (rcode < 0) return 0;
1410 FR_STATS_INC(auth, total_requests);
1412 if (rcode < 20) { /* AUTH_HDR_LEN */
1413 FR_STATS_INC(auth, total_malformed_requests);
1417 if ((client = client_listener_find(listener,
1418 &src_ipaddr, src_port)) == NULL) {
1419 rad_recv_discard(listener->fd);
1420 FR_STATS_INC(auth, total_invalid_requests);
1424 FR_STATS_TYPE_INC(client->auth.total_requests);
1427 * Some sanity checks, based on the packet code.
1430 case PW_AUTHENTICATION_REQUEST:
1431 fun = rad_authenticate;
1434 case PW_STATUS_SERVER:
1435 if (!mainconfig.status_server) {
1436 rad_recv_discard(listener->fd);
1437 FR_STATS_INC(auth, total_unknown_types);
1438 DEBUGW("Ignoring Status-Server request due to security configuration");
1441 fun = rad_status_server;
1445 rad_recv_discard(listener->fd);
1446 FR_STATS_INC(auth,total_unknown_types);
1448 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
1449 code, client->shortname, src_port);
1452 } /* switch over packet types */
1455 * Now that we've sanity checked everything, receive the
1458 packet = rad_recv(listener->fd, client->message_authenticator);
1460 FR_STATS_INC(auth, total_malformed_requests);
1461 DEBUG("%s", fr_strerror());
1465 if (!request_receive(listener, packet, client, fun)) {
1466 FR_STATS_INC(auth, total_packets_dropped);
1475 #ifdef WITH_ACCOUNTING
1477 * Receive packets from an accounting socket
1479 static int acct_socket_recv(rad_listen_t *listener)
1483 RADIUS_PACKET *packet;
1484 RAD_REQUEST_FUNP fun = NULL;
1485 RADCLIENT *client = NULL;
1486 fr_ipaddr_t src_ipaddr;
1488 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1489 if (rcode < 0) return 0;
1491 FR_STATS_INC(acct, total_requests);
1493 if (rcode < 20) { /* AUTH_HDR_LEN */
1494 FR_STATS_INC(acct, total_malformed_requests);
1498 if ((client = client_listener_find(listener,
1499 &src_ipaddr, src_port)) == NULL) {
1500 rad_recv_discard(listener->fd);
1501 FR_STATS_INC(acct, total_invalid_requests);
1505 FR_STATS_TYPE_INC(client->acct.total_requests);
1508 * Some sanity checks, based on the packet code.
1511 case PW_ACCOUNTING_REQUEST:
1512 fun = rad_accounting;
1515 case PW_STATUS_SERVER:
1516 if (!mainconfig.status_server) {
1517 rad_recv_discard(listener->fd);
1518 FR_STATS_INC(acct, total_unknown_types);
1520 DEBUGW("Ignoring Status-Server request due to security configuration");
1523 fun = rad_status_server;
1527 rad_recv_discard(listener->fd);
1528 FR_STATS_INC(acct, total_unknown_types);
1530 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
1531 code, client->shortname, src_port);
1533 } /* switch over packet types */
1536 * Now that we've sanity checked everything, receive the
1539 packet = rad_recv(listener->fd, 0);
1541 FR_STATS_INC(acct, total_malformed_requests);
1542 radlog(L_ERR, "%s", fr_strerror());
1547 * There can be no duplicate accounting packets.
1549 if (!request_receive(listener, packet, client, fun)) {
1550 FR_STATS_INC(acct, total_packets_dropped);
1561 static int do_proxy(REQUEST *request)
1565 if (request->in_proxy_hash ||
1566 (request->proxy_reply && (request->proxy_reply->code != 0))) {
1570 vp = pairfind(request->config_items, PW_HOME_SERVER_POOL, 0, TAG_ANY);
1573 if (!home_pool_byname(vp->vp_strvalue, HOME_TYPE_COA)) {
1574 RDEBUG2E("Cannot proxy to unknown pool %s",
1583 * Receive a CoA packet.
1585 static int rad_coa_recv(REQUEST *request)
1587 int rcode = RLM_MODULE_OK;
1592 * Get the correct response
1594 switch (request->packet->code) {
1595 case PW_COA_REQUEST:
1600 case PW_DISCONNECT_REQUEST:
1601 ack = PW_DISCONNECT_ACK;
1602 nak = PW_DISCONNECT_NAK;
1605 default: /* shouldn't happen */
1606 return RLM_MODULE_FAIL;
1610 #define WAS_PROXIED (request->proxy)
1612 #define WAS_PROXIED (0)
1617 * RFC 5176 Section 3.3. If we have a CoA-Request
1618 * with Service-Type = Authorize-Only, it MUST
1619 * have a State attribute in it.
1621 vp = pairfind(request->packet->vps, PW_SERVICE_TYPE, 0, TAG_ANY);
1622 if (request->packet->code == PW_COA_REQUEST) {
1623 if (vp && (vp->vp_integer == 17)) {
1624 vp = pairfind(request->packet->vps, PW_STATE, 0, TAG_ANY);
1625 if (!vp || (vp->length == 0)) {
1626 RDEBUGE("CoA-Request with Service-Type = Authorize-Only MUST contain a State attribute");
1627 request->reply->code = PW_COA_NAK;
1628 return RLM_MODULE_FAIL;
1633 * RFC 5176, Section 3.2.
1635 RDEBUGE("Disconnect-Request MUST NOT contain a Service-Type attribute");
1636 request->reply->code = PW_DISCONNECT_NAK;
1637 return RLM_MODULE_FAIL;
1640 rcode = module_recv_coa(0, request);
1642 case RLM_MODULE_FAIL:
1643 case RLM_MODULE_INVALID:
1644 case RLM_MODULE_REJECT:
1645 case RLM_MODULE_USERLOCK:
1647 request->reply->code = nak;
1650 case RLM_MODULE_HANDLED:
1653 case RLM_MODULE_NOOP:
1654 case RLM_MODULE_NOTFOUND:
1656 case RLM_MODULE_UPDATED:
1657 if (do_proxy(request)) return RLM_MODULE_OK;
1658 request->reply->code = ack;
1661 } else if (request->proxy_reply) {
1663 * Start the reply code with the proxy reply
1666 request->reply->code = request->proxy_reply->code;
1670 * Copy State from the request to the reply.
1671 * See RFC 5176 Section 3.3.
1673 vp = paircopy2(request->packet->vps, PW_STATE, 0, TAG_ANY);
1674 if (vp) pairadd(&request->reply->vps, vp);
1677 * We may want to over-ride the reply.
1679 if (request->reply->code) {
1680 rcode = module_send_coa(0, request);
1683 * We need to send CoA-NAK back if Service-Type
1684 * is Authorize-Only. Rely on the user's policy
1685 * to do that. We're not a real NAS, so this
1686 * restriction doesn't (ahem) apply to us.
1688 case RLM_MODULE_FAIL:
1689 case RLM_MODULE_INVALID:
1690 case RLM_MODULE_REJECT:
1691 case RLM_MODULE_USERLOCK:
1694 * Over-ride an ACK with a NAK
1696 request->reply->code = nak;
1699 case RLM_MODULE_HANDLED:
1702 case RLM_MODULE_NOOP:
1703 case RLM_MODULE_NOTFOUND:
1705 case RLM_MODULE_UPDATED:
1707 * Do NOT over-ride a previously set value.
1708 * Otherwise an "ok" here will re-write a
1711 if (request->reply->code == 0) {
1712 request->reply->code = ack;
1718 return RLM_MODULE_OK;
1723 * Check if an incoming request is "ok"
1725 * It takes packets, not requests. It sees if the packet looks
1726 * OK. If so, it does a number of sanity checks on it.
1728 static int coa_socket_recv(rad_listen_t *listener)
1732 RADIUS_PACKET *packet;
1733 RAD_REQUEST_FUNP fun = NULL;
1734 RADCLIENT *client = NULL;
1735 fr_ipaddr_t src_ipaddr;
1737 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
1738 if (rcode < 0) return 0;
1740 if (rcode < 20) { /* AUTH_HDR_LEN */
1741 FR_STATS_INC(coa, total_requests);
1742 FR_STATS_INC(coa, total_malformed_requests);
1746 if ((client = client_listener_find(listener,
1747 &src_ipaddr, src_port)) == NULL) {
1748 rad_recv_discard(listener->fd);
1749 FR_STATS_INC(coa, total_requests);
1750 FR_STATS_INC(coa, total_invalid_requests);
1755 * Some sanity checks, based on the packet code.
1758 case PW_COA_REQUEST:
1759 FR_STATS_INC(coa, total_requests);
1763 case PW_DISCONNECT_REQUEST:
1764 FR_STATS_INC(dsc, total_requests);
1769 rad_recv_discard(listener->fd);
1770 FR_STATS_INC(coa, total_unknown_types);
1771 DEBUG("Invalid packet code %d sent to coa port from client %s port %d : IGNORED",
1772 code, client->shortname, src_port);
1774 } /* switch over packet types */
1777 * Now that we've sanity checked everything, receive the
1780 packet = rad_recv(listener->fd, client->message_authenticator);
1782 FR_STATS_INC(coa, total_malformed_requests);
1783 DEBUG("%s", fr_strerror());
1787 if (!request_receive(listener, packet, client, fun)) {
1788 FR_STATS_INC(coa, total_packets_dropped);
1799 * Recieve packets from a proxy socket.
1801 static int proxy_socket_recv(rad_listen_t *listener)
1803 RADIUS_PACKET *packet;
1806 packet = rad_recv(listener->fd, 0);
1808 radlog(L_ERR, "%s", fr_strerror());
1813 * FIXME: Client MIB updates?
1815 switch(packet->code) {
1816 case PW_AUTHENTICATION_ACK:
1817 case PW_ACCESS_CHALLENGE:
1818 case PW_AUTHENTICATION_REJECT:
1821 #ifdef WITH_ACCOUNTING
1822 case PW_ACCOUNTING_RESPONSE:
1827 case PW_DISCONNECT_ACK:
1828 case PW_DISCONNECT_NAK:
1836 * FIXME: Update MIB for packet types?
1838 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1839 "from home server %s port %d - ID %d : IGNORED",
1841 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1842 packet->src_port, packet->id);
1847 if (!request_proxy_reply(packet)) {
1857 * Recieve packets from a proxy socket.
1859 static int proxy_socket_tcp_recv(rad_listen_t *listener)
1861 RADIUS_PACKET *packet;
1862 listen_socket_t *sock = listener->data;
1865 packet = fr_tcp_recv(listener->fd, 0);
1867 listener->status = RAD_LISTEN_STATUS_REMOVE_FD;
1868 event_new_fd(listener);
1873 * FIXME: Client MIB updates?
1875 switch(packet->code) {
1876 case PW_AUTHENTICATION_ACK:
1877 case PW_ACCESS_CHALLENGE:
1878 case PW_AUTHENTICATION_REJECT:
1881 #ifdef WITH_ACCOUNTING
1882 case PW_ACCOUNTING_RESPONSE:
1888 * FIXME: Update MIB for packet types?
1890 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
1891 "from home server %s port %d - ID %d : IGNORED",
1893 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
1894 packet->src_port, packet->id);
1899 packet->src_ipaddr = sock->other_ipaddr;
1900 packet->src_port = sock->other_port;
1901 packet->dst_ipaddr = sock->my_ipaddr;
1902 packet->dst_port = sock->my_port;
1905 * FIXME: Have it return an indication of packets that
1906 * are OK to ignore (dups, too late), versus ones that
1907 * aren't OK to ignore (unknown response, spoofed, etc.)
1909 * Close the socket on bad packets...
1911 if (!request_proxy_reply(packet)) {
1916 sock->opened = sock->last_packet = time(NULL);
1924 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1926 if (!request->reply->code) return 0;
1928 if (rad_encode(request->reply, request->packet,
1929 request->client->secret) < 0) {
1930 radlog_request(L_ERR, 0, request, "Failed encoding packet: %s",
1935 if (rad_sign(request->reply, request->packet,
1936 request->client->secret) < 0) {
1937 radlog_request(L_ERR, 0, request, "Failed signing packet: %s",
1946 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1948 if (rad_verify(request->packet, NULL,
1949 request->client->secret) < 0) {
1953 return rad_decode(request->packet, NULL,
1954 request->client->secret);
1958 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1960 if (rad_encode(request->proxy, NULL, request->home_server->secret) < 0) {
1961 radlog_request(L_ERR, 0, request, "Failed encoding proxied packet: %s",
1966 if (rad_sign(request->proxy, NULL, request->home_server->secret) < 0) {
1967 radlog_request(L_ERR, 0, request, "Failed signing proxied packet: %s",
1976 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1979 * rad_verify is run in event.c, received_proxy_response()
1982 return rad_decode(request->proxy_reply, request->proxy,
1983 request->home_server->secret);
1989 #include "command.c"
1991 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1993 { common_socket_parse, NULL,
1994 stats_socket_recv, auth_socket_send,
1995 socket_print, client_socket_encode, client_socket_decode },
1998 * This always gets defined.
2000 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
2005 { common_socket_parse, NULL,
2006 proxy_socket_recv, proxy_socket_send,
2007 socket_print, proxy_socket_encode, proxy_socket_decode },
2010 /* authentication */
2011 { common_socket_parse, NULL,
2012 auth_socket_recv, auth_socket_send,
2013 socket_print, client_socket_encode, client_socket_decode },
2015 #ifdef WITH_ACCOUNTING
2017 { common_socket_parse, NULL,
2018 acct_socket_recv, acct_socket_send,
2019 socket_print, client_socket_encode, client_socket_decode},
2024 { detail_parse, detail_free,
2025 detail_recv, detail_send,
2026 detail_print, detail_encode, detail_decode },
2030 /* vlan query protocol */
2031 { common_socket_parse, NULL,
2032 vqp_socket_recv, vqp_socket_send,
2033 socket_print, vqp_socket_encode, vqp_socket_decode },
2037 /* dhcp query protocol */
2038 { dhcp_socket_parse, NULL,
2039 dhcp_socket_recv, dhcp_socket_send,
2040 socket_print, dhcp_socket_encode, dhcp_socket_decode },
2043 #ifdef WITH_COMMAND_SOCKET
2044 /* TCP command socket */
2045 { command_socket_parse, command_socket_free,
2046 command_domain_accept, command_domain_send,
2047 command_socket_print, command_socket_encode, command_socket_decode },
2051 /* Change of Authorization */
2052 { common_socket_parse, NULL,
2053 coa_socket_recv, auth_socket_send, /* CoA packets are same as auth */
2054 socket_print, client_socket_encode, client_socket_decode },
2062 * Binds a listener to a socket.
2064 static int listen_bind(rad_listen_t *this)
2067 struct sockaddr_storage salocal;
2069 listen_socket_t *sock = this->data;
2071 #define proto_for_port "udp"
2072 #define sock_type SOCK_DGRAM
2074 const char *proto_for_port = "udp";
2075 int sock_type = SOCK_DGRAM;
2077 if (sock->proto == IPPROTO_TCP) {
2079 if (this->type == RAD_LISTEN_VQP) {
2080 radlog(L_ERR, "VQP does not support TCP transport");
2085 proto_for_port = "tcp";
2086 sock_type = SOCK_STREAM;
2091 * If the port is zero, then it means the appropriate
2092 * thing from /etc/services.
2094 if (sock->my_port == 0) {
2095 struct servent *svp;
2097 switch (this->type) {
2098 case RAD_LISTEN_AUTH:
2099 svp = getservbyname ("radius", proto_for_port);
2101 sock->my_port = ntohs(svp->s_port);
2103 sock->my_port = PW_AUTH_UDP_PORT;
2107 #ifdef WITH_ACCOUNTING
2108 case RAD_LISTEN_ACCT:
2109 svp = getservbyname ("radacct", proto_for_port);
2111 sock->my_port = ntohs(svp->s_port);
2113 sock->my_port = PW_ACCT_UDP_PORT;
2119 case RAD_LISTEN_PROXY:
2120 /* leave it at zero */
2125 case RAD_LISTEN_VQP:
2126 sock->my_port = 1589;
2130 #ifdef WITH_COMMAND_SOCKET
2131 case RAD_LISTEN_COMMAND:
2132 sock->my_port = PW_RADMIN_PORT;
2137 case RAD_LISTEN_COA:
2138 svp = getservbyname ("radius-dynauth", "udp");
2140 sock->my_port = ntohs(svp->s_port);
2142 sock->my_port = PW_COA_UDP_PORT;
2148 DEBUGW("Internal sanity check failed in binding to socket. Ignoring problem.");
2154 * Don't open sockets if we're checking the config.
2162 * Copy fr_socket() here, as we may need to bind to a device.
2164 this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
2168 this->print(this, buffer, sizeof(buffer));
2170 radlog(L_ERR, "Failed opening %s: %s", buffer, strerror(errno));
2176 * We don't want child processes inheriting these
2179 rcode = fcntl(this->fd, F_GETFD);
2181 if (fcntl(this->fd, F_SETFD, rcode | FD_CLOEXEC) < 0) {
2183 radlog(L_ERR, "Failed setting close on exec: %s", strerror(errno));
2190 * Bind to a device BEFORE touching IP addresses.
2192 if (sock->interface) {
2193 #ifdef SO_BINDTODEVICE
2196 memset(&ifreq, 0, sizeof(ifreq));
2197 strlcpy(ifreq.ifr_name, sock->interface, sizeof(ifreq.ifr_name));
2200 rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
2201 (char *)&ifreq, sizeof(ifreq));
2205 radlog(L_ERR, "Failed binding to interface %s: %s",
2206 sock->interface, strerror(errno));
2208 } /* else it worked. */
2210 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2211 #ifdef HAVE_NET_IF_H
2213 * Odds are that any system supporting "bind to
2214 * device" also supports IPv6, so this next bit
2215 * isn't necessary. But it's here for
2218 * If we're doing IPv6, and the scope hasn't yet
2219 * been defined, set the scope to the scope of
2222 if (sock->my_ipaddr.af == AF_INET6) {
2223 if (sock->my_ipaddr.scope == 0) {
2224 sock->my_ipaddr.scope = if_nametoindex(sock->interface);
2225 if (sock->my_ipaddr.scope == 0) {
2227 radlog(L_ERR, "Failed finding interface %s: %s",
2228 sock->interface, strerror(errno));
2231 } /* else scope was defined: we're OK. */
2236 * IPv4: no link local addresses,
2237 * and no bind to device.
2241 radlog(L_ERR, "Failed binding to interface %s: \"bind to device\" is unsupported", sock->interface);
2248 if (sock->proto == IPPROTO_TCP) {
2251 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2253 radlog(L_ERR, "Failed to reuse address: %s", strerror(errno));
2259 #if defined(WITH_TCP) && defined(WITH_UDPFROMTO)
2260 else /* UDP sockets get UDPfromto */
2263 #ifdef WITH_UDPFROMTO
2265 * Initialize udpfromto for all sockets.
2267 if (udpfromto_init(this->fd) != 0) {
2268 radlog(L_ERR, "Failed initializing udpfromto: %s",
2276 * Set up sockaddr stuff.
2278 if (!fr_ipaddr2sockaddr(&sock->my_ipaddr, sock->my_port, &salocal, &salen)) {
2283 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2284 if (sock->my_ipaddr.af == AF_INET6) {
2286 * Listening on '::' does NOT get you IPv4 to
2287 * IPv6 mapping. You've got to listen on an IPv4
2288 * address, too. This makes the rest of the server
2289 * design a little simpler.
2293 if (IN6_IS_ADDR_UNSPECIFIED(&sock->my_ipaddr.ipaddr.ip6addr)) {
2296 if (setsockopt(this->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2297 (char *)&on, sizeof(on)) < 0) {
2298 radlog(L_ERR, "Failed setting socket to IPv6 "
2299 "only: %s", strerror(errno));
2305 #endif /* IPV6_V6ONLY */
2307 #endif /* HAVE_STRUCT_SOCKADDR_IN6 */
2309 if (sock->my_ipaddr.af == AF_INET) {
2312 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
2314 * Disable PMTU discovery. On Linux, this
2315 * also makes sure that the "don't fragment"
2318 flag = IP_PMTUDISC_DONT;
2319 if (setsockopt(this->fd, IPPROTO_IP, IP_MTU_DISCOVER,
2320 &flag, sizeof(flag)) < 0) {
2321 radlog(L_ERR, "Failed disabling PMTU discovery: %s",
2329 #if defined(IP_DONTFRAG)
2331 * Ensure that the "don't fragment" flag is zero.
2334 if (setsockopt(this->fd, IPPROTO_IP, IP_DONTFRAG,
2335 &flag, sizeof(flag)) < 0) {
2336 radlog(L_ERR, "Failed setting don't fragment flag: %s",
2347 if (sock->broadcast) {
2350 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
2351 radlog(L_ERR, "Can't set broadcast option: %s",
2360 * May be binding to priviledged ports.
2362 if (sock->my_port != 0) {
2366 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
2367 radlog(L_ERR, "Can't set re-use address option: %s",
2374 rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
2380 this->print(this, buffer, sizeof(buffer));
2381 radlog(L_ERR, "Failed binding to %s: %s\n",
2382 buffer, strerror(errno));
2387 * FreeBSD jail issues. We bind to 0.0.0.0, but the
2388 * kernel instead binds us to a 1.2.3.4. If this
2389 * happens, notice, and remember our real IP.
2392 struct sockaddr_storage src;
2393 socklen_t sizeof_src = sizeof(src);
2395 memset(&src, 0, sizeof_src);
2396 if (getsockname(this->fd, (struct sockaddr *) &src,
2398 radlog(L_ERR, "Failed getting socket name: %s",
2403 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2404 &sock->my_ipaddr, &sock->my_port)) {
2405 radlog(L_ERR, "Socket has unsupported address family");
2412 if (sock->proto == IPPROTO_TCP) {
2413 if (listen(this->fd, 8) < 0) {
2415 radlog(L_ERR, "Failed in listen(): %s", strerror(errno));
2421 if (fr_nonblock(this->fd) < 0) {
2423 radlog(L_ERR, "Failed setting non-blocking on socket: %s",
2429 * Mostly for proxy sockets.
2431 sock->other_ipaddr.af = sock->my_ipaddr.af;
2434 * Don't screw up other people.
2436 #undef proto_for_port
2443 static int listener_free(void *ctx)
2447 this = talloc_get_type_abort(ctx, rad_listen_t);
2450 * Other code may have eaten the FD.
2452 if (this->fd >= 0) close(this->fd);
2454 if (master_listen[this->type].free) {
2455 master_listen[this->type].free(this);
2459 if ((this->type == RAD_LISTEN_AUTH)
2461 || (this->type == RAD_LISTEN_ACCT)
2464 || (this->type == RAD_LISTEN_PROXY)
2466 #ifdef WITH_COMMAND_SOCKET
2467 || ((this->type == RAD_LISTEN_COMMAND) &&
2468 (((fr_command_socket_t *) this->data)->magic != COMMAND_SOCKET_MAGIC))
2471 listen_socket_t *sock = this->data;
2474 if (sock->request) {
2475 pthread_mutex_destroy(&(sock->mutex));
2476 request_free(&sock->request);
2477 sock->packet = NULL;
2479 if (sock->ssn) session_free(sock->ssn);
2480 request_free(&sock->request);
2483 rad_free(&sock->packet);
2485 #endif /* WITH_TCP */
2491 * Allocate & initialize a new listener.
2493 static rad_listen_t *listen_alloc(TALLOC_CTX *ctx, RAD_LISTEN_TYPE type)
2497 this = talloc_zero(ctx, rad_listen_t);
2500 this->recv = master_listen[this->type].recv;
2501 this->send = master_listen[this->type].send;
2502 this->print = master_listen[this->type].print;
2503 this->encode = master_listen[this->type].encode;
2504 this->decode = master_listen[this->type].decode;
2506 talloc_set_destructor((void *) this, listener_free);
2510 case RAD_LISTEN_NONE:
2512 case RAD_LISTEN_AUTH:
2513 #ifdef WITH_ACCOUNTING
2514 case RAD_LISTEN_ACCT:
2517 case RAD_LISTEN_PROXY:
2520 case RAD_LISTEN_VQP:
2523 case RAD_LISTEN_COA:
2525 this->data = talloc_zero(this, listen_socket_t);
2529 case RAD_LISTEN_DHCP:
2530 this->data = talloc_zero(this, dhcp_socket_t);
2535 case RAD_LISTEN_DETAIL:
2540 #ifdef WITH_COMMAND_SOCKET
2541 case RAD_LISTEN_COMMAND:
2542 this->data = talloc_zero(this, fr_command_socket_t);
2547 rad_assert("Unsupported option!" == NULL);
2556 * Externally visible function for creating a new proxy LISTENER.
2558 * Not thread-safe, but all calls to it are protected by the
2559 * proxy mutex in event.c
2561 rad_listen_t *proxy_new_listener(home_server *home, int src_port)
2564 listen_socket_t *sock;
2567 if (!home) return NULL;
2569 if ((home->limit.max_connections > 0) &&
2570 (home->limit.num_connections >= home->limit.max_connections)) {
2571 DEBUGW("Home server has too many open connections (%d)",
2572 home->limit.max_connections);
2576 this = listen_alloc(mainconfig.config, RAD_LISTEN_PROXY);
2579 sock->other_ipaddr = home->ipaddr;
2580 sock->other_port = home->port;
2583 sock->my_ipaddr = home->src_ipaddr;
2584 sock->my_port = src_port;
2585 sock->proto = home->proto;
2587 if (debug_flag >= 2) {
2588 this->print(this, buffer, sizeof(buffer));
2589 DEBUG("Opening new %s", buffer);
2593 sock->opened = sock->last_packet = time(NULL);
2595 if (home->proto == IPPROTO_TCP) {
2596 this->recv = proxy_socket_tcp_recv;
2599 * FIXME: connect() is blocking!
2600 * We do this with the proxy mutex locked, which may
2601 * cause large delays!
2603 * http://www.developerweb.net/forum/showthread.php?p=13486
2605 this->fd = fr_tcp_client_socket(&home->src_ipaddr,
2606 &home->ipaddr, home->port);
2609 DEBUG("Trying SSL to port %d\n", home->port);
2610 sock->ssn = tls_new_client_session(home->tls, this->fd);
2616 this->recv = proxy_tls_recv;
2617 this->send = proxy_tls_send;
2622 this->fd = fr_socket(&home->src_ipaddr, src_port);
2625 this->print(this, buffer,sizeof(buffer));
2626 DEBUG("Failed opening client socket ::%s:: : %s",
2627 buffer, fr_strerror());
2633 * Figure out which port we were bound to.
2635 if (sock->my_port == 0) {
2636 struct sockaddr_storage src;
2637 socklen_t sizeof_src = sizeof(src);
2639 memset(&src, 0, sizeof_src);
2640 if (getsockname(this->fd, (struct sockaddr *) &src,
2642 radlog(L_ERR, "Failed getting socket name: %s",
2648 if (!fr_sockaddr2ipaddr(&src, sizeof_src,
2649 &sock->my_ipaddr, &sock->my_port)) {
2650 radlog(L_ERR, "Socket has unsupported address family");
2661 static const FR_NAME_NUMBER listen_compare[] = {
2663 { "status", RAD_LISTEN_NONE },
2665 { "auth", RAD_LISTEN_AUTH },
2666 #ifdef WITH_ACCOUNTING
2667 { "acct", RAD_LISTEN_ACCT },
2670 { "detail", RAD_LISTEN_DETAIL },
2673 { "proxy", RAD_LISTEN_PROXY },
2676 { "vmps", RAD_LISTEN_VQP },
2679 { "dhcp", RAD_LISTEN_DHCP },
2681 #ifdef WITH_COMMAND_SOCKET
2682 { "control", RAD_LISTEN_COMMAND },
2685 { "coa", RAD_LISTEN_COA },
2691 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
2699 cf_log_info(cs, "listen {");
2701 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
2703 if (rcode < 0) return NULL;
2705 cf_log_err(cf_sectiontoitem(cs),
2706 "No type specified in listen section");
2710 type = fr_str2int(listen_compare, listen_type, -1);
2712 cf_log_err(cf_sectiontoitem(cs),
2713 "Invalid type \"%s\" in listen section.",
2719 * Allow listen sections in the default config to
2720 * refer to a server.
2723 rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
2725 if (rcode == 1) { /* compatiblity with 2.0-pre */
2726 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
2729 if (rcode < 0) return NULL;
2734 * We were passed a virtual server, so the caller is
2735 * defining a proxy listener inside of a virtual server.
2736 * This isn't allowed right now.
2738 else if (type == RAD_LISTEN_PROXY) {
2739 radlog(L_ERR, "Error: listen type \"proxy\" Cannot appear in a virtual server section");
2745 * Set up cross-type data.
2747 this = listen_alloc(cs, type);
2748 this->server = server;
2752 * Call per-type parser.
2754 if (master_listen[type].parse(cs, this) < 0) {
2759 cf_log_info(cs, "}");
2765 static int is_loopback(const fr_ipaddr_t *ipaddr)
2768 * We shouldn't proxy on loopback.
2770 if ((ipaddr->af == AF_INET) &&
2771 (ipaddr->ipaddr.ip4addr.s_addr == htonl(INADDR_LOOPBACK))) {
2775 #ifdef HAVE_STRUCT_SOCKADDR_IN6
2776 if ((ipaddr->af == AF_INET6) &&
2777 (IN6_IS_ADDR_LINKLOCAL(&ipaddr->ipaddr.ip6addr))) {
2787 * Generate a list of listeners. Takes an input list of
2788 * listeners, too, so we don't close sockets with waiting packets.
2790 int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
2792 int override = FALSE;
2793 CONF_SECTION *cs = NULL;
2794 rad_listen_t **last;
2796 fr_ipaddr_t server_ipaddr;
2799 int defined_proxy = 0;
2802 spawn_flag = spawn_flag; /* -Wunused */
2806 * We shouldn't be called with a pre-existing list.
2808 rad_assert(head && (*head == NULL));
2811 server_ipaddr.af = AF_UNSPEC;
2814 * If the port is specified on the command-line,
2815 * it over-rides the configuration file.
2817 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
2819 if (mainconfig.port >= 0) {
2820 auth_port = mainconfig.port;
2823 * -p X but no -i Y on the command-line.
2825 if ((mainconfig.port > 0) &&
2826 (mainconfig.myip.af == AF_UNSPEC)) {
2827 radlog(L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
2834 * If the IP address was configured on the command-line,
2835 * use that as the "bind_address"
2837 if (mainconfig.myip.af != AF_UNSPEC) {
2838 listen_socket_t *sock;
2840 memcpy(&server_ipaddr, &mainconfig.myip,
2841 sizeof(server_ipaddr));
2845 if (strcmp(progname, "vmpsd") == 0) {
2846 this = listen_alloc(config, RAD_LISTEN_VQP);
2847 if (!auth_port) auth_port = 1589;
2850 this = listen_alloc(config, RAD_LISTEN_AUTH);
2854 sock->my_ipaddr = server_ipaddr;
2855 sock->my_port = auth_port;
2857 sock->clients = clients_parse_section(config);
2858 if (!sock->clients) {
2859 cf_log_err(cf_sectiontoitem(config),
2860 "Failed to find any clients for this listen section");
2865 if (listen_bind(this) < 0) {
2867 radlog(L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->my_port);
2871 auth_port = sock->my_port; /* may have been updated in listen_bind */
2873 cs = cf_section_sub_find_name2(config, "server",
2875 if (cs) this->server = mainconfig.name;
2879 last = &(this->next);
2885 if (strcmp(progname, "vmpsd") == 0) goto add_sockets;
2888 #ifdef WITH_ACCOUNTING
2890 * Open Accounting Socket.
2892 * If we haven't already gotten acct_port from
2893 * /etc/services, then make it auth_port + 1.
2895 this = listen_alloc(config, RAD_LISTEN_ACCT);
2899 * Create the accounting socket.
2901 * The accounting port is always the
2902 * authentication port + 1
2904 sock->my_ipaddr = server_ipaddr;
2905 sock->my_port = auth_port + 1;
2907 sock->clients = clients_parse_section(config);
2908 if (!sock->clients) {
2909 cf_log_err(cf_sectiontoitem(config),
2910 "Failed to find any clients for this listen section");
2914 if (listen_bind(this) < 0) {
2917 radlog(L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->my_port);
2922 cs = cf_section_sub_find_name2(config, "server",
2924 if (cs) this->server = mainconfig.name;
2928 last = &(this->next);
2933 * They specified an IP on the command-line, ignore
2934 * all listen sections except the one in '-n'.
2936 if (mainconfig.myip.af != AF_UNSPEC) {
2937 CONF_SECTION *subcs;
2938 const char *name2 = cf_section_name2(cs);
2940 cs = cf_section_sub_find_name2(config, "server",
2942 if (!cs) goto add_sockets;
2945 * Should really abstract this code...
2947 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2949 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2950 this = listen_parse(subcs, name2);
2957 last = &(this->next);
2958 } /* loop over "listen" directives in server <foo> */
2964 * Walk through the "listen" sections, if they exist.
2966 for (cs = cf_subsection_find_next(config, NULL, "listen");
2968 cs = cf_subsection_find_next(config, cs, "listen")) {
2969 this = listen_parse(cs, NULL);
2976 last = &(this->next);
2980 * Check virtual servers for "listen" sections, too.
2982 * FIXME: Move to virtual server init?
2984 for (cs = cf_subsection_find_next(config, NULL, "server");
2986 cs = cf_subsection_find_next(config, cs, "server")) {
2987 CONF_SECTION *subcs;
2988 const char *name2 = cf_section_name2(cs);
2990 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
2992 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
2993 this = listen_parse(subcs, name2);
3000 last = &(this->next);
3001 } /* loop over "listen" directives in virtual servers */
3002 } /* loop over virtual servers */
3006 * No sockets to receive packets, this is an error.
3007 * proxying is pointless.
3010 radlog(L_ERR, "The server is not configured to listen on any ports. Cannot start.");
3015 * Print out which sockets we're listening on, and
3016 * add them to the event list.
3018 for (this = *head; this != NULL; this = this->next) {
3020 if (this->type == RAD_LISTEN_PROXY) {
3027 if (!spawn_flag && this->tls) {
3028 cf_log_err(cf_sectiontoitem(this->cs), "Threading must be enabled for TLS sockets to function properly.");
3029 cf_log_err(cf_sectiontoitem(this->cs), "You probably need to do 'radiusd -fxx -l stdout' for debugging");
3033 if (!check_config) event_new_fd(this);
3037 * If we're proxying requests, open the proxy FD.
3038 * Otherwise, don't do anything.
3041 if ((mainconfig.proxy_requests == TRUE) &&
3043 (*head != NULL) && !defined_proxy) {
3044 listen_socket_t *sock = NULL;
3048 memset(&home, 0, sizeof(home));
3053 home.proto = IPPROTO_UDP;
3054 home.src_ipaddr = server_ipaddr;
3057 * Find the first authentication port,
3060 for (this = *head; this != NULL; this = this->next) {
3061 if (this->type == RAD_LISTEN_AUTH) {
3064 if (is_loopback(&sock->my_ipaddr)) continue;
3066 if (home.src_ipaddr.af == AF_UNSPEC) {
3067 home.src_ipaddr = sock->my_ipaddr;
3069 port = sock->my_port + 2;
3073 if (this->type == RAD_LISTEN_ACCT) {
3076 if (is_loopback(&sock->my_ipaddr)) continue;
3078 if (home.src_ipaddr.af == AF_UNSPEC) {
3079 home.src_ipaddr = sock->my_ipaddr;
3081 port = sock->my_port + 1;
3088 * Address is still unspecified, use IPv4.
3090 if (home.src_ipaddr.af == AF_UNSPEC) {
3091 home.src_ipaddr.af = AF_INET;
3092 /* everything else is already set to zero */
3095 home.ipaddr.af = home.src_ipaddr.af;
3096 /* everything else is already set to zero */
3098 this = proxy_new_listener(&home, port);
3104 if (!event_new_fd(this)) {
3113 * Haven't defined any sockets. Die.
3115 if (!*head) return -1;
3117 xlat_register("listen", xlat_listen, NULL);
3123 * Free a linked list of listeners;
3125 void listen_free(rad_listen_t **head)
3129 if (!head || !*head) return;
3133 rad_listen_t *next = this->next;
3142 RADCLIENT_LIST *listener_find_client_list(const fr_ipaddr_t *ipaddr,
3147 for (this = mainconfig.listen; this != NULL; this = this->next) {
3148 listen_socket_t *sock;
3150 if ((this->type != RAD_LISTEN_AUTH)
3151 #ifdef WITH_ACCOUNTING
3152 && (this->type != RAD_LISTEN_ACCT)
3158 if ((sock->my_port == port) &&
3159 (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) == 0)) {
3160 return sock->clients;
3168 rad_listen_t *listener_find_byipaddr(const fr_ipaddr_t *ipaddr, int port, int proto)
3172 for (this = mainconfig.listen; this != NULL; this = this->next) {
3173 listen_socket_t *sock;
3177 if (sock->my_port != port) continue;
3178 if (sock->proto != proto) continue;
3179 if (fr_ipaddr_cmp(ipaddr, &sock->my_ipaddr) != 0) continue;
3185 * Failed to find a specific one. Find INADDR_ANY
3187 for (this = mainconfig.listen; this != NULL; this = this->next) {
3188 listen_socket_t *sock;
3192 if (sock->my_port != port) continue;
3193 if (sock->proto != proto) continue;
3194 if (!fr_inaddr_any(&sock->my_ipaddr)) continue;