* Find a per-socket client.
*/
RADCLIENT *client_listener_find(rad_listen_t *listener,
- fr_ipaddr_t const *ipaddr, int src_port)
+ fr_ipaddr_t const *ipaddr, uint16_t src_port)
{
#ifdef WITH_DYNAMIC_CLIENTS
int rcode;
request->client = client;
request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
if (!request->packet) { /* badly formed, etc */
- request_free(&request);
+ talloc_free(request);
goto unknown;
}
+ (void) talloc_steal(request, request->packet);
request->reply = rad_alloc_reply(request, request->packet);
if (!request->reply) {
- request_free(&request);
+ talloc_free(request);
goto unknown;
}
gettimeofday(&request->packet->timestamp, NULL);
request->number = 0;
request->priority = listener->type;
request->server = client->client_server;
- request->root = &mainconfig;
+ request->root = &main_config;
/*
* Run a fake request through the given virtual server.
DEBUG("} # server %s", request->server);
if (rcode != RLM_MODULE_OK) {
- request_free(&request);
+ talloc_free(request);
goto unknown;
}
request->server = client->server;
exec_trigger(request, NULL, "server.client.add", false);
- request_free(&request);
+ talloc_free(request);
if (!created) goto unknown;
switch (rcode) {
case RLM_MODULE_OK:
case RLM_MODULE_UPDATED:
- request->reply->code = PW_CODE_AUTHENTICATION_ACK;
+ request->reply->code = PW_CODE_ACCESS_ACCEPT;
break;
case RLM_MODULE_FAIL:
default:
case RLM_MODULE_REJECT:
- request->reply->code = PW_CODE_AUTHENTICATION_REJECT;
+ request->reply->code = PW_CODE_ACCESS_REJECT;
break;
}
break;
* Allocate a packet for partial reads.
*/
if (!sock->packet) {
- sock->packet = rad_alloc(sock, 0);
+ sock->packet = rad_alloc(sock, false);
if (!sock->packet) return 0;
sock->packet->sockfd = listener->fd;
* Some sanity checks, based on the packet code.
*/
switch(packet->code) {
- case PW_CODE_AUTHENTICATION_REQUEST:
+ case PW_CODE_ACCESS_REQUEST:
if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
FR_STATS_INC(auth, total_requests);
fun = rad_authenticate;
#endif
case PW_CODE_STATUS_SERVER:
- if (!mainconfig.status_server) {
+ if (!main_config.status_server) {
FR_STATS_INC(auth, total_unknown_types);
- WDEBUG("Ignoring Status-Server request due to security configuration");
+ WARN("Ignoring Status-Server request due to security configuration");
rad_free(&sock->packet);
return 0;
}
static int dual_tcp_accept(rad_listen_t *listener)
{
- int newfd, src_port;
+ int newfd;
+ uint16_t src_port;
rad_listen_t *this;
socklen_t salen;
struct sockaddr_storage src;
salen = sizeof(src);
- DEBUG2(" ... new connection request on TCP socket.");
+ DEBUG2(" ... new connection request on TCP socket");
newfd = accept(listener->fd, (struct sockaddr *) &src, &salen);
if (newfd < 0) {
}
#endif
- DEBUG2(" ... failed to accept connection.");
+ DEBUG2(" ... failed to accept connection");
return -1;
}
if (!fr_sockaddr2ipaddr(&src, salen, &src_ipaddr, &src_port)) {
close(newfd);
- DEBUG2(" ... unknown address family.");
+ DEBUG2(" ... unknown address family");
return 0;
}
if (sock->proto != IPPROTO_TCP) return;
- if (!sock->parent) return;
-
/*
* Decrement the number of connections.
*/
- if (sock->parent->limit.num_connections > 0) {
+ if (sock->parent && (sock->parent->limit.num_connections > 0)) {
sock->parent->limit.num_connections--;
}
if (sock->client && sock->client->limit.num_connections > 0) {
extern bool check_config; /* radiusd.c */
static CONF_PARSER performance_config[] = {
- { "skip_duplicate_checks", PW_TYPE_BOOLEAN,
- offsetof(rad_listen_t, nodup), NULL, NULL },
+ { "skip_duplicate_checks", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rad_listen_t, nodup), NULL },
- { "synchronous", PW_TYPE_BOOLEAN,
- offsetof(rad_listen_t, synchronous), NULL, NULL },
+ { "synchronous", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rad_listen_t, synchronous), NULL },
- { "workers", PW_TYPE_INTEGER,
- offsetof(rad_listen_t, workers), NULL, NULL },
+ { "workers", FR_CONF_OFFSET(PW_TYPE_INTEGER, rad_listen_t, workers), NULL },
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
static CONF_PARSER limit_config[] = {
- { "max_pps", PW_TYPE_INTEGER,
- offsetof(listen_socket_t, max_rate), NULL, NULL },
+ { "max_pps", FR_CONF_OFFSET(PW_TYPE_INTEGER, listen_socket_t, max_rate), NULL },
#ifdef WITH_TCP
- { "max_connections", PW_TYPE_INTEGER,
- offsetof(listen_socket_t, limit.max_connections), NULL, "16" },
-
- { "lifetime", PW_TYPE_INTEGER,
- offsetof(listen_socket_t, limit.lifetime), NULL, "0" },
-
- { "idle_timeout", PW_TYPE_INTEGER,
- offsetof(listen_socket_t, limit.idle_timeout), NULL, "30" },
+ { "max_connections", FR_CONF_OFFSET(PW_TYPE_INTEGER, listen_socket_t, limit.max_connections), "16" },
+ { "lifetime", FR_CONF_OFFSET(PW_TYPE_INTEGER, listen_socket_t, limit.lifetime), "0" },
+ { "idle_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, listen_socket_t, limit.idle_timeout), STRINGIFY(30) },
#endif
{ NULL, -1, 0, NULL, NULL } /* end the list */
int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
{
int rcode;
- int listen_port;
+ uint16_t listen_port;
fr_ipaddr_t ipaddr;
listen_socket_t *sock = this->data;
- char *section_name = NULL;
+ char const *section_name = NULL;
CONF_SECTION *client_cs, *parentcs;
CONF_SECTION *subcs;
*/
memset(&ipaddr, 0, sizeof(ipaddr));
ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
- rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
- &ipaddr.ipaddr.ip4addr, NULL);
- if (rcode < 0) return -1;
-
- if (rcode == 0) { /* successfully parsed IPv4 */
- ipaddr.af = AF_INET;
-
- } else { /* maybe IPv6? */
- rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
- &ipaddr.ipaddr.ip6addr, NULL);
- if (rcode < 0) return -1;
- if (rcode == 1) {
- cf_log_err_cs(cs,
- "No address specified in listen section");
- return -1;
- }
- ipaddr.af = AF_INET6;
+ rcode = cf_item_parse(cs, "ipaddr", FR_ITEM_POINTER(PW_TYPE_IP_ADDR, &ipaddr), NULL);
+ if (rcode < 0) return -1;
+ if (rcode != 0) rcode = cf_item_parse(cs, "ipv4addr", FR_ITEM_POINTER(PW_TYPE_IPV4_ADDR, &ipaddr), NULL);
+ if (rcode < 0) return -1;
+ if (rcode != 0) rcode = cf_item_parse(cs, "ipv6addr", FR_ITEM_POINTER(PW_TYPE_IPV6_ADDR, &ipaddr), NULL);
+ if (rcode < 0) return -1;
+ if (rcode != 0) {
+ cf_log_err_cs(cs, "No address specified in listen section");
+ return -1;
}
- rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
- &listen_port, "0");
+ rcode = cf_item_parse(cs, "port", FR_ITEM_POINTER(PW_TYPE_SHORT, &listen_port), "0");
if (rcode < 0) return -1;
- if ((listen_port < 0) || (listen_port > 65535)) {
- cf_log_err_cs(cs,
- "Invalid value for \"port\"");
- return -1;
- }
-
sock->proto = IPPROTO_UDP;
if (cf_pair_find(cs, "proto")) {
#ifndef WITH_TCP
cf_log_err_cs(cs,
- "System does not support the TCP protocol. Delete this line from the configuration file.");
+ "System does not support the TCP protocol. Delete this line from the configuration file");
return -1;
#else
- char *proto = NULL;
+ char const *proto = NULL;
#ifdef WITH_TLS
CONF_SECTION *tls;
#endif
- rcode = cf_item_parse(cs, "proto", PW_TYPE_STRING_PTR,
- &proto, "udp");
+ rcode = cf_item_parse(cs, "proto", FR_ITEM_POINTER(PW_TYPE_STRING, &proto), "udp");
if (rcode < 0) return -1;
if (strcmp(proto, "udp") == 0) {
*/
if (sock->proto != IPPROTO_TCP) {
cf_log_err_cs(cs,
- "TLS transport is not available for UDP sockets.");
+ "TLS transport is not available for UDP sockets");
return -1;
}
*/
if (cf_section_sub_find(cs, "tls")) {
cf_log_err_cs(cs,
- "TLS transport is not available in this executable.");
+ "TLS transport is not available in this executable");
return -1;
}
#endif /* WITH_TLS */
*/
} else if (cf_section_sub_find(cs, "tls")) {
cf_log_err_cs(cs,
- "TLS transport is not available in this \"listen\" section.");
+ "TLS transport is not available in this \"listen\" section");
return -1;
}
if (home_server_find(&sock->my_ipaddr, sock->my_port, sock->proto)) {
char buffer[128];
- EDEBUG("We have been asked to listen on %s port %d, which is also listed as a "
+ ERROR("We have been asked to listen on %s port %d, which is also listed as a "
"home server. This can create a proxy loop",
ip_ntoh(&sock->my_ipaddr, buffer, sizeof(buffer)), sock->my_port);
return -1;
if (cf_pair_find(cs, "broadcast")) {
#ifndef SO_BROADCAST
cf_log_err_cs(cs,
- "System does not support broadcast sockets. Delete this line from the configuration file.");
+ "System does not support broadcast sockets. Delete this line from the configuration file");
return -1;
#else
char const *value;
if (this->type != RAD_LISTEN_DHCP) {
cf_log_err_cp(cp,
- "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file.");
+ "Broadcast can only be set for DHCP listeners. Delete this line from the configuration file");
return -1;
}
*/
client_cs = NULL;
parentcs = cf_top_section(cs);
- rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
- §ion_name, NULL);
+ rcode = cf_item_parse(cs, "clients", FR_ITEM_POINTER(PW_TYPE_STRING, §ion_name), NULL);
if (rcode < 0) return -1; /* bad string */
if (rcode == 0) {
/*
* Explicit list given: use it.
*/
- client_cs = cf_section_sub_find_name2(parentcs,
- "clients",
- section_name);
+ client_cs = cf_section_sub_find_name2(parentcs, "clients", section_name);
if (!client_cs) {
client_cs = cf_section_find(section_name);
}
static int stats_socket_recv(rad_listen_t *listener)
{
ssize_t rcode;
- int code, src_port;
+ int code;
+ uint16_t src_port;
RADIUS_PACKET *packet;
RADCLIENT *client = NULL;
fr_ipaddr_t src_ipaddr;
static int auth_socket_recv(rad_listen_t *listener)
{
ssize_t rcode;
- int code, src_port;
+ int code;
+ uint16_t src_port;
RADIUS_PACKET *packet;
RAD_REQUEST_FUNP fun = NULL;
RADCLIENT *client = NULL;
* Some sanity checks, based on the packet code.
*/
switch(code) {
- case PW_CODE_AUTHENTICATION_REQUEST:
+ case PW_CODE_ACCESS_REQUEST:
fun = rad_authenticate;
break;
case PW_CODE_STATUS_SERVER:
- if (!mainconfig.status_server) {
+ if (!main_config.status_server) {
rad_recv_discard(listener->fd);
FR_STATS_INC(auth, total_unknown_types);
- WDEBUG("Ignoring Status-Server request due to security configuration");
+ WARN("Ignoring Status-Server request due to security configuration");
return 0;
}
fun = rad_status_server;
static int acct_socket_recv(rad_listen_t *listener)
{
ssize_t rcode;
- int code, src_port;
+ int code;
+ uint16_t src_port;
RADIUS_PACKET *packet;
RAD_REQUEST_FUNP fun = NULL;
RADCLIENT *client = NULL;
break;
case PW_CODE_STATUS_SERVER:
- if (!mainconfig.status_server) {
+ if (!main_config.status_server) {
rad_recv_discard(listener->fd);
FR_STATS_INC(acct, total_unknown_types);
- WDEBUG("Ignoring Status-Server request due to security configuration");
+ WARN("Ignoring Status-Server request due to security configuration");
return 0;
}
fun = rad_status_server;
static int coa_socket_recv(rad_listen_t *listener)
{
ssize_t rcode;
- int code, src_port;
+ int code;
+ uint16_t src_port;
RADIUS_PACKET *packet;
RAD_REQUEST_FUNP fun = NULL;
RADCLIENT *client = NULL;
* FIXME: Client MIB updates?
*/
switch(packet->code) {
- case PW_CODE_AUTHENTICATION_ACK:
+ case PW_CODE_ACCESS_ACCEPT:
case PW_CODE_ACCESS_CHALLENGE:
- case PW_CODE_AUTHENTICATION_REJECT:
+ case PW_CODE_ACCESS_REJECT:
break;
#ifdef WITH_ACCOUNTING
* FIXME: Client MIB updates?
*/
switch(packet->code) {
- case PW_CODE_AUTHENTICATION_ACK:
+ case PW_CODE_ACCESS_ACCEPT:
case PW_CODE_ACCESS_CHALLENGE:
- case PW_CODE_AUTHENTICATION_REJECT:
+ case PW_CODE_ACCESS_REJECT:
break;
#ifdef WITH_ACCOUNTING
#endif
default:
- WDEBUG("Internal sanity check failed in binding to socket. Ignoring problem.");
+ WARN("Internal sanity check failed in binding to socket. Ignoring problem");
return -1;
}
}
* May be binding to priviledged ports.
*/
if (sock->my_port != 0) {
-#ifdef SO_REUSEADDR
- int on = 1;
-
- if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
- ERROR("Can't set re-use address option: %s",
- fr_syserror(errno));
- return -1;
- }
-#endif
-
fr_suid_up();
rcode = bind(this->fd, (struct sockaddr *) &salocal, salen);
fr_suid_down();
#ifdef WITH_TCP
if (sock->proto == IPPROTO_TCP) {
/*
- * If there are hard-coded worker threads, they're blocking.
+ * If there are hard-coded worker threads, OR
+ * it's a TLS connection, it's blocking.
*
* Otherwise, they're non-blocking.
*/
- if (!this->workers && fr_nonblock(this->fd) < 0) {
- close(this->fd);
- ERROR("Failed setting non-blocking on socket: %s",
- fr_syserror(errno));
- return -1;
+ if (!this->workers
+#ifdef WITH_PROXY
+#ifdef WITH_TLS
+ && (this->type == RAD_LISTEN_PROXY) && !this->tls
+#endif
+#endif
+ ) {
+ if (fr_nonblock(this->fd) < 0) {
+ close(this->fd);
+ ERROR("Failed setting non-blocking on socket: %s",
+ fr_syserror(errno));
+ return -1;
+ }
}
/*
- * Allow a backlog of 8 listeners
+ * Allow a backlog of 8 listeners, but only for incoming interfaces.
*/
+#ifdef WITH_PROXY
+ if (this->type != RAD_LISTEN_PROXY)
+#endif
if (listen(this->fd, 8) < 0) {
close(this->fd);
ERROR("Failed in listen(): %s", fr_syserror(errno));
}
-static int listener_free(void *ctx)
+static int _listener_free(rad_listen_t *this)
{
- rad_listen_t *this;
-
- this = talloc_get_type_abort(ctx, rad_listen_t);
-
/*
* Other code may have eaten the FD.
*/
* may be used by multiple listeners.
*/
if (this->tls) {
- if (sock->ssn) session_free(sock->ssn);
- request_free(&sock->request);
+ TALLOC_FREE(sock->ssn);
+ TALLOC_FREE(sock->request);
#ifdef HAVE_PTHREAD_H
pthread_mutex_destroy(&(sock->mutex));
#endif
this->encode = master_listen[this->type].encode;
this->decode = master_listen[this->type].decode;
- talloc_set_destructor((void *) this, listener_free);
+ talloc_set_destructor(this, _listener_free);
this->data = talloc_zero_array(this, uint8_t, master_listen[this->type].inst_size);
* Not thread-safe, but all calls to it are protected by the
* proxy mutex in event.c
*/
-rad_listen_t *proxy_new_listener(home_server_t *home, int src_port)
+rad_listen_t *proxy_new_listener(home_server_t *home, uint16_t src_port)
{
time_t now;
rad_listen_t *this;
if ((home->limit.max_connections > 0) &&
(home->limit.num_connections >= home->limit.max_connections)) {
- static time_t last_complained = 0;
-
- now = time(NULL); /* we do this WAY too often */
- if (last_complained == now) return NULL;
- last_complained = now;
-
- INFO("Home server %s has too many open connections (%d)",
- home->name, home->limit.max_connections);
+ RATE_LIMIT(INFO("Home server %s has too many open connections (%d)",
+ home->name, home->limit.max_connections));
return NULL;
}
now = time(NULL);
if (home->last_failed_open == now) {
- WDEBUG("Suppressing attempt to open socket to 'down' home server");
+ WARN("Suppressing attempt to open socket to 'down' home server");
return NULL;
}
- this = listen_alloc(mainconfig.config, RAD_LISTEN_PROXY);
+ this = listen_alloc(main_config.config, RAD_LISTEN_PROXY);
sock = this->data;
sock->other_ipaddr = home->ipaddr;
static rad_listen_t *listen_parse(CONF_SECTION *cs, char const *server)
{
int type, rcode;
- char *listen_type;
+ char const *listen_type;
rad_listen_t *this;
CONF_PAIR *cp;
char const *value;
cf_log_info(cs, "listen {");
listen_type = NULL;
- rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
- &listen_type, "");
+ rcode = cf_item_parse(cs, "type", FR_ITEM_POINTER(PW_TYPE_STRING, &listen_type), "");
if (rcode < 0) return NULL;
if (rcode == 1) {
cf_log_err_cs(cs,
* refer to a server.
*/
if (!server) {
- rcode = cf_item_parse(cs, "virtual_server", PW_TYPE_STRING_PTR,
- &server, NULL);
- if (rcode == 1) { /* compatiblity with 2.0-pre */
- rcode = cf_item_parse(cs, "server", PW_TYPE_STRING_PTR,
- &server, NULL);
- }
+ rcode = cf_item_parse(cs, "virtual_server", FR_ITEM_POINTER(PW_TYPE_STRING, &server), NULL);
if (rcode < 0) return NULL;
}
rad_listen_t **last;
rad_listen_t *this;
fr_ipaddr_t server_ipaddr;
- int auth_port = 0;
+ uint16_t auth_port = 0;
#ifdef WITH_PROXY
bool defined_proxy = false;
#endif
*
* FIXME: If argv[0] == "vmpsd", then don't listen on auth/acct!
*/
- if (mainconfig.port >= 0) {
- auth_port = mainconfig.port;
+ if (main_config.port > 0) {
+ auth_port = main_config.port;
/*
* -p X but no -i Y on the command-line.
*/
- if ((mainconfig.port > 0) &&
- (mainconfig.myip.af == AF_UNSPEC)) {
+ if (main_config.myip.af == AF_UNSPEC) {
ERROR("The command-line says \"-p %d\", but there is no associated IP address to use",
- mainconfig.port);
+ main_config.port);
return -1;
}
}
* If the IP address was configured on the command-line,
* use that as the "bind_address"
*/
- if (mainconfig.myip.af != AF_UNSPEC) {
+ if (main_config.myip.af != AF_UNSPEC) {
listen_socket_t *sock;
- memcpy(&server_ipaddr, &mainconfig.myip,
+ memcpy(&server_ipaddr, &main_config.myip,
sizeof(server_ipaddr));
override = true;
auth_port = sock->my_port; /* may have been updated in listen_bind */
if (override) {
cs = cf_section_sub_find_name2(config, "server",
- mainconfig.name);
- if (cs) this->server = mainconfig.name;
+ main_config.name);
+ if (cs) this->server = main_config.name;
}
*last = this;
if (override) {
cs = cf_section_sub_find_name2(config, "server",
- mainconfig.name);
- if (cs) this->server = mainconfig.name;
+ main_config.name);
+ if (cs) this->server = main_config.name;
}
*last = this;
* They specified an IP on the command-line, ignore
* all listen sections except the one in '-n'.
*/
- if (mainconfig.myip.af != AF_UNSPEC) {
+ if (main_config.myip.af != AF_UNSPEC) {
CONF_SECTION *subcs;
char const *name2 = cf_section_name2(cs);
cs = cf_section_sub_find_name2(config, "server",
- mainconfig.name);
+ main_config.name);
if (!cs) goto add_sockets;
/*
* proxying is pointless.
*/
if (!*head) {
- ERROR("The server is not configured to listen on any ports. Cannot start.");
+ ERROR("The server is not configured to listen on any ports. Cannot start");
return -1;
}
}
if (this->workers) {
-#ifndef HAVE_PTHREAD_H
- WARN("Setting 'workers' requires 'synchronous'. Disabling 'workers'");
- this->workers = 0;
-#else
- int i, rcode;
+#ifdef HAVE_PTHREAD_H
+ int rcode;
+ uint32_t i;
char buffer[256];
this->print(this, buffer, sizeof(buffer));
DEBUG("Thread %d for %s\n", i, buffer);
}
+#else
+ WARN("Setting 'workers' requires 'synchronous'. Disabling 'workers'");
+ this->workers = 0;
#endif
+
} else {
radius_update_listener(this);
}
* Otherwise, don't do anything.
*/
#ifdef WITH_PROXY
- if ((mainconfig.proxy_requests == true) &&
+ if ((main_config.proxy_requests == true) &&
!check_config &&
(*head != NULL) && !defined_proxy) {
- int port ;
+ uint16_t port = 0;
home_server_t home;
memset(&home, 0, sizeof(home));
}
#ifdef WITH_STATS
-RADCLIENT_LIST *listener_find_client_list(fr_ipaddr_t const *ipaddr,
- int port)
+RADCLIENT_LIST *listener_find_client_list(fr_ipaddr_t const *ipaddr, uint16_t port)
{
rad_listen_t *this;
- for (this = mainconfig.listen; this != NULL; this = this->next) {
+ for (this = main_config.listen; this != NULL; this = this->next) {
listen_socket_t *sock;
if ((this->type != RAD_LISTEN_AUTH)
}
#endif
-rad_listen_t *listener_find_byipaddr(fr_ipaddr_t const *ipaddr, int port, int proto)
+rad_listen_t *listener_find_byipaddr(fr_ipaddr_t const *ipaddr, uint16_t port, int proto)
{
rad_listen_t *this;
- for (this = mainconfig.listen; this != NULL; this = this->next) {
+ for (this = main_config.listen; this != NULL; this = this->next) {
listen_socket_t *sock;
sock = this->data;
/*
* Failed to find a specific one. Find INADDR_ANY
*/
- for (this = mainconfig.listen; this != NULL; this = this->next) {
+ for (this = main_config.listen; this != NULL; this = this->next) {
listen_socket_t *sock;
sock = this->data;