summaryrefslogtreecommitdiff
path: root/accel-pptpd/radius
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-23 09:54:52 +0400
committerKozlov Dmitry <dima@server>2010-09-23 09:54:52 +0400
commit82b0f0953159fc9ab8e387f5e6014dc377b14b38 (patch)
tree974bf5ff111aed10829c4326d627c9e26d7f2189 /accel-pptpd/radius
parent3e61cb3f8d58f64c8023e95bf74341e6bc61560e (diff)
downloadaccel-ppp-82b0f0953159fc9ab8e387f5e6014dc377b14b38.tar.gz
accel-ppp-82b0f0953159fc9ab8e387f5e6014dc377b14b38.zip
radius: implemented attributes Calling-Station-Id, Called-Station-Id, NAS-IP-Address
radius: implemented extension Acct-Input-Gigawords, Acct-Output-Gigawords lcp: implemented maximum/minimum mtu/mru checks
Diffstat (limited to 'accel-pptpd/radius')
-rw-r--r--accel-pptpd/radius/acct.c19
-rw-r--r--accel-pptpd/radius/packet.c7
-rw-r--r--accel-pptpd/radius/radius.c33
-rw-r--r--accel-pptpd/radius/radius.h1
-rw-r--r--accel-pptpd/radius/radius_p.h6
-rw-r--r--accel-pptpd/radius/req.c13
6 files changed, 64 insertions, 15 deletions
diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c
index 6004138..fb5e2e2 100644
--- a/accel-pptpd/radius/acct.c
+++ b/accel-pptpd/radius/acct.c
@@ -12,6 +12,8 @@
#include "memdebug.h"
+#define STAT_UPDATE_INTERVAL (10 * 60 * 1000)
+
static int req_set_RA(struct rad_req_t *req, const char *secret)
{
MD5_CTX ctx;
@@ -40,10 +42,20 @@ static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp)
return;
}
+ if (ifreq.stats.p.ppp_ibytes < req->rpd->acct_input_octets)
+ req->rpd->acct_input_gigawords++;
+ req->rpd->acct_input_octets = ifreq.stats.p.ppp_ibytes;
+
+ if (ifreq.stats.p.ppp_obytes < req->rpd->acct_output_octets)
+ req->rpd->acct_output_gigawords++;
+ req->rpd->acct_output_octets = ifreq.stats.p.ppp_obytes;
+
rad_packet_change_int(req->pack, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes);
rad_packet_change_int(req->pack, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes);
rad_packet_change_int(req->pack, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets);
rad_packet_change_int(req->pack, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets);
+ rad_packet_change_int(req->pack, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords);
+ rad_packet_change_int(req->pack, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords);
rad_packet_change_int(req->pack, "Acct-Session-Time", time(NULL) - ppp->start_time);
}
@@ -89,8 +101,11 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
if (rpd->acct_req->timeout.tpd)
return;
- rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Interim-Update");
req_set_stat(rpd->acct_req, rpd->ppp);
+ if (!rpd->acct_interim_interval)
+ return;
+
+ rad_packet_change_val(rpd->acct_req->pack, "Acct-Status-Type", "Interim-Update");
req_set_RA(rpd->acct_req, conf_acct_secret);
rad_req_send(rpd->acct_req);
rpd->acct_req->timeout.period = conf_timeout * 1000;
@@ -135,7 +150,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
}
rpd->acct_interim_timer.expire = rad_acct_interim_update;
- rpd->acct_interim_timer.period = rpd->acct_interim_interval * 1000;
+ rpd->acct_interim_timer.period = rpd->acct_interim_interval ? rpd->acct_interim_interval * 1000 : STAT_UPDATE_INTERVAL;
if (rpd->acct_interim_interval && triton_timer_add(rpd->ppp->ctrl->ctx, &rpd->acct_interim_timer, 0)) {
triton_md_unregister_handler(&rpd->acct_req->hnd);
triton_timer_del(&rpd->acct_req->timeout);
diff --git a/accel-pptpd/radius/packet.c b/accel-pptpd/radius/packet.c
index 8623f52..6d22e7a 100644
--- a/accel-pptpd/radius/packet.c
+++ b/accel-pptpd/radius/packet.c
@@ -231,7 +231,6 @@ void rad_packet_free(struct rad_packet_t *pack)
while(!list_empty(&pack->attrs)) {
attr = list_entry(pack->attrs.next, typeof(*attr), entry);
- log_ppp_debug("free: %s\n", attr->attr->name);
list_del(&attr->entry);
if (attr->attr->type == ATTR_TYPE_STRING || attr->attr->type == ATTR_TYPE_OCTETS)
_free(attr->val.string);
@@ -498,6 +497,12 @@ int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const cha
return 0;
}
+int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr)
+{
+ return rad_packet_add_int(pack, name, ipaddr);
+}
+
+
struct rad_attr_t *rad_packet_find_attr(struct rad_packet_t *pack, const char *name)
{
struct rad_attr_t *ra;
diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c
index 8a5e7b8..38ace95 100644
--- a/accel-pptpd/radius/radius.c
+++ b/accel-pptpd/radius/radius.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <arpa/inet.h>
+#include "mempool.h"
#include "events.h"
#include "log.h"
#include "ppp.h"
@@ -41,6 +42,8 @@ static pthread_rwlock_t sessions_lock = PTHREAD_RWLOCK_INITIALIZER;
static void *pd_key;
static struct ipdb_t ipdb;
+static mempool_t rpd_pool;
+
void rad_proc_attrs(struct rad_req_t *req)
{
struct rad_attr_t *attr;
@@ -104,16 +107,16 @@ static struct ipdb_item_t *get_ip(struct ppp_t *ppp)
static void ppp_starting(struct ppp_t *ppp)
{
- struct radius_pd_t *pd = _malloc(sizeof(*pd));
+ struct radius_pd_t *rpd = mempool_alloc(rpd_pool);
- memset(pd, 0, sizeof(*pd));
- pd->pd.key = &pd_key;
- pd->ppp = ppp;
- pthread_mutex_init(&pd->lock, NULL);
- list_add_tail(&pd->pd.entry, &ppp->pd_list);
+ memset(rpd, 0, sizeof(*rpd));
+ rpd->pd.key = &pd_key;
+ rpd->ppp = ppp;
+ pthread_mutex_init(&rpd->lock, NULL);
+ list_add_tail(&rpd->pd.entry, &ppp->pd_list);
pthread_rwlock_wrlock(&sessions_lock);
- list_add_tail(&pd->entry, &sessions);
+ list_add_tail(&rpd->entry, &sessions);
pthread_rwlock_unlock(&sessions_lock);
}
@@ -147,7 +150,8 @@ static void ppp_finished(struct ppp_t *ppp)
rad_packet_free(rpd->dm_coa_req);
list_del(&rpd->pd.entry);
- _free(rpd);
+
+ mempool_free(rpd);
}
struct radius_pd_t *find_pd(struct ppp_t *ppp)
@@ -166,7 +170,7 @@ struct radius_pd_t *find_pd(struct ppp_t *ppp)
}
-struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, int port_id, in_addr_t ipaddr)
+struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, int port_id, in_addr_t ipaddr, const char *csid)
{
struct radius_pd_t *rpd;
@@ -180,6 +184,8 @@ struct radius_pd_t *rad_find_session(const char *sessionid, const char *username
continue;
if (ipaddr && ipaddr != rpd->ipaddr.peer_addr)
continue;
+ if (csid && rpd->ppp->ctrl->calling_station_id && strcmp(csid, rpd->ppp->ctrl->calling_station_id))
+ continue;
pthread_mutex_lock(&rpd->lock);
pthread_rwlock_unlock(&sessions_lock);
return rpd;
@@ -193,6 +199,7 @@ struct radius_pd_t *rad_find_session_pack(struct rad_packet_t *pack)
struct rad_attr_t *attr;
const char *sessionid = NULL;
const char *username = NULL;
+ const char *csid = NULL;
int port_id = -1;
in_addr_t ipaddr = 0;
@@ -205,15 +212,17 @@ struct radius_pd_t *rad_find_session_pack(struct rad_packet_t *pack)
port_id = attr->val.integer;
else if (!strcmp(attr->attr->name, "Framed-IP-Address"))
ipaddr = attr->val.ipaddr;
+ else if (!strcmp(attr->attr->name, "Calling-Station-Id"))
+ csid = attr->val.string;
}
- if (!sessionid && !username && port_id == -1 && ipaddr == 0)
+ if (!sessionid && !username && port_id == -1 && ipaddr == 0 && !csid)
return NULL;
if (username && !sessionid)
return NULL;
- return rad_find_session(sessionid, username, port_id, ipaddr);
+ return rad_find_session(sessionid, username, port_id, ipaddr, csid);
}
int rad_check_nas_pack(struct rad_packet_t *pack)
@@ -275,6 +284,8 @@ static void __init radius_init(void)
{
char *opt;
+ rpd_pool = mempool_create(sizeof(struct radius_pd_t));
+
opt = conf_get_opt("radius", "max-try");
if (opt && atoi(opt) > 0)
conf_max_try = atoi(opt);
diff --git a/accel-pptpd/radius/radius.h b/accel-pptpd/radius/radius.h
index dca93d4..e202e26 100644
--- a/accel-pptpd/radius/radius.h
+++ b/accel-pptpd/radius/radius.h
@@ -99,6 +99,7 @@ int rad_packet_add_str(struct rad_packet_t *pack, const char *name, const char *
int rad_packet_add_octets(struct rad_packet_t *pack, const char *name, uint8_t *val, int len);
int rad_packet_change_int(struct rad_packet_t *pack, const char *name, int val);
int rad_packet_change_val(struct rad_packet_t *pack, const char *name, const char *val);
+int rad_packet_add_ipaddr(struct rad_packet_t *pack, const char *name, in_addr_t ipaddr);
int rad_packet_add_vendor_octets(struct rad_packet_t *pack, const char *vendor_name, const char *name, const uint8_t *val, int len);
struct rad_attr_t *rad_packet_find_vendor_attr(struct rad_packet_t *pack, const char *vendor_name, const char *name);
diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h
index 3aa5406..ae44223 100644
--- a/accel-pptpd/radius/radius_p.h
+++ b/accel-pptpd/radius/radius_p.h
@@ -18,6 +18,10 @@ struct radius_pd_t
struct rad_req_t *acct_req;
struct triton_timer_t acct_interim_timer;
+ uint32_t acct_input_octets;
+ uint32_t acct_output_octets;
+ uint32_t acct_input_gigawords;
+ uint32_t acct_output_gigawords;
struct rad_packet_t *dm_coa_req;
struct sockaddr_in dm_coa_addr;
@@ -55,7 +59,7 @@ extern int conf_acct_server_port;
extern char *conf_dm_coa_secret;
int rad_check_nas_pack(struct rad_packet_t *pack);
-struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, int port_id, in_addr_t ipaddr);
+struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, int port_id, in_addr_t ipaddr, const char *csid);
struct radius_pd_t *rad_find_session_pack(struct rad_packet_t *pack);
int rad_dict_load(const char *fname);
diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c
index 6b812f1..cd4a31b 100644
--- a/accel-pptpd/radius/req.c
+++ b/accel-pptpd/radius/req.c
@@ -52,6 +52,9 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u
if (conf_nas_identifier)
if (rad_packet_add_str(req->pack, "NAS-Identifier", conf_nas_identifier, strlen(conf_nas_identifier)))
goto out_err;
+ if (conf_nas_ip_address)
+ if (rad_packet_add_ipaddr(req->pack, "NAS-IP-Address", inet_addr(conf_nas_ip_address)))
+ goto out_err;
if (rad_packet_add_int(req->pack, "NAS-Port", rpd->ppp->unit_idx))
goto out_err;
if (rad_packet_add_val(req->pack, "NAS-Port-Type", "Virtual"))
@@ -60,6 +63,12 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u
goto out_err;
if (rad_packet_add_val(req->pack, "Framed-Protocol", "PPP"))
goto out_err;
+ if (rpd->ppp->ctrl->calling_station_id)
+ if (rad_packet_add_str(req->pack, "Calling-Station-Id", rpd->ppp->ctrl->calling_station_id, strlen(rpd->ppp->ctrl->calling_station_id)))
+ goto out_err;
+ if (rpd->ppp->ctrl->called_station_id)
+ if (rad_packet_add_str(req->pack, "Called-Station-Id", rpd->ppp->ctrl->called_station_id, strlen(rpd->ppp->ctrl->called_station_id)))
+ goto out_err;
return req;
@@ -91,6 +100,10 @@ int rad_req_acct_fill(struct rad_req_t *req)
return -1;
if (rad_packet_add_int(req->pack, "Acct-Output-Packets", 0))
return -1;
+ if (rad_packet_add_int(req->pack, "Acct-Input-Gigawords", 0))
+ return -1;
+ if (rad_packet_add_int(req->pack, "Acct-Output-Gigawords", 0))
+ return -1;
return 0;
}