diff options
author | Kozlov Dmitry <dima@server> | 2011-04-28 12:12:10 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2011-04-28 12:12:26 +0400 |
commit | e6bd476ac97b342d201d5eb436b9a6c43e7f135e (patch) | |
tree | 2433a1fcb5d260425a4869e28b3b3630cfaf8f03 /accel-pppd | |
parent | 2dbb0397c7371ad55f6c90fe0fbe305058a39a09 (diff) | |
download | accel-ppp-e6bd476ac97b342d201d5eb436b9a6c43e7f135e.tar.gz accel-ppp-e6bd476ac97b342d201d5eb436b9a6c43e7f135e.zip |
various ppp and mppe improvements
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ppp/ccp_mppe.c | 24 | ||||
-rw-r--r-- | accel-pppd/ppp/ipcp_opt_ipaddr.c | 51 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_ccp.c | 30 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_fsm.c | 8 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_fsm.h | 1 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_ipcp.c | 40 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_ipcp.h | 4 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 2 |
8 files changed, 106 insertions, 54 deletions
diff --git a/accel-pppd/ppp/ccp_mppe.c b/accel-pppd/ppp/ccp_mppe.c index 21280c4..9c3febe 100644 --- a/accel-pppd/ppp/ccp_mppe.c +++ b/accel-pppd/ppp/ccp_mppe.c @@ -35,6 +35,7 @@ struct mppe_option_t { struct ccp_option_t opt; int mppe; + int enabled; uint8_t recv_key[16]; uint8_t send_key[16]; int policy; // 1 - allowed, 2 - required @@ -55,11 +56,17 @@ static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp) { struct mppe_option_t *mppe_opt = _malloc(sizeof(*mppe_opt)); memset(mppe_opt, 0, sizeof(*mppe_opt)); - mppe_opt->policy = conf_mppe; - if (conf_mppe) + + if (conf_mppe != -1) + mppe_opt->policy = conf_mppe; + else + mppe_opt->policy = 1; + + if (conf_mppe > 0) mppe_opt->mppe = 1; else mppe_opt->mppe = -1; + mppe_opt->opt.id = CI_MPPE; mppe_opt->opt.len = 6; @@ -142,11 +149,11 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr; - /*if (!ptr) { + if (!ptr) { if (mppe_opt->policy == 2) return CCP_OPT_NAK; return CCP_OPT_ACK; - }*/ + } if (opt32->hdr.len != 6) return CCP_OPT_REJ; @@ -157,7 +164,7 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u } else if (mppe_opt->policy == 1) { if (ntohl(opt32->val) == (MPPE_S | MPPE_H)) mppe_opt->mppe = 1; - else if ((ntohl(opt32->val) & (MPPE_S | MPPE_H)) == (MPPE_S | MPPE_H)) { + else if (((ntohl(opt32->val) & (MPPE_S | MPPE_H)) == (MPPE_S | MPPE_H)) || conf_mppe == 1) { mppe_opt->mppe = 1; return CCP_OPT_NAK; } else if (opt32->val) { @@ -172,7 +179,10 @@ static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u if (setup_mppe_key(ccp->ppp->unit_fd, 1, mppe_opt->send_key)) return CCP_OPT_REJ; - decrease_mtu(ccp->ppp); + if (!mppe_opt->enabled) { + decrease_mtu(ccp->ppp); + mppe_opt->enabled = 1; + } log_ppp_debug(" (mppe enabled)"); } @@ -184,7 +194,7 @@ static int mppe_recv_conf_rej(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, u { struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); - if (mppe_opt->mppe != 2) { + if (mppe_opt->policy != 2) { mppe_opt->mppe = -1; return 0; } diff --git a/accel-pppd/ppp/ipcp_opt_ipaddr.c b/accel-pppd/ppp/ipcp_opt_ipaddr.c index 334f425..26d72d4 100644 --- a/accel-pppd/ppp/ipcp_opt_ipaddr.c +++ b/accel-pppd/ppp/ipcp_opt_ipaddr.c @@ -126,15 +126,16 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o { struct ipaddr_option_t *ipaddr_opt = container_of(opt,typeof(*ipaddr_opt), opt); struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t*)ptr; - struct ifreq ifr; - struct sockaddr_in addr; - struct npioctl np; if (opt32->hdr.len != 6) return IPCP_OPT_REJ; - if (ipaddr_opt->ip->peer_addr == opt32->val) - goto ack; + if (ipaddr_opt->ip->peer_addr == opt32->val) { + ipcp->ppp->ipaddr = ipaddr_opt->ip->addr; + ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr; + ipcp->delay_ack = 1; + return IPCP_OPT_ACK; + } /*if (!ipaddr_opt->peer_addr) { ipaddr_opt->peer_addr = opt32->val; @@ -142,28 +143,19 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o }*/ return IPCP_OPT_NAK; +} -ack: - if (ipaddr_opt->started) - return IPCP_OPT_ACK; +static void if_up(struct ppp_t *ppp) +{ + struct ipaddr_option_t *ipaddr_opt = container_of(ipcp_find_option(ppp, &ipaddr_opt_hnd), typeof(*ipaddr_opt), opt); + struct ifreq ifr; + struct sockaddr_in addr; + struct npioctl np; - ipaddr_opt->started = 1; - - ipcp->ppp->ipaddr = ipaddr_opt->ip->addr; - ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr; - - triton_event_fire(EV_PPP_ACCT_START, ipcp->ppp); - if (ipcp->ppp->stop_time) - return IPCP_OPT_ACK; - - triton_event_fire(EV_PPP_PRE_UP, ipcp->ppp); - if (ipcp->ppp->stop_time) - return IPCP_OPT_ACK; - memset(&ifr, 0, sizeof(ifr)); memset(&addr, 0, sizeof(addr)); - strcpy(ifr.ifr_name, ipcp->ppp->ifname); + strcpy(ifr.ifr_name, ppp->ifname); addr.sin_family = AF_INET; addr.sin_addr.s_addr = ipaddr_opt->ip->addr; @@ -177,6 +169,14 @@ ack: if (ioctl(sock_fd, SIOCSIFDSTADDR, &ifr)) log_ppp_error("ipcp: failed to set remote PA address: %s\n", strerror(errno)); + + triton_event_fire(EV_PPP_ACCT_START, ppp); + if (ppp->stop_time) + return; + + triton_event_fire(EV_PPP_PRE_UP, ppp); + if (ppp->stop_time) + return; if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr)) log_ppp_error("ipcp: failed to get interface flags: %s\n", strerror(errno)); @@ -189,10 +189,10 @@ ack: np.protocol = PPP_IP; np.mode = NPMODE_PASS; - if (ioctl(ipcp->ppp->unit_fd, PPPIOCSNPMODE, &np)) + if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) log_ppp_error("ipcp: failed to set NP mode: %s\n", strerror(errno)); - - return IPCP_OPT_ACK; + + ipcp_send_ack(ppp); } static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr) @@ -223,5 +223,6 @@ static void __init ipaddr_opt_init() ipcp_option_register(&ipaddr_opt_hnd); load_config(); triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); + triton_event_register_handler(EV_PPP_STARTED, (triton_event_func)if_up); } diff --git a/accel-pppd/ppp/ppp_ccp.c b/accel-pppd/ppp/ppp_ccp.c index d4732fa..20ccd69 100644 --- a/accel-pppd/ppp/ppp_ccp.c +++ b/accel-pppd/ppp/ppp_ccp.c @@ -180,9 +180,8 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm) { struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm); - log_ppp_debug("ccp_layer_started\n"); - if (!ccp->started) { + log_ppp_debug("ccp_layer_started\n"); ccp->started = 1; if (ccp_set_flags(ccp->ppp->unit_fd, 1, 1)) { ppp_terminate(ccp->ppp, TERM_NAS_ERROR, 0); @@ -236,7 +235,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) ccp_hdr->proto = htons(PPP_CCP); ccp_hdr->code = CONFREQ; - ccp_hdr->id = ++ccp->fsm.id; + ccp_hdr->id = ccp->fsm.id; ccp_hdr->len = 0; ptr = (uint8_t*)(ccp_hdr + 1); @@ -286,7 +285,7 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm); uint8_t *buf = _malloc(ccp->conf_req_len), *ptr = buf; struct ccp_hdr_t *ccp_hdr = (struct ccp_hdr_t*)ptr; - struct recv_opt_t *ropt; + struct ccp_option_t *lopt; if (conf_ppp_verbose) log_ppp_info2("send [CCP ConfNak id=%x", ccp->fsm.recv_id); @@ -298,13 +297,13 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) ptr += sizeof(*ccp_hdr); - list_for_each_entry(ropt, &ccp->ropt_list, entry) { - if (ropt->state == CCP_OPT_NAK) { + list_for_each_entry(lopt, &ccp->options, entry) { + if (lopt->state == CCP_OPT_NAK) { if (conf_ppp_verbose) { log_ppp_info2(" "); - ropt->lopt->h->print(log_ppp_info2, ropt->lopt, NULL); + lopt->h->print(log_ppp_info2, lopt, NULL); } - ptr += ropt->lopt->h->send_conf_nak(ccp, ropt->lopt, ptr); + ptr += lopt->h->send_conf_nak(ccp, lopt, ptr); } } @@ -427,15 +426,14 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp, uint8_t *data, int size) if (conf_ppp_verbose) log_ppp_info2("]\n"); - /*list_for_each_entry(lopt,&ccp->options,entry) - { - if (lopt->state==CCP_OPT_NONE) - { - r=lopt->h->recv_conf_req(ccp,lopt,NULL); - lopt->state=r; - if (r<ret) ret=r; + list_for_each_entry(lopt, &ccp->options, entry) { + if (lopt->state == CCP_OPT_NONE) { + r = lopt->h->recv_conf_req(ccp, lopt, NULL); + lopt->state = r; + if (r < ret) + ret = r; } - }*/ + } return ret; } diff --git a/accel-pppd/ppp/ppp_fsm.c b/accel-pppd/ppp/ppp_fsm.c index c6bc430..0e27a78 100644 --- a/accel-pppd/ppp/ppp_fsm.c +++ b/accel-pppd/ppp/ppp_fsm.c @@ -14,7 +14,7 @@ static int conf_max_terminate = 2; static int conf_max_configure = 10; static int conf_max_failure = 10; -static int conf_timeout = 5; +static int conf_timeout = 1; void send_term_req(struct ppp_fsm_t *layer); void send_term_ack(struct ppp_fsm_t *layer); @@ -35,7 +35,8 @@ void ppp_fsm_init(struct ppp_fsm_t *layer) layer->max_terminate = conf_max_terminate; layer->max_configure = conf_max_configure; layer->max_failure = conf_max_failure; - layer->timeout = conf_timeout; + + layer->id = 1; } void ppp_fsm_free(struct ppp_fsm_t *layer) { @@ -168,7 +169,6 @@ void ppp_fsm_timeout0(struct ppp_fsm_t *layer) case FSM_Req_Sent: case FSM_Ack_Sent: --layer->restart_counter; - --layer->id; if (layer->send_conf_req) layer->send_conf_req(layer); break; default: @@ -315,6 +315,7 @@ void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer) void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer) { + ++layer->id; switch(layer->fsm_state) { case FSM_Closed: @@ -351,6 +352,7 @@ void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer) void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer) { + ++layer->id; switch(layer->fsm_state) { case FSM_Closed: diff --git a/accel-pppd/ppp/ppp_fsm.h b/accel-pppd/ppp/ppp_fsm.h index 6010240..6d2fb14 100644 --- a/accel-pppd/ppp/ppp_fsm.h +++ b/accel-pppd/ppp/ppp_fsm.h @@ -30,7 +30,6 @@ struct ppp_fsm_t int max_terminate; int max_configure; int max_failure; - int timeout; int conf_failure; int id; diff --git a/accel-pppd/ppp/ppp_ipcp.c b/accel-pppd/ppp/ppp_ipcp.c index 5d66c9d..f8b2f48 100644 --- a/accel-pppd/ppp/ppp_ipcp.c +++ b/accel-pppd/ppp/ppp_ipcp.c @@ -23,6 +23,7 @@ struct recv_opt_t }; static LIST_HEAD(option_handlers); +static struct ppp_layer_t ipcp_layer; static void ipcp_layer_up(struct ppp_fsm_t*); static void ipcp_layer_down(struct ppp_fsm_t*); @@ -60,6 +61,9 @@ static void ipcp_options_free(struct ppp_ipcp_t *ipcp) list_del(&lopt->entry); lopt->h->free(ipcp, lopt); } + + if (ipcp->buf) + _free(ipcp->buf); } static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp) @@ -181,7 +185,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) ipcp_hdr->proto = htons(PPP_IPCP); ipcp_hdr->code = CONFREQ; - ipcp_hdr->id = ++ipcp->fsm.id; + ipcp_hdr->id = ipcp->fsm.id; ipcp_hdr->len = 0; ptr += sizeof(*ipcp_hdr); @@ -221,6 +225,27 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm); struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf; + if (ipcp->delay_ack) { + if (!ipcp->buf) { + ipcp->buf = _malloc(ntohs(hdr->len) + 2); + memcpy(ipcp->buf, ipcp->ppp->buf, ntohs(hdr->len) + 2); + } + return; + } + + hdr->code = CONFACK; + + if (conf_ppp_verbose) + log_ppp_info2("send [IPCP ConfAck id=%x]\n", ipcp->fsm.recv_id); + + ppp_unit_send(ipcp->ppp, hdr, ntohs(hdr->len) + 2); +} + +void ipcp_send_ack(struct ppp_t *ppp) +{ + struct ppp_ipcp_t *ipcp = container_of(ppp_find_layer_data(ppp, &ipcp_layer), typeof(*ipcp), ld); + struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->buf; + hdr->code = CONFACK; if (conf_ppp_verbose) @@ -650,6 +675,19 @@ int ipcp_option_register(struct ipcp_option_handler_t *h) return 0; } +struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h) +{ + struct ppp_ipcp_t *ipcp = container_of(ppp_find_layer_data(ppp, &ipcp_layer), typeof(*ipcp), ld); + struct ipcp_option_t *opt; + + list_for_each_entry(opt, &ipcp->options, entry) + if (opt->h == h) + return opt; + + log_emerg("ipcp: BUG: option not found\n"); + abort(); +} + static struct ppp_layer_t ipcp_layer = { .init = ipcp_layer_init, diff --git a/accel-pppd/ppp/ppp_ipcp.h b/accel-pppd/ppp/ppp_ipcp.h index c955987..2197edd 100644 --- a/accel-pppd/ppp/ppp_ipcp.h +++ b/accel-pppd/ppp/ppp_ipcp.h @@ -82,15 +82,19 @@ struct ppp_ipcp_t struct ppp_fsm_t fsm; struct ppp_t *ppp; struct list_head options; + void *buf; struct list_head ropt_list; // last received ConfReq int ropt_len; int conf_req_len; int started:1; + int delay_ack:1; }; int ipcp_option_register(struct ipcp_option_handler_t *h); +struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h); +void ipcp_send_ack(struct ppp_t *); #endif diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index 1d23ac6..279d815 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -214,7 +214,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) lcp_hdr->proto = htons(PPP_LCP); lcp_hdr->code = CONFREQ; - lcp_hdr->id = ++lcp->fsm.id; + lcp_hdr->id = lcp->fsm.id; lcp_hdr->len = 0; ptr += sizeof(*lcp_hdr); |