summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/include/events.h1
-rw-r--r--accel-pppd/ipv6/dhcpv6.c12
-rw-r--r--accel-pppd/radius/acct.c22
-rw-r--r--accel-pppd/radius/radius.c14
-rw-r--r--accel-pppd/radius/radius_p.h2
5 files changed, 46 insertions, 5 deletions
diff --git a/accel-pppd/include/events.h b/accel-pppd/include/events.h
index 37dfa82..c388575 100644
--- a/accel-pppd/include/events.h
+++ b/accel-pppd/include/events.h
@@ -22,6 +22,7 @@
#define EV_MPPE_KEYS 102
#define EV_DNS 103
#define EV_WINS 104
+#define EV_FORCE_INTERIM_UPDATE 105
#define EV_RADIUS_ACCESS_ACCEPT 200
#define EV_RADIUS_COA 201
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index 595b597..e170ae2 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -363,8 +363,11 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
ia_na->T1 = conf_pref_lifetime == -1 ? -1 : htonl(conf_pref_lifetime / 2);
ia_na->T2 = conf_pref_lifetime == -1 ? -1 : htonl((conf_pref_lifetime * 4) / 5);
- if (!ses->ipv6_dp)
+ if (!ses->ipv6_dp) {
ses->ipv6_dp = ipdb_get_ipv6_prefix(ses);
+ if (ses->ipv6_dp)
+ triton_event_fire(EV_FORCE_INTERIM_UPDATE, ses);
+ }
if ((req->hdr->type == D6_RENEW) && pd->dp_iaid != ia_na->iaid) {
insert_status(reply, opt1, D6_STATUS_NoBinding);
@@ -539,8 +542,11 @@ static void dhcpv6_send_reply2(struct dhcpv6_packet *req, struct dhcpv6_pd *pd,
ia_na->T1 = conf_pref_lifetime == -1 ? -1 : htonl(conf_pref_lifetime / 2);
ia_na->T2 = conf_pref_lifetime == -1 ? -1 : htonl((conf_pref_lifetime * 4) / 5);
- if (!ses->ipv6_dp)
- ses->ipv6_dp = ipdb_get_ipv6_prefix(req->ses);
+ if (!ses->ipv6_dp) {
+ ses->ipv6_dp = ipdb_get_ipv6_prefix(ses);
+ if (ses->ipv6_dp)
+ triton_event_fire(EV_FORCE_INTERIM_UPDATE, ses);
+ }
if (!ses->ipv6_dp)
goto out;
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 3d19447..9292fda 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -147,13 +147,15 @@ static void rad_acct_timeout(struct triton_timer_t *t)
static void rad_acct_interim_update(struct triton_timer_t *t)
{
struct radius_pd_t *rpd = container_of(t, typeof(*rpd), acct_interim_timer);
+ struct ap_session *ses = rpd->ses;
struct timespec ts;
+ int force = 0;
if (rpd->acct_req->entry.next || rpd->acct_req->timeout.tpd)
return;
if (rpd->session_timeout.expire_tv.tv_sec &&
- rpd->session_timeout.expire_tv.tv_sec - (_time() - rpd->ses->start_time) < INTERIM_SAFE_TIME)
+ rpd->session_timeout.expire_tv.tv_sec - (_time() - ses->start_time) < INTERIM_SAFE_TIME)
return;
if (req_set_stat(rpd->acct_req, rpd->ses)) {
@@ -161,7 +163,15 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
return;
}
- if (!rpd->acct_interim_interval)
+ if (ses->ipv6_dp && !rpd->ipv6_dp_sent) {
+ struct ipv6db_addr_t *a;
+ list_for_each_entry(a, &ses->ipv6_dp->prefix_list, entry)
+ rad_packet_add_ipv6prefix(rpd->acct_req->pack, NULL, "Delegated-IPv6-Prefix", &a->addr, a->prefix_len);
+ rpd->ipv6_dp_sent = 1;
+ force = 1;
+ }
+
+ if (!rpd->acct_interim_interval && !force)
return;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -180,6 +190,14 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
}
}
+void rad_acct_force_interim_update(struct radius_pd_t *rpd)
+{
+ if (!rpd->acct_req)
+ return;
+
+ rad_acct_interim_update(&rpd->acct_interim_timer);
+}
+
static int rad_acct_before_send(struct rad_req_t *req)
{
struct timespec ts;
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 24ca20a..c8eaf95 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -520,6 +520,19 @@ static void ses_finished(struct ap_session *ses)
release_pd(rpd);
}
+static void force_interim_update(struct ap_session *ses)
+{
+ struct radius_pd_t *rpd = find_pd(ses);
+
+ if (ses->terminating)
+ return;
+
+ if (!rpd)
+ return;
+
+ rad_acct_force_interim_update(rpd);
+}
+
struct radius_pd_t *find_pd(struct ap_session *ses)
{
struct ap_private *pd;
@@ -806,6 +819,7 @@ static void radius_init(void)
triton_event_register_handler(EV_SES_ACCT_START, (triton_event_func)ses_acct_start);
triton_event_register_handler(EV_SES_FINISHING, (triton_event_func)ses_finishing);
triton_event_register_handler(EV_SES_FINISHED, (triton_event_func)ses_finished);
+ triton_event_register_handler(EV_FORCE_INTERIM_UPDATE, (triton_event_func)force_interim_update);
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index 0e1789f..24cfdbd 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -41,6 +41,7 @@ struct radius_pd_t {
int authenticated:1;
int acct_started:1;
int ipv6_dp_assigned:1;
+ int ipv6_dp_sent:1;
struct rad_req_t *acct_req;
struct triton_timer_t acct_interim_timer;
@@ -202,6 +203,7 @@ int rad_auth_null(struct radius_pd_t *rpd, const char *username, va_list args);
int rad_acct_start(struct radius_pd_t *rpd);
int rad_acct_stop(struct radius_pd_t *rpd);
void rad_acct_stop_defer(struct radius_pd_t *rpd);
+void rad_acct_force_interim_update(struct radius_pd_t *rpd);
struct rad_packet_t *rad_packet_alloc(int code);
int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA);