diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2011-01-05 15:18:59 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2011-01-05 15:18:59 +0300 |
commit | f28cb1b0a926f1ea98700b7871537ad1793511fd (patch) | |
tree | baf35570bc6b38b6fab5b6524e8f19f58f71e57f /accel-pptpd/radius/acct.c | |
parent | 2fdf3586c13a72c36f9530084962e29d57dc0329 (diff) | |
download | accel-ppp-xebd-f28cb1b0a926f1ea98700b7871537ad1793511fd.tar.gz accel-ppp-xebd-f28cb1b0a926f1ea98700b7871537ad1793511fd.zip |
rename accel-pptp to accel-ppp
Diffstat (limited to 'accel-pptpd/radius/acct.c')
-rw-r--r-- | accel-pptpd/radius/acct.c | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c deleted file mode 100644 index ddb3e08..0000000 --- a/accel-pptpd/radius/acct.c +++ /dev/null @@ -1,328 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include "linux_ppp.h" - -#include <openssl/md5.h> - -#include "log.h" -#include "radius_p.h" - -#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; - - if (rad_packet_build(req->pack, req->RA)) - return -1; - - MD5_Init(&ctx); - MD5_Update(&ctx, req->pack->buf, req->pack->len); - MD5_Update(&ctx, secret, strlen(secret)); - MD5_Final(req->pack->buf + 4, &ctx); - - return 0; -} - -static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp) -{ - struct ifpppstatsreq ifreq; - time_t stop_time; - - if (ppp->stop_time) - stop_time = ppp->stop_time; - else - time(&stop_time); - - memset(&ifreq, 0, sizeof(ifreq)); - ifreq.stats_ptr = (void *)&ifreq.stats; - strcpy(ifreq.ifr__name, ppp->ifname); - - if (ioctl(sock_fd, SIOCGPPPSTATS, &ifreq)) { - log_ppp_error("radius: failed to get ppp statistics: %s\n", strerror(errno)); - 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, NULL, "Acct-Input-Octets", ifreq.stats.p.ppp_ibytes); - rad_packet_change_int(req->pack, NULL, "Acct-Output-Octets", ifreq.stats.p.ppp_obytes); - rad_packet_change_int(req->pack, NULL, "Acct-Input-Packets", ifreq.stats.p.ppp_ipackets); - rad_packet_change_int(req->pack, NULL, "Acct-Output-Packets", ifreq.stats.p.ppp_opackets); - rad_packet_change_int(req->pack, NULL, "Acct-Input-Gigawords", req->rpd->acct_input_gigawords); - rad_packet_change_int(req->pack, NULL, "Acct-Output-Gigawords", req->rpd->acct_output_gigawords); - rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ppp->start_time); -} - -static int rad_acct_read(struct triton_md_handler_t *h) -{ - struct rad_req_t *req = container_of(h, typeof(*req), hnd); - struct rad_packet_t *pack; - int r; - - if (req->reply) { - rad_packet_free(req->reply); - req->reply = NULL; - } - - while (1) { - r = rad_packet_recv(h->fd, &pack, NULL); - - if (pack) { - if (req->reply) - rad_packet_free(req->reply); - req->reply = pack; - if (conf_interim_verbose) { - log_ppp_info2("recv "); - rad_packet_print(req->reply, log_ppp_info2); - } - } - - if (r) - break; - } - - if (!req->reply) - return 0; - - if (req->reply->code != CODE_ACCOUNTING_RESPONSE || req->reply->id != req->pack->id) { - rad_packet_free(req->reply); - req->reply = NULL; - } else { - if (req->timeout.tpd) - triton_timer_del(&req->timeout); - } - - return 0; -} - -static void rad_acct_timeout(struct triton_timer_t *t) -{ - struct rad_req_t *req = container_of(t, typeof(*req), timeout); - time_t ts, dt; - - __sync_add_and_fetch(&stat_interim_lost, 1); - - time(&ts); - - dt = ts - req->rpd->acct_timestamp; - - if (dt > conf_acct_timeout) { - log_ppp_warn("radius:acct: no response, terminating session...\n"); - ppp_terminate(req->rpd->ppp, TERM_NAS_ERROR, 0); - return; - } - if (dt > conf_acct_timeout / 2) { - req->timeout.period += 1000; - triton_timer_mod(&req->timeout, 0); - } else if (dt > conf_acct_timeout / 3) { - if (req->timeout.period != conf_timeout * 2000) { - req->timeout.period = conf_timeout * 2000; - triton_timer_mod(&req->timeout, 0); - } - } - - req->pack->id++; - - rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt); - req_set_RA(req, conf_acct_secret); - rad_req_send(req, conf_interim_verbose); - __sync_add_and_fetch(&stat_interim_sent, 1); -} - -static void rad_acct_interim_update(struct triton_timer_t *t) -{ - struct radius_pd_t *rpd = container_of(t, typeof(*rpd), acct_interim_timer); - - if (rpd->acct_req->timeout.tpd) - return; - - req_set_stat(rpd->acct_req, rpd->ppp); - if (!rpd->acct_interim_interval) - return; - - time(&rpd->acct_timestamp); - rpd->acct_req->pack->id++; - - rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Interim-Update"); - rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0); - req_set_RA(rpd->acct_req, conf_acct_secret); - rad_req_send(rpd->acct_req, conf_interim_verbose); - __sync_add_and_fetch(&stat_interim_sent, 1); - if (conf_acct_timeout) { - rpd->acct_req->timeout.period = conf_timeout * 1000; - triton_timer_add(rpd->ppp->ctrl->ctx, &rpd->acct_req->timeout, 0); - } -} - -int rad_acct_start(struct radius_pd_t *rpd) -{ - int i; - time_t ts; - - rpd->acct_req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ppp->username); - if (!rpd->acct_req) { - log_emerg("radius: out of memory\n"); - return -1; - } - - if (rad_req_acct_fill(rpd->acct_req)) { - log_ppp_error("radius:acct: failed to fill accounting attributes\n"); - goto out_err; - } - - //if (rad_req_add_val(rpd->acct_req, "Acct-Status-Type", "Start", 4)) - // goto out_err; - //if (rad_req_add_str(rpd->acct_req, "Acct-Session-Id", rpd->ppp->sessionid, PPP_SESSIONID_LEN, 1)) - // goto out_err; - - if (rpd->acct_req->reply) { - rad_packet_free(rpd->acct_req->reply); - rpd->acct_req->reply = NULL; - } - - time(&rpd->acct_timestamp); - - for (i = 0; i < conf_max_try; i++) { - time(&ts); - rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp); - if (req_set_RA(rpd->acct_req, conf_acct_secret)) - goto out_err; - if (rad_req_send(rpd->acct_req, conf_verbose)) - goto out_err; - __sync_add_and_fetch(&stat_acct_sent, 1); - rad_req_wait(rpd->acct_req, conf_timeout); - if (!rpd->acct_req->reply) { - rpd->acct_req->pack->id++; - __sync_add_and_fetch(&stat_acct_lost, 1); - continue; - } - if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) { - rad_packet_free(rpd->acct_req->reply); - rpd->acct_req->reply = NULL; - rpd->acct_req->pack->id++; - __sync_add_and_fetch(&stat_acct_lost, 1); - } else - break; - } - - if (!rpd->acct_req->reply) { - log_ppp_warn("radius:acct_start: no response\n"); - goto out_err; - } - - rpd->acct_req->hnd.read = rad_acct_read; - - triton_md_register_handler(rpd->ppp->ctrl->ctx, &rpd->acct_req->hnd); - if (triton_md_enable_handler(&rpd->acct_req->hnd, MD_MODE_READ)) - goto out_err; - - rpd->acct_req->timeout.expire = rad_acct_timeout; - rpd->acct_req->timeout.period = conf_timeout * 1000; - - rpd->acct_interim_timer.expire = rad_acct_interim_update; - 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); - goto out_err; - } - return 0; - -out_err: - rad_req_free(rpd->acct_req); - rpd->acct_req = NULL; - return -1; -} - -void rad_acct_stop(struct radius_pd_t *rpd) -{ - int i; - time_t ts; - - if (rpd->acct_interim_timer.tpd) - triton_timer_del(&rpd->acct_interim_timer); - - if (rpd->acct_req) { - triton_md_unregister_handler(&rpd->acct_req->hnd); - if (rpd->acct_req->timeout.tpd) - triton_timer_del(&rpd->acct_req->timeout); - - switch (rpd->ppp->terminate_cause) { - case TERM_USER_REQUEST: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Request"); - break; - case TERM_SESSION_TIMEOUT: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Session-Timeout"); - break; - case TERM_ADMIN_RESET: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Admin-Reset"); - break; - case TERM_USER_ERROR: - case TERM_AUTH_ERROR: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Error"); - break; - case TERM_NAS_ERROR: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Error"); - break; - case TERM_NAS_REQUEST: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Request"); - break; - case TERM_NAS_REBOOT: - rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Reboot"); - break; - } - rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop"); - req_set_stat(rpd->acct_req, rpd->ppp); - req_set_RA(rpd->acct_req, conf_acct_secret); - /// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", ""); - - if (rpd->acct_req->reply) { - rad_packet_free(rpd->acct_req->reply); - rpd->acct_req->reply = NULL; - } - - time(&rpd->acct_timestamp); - - for(i = 0; i < conf_max_try; i++) { - time(&ts); - rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp); - rpd->acct_req->pack->id++; - if (req_set_RA(rpd->acct_req, conf_acct_secret)) - break; - if (rad_req_send(rpd->acct_req, conf_verbose)) - break; - __sync_add_and_fetch(&stat_acct_sent, 1); - rad_req_wait(rpd->acct_req, conf_timeout); - if (!rpd->acct_req->reply) { - __sync_add_and_fetch(&stat_acct_lost, 1); - continue; - } - if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) { - rad_packet_free(rpd->acct_req->reply); - rpd->acct_req->reply = NULL; - __sync_add_and_fetch(&stat_acct_lost, 1); - } else - break; - } - if (!rpd->acct_req->reply) - log_ppp_warn("radius:acct_stop: no response\n"); - - rad_req_free(rpd->acct_req); - rpd->acct_req = NULL; - } -} - |