diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2013-04-22 23:07:07 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-04-22 23:07:07 +0400 |
commit | bd33158c6da7bbc97f27aa89bdc9de5d7517b981 (patch) | |
tree | 5aef38cb2c410a9fce3860cf220fdf09416c8d4b /accel-pppd/extra | |
parent | fc503382df18bf579375ee22d78184d7dcfaea9e (diff) | |
download | accel-ppp-bd33158c6da7bbc97f27aa89bdc9de5d7517b981.tar.gz accel-ppp-bd33158c6da7bbc97f27aa89bdc9de5d7517b981.zip |
pppd_compat: create radattr file in SES_PRE_UP
Diffstat (limited to 'accel-pppd/extra')
-rw-r--r-- | accel-pppd/extra/pppd_compat.c | 118 |
1 files changed, 75 insertions, 43 deletions
diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c index ae69a78..85fc02e 100644 --- a/accel-pppd/extra/pppd_compat.c +++ b/accel-pppd/extra/pppd_compat.c @@ -31,12 +31,12 @@ static char *conf_ip_up = "/etc/ppp/ip-up"; static char *conf_ip_pre_up; static char *conf_ip_down = "/etc/ppp/ip-down"; static char *conf_ip_change; -static char *conf_radattr_prefix = "/var/run/radattr."; +static char *conf_radattr_prefix = "/var/run/radattr"; static int conf_verbose = 0; static void *pd_key; -struct pppd_compat_pd_t +struct pppd_compat_pd { struct ap_private pd; struct ap_session *ses; @@ -45,6 +45,7 @@ struct pppd_compat_pd_t struct sigchld_handler_t ip_change_hnd; struct sigchld_handler_t ip_down_hnd; #ifdef RADIUS + char *tmp_fname; int radattr_saved:1; #endif int started:1; @@ -53,17 +54,17 @@ struct pppd_compat_pd_t in_addr_t ipv4_peer_addr; }; -static struct pppd_compat_pd_t *find_pd(struct ap_session *ses); -static void fill_argv(char **argv, struct pppd_compat_pd_t *pd, char *path); -static void fill_env(char **env, struct pppd_compat_pd_t *pd); +static struct pppd_compat_pd *find_pd(struct ap_session *ses); +static void fill_argv(char **argv, struct pppd_compat_pd *pd, char *path); +static void fill_env(char **env, struct pppd_compat_pd *pd); #ifdef RADIUS -static void remove_radattr(struct ap_session *ses); -static void write_radattr(struct ap_session *ses, struct rad_packet_t *pack, int save_old); +static void remove_radattr(struct pppd_compat_pd *); +static void write_radattr(struct pppd_compat_pd *, struct rad_packet_t *pack); #endif static void ip_pre_up_handler(struct sigchld_handler_t *h, int status) { - struct pppd_compat_pd_t *pd = container_of(h, typeof(*pd), ip_pre_up_hnd); + struct pppd_compat_pd *pd = container_of(h, typeof(*pd), ip_pre_up_hnd); if (conf_verbose) { log_switch(NULL, pd->ses); log_ppp_info2("pppd_compat: ip-pre-up finished (%i)\n", status); @@ -75,7 +76,7 @@ static void ip_pre_up_handler(struct sigchld_handler_t *h, int status) static void ip_up_handler(struct sigchld_handler_t *h, int status) { - struct pppd_compat_pd_t *pd = container_of(h, typeof(*pd), ip_up_hnd); + struct pppd_compat_pd *pd = container_of(h, typeof(*pd), ip_up_hnd); if (conf_verbose) { log_switch(NULL, pd->ses); log_ppp_info2("pppd_compat: ip-up finished (%i)\n", status); @@ -84,7 +85,7 @@ static void ip_up_handler(struct sigchld_handler_t *h, int status) static void ip_down_handler(struct sigchld_handler_t *h, int status) { - struct pppd_compat_pd_t *pd = container_of(h, typeof(*pd), ip_down_hnd); + struct pppd_compat_pd *pd = container_of(h, typeof(*pd), ip_down_hnd); if (conf_verbose) { log_switch(NULL, pd->ses); log_ppp_info2("pppd_compat: ip-down finished (%i)\n", status); @@ -95,7 +96,7 @@ static void ip_down_handler(struct sigchld_handler_t *h, int status) static void ip_change_handler(struct sigchld_handler_t *h, int status) { - struct pppd_compat_pd_t *pd = container_of(h, typeof(*pd), ip_change_hnd); + struct pppd_compat_pd *pd = container_of(h, typeof(*pd), ip_change_hnd); if (conf_verbose) { log_switch(NULL, pd->ses); log_ppp_info2("pppd_compat: ip-change finished (%i)\n", status); @@ -107,7 +108,7 @@ static void ip_change_handler(struct sigchld_handler_t *h, int status) static void ev_ses_starting(struct ap_session *ses) { - struct pppd_compat_pd_t *pd; + struct pppd_compat_pd *pd; pd = _malloc(sizeof(*pd)); if (!pd) { @@ -135,10 +136,29 @@ static void ev_ses_pre_up(struct ap_session *ses) char peername[64]; char calling_sid[64]; char called_sid[64]; - struct pppd_compat_pd_t *pd = find_pd(ses); + struct pppd_compat_pd *pd = find_pd(ses); if (!pd) return; + +#ifdef RADIUS + { + char *fname = _malloc(PATH_MAX); + if (!fname) { + log_emerg("pppd_compat: out of memory\n"); + return; + } + + sprintf(fname, "%s.%s", conf_radattr_prefix, ses->ifname); + + rename(pd->tmp_fname, fname); + + _free(fname); + _free(pd->tmp_fname); + pd->tmp_fname = NULL; + } +#endif + if (ses->ipv4) { pd->ipv4_addr = ses->ipv4->addr; @@ -194,7 +214,7 @@ static void ev_ses_started(struct ap_session *ses) char peername[64]; char calling_sid[64]; char called_sid[64]; - struct pppd_compat_pd_t *pd = find_pd(ses); + struct pppd_compat_pd *pd = find_pd(ses); if (!pd) return; @@ -246,7 +266,7 @@ static void ev_ses_finished(struct ap_session *ses) char connect_time[24]; char bytes_sent[24]; char bytes_rcvd[24]; - struct pppd_compat_pd_t *pd = find_pd(ses); + struct pppd_compat_pd *pd = find_pd(ses); if (!pd) return; @@ -311,7 +331,7 @@ static void ev_ses_finished(struct ap_session *ses) skip: #ifdef RADIUS if (pd->radattr_saved) - remove_radattr(ses); + remove_radattr(pd); #endif list_del(&pd->pd.entry); @@ -321,12 +341,12 @@ skip: #ifdef RADIUS static void ev_radius_access_accept(struct ev_radius_t *ev) { - struct pppd_compat_pd_t *pd = find_pd(ev->ses); + struct pppd_compat_pd *pd = find_pd(ev->ses); if (!pd) return; - write_radattr(ev->ses, ev->reply, 0); + write_radattr(pd, ev->reply); pd->radattr_saved = 1; } @@ -341,12 +361,12 @@ static void ev_radius_coa(struct ev_radius_t *ev) char peername[64]; char calling_sid[64]; char called_sid[64]; - struct pppd_compat_pd_t *pd = find_pd(ev->ses); + struct pppd_compat_pd *pd = find_pd(ev->ses); if (!pd) return; - write_radattr(ev->ses, ev->request, 1); + write_radattr(pd, ev->request); argv[4] = ipaddr; argv[5] = peer_ipaddr; @@ -377,28 +397,35 @@ static void ev_radius_coa(struct ev_radius_t *ev) log_error("pppd_compat: fork: %s\n", strerror(errno)); } -static void remove_radattr(struct ap_session *ses) +static void remove_radattr(struct pppd_compat_pd *pd) { char *fname; + + if (pd->tmp_fname) { + unlink(pd->tmp_fname); + _free(pd->tmp_fname); + } else { + fname = _malloc(PATH_MAX); + if (!fname) { + log_emerg("pppd_compat: out of memory\n"); + return; + } - fname = _malloc(PATH_MAX); - if (!fname) { - log_emerg("pppd_compat: out of memory\n"); - return; - } + sprintf(fname, "%s.%s", conf_radattr_prefix, pd->ses->ifname); - sprintf(fname, "%s.%s", conf_radattr_prefix, ses->ifname); - if (unlink(fname)) { - log_ppp_warn("pppd_compat: failed to remove '%s': %s\n", fname, strerror(errno)); - } - sprintf(fname, "%s_old.%s", conf_radattr_prefix, ses->ifname); - unlink(fname); + if (unlink(fname)) { + log_ppp_warn("pppd_compat: failed to remove '%s': %s\n", fname, strerror(errno)); + } + sprintf(fname, "%s_old.%s", conf_radattr_prefix, pd->ses->ifname); + unlink(fname); - _free(fname); + _free(fname); + } } -static void write_radattr(struct ap_session *ses, struct rad_packet_t *pack, int save_old) +static void write_radattr(struct pppd_compat_pd *pd, struct rad_packet_t *pack) { + struct ap_session *ses = pd->ses; struct rad_attr_t *attr; struct rad_dict_value_t *val; FILE *f; @@ -411,7 +438,7 @@ static void write_radattr(struct ap_session *ses, struct rad_packet_t *pack, int return; } - if (save_old) { + if (ses->state == AP_STATE_ACTIVE) { fname2 = _malloc(PATH_MAX); if (!fname2) { log_emerg("pppd_compat: out of memory\n"); @@ -420,12 +447,15 @@ static void write_radattr(struct ap_session *ses, struct rad_packet_t *pack, int } } - sprintf(fname1, "%s.%s", conf_radattr_prefix, ses->ifname); - if (save_old) { + if (ses->state == AP_STATE_ACTIVE) { + sprintf(fname1, "%s.%s", conf_radattr_prefix, ses->ifname); sprintf(fname2, "%s_old.%s", conf_radattr_prefix, ses->ifname); if (rename(fname1, fname2)) { log_ppp_warn("pppd_compat: rename: %s\n", strerror(errno)); } + } else { + sprintf(fname1, "%s.XXXXXX", conf_radattr_prefix); + mktemp(fname1); } f = fopen(fname1, "w"); @@ -460,16 +490,18 @@ static void write_radattr(struct ap_session *ses, struct rad_packet_t *pack, int } else log_ppp_warn("pppd_compat: failed to create '%s': %s\n", fname1, strerror(errno)); - _free(fname1); - if (save_old) + if (ses->state == AP_STATE_ACTIVE) { + _free(fname1); _free(fname2); + } else + pd->tmp_fname = fname1; } #endif -static struct pppd_compat_pd_t *find_pd(struct ap_session *ses) +static struct pppd_compat_pd *find_pd(struct ap_session *ses) { struct ap_private *pd; - struct pppd_compat_pd_t *cpd; + struct pppd_compat_pd *cpd; list_for_each_entry(pd, &ses->pd_list, entry) { if (pd->key == &pd_key) { @@ -482,7 +514,7 @@ static struct pppd_compat_pd_t *find_pd(struct ap_session *ses) return NULL; } -static void fill_argv(char **argv, struct pppd_compat_pd_t *pd, char *path) +static void fill_argv(char **argv, struct pppd_compat_pd *pd, char *path) { argv[0] = path; argv[1] = pd->ses->ifname; @@ -494,7 +526,7 @@ static void fill_argv(char **argv, struct pppd_compat_pd_t *pd, char *path) argv[7] = NULL; } -static void fill_env(char **env, struct pppd_compat_pd_t *pd) +static void fill_env(char **env, struct pppd_compat_pd *pd) { struct ap_session *ses = pd->ses; uint64_t tx_bytes, rx_bytes; |