summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2020-01-20 04:40:09 +0500
committerVladislav Grishenko <themiron@mail.ru>2020-01-20 04:40:09 +0500
commit6c08c083e689e807e7e240f1a814b79a568b016e (patch)
tree4dfcb8a94c009d376cabc7ec0c43b55b45c36d79
parent183ecb17cdb3f3a29912e1eea70603657ad221f0 (diff)
downloadaccel-ppp-6c08c083e689e807e7e240f1a814b79a568b016e.tar.gz
accel-ppp-6c08c083e689e807e7e240f1a814b79a568b016e.zip
radius: implement jitter of accounting update interval
-rw-r--r--accel-pppd/accel-ppp.conf2
-rw-r--r--accel-pppd/accel-ppp.conf.53
-rw-r--r--accel-pppd/radius/acct.c18
-rw-r--r--accel-pppd/radius/backup.c4
-rw-r--r--accel-pppd/radius/radius.c8
-rw-r--r--accel-pppd/radius/radius_p.h2
6 files changed, 35 insertions, 2 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 144bf1f4..1635e177 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -209,6 +209,8 @@ verbose=1
#acct-timeout=120
#acct-delay-time=0
#acct-on=0
+#acct-interim-interval=0
+#acct-interim-jitter=0
#attr-tunnel-type=My-Tunnel-Type
[client-ip-range]
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index 3e6312f8..41ee09c5 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -838,6 +838,9 @@ Specifies secret to use in DM/CoA communication.
.BI "acct-interim-interval=" n
Specifies interval in seconds to send accounting information (may be overriden by radius Acct-Interim-Interval attribute)
.TP
+.BI "acct-interim-jitter=" n
+Specifies absolute maximum jitter value in seconds to be applied to accounting information interval.
+.TP
.BI "verbose=" n
If this option is given and
.B n
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index c0b01900..9300bcb8 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -18,6 +18,10 @@
#include "memdebug.h"
+#ifndef max
+#define max(x,y) ((x) > (y) ? (x) : (y))
+#endif
+
#define INTERIM_SAFE_TIME 10
static int req_set_RA(struct rad_req_t *req, const char *secret)
@@ -188,6 +192,12 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
if (rad_req_send(rpd->acct_req) && conf_acct_timeout) {
log_ppp_warn("radius:acct: no servers available, terminating session...\n");
ap_session_terminate(rpd->ses, TERM_NAS_ERROR, 0);
+ } else if (rpd->acct_interim_interval && rpd->acct_interim_jitter) {
+ t->period = max(rpd->acct_interim_interval -
+ rpd->acct_interim_jitter, INTERIM_SAFE_TIME) * 1000;
+ t->period += ((rpd->acct_interim_interval +
+ rpd->acct_interim_jitter) * 1000 - t->period) * random() / RAND_MAX;
+ triton_timer_mod(t, 0);
}
}
@@ -250,7 +260,13 @@ static void rad_acct_start_recv(struct rad_req_t *req)
rad_packet_change_val(req->pack, NULL, "Acct-Status-Type", "Interim-Update");
rpd->acct_interim_timer.expire = rad_acct_interim_update;
- rpd->acct_interim_timer.period = rpd->acct_interim_interval * 1000;
+ if (rpd->acct_interim_jitter) {
+ rpd->acct_interim_timer.period = max(rpd->acct_interim_interval -
+ rpd->acct_interim_jitter, INTERIM_SAFE_TIME) * 1000;
+ rpd->acct_interim_timer.period += ((rpd->acct_interim_interval +
+ rpd->acct_interim_jitter) * 1000 - rpd->acct_interim_timer.period) * random() / RAND_MAX;
+ } else
+ rpd->acct_interim_timer.period = rpd->acct_interim_interval * 1000;
triton_timer_add(rpd->ses->ctrl->ctx, &rpd->acct_interim_timer, 0);
req->timeout.expire = rad_acct_timeout;
diff --git a/accel-pppd/radius/backup.c b/accel-pppd/radius/backup.c
index b73d3bab..6d4db636 100644
--- a/accel-pppd/radius/backup.c
+++ b/accel-pppd/radius/backup.c
@@ -44,6 +44,7 @@ static int session_save(struct ap_session *ses, struct backup_mod *m)
idle_timeout = rpd->idle_timeout.period / 1000;
add_tag(RAD_TAG_INTERIM_INTERVAL, &rpd->acct_interim_interval, 4);
+ add_tag(RAD_TAG_INTERIM_JITTER, &rpd->acct_interim_jitter, 4);
if (rpd->session_timeout.tpd)
add_tag(RAD_TAG_SESSION_TIMEOUT, &session_timeout, 8);
@@ -122,6 +123,9 @@ void radius_restore_session(struct ap_session *ses, struct radius_pd_t *rpd)
case RAD_TAG_INTERIM_INTERVAL:
rpd->acct_interim_interval = *(uint32_t *)tag->data;
break;
+ case RAD_TAG_INTERIM_JITTER:
+ rpd->acct_interim_jitter = *(uint32_t *)tag->data;
+ break;
case RAD_TAG_SESSION_TIMEOUT:
rpd->session_timeout.expire_tv.tv_sec = *(uint64_t *)tag->data - ses->start_time;
break;
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 7cb01d80..e5a65a56 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -41,6 +41,7 @@ char *conf_dm_coa_secret;
int conf_sid_in_auth;
int conf_require_nas_ident;
int conf_acct_interim_interval;
+int conf_acct_interim_jitter;
int conf_accounting;
int conf_fail_time;
@@ -277,6 +278,7 @@ int rad_proc_attrs(struct rad_req_t *req)
struct radius_pd_t *rpd = req->rpd;
req->rpd->acct_interim_interval = conf_acct_interim_interval;
+ req->rpd->acct_interim_jitter = conf_acct_interim_jitter;
list_for_each_entry(attr, &req->reply->attrs, entry) {
if (attr->vendor && attr->vendor->id == Vendor_Microsoft) {
@@ -969,9 +971,13 @@ static int load_config(void)
conf_require_nas_ident = atoi(opt);
opt = conf_get_opt("radius", "acct-interim-interval");
- if (opt && atoi(opt) > 0)
+ if (opt && atoi(opt) >= 0)
conf_acct_interim_interval = atoi(opt);
+ opt = conf_get_opt("radius", "acct-interim-jitter");
+ if (opt && atoi(opt) >= 0)
+ conf_acct_interim_jitter = atoi(opt);
+
opt = conf_get_opt("radius", "acct-delay-time");
if (opt)
conf_acct_delay_time = atoi(opt);
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index 172504cf..0c185d28 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -66,6 +66,7 @@ struct radius_pd_t {
struct ipv6db_item_t ipv6_addr;
struct ipv6db_prefix_t ipv6_dp;
int acct_interim_interval;
+ int acct_interim_jitter;
char *acct_username;
uint8_t *attr_class;
@@ -185,6 +186,7 @@ extern int conf_require_nas_ident;
extern in_addr_t conf_dm_coa_server;
extern int conf_dm_coa_port;
extern int conf_acct_interim_interval;
+extern int conf_acct_interim_jitter;
extern int conf_accounting;
extern const char *conf_attr_tunnel_type;