summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2011-04-28 12:12:10 +0400
committerKozlov Dmitry <dima@server>2011-04-28 12:12:26 +0400
commite6bd476ac97b342d201d5eb436b9a6c43e7f135e (patch)
tree2433a1fcb5d260425a4869e28b3b3630cfaf8f03 /accel-pppd
parent2dbb0397c7371ad55f6c90fe0fbe305058a39a09 (diff)
downloadaccel-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.c24
-rw-r--r--accel-pppd/ppp/ipcp_opt_ipaddr.c51
-rw-r--r--accel-pppd/ppp/ppp_ccp.c30
-rw-r--r--accel-pppd/ppp/ppp_fsm.c8
-rw-r--r--accel-pppd/ppp/ppp_fsm.h1
-rw-r--r--accel-pppd/ppp/ppp_ipcp.c40
-rw-r--r--accel-pppd/ppp/ppp_ipcp.h4
-rw-r--r--accel-pppd/ppp/ppp_lcp.c2
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);