#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/module.h>
+#include <freeradius-devel/server/log.h>
+
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/misc.h>
uint32_t num_connections; //!< number of dynamic connections
uint32_t num_pending_packets; //!< number of pending packets
uint64_t client_id; //!< Unique client identifier.
- fr_rate_limit_t unknown_client;
- fr_rate_limit_t repeat_nak;
- fr_rate_limit_t queue_full;
+
+ struct {
+ fr_rate_limit_t accept_failed;
+ fr_rate_limit_t alloc_failed;
+ fr_rate_limit_t bad_type;
+ fr_rate_limit_t conn_alloc_failed;
+ fr_rate_limit_t max_connections;
+ fr_rate_limit_t queue_full;
+ fr_rate_limit_t repeat_nak;
+ fr_rate_limit_t too_many_pending;
+ fr_rate_limit_t tracking_failed;
+ fr_rate_limit_t unknown_client;
+ } rate_limit;
} fr_io_thread_t;
/** A saved packet
(void) fr_trie_walk(thread->trie, &thread->num_connections, count_connections);
if ((thread->num_connections + 1) >= max_connections) {
- DEBUG("proto_%s - Ignoring connection from client %s - 'max_connections' limit reached.",
- inst->app->common.name, client->radclient->shortname);
+ RATE_LIMIT_LOCAL(&thread->rate_limit.max_connections, INFO,
+ "proto_%s - Ignoring connection from client %s - 'max_connections' limit reached.",
+ inst->app->common.name, client->radclient->shortname);
if (fd >= 0) close(fd);
return NULL;
}
int value, accept_fd = -1;
uint32_t priority = PRIORITY_NORMAL;
+/** Log that we ignore clients in debug mode, or when it's enabled for a listener
+ */
+#define LOG_IGNORED_CLIENTS(_inst) ((_inst)->log_ignored_clients || fr_debug_lvl >= 1)
+
get_inst(li, &inst, &thread, &connection, &child);
track = NULL;
* OK. So don't return -1.
*/
if (accept_fd < 0) {
- INFO("proto_%s - failed to accept new socket: %s",
- inst->app->common.name, fr_syserror(errno));
+ RATE_LIMIT_LOCAL(&thread->rate_limit.accept_failed,
+ INFO, "proto_%s - failed to accept new socket: %s",
+ inst->app->common.name, fr_syserror(errno));
return 0;
}
* the "name" of the socket, in the
* listener?
*/
- DEBUG2("proto_%s - ignoring packet from IP %pV. It is not configured as 'type = ...'",
- inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
+ if (LOG_IGNORED_CLIENTS(inst)) {
+ RATE_LIMIT_LOCAL(&thread->rate_limit.bad_type, INFO,
+ "proto_%s - ignoring packet from IP %pV. It is not configured as 'type = ...'",
+ inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
+ }
return 0;
}
priority = value;
close(accept_fd);
}
- if (DEBUG_ENABLED) {
- DEBUG("proto_%s - Ignoring %s from IP address %pV - %s",
- inst->app_io->common.name, msg, fr_box_ipaddr(address.socket.inet.src_ipaddr),
- error);
- } else {
- RATE_LIMIT_LOCAL(&thread->unknown_client, ERROR, "proto_%s - Ignoring %s from IP address %pV - %s",
+ if (LOG_IGNORED_CLIENTS(inst)) {
+ RATE_LIMIT_LOCAL(&thread->rate_limit.unknown_client,
+ ERROR, "proto_%s - Ignoring %s from IP address %pV - %s",
inst->app_io->common.name, msg, fr_box_ipaddr(address.socket.inet.src_ipaddr),
error);
}
*/
if (accept_fd >= 0) {
if (!fr_io_connection_alloc(inst, thread, client, accept_fd, &address, NULL)) {
- DEBUG("Failed to allocate connection from client %s.", client->radclient->shortname);
+ RATE_LIMIT_LOCAL(&thread->rate_limit.conn_alloc_failed,
+ ERROR, "Failed to allocate connection from client %s", client->radclient->shortname);
}
return 0;
track = fr_io_track_add(client, &address, buffer, packet_len, recv_time, &is_dup);
if (!track) {
- DEBUG("Failed tracking packet from client %s - discarding it",
- client->radclient->shortname);
+ RATE_LIMIT_LOCAL(&thread->rate_limit.tracking_failed,
+ ERROR, "Failed tracking packet from client %s - discarding it",
+ client->radclient->shortname);
return 0;
}
* to track pending packets.
*/
if (!connection && inst->max_pending_packets && (thread->num_pending_packets >= inst->max_pending_packets)) {
- DEBUG("Too many pending packets from dynamic client %pV - discarding packet",
- fr_box_ipaddr(client->src_ipaddr));
+ RATE_LIMIT_LOCAL(&thread->rate_limit.too_many_pending,
+ ERROR, "Too many pending dynamic client packets for listener - discarding packet from %pV",
+ fr_box_ipaddr(client->src_ipaddr));
discard:
talloc_free(to_free);
pending = fr_io_pending_alloc(connection, client, buffer, packet_len,
track, priority);
if (!pending) {
- INFO("proto_%s - Failed allocating space for dynamic client %pV - discarding packet",
- inst->app_io->common.name, fr_box_ipaddr(client->src_ipaddr));
+ RATE_LIMIT_LOCAL(&thread->rate_limit.alloc_failed,
+ ERROR, "proto_%s - Failed allocating space for dynamic client %pV - discarding packet",
+ inst->app_io->common.name, fr_box_ipaddr(client->src_ipaddr));
goto discard;
}
* for it.
*/
if (nak) {
- RATE_LIMIT_LOCAL(&thread->repeat_nak, ERROR, "proto_%s - Discarding repeated packet from NAK'd dynamic client %pV",
+ RATE_LIMIT_LOCAL(&thread->rate_limit.repeat_nak, ERROR, "proto_%s - Discarding repeated packet from NAK'd dynamic client %pV",
inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
DEBUG("Discarding packet to NAKed connection %s", connection->name);
if (!connection) {
connection = fr_io_connection_alloc(inst, thread, client, -1, &address, NULL);
if (!connection) {
- DEBUG("Failed to allocate connection from client %s. Discarding packet.", client->radclient->shortname);
+ RATE_LIMIT_LOCAL(&thread->rate_limit.conn_alloc_failed,
+ ERROR, "Failed to allocate connection from client %s. Discarding packet.", client->radclient->shortname);
return 0;
}
}
*/
if (fr_network_listen_inject(connection->nr, connection->listen,
buffer, packet_len, recv_time) < 0) {
- RATE_LIMIT_LOCAL(&thread->queue_full, ERROR, "proto_%s - Discarding packet from dynamic client %pV - cannot push packet to connected socket due to %s",
- inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr), fr_strerror());
+ RATE_LIMIT_LOCAL(&thread->rate_limit.queue_full, PERROR,
+ "proto_%s - Discarding packet from dynamic client %pV - cannot push packet to connected socket",
+ inst->app_io->common.name, fr_box_ipaddr(address.socket.inet.src_ipaddr));
/*
* Don't return an error, because that will cause the listener to close its socket.
*/