From: Alan T. DeKok Date: Sun, 30 Jul 2017 14:51:23 +0000 (-0400) Subject: Add 'replicate' flag. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42c419f3d75b1fa1dc44658abe4da16da131fac1;p=thirdparty%2Ffreeradius-server.git Add 'replicate' flag. This allows the module to send packets and not expect responses --- diff --git a/src/modules/rlm_radius/TODO.md b/src/modules/rlm_radius/TODO.md index 9d09ac85225..fa39a919284 100644 --- a/src/modules/rlm_radius/TODO.md +++ b/src/modules/rlm_radius/TODO.md @@ -123,8 +123,3 @@ list of allowed packet types. We then need to require config for username / password, for Access-Request, and just username for Accounting-Request. -## Replication (i.e. not proxying) - -allow for "no reply" proxying, where we don't care about getting the reply -i.e. we still drain the socket, we just don't do anything with the replies - diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 0ec098eed0f..4deda7c1452 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -96,6 +96,8 @@ static CONF_PARSER const module_config[] = { { FR_CONF_OFFSET("transport", FR_TYPE_VOID, rlm_radius_t, io_submodule), .func = transport_parse }, + { FR_CONF_OFFSET("replicate", FR_TYPE_BOOL, rlm_radius_t, replicate) }, + { FR_CONF_OFFSET("type", FR_TYPE_UINT32 | FR_TYPE_MULTI | FR_TYPE_NOT_EMPTY | FR_TYPE_REQUIRED, rlm_radius_t, types), .func = type_parse }, diff --git a/src/modules/rlm_radius/rlm_radius.h b/src/modules/rlm_radius/rlm_radius.h index 663e795a41d..59e4ff0e774 100644 --- a/src/modules/rlm_radius/rlm_radius.h +++ b/src/modules/rlm_radius/rlm_radius.h @@ -76,6 +76,8 @@ struct rlm_radius_t { struct timeval reconnection_delay; struct timeval idle_timeout; + bool replicate; //!< are we ignoring responses? + dl_instance_t *io_submodule; //!< As provided by the transport_parse fr_radius_client_io_t const *io; //!< Easy access to the IO handle void *io_instance; //!< Easy access to the IO instance diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index ed94f2956a8..22d90b812f3 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -51,6 +51,7 @@ typedef struct rlm_radius_udp_t { bool recv_buff_is_set; //!< Whether we were provided with a recv_buf bool send_buff_is_set; //!< Whether we were provided with a send_buf + bool replicate; //!< copied from parent->replicate } rlm_radius_udp_t; @@ -234,6 +235,11 @@ static void conn_read(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx) ssize_t data_len; uint8_t original[20]; + /* + * @todo - call read() until it returns no data. There + * may be multiple packets pending! We don't want to go + * through a whole kevent cycle just to read another packet. + */ data_len = read(fd, c->buffer, c->buflen); if (data_len == 0) return; @@ -242,6 +248,11 @@ static void conn_read(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx) return; } + /* + * Replicating? Drain the socket, but ignore all responses. + */ + if (c->inst->replicate) return; + packet_len = data_len; if (!fr_radius_ok(c->buffer, &packet_len, false, &reason)) { DEBUG("Ignoring malformed packet"); @@ -363,6 +374,16 @@ static void conn_writable(fr_event_list_t *el, int fd, UNUSED int flags, void *u return; } + /* + * We're replicating, so we don't care about the + * responses. Don't do any retransmission + * timers, etc. + */ + if (c->inst->replicate) { + mod_finished_request(c, u); + continue; + } + /* * Start the retransmission timers. */ @@ -782,6 +803,7 @@ static int mod_instantiate(rlm_radius_t *parent, void *instance, CONF_SECTION *c rlm_radius_udp_t *inst = talloc_get_type_abort(instance, rlm_radius_udp_t); inst->parent = parent; + inst->replicate = parent->replicate; /* * Ensure that we have a destination address.