diff options
author | Vladislav Grishenko <themiron@mail.ru> | 2020-01-20 04:40:09 +0500 |
---|---|---|
committer | Vladislav Grishenko <themiron@mail.ru> | 2020-01-20 04:40:09 +0500 |
commit | 6c08c083e689e807e7e240f1a814b79a568b016e (patch) | |
tree | 4dfcb8a94c009d376cabc7ec0c43b55b45c36d79 | |
parent | 183ecb17cdb3f3a29912e1eea70603657ad221f0 (diff) | |
download | accel-ppp-6c08c083e689e807e7e240f1a814b79a568b016e.tar.gz accel-ppp-6c08c083e689e807e7e240f1a814b79a568b016e.zip |
radius: implement jitter of accounting update interval
-rw-r--r-- | accel-pppd/accel-ppp.conf | 2 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 3 | ||||
-rw-r--r-- | accel-pppd/radius/acct.c | 18 | ||||
-rw-r--r-- | accel-pppd/radius/backup.c | 4 | ||||
-rw-r--r-- | accel-pppd/radius/radius.c | 8 | ||||
-rw-r--r-- | accel-pppd/radius/radius_p.h | 2 |
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; |