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/radius_snmp.h>
29 #include <freeradius-devel/modules.h>
30 #include <freeradius-devel/rad_assert.h>
31 #include <freeradius-devel/vqp.h>
33 #include <sys/resource.h>
39 #ifdef HAVE_SYS_STAT_H
45 #define USEC (1000000)
48 * We'll use this below.
50 typedef int (*rad_listen_parse_t)(CONF_SECTION *, rad_listen_t *);
51 typedef void (*rad_listen_free_t)(rad_listen_t *);
53 typedef struct rad_listen_master_t {
54 rad_listen_parse_t parse;
55 rad_listen_free_t free;
56 rad_listen_recv_t recv;
57 rad_listen_send_t send;
58 rad_listen_print_t print;
59 rad_listen_encode_t encode;
60 rad_listen_decode_t decode;
61 } rad_listen_master_t;
63 typedef struct listen_socket_t {
69 RADCLIENT_LIST *clients;
72 typedef struct listen_detail_t {
78 lrad_ipaddr_t client_ip;
79 int load_factor; /* 1..100 */
85 struct timeval last_packet;
90 * Find a per-socket client.
92 static RADCLIENT *client_listener_find(const rad_listen_t *listener,
93 const lrad_ipaddr_t *ipaddr)
95 const RADCLIENT_LIST *clients;
97 rad_assert(listener != NULL);
98 rad_assert(ipaddr != NULL);
100 rad_assert((listener->type == RAD_LISTEN_AUTH) ||
101 (listener->type == RAD_LISTEN_ACCT) ||
102 (listener->type == RAD_LISTEN_VQP));
104 clients = ((listen_socket_t *)listener->data)->clients;
105 if (!clients) clients = mainconfig.clients;
107 rad_assert(clients != NULL);
109 return client_find(clients, ipaddr);
112 static int listen_bind(rad_listen_t *this);
115 * Process and reply to a server-status request.
116 * Like rad_authenticate and rad_accounting this should
117 * live in it's own file but it's so small we don't bother.
119 static int rad_status_server(REQUEST *request)
121 int rcode = RLM_MODULE_OK;
124 switch (request->listener->type) {
125 case RAD_LISTEN_AUTH:
126 dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
128 rcode = module_authorize(dval->value, request);
130 rcode = RLM_MODULE_OK;
135 case RLM_MODULE_UPDATED:
136 request->reply->code = PW_AUTHENTICATION_ACK;
139 case RLM_MODULE_FAIL:
140 case RLM_MODULE_HANDLED:
141 request->reply->code = 0; /* don't reply */
145 case RLM_MODULE_REJECT:
146 request->reply->code = PW_AUTHENTICATION_REJECT;
151 case RAD_LISTEN_ACCT:
152 dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
154 rcode = module_accounting(dval->value, request);
156 rcode = RLM_MODULE_OK;
161 case RLM_MODULE_UPDATED:
162 request->reply->code = PW_ACCOUNTING_RESPONSE;
166 request->reply->code = 0; /* don't reply */
179 static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
182 listen_socket_t *sock = this->data;
184 if ((sock->ipaddr.af == AF_INET) &&
185 (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
188 ip_ntoh(&sock->ipaddr, buffer, bufsize);
191 len = strlen(buffer);
194 return len + snprintf(buffer + len, bufsize - len, " port %d",
198 return len + snprintf(buffer + len, bufsize - len, " port %d as server %s",
199 sock->port, this->server);
204 * Parse an authentication or accounting socket.
206 static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
210 lrad_ipaddr_t ipaddr;
211 listen_socket_t *sock = this->data;
212 const char *section_name = NULL;
213 CONF_SECTION *client_cs;
218 ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
219 rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
220 &ipaddr.ipaddr.ip4addr, NULL);
221 if (rcode < 0) return -1;
223 if (rcode == 0) { /* successfully parsed IPv4 */
226 } else { /* maybe IPv6? */
227 rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
228 &ipaddr.ipaddr.ip6addr, NULL);
229 if (rcode < 0) return -1;
232 radlog(L_ERR, "%s[%d]: No address specified in listen section",
233 cf_section_filename(cs), cf_section_lineno(cs));
236 ipaddr.af = AF_INET6;
239 rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
241 if (rcode < 0) return -1;
243 sock->ipaddr = ipaddr;
244 sock->port = listen_port;
247 * And bind it to the port.
249 if (listen_bind(this) < 0) {
251 radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
252 cf_section_filename(cs), cf_section_lineno(cs),
253 ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
259 * If we can bind to interfaces, do so,
262 if (cf_pair_find(cs, "interface")) {
263 #ifndef SO_BINDTODEVICE
264 radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
265 cf_section_filename(cs), cf_section_lineno(cs));
269 CONF_PAIR *cp = cf_pair_find(cs, "interface");
272 rad_assert(cp != NULL);
273 value = cf_pair_value(cp);
275 radlog(L_CONS|L_ERR, "%s[%d]: No interface name given",
276 cf_section_filename(cs), cf_section_lineno(cs));
280 strcpy(ifreq.ifr_name, value);
282 if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
283 (char *)&ifreq, sizeof(ifreq)) < 0) {
284 radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
285 cf_section_filename(cs), cf_section_lineno(cs),
286 value, strerror(errno));
288 } /* else it worked. */
293 * If we have a server, prefer to use clients defined
294 * in that server, and ignore any "clients = "
295 * directive, UNLESS there are no clients in the server.
298 client_cs = cf_section_sub_find_name2(mainconfig.config,
303 * Found a "server foo" section, but there are no
304 * clients in it. Don't use this section.
307 (cf_section_sub_find(client_cs, "client") == NULL)) {
312 * No clients, look for the name of a section that holds
316 rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
317 §ion_name, NULL);
318 if (rcode < 0) return -1; /* bad string */
321 * Explicit list given: use it.
323 client_cs = cf_section_find(section_name);
326 radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
327 cf_section_filename(cs), cf_section_lineno(cs), section_name);
330 } /* else there was no "clients = " entry. */
334 * Still nothing. Make it global.
336 if (!client_cs) client_cs = mainconfig.config;
338 sock->clients = clients_parse_section(client_cs);
339 if (!sock->clients) {
347 * Send an authentication response packet
349 static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
351 rad_assert(request->listener == listener);
352 rad_assert(listener->send == auth_socket_send);
354 return rad_send(request->reply, request->packet,
355 request->client->secret);
360 * Send an accounting response packet (or not)
362 static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
364 rad_assert(request->listener == listener);
365 rad_assert(listener->send == acct_socket_send);
368 * Accounting reject's are silently dropped.
370 * We do it here to avoid polluting the rest of the
371 * code with this knowledge
373 if (request->reply->code == 0) return 0;
375 return rad_send(request->reply, request->packet,
376 request->client->secret);
381 * Send a packet to a home server.
383 * FIXME: have different code for proxy auth & acct!
385 static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
387 listen_socket_t *sock = listener->data;
389 rad_assert(request->proxy_listener == listener);
390 rad_assert(listener->send == proxy_socket_send);
392 request->proxy->src_ipaddr = sock->ipaddr;
393 request->proxy->src_port = sock->port;
395 return rad_send(request->proxy, request->packet,
396 request->home_server->secret);
401 * Check if an incoming request is "ok"
403 * It takes packets, not requests. It sees if the packet looks
404 * OK. If so, it does a number of sanity checks on it.
406 static int auth_socket_recv(rad_listen_t *listener,
407 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
411 RADIUS_PACKET *packet;
412 RAD_REQUEST_FUNP fun = NULL;
415 lrad_ipaddr_t src_ipaddr;
417 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
418 if (rcode < 0) return 0;
420 RAD_SNMP_TYPE_INC(listener, total_requests);
422 if (rcode < 20) { /* AUTH_HDR_LEN */
423 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
427 if ((client = client_listener_find(listener,
428 &src_ipaddr)) == NULL) {
429 rad_recv_discard(listener->fd);
430 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
433 * This is debugging rather than logging, so that
434 * DoS attacks don't affect us.
436 DEBUG("Ignoring request from unknown client %s port %d",
437 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
438 buffer, sizeof(buffer)), src_port);
443 * Some sanity checks, based on the packet code.
446 case PW_AUTHENTICATION_REQUEST:
447 RAD_SNMP_CLIENT_INC(listener, client, requests);
448 fun = rad_authenticate;
451 case PW_STATUS_SERVER:
452 if (!mainconfig.status_server) {
453 rad_recv_discard(listener->fd);
454 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
455 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
456 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
459 fun = rad_status_server;
463 rad_recv_discard(listener->fd);
464 RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
465 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
467 DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
468 code, client->shortname, src_port);
471 } /* switch over packet types */
474 * Now that we've sanity checked everything, receive the
477 packet = rad_recv(listener->fd);
479 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
480 radlog(L_ERR, "%s", librad_errstr);
484 if (!received_request(listener, packet, prequest, client)) {
485 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
486 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
497 * Receive packets from an accounting socket
499 static int acct_socket_recv(rad_listen_t *listener,
500 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
504 RADIUS_PACKET *packet;
505 RAD_REQUEST_FUNP fun = NULL;
508 lrad_ipaddr_t src_ipaddr;
510 rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
511 if (rcode < 0) return 0;
513 RAD_SNMP_TYPE_INC(listener, total_requests);
515 if (rcode < 20) { /* AUTH_HDR_LEN */
516 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
520 if ((client = client_listener_find(listener,
521 &src_ipaddr)) == NULL) {
522 rad_recv_discard(listener->fd);
523 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
526 * This is debugging rather than logging, so that
527 * DoS attacks don't affect us.
529 DEBUG("Ignoring request from unknown client %s port %d",
530 inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
531 buffer, sizeof(buffer)), src_port);
536 * Some sanity checks, based on the packet code.
539 case PW_ACCOUNTING_REQUEST:
540 RAD_SNMP_CLIENT_INC(listener, client, requests);
541 fun = rad_accounting;
544 case PW_STATUS_SERVER:
545 if (!mainconfig.status_server) {
546 rad_recv_discard(listener->fd);
547 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
548 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
550 DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
553 fun = rad_status_server;
557 rad_recv_discard(listener->fd);
558 RAD_SNMP_TYPE_INC(listener, total_unknown_types);
559 RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
561 DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
562 code, client->shortname, src_port);
564 } /* switch over packet types */
567 * Now that we've sanity checked everything, receive the
570 packet = rad_recv(listener->fd);
572 RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
573 radlog(L_ERR, "%s", librad_errstr);
578 * There can be no duplicate accounting packets.
580 if (!received_request(listener, packet, prequest, client)) {
581 RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
582 RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
593 * Recieve packets from a proxy socket.
595 static int proxy_socket_recv(rad_listen_t *listener,
596 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
599 RADIUS_PACKET *packet;
600 RAD_REQUEST_FUNP fun = NULL;
603 packet = rad_recv(listener->fd);
605 radlog(L_ERR, "%s", librad_errstr);
610 * FIXME: Client MIB updates?
612 switch(packet->code) {
613 case PW_AUTHENTICATION_ACK:
614 case PW_ACCESS_CHALLENGE:
615 case PW_AUTHENTICATION_REJECT:
616 fun = rad_authenticate;
619 case PW_ACCOUNTING_RESPONSE:
620 fun = rad_accounting;
625 * FIXME: Update MIB for packet types?
627 radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
628 "from home server %s port %d - ID %d : IGNORED",
630 ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
631 packet->src_port, packet->id);
636 request = received_proxy_response(packet);
641 rad_assert(fun != NULL);
649 static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
651 if (!request->reply->code) return 0;
653 rad_encode(request->reply, request->packet,
654 request->client->secret);
655 rad_sign(request->reply, request->packet,
656 request->client->secret);
662 static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
664 if (rad_verify(request->packet, NULL,
665 request->client->secret) < 0) {
669 return rad_decode(request->packet, NULL,
670 request->client->secret);
673 static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
675 rad_encode(request->proxy, NULL, request->home_server->secret);
676 rad_sign(request->proxy, NULL, request->home_server->secret);
682 static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
684 if (rad_verify(request->proxy_reply, request->proxy,
685 request->home_server->secret) < 0) {
689 return rad_decode(request->proxy_reply, request->proxy,
690 request->home_server->secret);
694 #define STATE_UNOPENED (0)
695 #define STATE_UNLOCKED (1)
696 #define STATE_HEADER (2)
697 #define STATE_READING (3)
698 #define STATE_QUEUED (4)
699 #define STATE_RUNNING (5)
700 #define STATE_NO_REPLY (6)
701 #define STATE_REPLIED (7)
704 * If we're limiting outstanding packets, then mark the response
707 static int detail_send(rad_listen_t *listener, REQUEST *request)
711 listen_detail_t *data = listener->data;
713 rad_assert(request->listener == listener);
714 rad_assert(listener->send == detail_send);
717 * This request timed out. Remember that, and tell the
718 * caller it's OK to read more "detail" file stuff.
720 if (request->reply->code == 0) {
721 radius_signal_self(RADIUS_SIGNAL_SELF_DETAIL);
722 data->state = STATE_NO_REPLY;
727 * We call gettimeofday a lot. But here it should be OK,
728 * because there's nothing else to do.
730 gettimeofday(&now, NULL);
733 * If we haven't sent a packet in the last second, reset
737 if (timercmp(&data->last_packet, &now, <)) {
738 data->has_rtt = FALSE;
743 * Only one detail packet may be outstanding at a time,
744 * so it's safe to update some entries in the detail
747 * We keep smoothed round trip time (SRTT), but not round
748 * trip timeout (RTO). We use SRTT to calculate a rough
751 rtt = now.tv_sec - request->received.tv_sec;
754 rtt -= request->received.tv_usec;
757 * If we're proxying, the RTT is our processing time,
758 * plus the network delay there and back, plus the time
759 * on the other end to process the packet. Ideally, we
760 * should remove the network delays from the RTT, but we
761 * don't know what they are.
763 * So, to be safe, we over-estimate the total cost of
764 * processing the packet.
766 if (!data->has_rtt) {
767 data->has_rtt = TRUE;
769 data->rttvar = rtt / 2;
772 data->rttvar -= data->rttvar >> 2;
773 data->rttvar += (data->srtt - rtt);
774 data->srtt -= data->srtt >> 3;
775 data->srtt += rtt >> 3;
779 * Calculate the time we wait before sending the next
782 * rtt / (rtt + delay) = load_factor / 100
784 data->delay_time = (data->srtt * (100 - data->load_factor)) / (data->load_factor);
787 * FIXME: Push this delay to the event handler!
789 DEBUG2("RTT %d\tdelay %d", data->srtt, data->delay_time);
791 usleep(data->delay_time);
792 data->last_packet = now;
793 data->state = STATE_REPLIED;
800 * Open the detail file..
802 * FIXME: create it, if it's not already there, so that the main
803 * server select() will wake us up if there's anything to read.
805 static int detail_open(rad_listen_t *this)
809 listen_detail_t *data = this->data;
811 rad_assert(data->state == STATE_UNOPENED);
812 snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
815 * Open detail.work first, so we don't lose
816 * accounting packets. It's probably better to
817 * duplicate them than to lose them.
819 * Note that we're not writing to the file, but
820 * we've got to open it for writing in order to
821 * establish the lock, to prevent rlm_detail from
824 this->fd = open(buffer, O_RDWR);
827 * Try reading the detail file. If it
828 * doesn't exist, we can't do anything.
830 * Doing the stat will tell us if the file
831 * exists, even if we don't have permissions
834 if (stat(data->filename, &st) < 0) {
839 * Open it BEFORE we rename it, just to
842 this->fd = open(data->filename, O_RDWR);
844 radlog(L_ERR, "Failed to open %s: %s",
845 data->filename, strerror(errno));
850 * Rename detail to detail.work
852 if (rename(data->filename, buffer) < 0) {
857 } /* else detail.work existed, and we opened it */
859 rad_assert(data->vps == NULL);
861 rad_assert(data->fp == NULL);
862 data->fp = fdopen(this->fd, "r");
864 radlog(L_ERR, "Failed to re-open %s: %s",
865 data->filename, strerror(errno));
869 data->state = STATE_UNLOCKED;
871 data->client_ip.af = AF_UNSPEC;
878 * FIXME: this should be dynamically allocated.
880 static const RADCLIENT detail_client = {
899 * FIXME: add a configuration "exit when done" so that the detail
900 * file reader can be used as a one-off tool to update stuff.
902 * The time sequence for reading from the detail file is:
904 * t_0 signalled that the server is idle, and we
905 * can read from the detail file.
907 * t_rtt the packet has been processed successfully,
908 * wait for t_delay to enforce load factor.
910 * t_rtt + t_delay wait for signal that the server is idle.
913 static int detail_recv(rad_listen_t *listener,
914 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
916 char key[256], value[1024];
917 VALUE_PAIR *vp, **tail;
918 RADIUS_PACKET *packet;
920 listen_detail_t *data = listener->data;
922 switch (data->state) {
924 rad_assert(listener->fd < 0);
927 * FIXME: If the file doesn't exist, then
928 * return "sleep for 1s", to avoid busy
931 if (!detail_open(listener)) return 0;
933 rad_assert(data->state == STATE_UNLOCKED);
934 rad_assert(listener->fd >= 0);
939 * Try to lock fd. If we can't, return.
940 * If we can, continue. This means that
941 * the server doesn't block while waiting
942 * for the lock to open...
946 * Note that we do NOT block waiting for
947 * the lock. We've re-named the file
948 * above, so we've already guaranteed
949 * that any *new* detail writer will not
950 * be opening this file. The only
951 * purpose of the lock is to catch a race
952 * condition where the execution
953 * "ping-pongs" between radiusd &
956 if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
960 * Look for the header
962 data->state = STATE_HEADER;
970 * End of file. Delete it, and re-set
973 if (feof(data->fp)) {
975 snprintf(buffer, sizeof(buffer),
976 "%s.work", data->filename);
978 fclose(data->fp); /* closes listener->fd */
981 data->state = STATE_UNOPENED;
982 rad_assert(data->vps == NULL);
987 * Else go read something.
992 * Read more value-pair's, unless we're
993 * at EOF. In that case, queue whatever
997 if (!feof(data->fp)) break;
998 data->state = STATE_QUEUED;
1006 * We still have an outstanding packet.
1007 * Don't read any more.
1013 * If there's no reply, keep
1014 * retransmitting the current packet
1017 case STATE_NO_REPLY:
1018 data->state = STATE_QUEUED;
1022 * We have a reply. Clean up the old
1023 * request, and go read another one.
1026 pairfree(&data->vps);
1027 data->state = STATE_HEADER;
1032 while (*tail) tail = &(*tail)->next;
1035 * Read a header, OR a value-pair.
1037 while (fgets(buffer, sizeof(buffer), data->fp)) {
1039 * Badly formatted file: delete it.
1041 * FIXME: Maybe flag an error?
1043 if (!strchr(buffer, '\n')) {
1044 pairfree(&data->vps);
1049 * We're reading VP's, and got a blank line.
1052 if ((data->state == STATE_READING) &&
1053 (buffer[0] == '\n')) {
1054 data->state = STATE_QUEUED;
1059 * Look for date/time header, and read VP's if
1060 * found. If not, keep reading lines until we
1063 if (data->state == STATE_HEADER) {
1066 if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
1067 data->state = STATE_READING;
1073 * We have a full "attribute = value" line.
1074 * If it doesn't look reasonable, skip it.
1076 * FIXME: print an error for badly formatted attributes?
1078 if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
1083 * Skip non-protocol attributes.
1085 if (!strcasecmp(key, "Request-Authenticator")) continue;
1088 * Set the original client IP address, based on
1089 * what's in the detail file.
1091 * Hmm... we don't set the server IP address.
1094 if (!strcasecmp(key, "Client-IP-Address")) {
1095 data->client_ip.af = AF_INET;
1096 ip_hton(value, AF_INET, &data->client_ip);
1101 * The original time at which we received the
1102 * packet. We need this to properly calculate
1105 if (!strcasecmp(key, "Timestamp")) {
1106 data->timestamp = atoi(value);
1113 * FIXME: do we want to check for non-protocol
1114 * attributes like radsqlrelay does?
1117 if ((userparse(buffer, &vp) > 0) &&
1125 * Some kind of error.
1127 * FIXME: Leave the file in-place, and warn the
1130 if (ferror(data->fp)) goto cleanup;
1133 * Process the packet.
1136 rad_assert(data->state == STATE_QUEUED);
1139 * We're done reading the file, but we didn't read
1140 * anything. Clean up, and don't return anything.
1143 data->state = STATE_HEADER;
1148 * Allocate the packet. If we fail, it's a serious
1151 packet = rad_alloc(1);
1153 data->state = STATE_NO_REPLY; /* try again later */
1154 return 0; /* maybe memory will magically free up... */
1157 memset(packet, 0, sizeof(*packet));
1158 packet->sockfd = -1;
1159 packet->src_ipaddr.af = AF_INET;
1160 packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1161 packet->code = PW_ACCOUNTING_REQUEST;
1162 packet->timestamp = time(NULL);
1165 * Remember where it came from, so that we don't
1166 * proxy it to the place it came from...
1168 if (data->client_ip.af != AF_UNSPEC) {
1169 packet->src_ipaddr = data->client_ip;
1172 vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
1174 packet->src_ipaddr.af = AF_INET;
1175 packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1177 vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
1179 packet->src_ipaddr.af = AF_INET6;
1180 memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
1181 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1185 vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
1187 packet->dst_ipaddr.af = AF_INET;
1188 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
1190 vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
1192 packet->dst_ipaddr.af = AF_INET6;
1193 memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
1194 &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
1199 * We've got to give SOME value for Id & ports, so that
1200 * the packets can be added to the request queue.
1201 * However, we don't want to keep track of used/unused
1202 * id's and ports, as that's a lot of work. This hack
1203 * ensures that (if we have real random numbers), that
1204 * there will be a collision on every 2^(16+15+15+24 - 1)
1205 * packets, on average. That means we can read 2^37
1206 * packets before having a collision, which means it's
1207 * effectively impossible.
1209 packet->id = lrad_rand() & 0xffff;
1210 packet->src_port = 1024 + (lrad_rand() & 0x7fff);
1211 packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
1213 packet->dst_ipaddr.af = AF_INET;
1214 packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
1217 * If everything's OK, this is a waste of memory.
1218 * Otherwise, it lets us re-send the original packet
1219 * contents, unmolested.
1221 packet->vps = paircopy(data->vps);
1224 * Look for Acct-Delay-Time, and update
1225 * based on Acct-Delay-Time += (time(NULL) - timestamp)
1227 vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
1229 vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
1230 rad_assert(vp != NULL);
1231 pairadd(&packet->vps, vp);
1233 if (data->timestamp != 0) {
1234 vp->vp_integer += time(NULL) - data->timestamp;
1237 *pfun = rad_accounting;
1240 printf("detail_recv: Read packet from %s\n", data->filename);
1241 for (vp = packet->vps; vp; vp = vp->next) {
1243 vp_print(stdout, vp);
1249 * FIXME: many of these checks may not be necessary when
1250 * reading from the detail file.
1252 * Try again later...
1254 if (!received_request(listener, packet, prequest, &detail_client)) {
1256 data->state = STATE_NO_REPLY; /* try again later */
1260 data->state = STATE_RUNNING;
1267 * Free detail-specific stuff.
1269 static void detail_free(rad_listen_t *this)
1271 listen_detail_t *data = this->data;
1273 free(data->filename);
1274 pairfree(&data->vps);
1276 if (data->fp != NULL) fclose(data->fp);
1280 static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
1282 if (!this->server) {
1283 return snprintf(buffer, bufsize, "%s",
1284 ((listen_detail_t *)(this->data))->filename);
1287 return snprintf(buffer, bufsize, "%s as server %s",
1288 ((listen_detail_t *)(this->data))->filename,
1292 static int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1295 * We never encode responses "sent to" the detail file.
1300 static int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
1303 * We never decode responses read from the detail file.
1309 static const CONF_PARSER detail_config[] = {
1310 { "filename", PW_TYPE_STRING_PTR,
1311 offsetof(listen_detail_t, filename), NULL, NULL },
1312 { "load_factor", PW_TYPE_INTEGER,
1313 offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},
1315 { NULL, -1, 0, NULL, NULL } /* end the list */
1320 * Parse a detail section.
1322 static int detail_parse(CONF_SECTION *cs, rad_listen_t *this)
1325 listen_detail_t *data;
1329 rcode = cf_section_parse(cs, data, detail_config);
1331 radlog(L_ERR, "%s[%d]: Failed parsing listen section",
1332 cf_section_filename(cs), cf_section_lineno(cs));
1336 if (!data->filename) {
1337 radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
1338 cf_section_filename(cs), cf_section_lineno(cs));
1342 if ((data->load_factor < 1) || (data->load_factor > 100)) {
1343 radlog(L_ERR, "%s[%d]: Load factor must be between 1 and 100",
1344 cf_section_filename(cs), cf_section_lineno(cs));
1350 data->state = STATE_UNOPENED;
1358 static int radius_snmp_recv(rad_listen_t *listener,
1359 UNUSED RAD_REQUEST_FUNP *pfun,
1360 UNUSED REQUEST **prequest)
1362 if (!mainconfig.do_snmp) return 0;
1364 if ((rad_snmp.smux_fd >= 0) &&
1365 (rad_snmp.smux_event == SMUX_READ)) {
1370 * If we've got to re-connect, then do so now,
1371 * before calling select again.
1373 if (rad_snmp.smux_event == SMUX_CONNECT) {
1378 * Reset this every time, as the smux connect may have
1379 * opened a new socket.
1381 listener->fd = rad_snmp.smux_fd;
1387 static int radius_snmp_print(UNUSED rad_listen_t *this, char *buffer, size_t bufsize)
1389 return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");
1396 * Check if an incoming request is "ok"
1398 * It takes packets, not requests. It sees if the packet looks
1399 * OK. If so, it does a number of sanity checks on it.
1401 static int vqp_socket_recv(rad_listen_t *listener,
1402 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
1404 RADIUS_PACKET *packet;
1405 RAD_REQUEST_FUNP fun = NULL;
1409 packet = vqp_recv(listener->fd);
1411 radlog(L_ERR, "%s", librad_errstr);
1415 if ((client = client_listener_find(listener,
1416 &packet->src_ipaddr)) == NULL) {
1417 RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
1419 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
1420 inet_ntop(packet->src_ipaddr.af,
1421 &packet->src_ipaddr.ipaddr,
1422 buffer, sizeof(buffer)),
1433 if (!received_request(listener, packet, prequest, client)) {
1445 * Send an authentication response packet
1447 static int vqp_socket_send(rad_listen_t *listener, REQUEST *request)
1449 rad_assert(request->listener == listener);
1450 rad_assert(listener->send == vqp_socket_send);
1452 if (vqp_encode(request->reply, request->packet) < 0) {
1453 DEBUG2("Failed encoding packet: %s\n", librad_errstr);
1457 return vqp_send(request->reply);
1461 static int vqp_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
1463 return vqp_encode(request->reply, request->packet);
1467 static int vqp_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
1469 return vqp_decode(request->packet);
1471 #endif /* WITH_VMPS */
1474 static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
1475 { NULL, NULL, NULL, NULL, NULL, NULL, NULL}, /* RAD_LISTEN_NONE */
1479 proxy_socket_recv, proxy_socket_send,
1480 socket_print, proxy_socket_encode, proxy_socket_decode },
1482 /* authentication */
1483 { common_socket_parse, NULL,
1484 auth_socket_recv, auth_socket_send,
1485 socket_print, client_socket_encode, client_socket_decode },
1488 { common_socket_parse, NULL,
1489 acct_socket_recv, acct_socket_send,
1490 socket_print, client_socket_encode, client_socket_decode},
1493 { detail_parse, detail_free,
1494 detail_recv, detail_send,
1495 detail_print, detail_encode, detail_decode },
1498 /* vlan query protocol */
1499 { common_socket_parse, NULL,
1500 vqp_socket_recv, vqp_socket_send,
1501 socket_print, vqp_socket_encode, vqp_socket_decode },
1503 { NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1506 { NULL, NULL, NULL, NULL, NULL, NULL, NULL} /* RAD_LISTEN_SNMP */
1512 * Binds a listener to a socket.
1514 static int listen_bind(rad_listen_t *this)
1516 rad_listen_t **last;
1517 listen_socket_t *sock = this->data;
1520 * If the port is zero, then it means the appropriate
1521 * thing from /etc/services.
1523 if (sock->port == 0) {
1524 struct servent *svp;
1526 switch (this->type) {
1527 case RAD_LISTEN_AUTH:
1528 svp = getservbyname ("radius", "udp");
1530 sock->port = ntohs(svp->s_port);
1532 sock->port = PW_AUTH_UDP_PORT;
1536 case RAD_LISTEN_ACCT:
1537 svp = getservbyname ("radacct", "udp");
1539 sock->port = ntohs(svp->s_port);
1541 sock->port = PW_ACCT_UDP_PORT;
1546 case RAD_LISTEN_VQP:
1552 radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
1558 * Find it in the old list, AFTER updating the port. If
1559 * it's there, use that, rather than creating a new
1560 * socket. This allows HUP's to re-use the old sockets,
1561 * which means that packets waiting in the socket queue
1564 for (last = &mainconfig.listen;
1566 last = &((*last)->next)) {
1567 listen_socket_t *other;
1569 if (this->type != (*last)->type) continue;
1571 if ((this->type == RAD_LISTEN_DETAIL) ||
1572 (this->type == RAD_LISTEN_SNMP)) continue;
1574 other = (listen_socket_t *)((*last)->data);
1576 if ((sock->port == other->port) &&
1577 (sock->ipaddr.af == other->ipaddr.af) &&
1578 (lrad_ipaddr_cmp(&sock->ipaddr, &other->ipaddr) == 0)) {
1579 this->fd = (*last)->fd;
1585 this->fd = lrad_socket(&sock->ipaddr, sock->port);
1587 radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
1594 if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0) {
1595 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1599 flags |= O_NONBLOCK;
1600 if( fcntl(this->fd, F_SETFL, flags) < 0) {
1601 radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
1612 * Allocate & initialize a new listener.
1614 static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
1618 this = rad_malloc(sizeof(*this));
1619 memset(this, 0, sizeof(*this));
1622 this->recv = master_listen[this->type].recv;
1623 this->send = master_listen[this->type].send;
1624 this->print = master_listen[this->type].print;
1625 this->encode = master_listen[this->type].encode;
1626 this->decode = master_listen[this->type].decode;
1629 case RAD_LISTEN_AUTH:
1630 case RAD_LISTEN_ACCT:
1631 case RAD_LISTEN_PROXY:
1632 case RAD_LISTEN_VQP:
1633 this->data = rad_malloc(sizeof(listen_socket_t));
1634 memset(this->data, 0, sizeof(listen_socket_t));
1637 case RAD_LISTEN_DETAIL:
1638 this->data = rad_malloc(sizeof(listen_detail_t));
1639 memset(this->data, 0, sizeof(listen_detail_t));
1642 rad_assert("Unsupported option!" == NULL);
1651 * Externally visible function for creating a new proxy LISTENER.
1653 * For now, don't take ipaddr or port.
1655 * Not thread-safe, but all calls to it are protected by the
1656 * proxy mutex in request_list.c
1658 rad_listen_t *proxy_new_listener()
1660 int last_proxy_port, port;
1661 rad_listen_t *this, *tmp, **last;
1662 listen_socket_t *sock, *old;
1664 this = listen_alloc(RAD_LISTEN_PROXY);
1667 * Find an existing proxy socket to copy.
1669 * FIXME: Make it per-realm, or per-home server!
1671 last_proxy_port = 0;
1673 last = &mainconfig.listen;
1674 for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
1675 if (tmp->type == RAD_LISTEN_PROXY) {
1677 if (sock->port > last_proxy_port) {
1678 last_proxy_port = sock->port + 1;
1680 if (!old) old = sock;
1683 last = &(tmp->next);
1686 if (!old) return NULL; /* This is a serious error. */
1689 * FIXME: find a new IP address to listen on?
1691 * This could likely be done in the "home server"
1692 * configuration, to have per-home-server source IP's.
1695 memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
1698 * Keep going until we find an unused port.
1700 for (port = last_proxy_port; port < 64000; port++) {
1702 if (listen_bind(this) == 0) {
1704 * Add the new listener to the list of
1716 static const LRAD_NAME_NUMBER listen_compare[] = {
1717 { "auth", RAD_LISTEN_AUTH },
1718 { "acct", RAD_LISTEN_ACCT },
1719 { "detail", RAD_LISTEN_DETAIL },
1721 { "vmps", RAD_LISTEN_VQP },
1727 static rad_listen_t *listen_parse(CONF_SECTION *cs, const char *server)
1735 DEBUG2(" listen {");
1737 rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
1739 if (rcode < 0) return NULL;
1742 radlog(L_ERR, "%s[%d]: No type specified in listen section",
1743 cf_section_filename(cs), cf_section_lineno(cs));
1747 type = lrad_str2int(listen_compare, listen_type,
1750 if (type == RAD_LISTEN_NONE) {
1751 radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
1752 cf_section_filename(cs), cf_section_lineno(cs));
1757 * Allow listen sections in the default config to
1758 * refer to a server.
1761 rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
1763 if (rcode < 0) return NULL;
1767 * Set up cross-type data.
1769 this = listen_alloc(type);
1770 this->server = server;
1774 * Call per-type parser.
1776 if (master_listen[type].parse(cs, this) < 0) {
1787 * Generate a list of listeners. Takes an input list of
1788 * listeners, too, so we don't close sockets with waiting packets.
1790 int listen_init(CONF_SECTION *config, rad_listen_t **head)
1794 rad_listen_t **last;
1796 lrad_ipaddr_t server_ipaddr;
1800 * We shouldn't be called with a pre-existing list.
1802 rad_assert(head && (*head == NULL));
1805 server_ipaddr.af = AF_UNSPEC;
1808 * If the port is specified on the command-line,
1809 * it over-rides the configuration file.
1811 * FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
1813 if (mainconfig.port >= 0) auth_port = mainconfig.port;
1816 * If the IP address was configured on the command-line,
1817 * use that as the "bind_address"
1819 if (mainconfig.myip.af != AF_UNSPEC) {
1820 memcpy(&server_ipaddr, &mainconfig.myip,
1821 sizeof(server_ipaddr));
1826 * Else look for bind_address and/or listen sections.
1828 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
1829 rcode = cf_item_parse(config, "bind_address",
1831 &server_ipaddr.ipaddr.ip4addr, NULL);
1832 if (rcode < 0) return -1; /* error parsing it */
1834 if (rcode == 0) { /* successfully parsed IPv4 */
1835 listen_socket_t *sock;
1836 server_ipaddr.af = AF_INET;
1838 radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
1842 if (strcmp(progname, "vmpsd") == 0) {
1843 this = listen_alloc(RAD_LISTEN_VQP);
1844 if (!auth_port) auth_port = 1589;
1847 this = listen_alloc(RAD_LISTEN_AUTH);
1851 sock->ipaddr = server_ipaddr;
1852 sock->port = auth_port;
1854 if (listen_bind(this) < 0) {
1857 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
1860 auth_port = sock->port; /* may have been updated in listen_bind */
1862 last = &(this->next);
1868 if (strcmp(progname, "vmpsd") == 0) goto do_proxy;
1872 * Open Accounting Socket.
1874 * If we haven't already gotten acct_port from
1875 * /etc/services, then make it auth_port + 1.
1877 this = listen_alloc(RAD_LISTEN_ACCT);
1881 * Create the accounting socket.
1883 * The accounting port is always the
1884 * authentication port + 1
1886 sock->ipaddr = server_ipaddr;
1887 sock->port = auth_port + 1;
1889 if (listen_bind(this) < 0) {
1892 radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
1897 last = &(this->next);
1899 } else if (mainconfig.port > 0) { /* no bind address, but a port */
1900 radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
1906 * They specified an IP on the command-line, ignore
1907 * all listen sections.
1909 if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
1912 * Walk through the "listen" sections, if they exist.
1914 for (cs = cf_subsection_find_next(config, NULL, "listen");
1916 cs = cf_subsection_find_next(config, cs, "listen")) {
1917 this = listen_parse(cs, NULL);
1924 last = &(this->next);
1928 * Check virtual servers for "listen" sections, too.
1930 * FIXME: Move to virtual server init?
1932 for (cs = cf_subsection_find_next(config, NULL, "server");
1934 cs = cf_subsection_find_next(config, cs, "server")) {
1935 CONF_SECTION *subcs;
1936 const char *name2 = cf_section_name2(cs);
1938 for (subcs = cf_subsection_find_next(cs, NULL, "listen");
1940 subcs = cf_subsection_find_next(cs, subcs, "listen")) {
1941 this = listen_parse(subcs, name2);
1948 last = &(this->next);
1949 } /* loop over "listen" directives in virtual servers */
1950 } /* loop over virtual servers */
1953 * If we're proxying requests, open the proxy FD.
1954 * Otherwise, don't do anything.
1957 if (mainconfig.proxy_requests == TRUE) {
1959 listen_socket_t *sock = NULL;
1962 * No sockets to receive packets, therefore
1963 * proxying is pointless.
1965 if (!*head) return -1;
1968 * If we previously had proxy sockets, copy them
1969 * to the new config.
1971 if (mainconfig.listen != NULL) {
1972 rad_listen_t *old, *next, **tail;
1974 tail = &mainconfig.listen;
1975 for (old = mainconfig.listen;
1980 if (old->type != RAD_LISTEN_PROXY) {
1981 tail = &((*tail)->next);
1988 last = &(old->next);
1995 * Find the first authentication port,
1998 for (this = *head; this != NULL; this = this->next) {
1999 if (this->type == RAD_LISTEN_AUTH) {
2001 if (server_ipaddr.af == AF_UNSPEC) {
2002 server_ipaddr = sock->ipaddr;
2004 port = sock->port + 2; /* skip acct port */
2007 if (this->type == RAD_LISTEN_VQP) {
2009 if (server_ipaddr.af == AF_UNSPEC) {
2010 server_ipaddr = sock->ipaddr;
2012 port = sock->port + 1;
2017 if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
2020 * Address is still unspecified, use IPv4.
2022 if (server_ipaddr.af == AF_UNSPEC) {
2023 server_ipaddr.af = AF_INET;
2024 server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
2027 this = listen_alloc(RAD_LISTEN_PROXY);
2031 * Create the first proxy socket.
2033 sock->ipaddr = server_ipaddr;
2036 * Try to find a proxy port (value doesn't matter)
2038 for (sock->port = port;
2041 if (listen_bind(this) == 0) {
2043 last = &(this->next); /* just in case */
2048 if (sock->port >= 64000) {
2051 radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
2058 if (mainconfig.do_snmp) {
2062 * Forget about the old one.
2064 for (this = mainconfig.listen;
2066 this = this->next) {
2067 if (this->type != RAD_LISTEN_SNMP) continue;
2071 this = rad_malloc(sizeof(*this));
2072 memset(this, 0, sizeof(*this));
2074 this->type = RAD_LISTEN_SNMP;
2075 this->fd = rad_snmp.smux_fd;
2077 this->recv = radius_snmp_recv;
2078 this->print = radius_snmp_print;
2081 last = &(this->next);
2089 * Free a linked list of listeners;
2091 void listen_free(rad_listen_t **head)
2095 if (!head || !*head) return;
2099 rad_listen_t *next = this->next;
2102 * Other code may have eaten the FD.
2104 if (this->fd >= 0) close(this->fd);
2106 if (master_listen[this->type].free) {
2107 master_listen[this->type].free(this);