diff options
-rw-r--r-- | accel-pppd/include/events.h | 1 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.c | 12 | ||||
-rw-r--r-- | accel-pppd/radius/acct.c | 22 | ||||
-rw-r--r-- | accel-pppd/radius/radius.c | 14 | ||||
-rw-r--r-- | accel-pppd/radius/radius_p.h | 2 |
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); |