diff options
author | Kozlov Dmitry <dima@server> | 2010-09-23 09:54:52 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-23 09:54:52 +0400 |
commit | 82b0f0953159fc9ab8e387f5e6014dc377b14b38 (patch) | |
tree | 974bf5ff111aed10829c4326d627c9e26d7f2189 /accel-pptpd/radius | |
parent | 3e61cb3f8d58f64c8023e95bf74341e6bc61560e (diff) | |
download | accel-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.c | 19 | ||||
-rw-r--r-- | accel-pptpd/radius/packet.c | 7 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.c | 33 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.h | 1 | ||||
-rw-r--r-- | accel-pptpd/radius/radius_p.h | 6 | ||||
-rw-r--r-- | accel-pptpd/radius/req.c | 13 |
6 files changed, 64 insertions, 15 deletions
diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c index 6004138d..fb5e2e21 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 8623f523..6d22e7a4 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 8a5e7b85..38ace958 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 dca93d4f..e202e264 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 3aa54064..ae442238 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 6b812f11..cd4a31be 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; } |