summaryrefslogtreecommitdiff
path: root/accel-pppd/radius
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/radius')
-rw-r--r--accel-pppd/radius/radius.c62
-rw-r--r--accel-pppd/radius/radius_p.h3
2 files changed, 22 insertions, 43 deletions
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 89f1e398..cb26132e 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -488,31 +488,14 @@ err:
return -1;
}
-/*
- * Number of IPv6 DNS servers kept per session. Matches the number of dns=
- * options the ipv6_nd and ipv6_dhcp modules accept in [ipv6-dns], and keeps
- * the RDNSS option of a router advertisement to a sane size.
- */
-#define MAX_DNS6_COUNT 3
-
-static void free_ipv6_dns(struct radius_pd_t *rpd)
-{
- struct ipv6db_addr_t *a;
-
- while (!list_empty(&rpd->ipv6_dns.addr_list)) {
- a = list_entry(rpd->ipv6_dns.addr_list.next, typeof(*a), entry);
- list_del(&a->entry);
- _free(a);
- }
-}
-
int rad_proc_attrs(struct rad_req_t *req)
{
struct ev_wins_t wins = {};
struct ev_dns_t dns = {};
struct rad_attr_t *attr;
struct ipv6db_addr_t *a;
- int dns6_count = -1;
+ unsigned int dns6_count = 0;
+ unsigned int dns6_index = 0;
int res = 0;
struct radius_pd_t *rpd = req->rpd;
@@ -520,6 +503,16 @@ int rad_proc_attrs(struct rad_req_t *req)
req->rpd->acct_interim_jitter = conf_acct_interim_jitter;
list_for_each_entry(attr, &req->reply->attrs, entry) {
+ if (!attr->vendor && attr->attr->id == DNS_Server_IPv6_Address)
+ dns6_count++;
+ }
+
+ if (dns6_count && ipv6_dns_reserve(&rpd->ipv6_dns, dns6_count)) {
+ log_emerg("radius: out of memory allocating IPv6 DNS servers\n");
+ return -1;
+ }
+
+ list_for_each_entry(attr, &req->reply->attrs, entry) {
if (attr->vendor) {
if (attr->vendor->id == VENDOR_Microsoft) {
switch (attr->attr->id) {
@@ -629,26 +622,7 @@ int rad_proc_attrs(struct rad_req_t *req)
list_add_tail(&a->entry, &rpd->ipv6_dp.prefix_list);
break;
case DNS_Server_IPv6_Address:
- if (dns6_count < 0) {
- /* This reply carries a DNS server list of
- its own, it replaces whatever a previous
- one assigned */
- free_ipv6_dns(rpd);
- dns6_count = 0;
- }
- if (dns6_count >= MAX_DNS6_COUNT) {
- if (dns6_count == MAX_DNS6_COUNT)
- log_ppp_warn("radius: ignoring DNS-Server-IPv6-Address"
- " beyond the first %i\n", MAX_DNS6_COUNT);
- dns6_count++;
- break;
- }
- a = _malloc(sizeof(*a));
- memset(a, 0, sizeof(*a));
- a->prefix_len = 128;
- a->addr = attr->val.ipv6addr;
- list_add_tail(&a->entry, &rpd->ipv6_dns.addr_list);
- dns6_count++;
+ rpd->ipv6_dns.addr[dns6_index++] = attr->val.ipv6addr;
break;
case NAS_Port:
rpd->ses->unit_idx = attr->val.integer;
@@ -685,7 +659,9 @@ int rad_proc_attrs(struct rad_req_t *req)
/* Like the IPv4 DNS servers, absent attributes leave whatever a
previous reply assigned in place */
- if (!list_empty(&rpd->ipv6_dns.addr_list))
+ if (dns6_count)
+ rpd->ipv6_dns.count = dns6_count;
+ if (rpd->ipv6_dns.count)
rpd->ses->ipv6_dns = &rpd->ipv6_dns;
return res;
@@ -852,7 +828,6 @@ static void ses_starting(struct ap_session *ses)
INIT_LIST_HEAD(&rpd->plugin_list);
INIT_LIST_HEAD(&rpd->ipv6_addr.addr_list);
INIT_LIST_HEAD(&rpd->ipv6_dp.prefix_list);
- INIT_LIST_HEAD(&rpd->ipv6_dns.addr_list);
rpd->ipv4_addr.owner = &ipdb;
rpd->ipv6_addr.owner = &ipdb;
@@ -1036,7 +1011,10 @@ static void ses_finished(struct ap_session *ses)
}
ses->ipv6_dns = NULL;
- free_ipv6_dns(rpd);
+ _free(rpd->ipv6_dns.addr);
+ rpd->ipv6_dns.addr = NULL;
+ rpd->ipv6_dns.count = 0;
+ rpd->ipv6_dns.capacity = 0;
fr6 = rpd->fr6;
while (fr6) {
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index e4b84740..354d54fc 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -9,6 +9,7 @@
#include "radius.h"
#include "ppp.h"
#include "ipdb.h"
+#include "ipv6_dns.h"
#include "pwdb.h"
struct rad_server_t;
@@ -65,7 +66,7 @@ struct radius_pd_t {
struct ipv4db_item_t ipv4_addr;
struct ipv6db_item_t ipv6_addr;
struct ipv6db_prefix_t ipv6_dp;
- struct ipv6db_item_t ipv6_dns;
+ struct ipv6_dns_t ipv6_dns;
int acct_interim_interval;
int acct_interim_jitter;