summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/ppp/ccp_mppe.c10
-rw-r--r--accel-pppd/ppp/ipcp_opt_ipaddr.c3
-rw-r--r--accel-pppd/ppp/ppp.h1
-rw-r--r--accel-pppd/ppp/ppp_ccp.c63
-rw-r--r--accel-pppd/ppp/ppp_ccp.h6
-rw-r--r--accel-pppd/ppp/ppp_fsm.c8
6 files changed, 69 insertions, 22 deletions
diff --git a/accel-pppd/ppp/ccp_mppe.c b/accel-pppd/ppp/ccp_mppe.c
index 58f5d4f2..cdc8950a 100644
--- a/accel-pppd/ppp/ccp_mppe.c
+++ b/accel-pppd/ppp/ccp_mppe.c
@@ -66,6 +66,9 @@ static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp)
mppe_opt->mppe = 1;
else
mppe_opt->mppe = -1;
+
+ if (conf_mppe == 2)
+ ccp->passive = 0;
mppe_opt->opt.id = CI_MPPE;
mppe_opt->opt.len = 6;
@@ -252,10 +255,12 @@ static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t *o
static void ev_mppe_keys(struct ev_mppe_keys_t *ev)
{
+ struct ppp_ccp_t *ccp = ccp_find_layer_data(ev->ppp);
struct mppe_option_t *mppe_opt = container_of(ccp_find_option(ev->ppp, &mppe_opt_hnd), typeof(*mppe_opt), opt);
if ((ev->type & 0x04) == 0) {
log_ppp_warn("mppe: 128-bit session keys not allowed, disabling mppe ...\n");
+ mppe_opt->mppe = 0;
return;
}
@@ -263,9 +268,10 @@ static void ev_mppe_keys(struct ev_mppe_keys_t *ev)
memcpy(mppe_opt->send_key, ev->send_key, 16);
mppe_opt->policy = ev->policy;
- if (ev->policy == 2)
+ if (ev->policy == 2) {
mppe_opt->mppe = 1;
- else if (ev->policy == 1) {
+ ccp->passive = 0;
+ } else if (ev->policy == 1) {
if (conf_mppe == 1)
mppe_opt->mppe = 1;
else
diff --git a/accel-pppd/ppp/ipcp_opt_ipaddr.c b/accel-pppd/ppp/ipcp_opt_ipaddr.c
index 388df199..d584fd7f 100644
--- a/accel-pppd/ppp/ipcp_opt_ipaddr.c
+++ b/accel-pppd/ppp/ipcp_opt_ipaddr.c
@@ -9,6 +9,7 @@
#include "ppp.h"
#include "ppp_ipcp.h"
+#include "ppp_ccp.h"
#include "log.h"
#include "ipdb.h"
#include "iprange.h"
@@ -133,7 +134,7 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
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 = !ipcp->ppp->ccp_started;
+ ipcp->delay_ack = ccp_ipcp_started(ipcp->ppp);
return IPCP_OPT_ACK;
}
diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h
index 4476f05a..9d2409ed 100644
--- a/accel-pppd/ppp/ppp.h
+++ b/accel-pppd/ppp/ppp.h
@@ -103,7 +103,6 @@ struct ppp_t
int terminating:1;
int terminated:1;
int terminate_cause;
- int ccp_started:1;
void *buf;
int buf_size;
diff --git a/accel-pppd/ppp/ppp_ccp.c b/accel-pppd/ppp/ppp_ccp.c
index 9b7ac3e7..e59a0638 100644
--- a/accel-pppd/ppp/ppp_ccp.c
+++ b/accel-pppd/ppp/ppp_ccp.c
@@ -25,6 +25,7 @@ struct recv_opt_t
};
static int conf_ccp = 1;
+static int conf_ccp_max_configure = 3;
static struct ppp_layer_t ccp_layer;
static LIST_HEAD(option_handlers);
@@ -104,14 +105,16 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp)
ppp_register_unit_handler(ppp, &ccp->hnd);
+ ccp->passive = 1;
+
INIT_LIST_HEAD(&ccp->options);
ccp_options_init(ccp);
-
- ccp->passive = 0;
ccp->fsm.proto = PPP_CCP;
ppp_fsm_init(&ccp->fsm);
+ ccp->fsm.max_configure = conf_ccp_max_configure;
+
ccp->fsm.layer_up = ccp_layer_up;
ccp->fsm.layer_finished = ccp_layer_down;
ccp->fsm.send_conf_req = send_conf_req;
@@ -133,14 +136,18 @@ int ccp_layer_start(struct ppp_layer_data_t *ld)
log_ppp_debug("ccp_layer_start\n");
if (list_empty(&ccp->options) || !conf_ccp) {
- ccp->ppp->ccp_started = 1;
+ ccp->started = 1;
ppp_layer_started(ccp->ppp, &ccp->ld);
return 0;
}
-
- ppp_fsm_lower_up(&ccp->fsm);
- if (ppp_fsm_open(&ccp->fsm))
- return -1;
+
+ ccp->starting = 1;
+
+ if (!ccp->passive) {
+ ppp_fsm_lower_up(&ccp->fsm);
+ if (ppp_fsm_open(&ccp->fsm))
+ return -1;
+ }
if (ccp_set_flags(ccp->ppp->unit_fd, 1, 0)) {
ppp_fsm_close(&ccp->fsm);
@@ -184,7 +191,6 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm)
if (!ccp->started) {
log_ppp_debug("ccp_layer_started\n");
ccp->started = 1;
- ccp->ppp->ccp_started = 1;
if (ccp_set_flags(ccp->ppp->unit_fd, 1, 1)) {
ppp_terminate(ccp->ppp, TERM_NAS_ERROR, 0);
return;
@@ -199,7 +205,6 @@ static void ccp_layer_down(struct ppp_fsm_t *fsm)
log_ppp_debug("ccp_layer_finished\n");
- ccp->ppp->ccp_started = 1;
if (!ccp->started) {
ccp->started = 1;
ppp_fsm_close(fsm);
@@ -229,10 +234,8 @@ static int send_conf_req(struct ppp_fsm_t *fsm)
ccp->need_req = 0;
- if (ccp->passive) {
- ccp->passive--;
+ if (ccp->passive)
return 0;
- }
buf = _malloc(ccp->conf_req_len);
ccp_hdr = (struct ccp_hdr_t*)buf;
@@ -613,7 +616,7 @@ static void ccp_recv(struct ppp_handler_t*h)
struct ppp_ccp_t *ccp = container_of(h, typeof(*ccp), hnd);
int r;
- if (ccp->fsm.fsm_state == FSM_Initial || ccp->fsm.fsm_state == FSM_Closed || ccp->ppp->terminating) {
+ if (!ccp->starting || ccp->fsm.fsm_state == FSM_Closed || ccp->ppp->terminating) {
if (conf_ppp_verbose)
log_ppp_warn("CCP: discarding packet\n");
if (ccp->fsm.fsm_state == FSM_Closed || !conf_ccp)
@@ -638,8 +641,13 @@ static void ccp_recv(struct ppp_handler_t*h)
ccp->fsm.recv_id = hdr->id;
switch(hdr->code) {
- case CONFREQ:
+ case CONFREQ:
r = ccp_recv_conf_req(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
+ if (ccp->passive) {
+ ppp_fsm_lower_up(&ccp->fsm);
+ ppp_fsm_open(&ccp->fsm);
+ ccp->passive = 0;
+ }
if (ccp->started) {
if (r == CCP_OPT_ACK)
send_conf_ack(&ccp->fsm);
@@ -660,10 +668,10 @@ static void ccp_recv(struct ppp_handler_t*h)
}
ccp_free_conf_req(ccp);
- if (r == CCP_OPT_ACK && ccp->passive) {
+ /*if (r == CCP_OPT_ACK && ccp->passive) {
ccp->passive = 0;
send_conf_req(&ccp->fsm);
- }
+ }*/
if (r == CCP_OPT_FAIL)
ppp_terminate(ccp->ppp, TERM_USER_ERROR, 0);
break;
@@ -732,6 +740,10 @@ int ccp_option_register(struct ccp_option_handler_t *h)
return 0;
}
+struct ppp_ccp_t *ccp_find_layer_data(struct ppp_t *ppp)
+{
+ return container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(struct ppp_ccp_t), ld);
+}
struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h)
{
struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld);
@@ -745,6 +757,21 @@ struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handle
abort();
}
+int ccp_ipcp_started(struct ppp_t *ppp)
+{
+ struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld);
+
+ if (ccp->passive) {
+ ccp->fsm.fsm_state = FSM_Closed;
+ ccp->started = 1;
+ ppp_layer_started(ccp->ppp, &ccp->ld);
+
+ return 0;
+ }
+
+ return !ccp->started;
+}
+
static struct ppp_layer_t ccp_layer=
{
.init = ccp_layer_init,
@@ -760,6 +787,10 @@ static void load_config(void)
opt = conf_get_opt("ppp", "ccp");
if (opt && atoi(opt) >= 0)
conf_ccp = atoi(opt);
+
+ opt = conf_get_opt("ppp", "ccp-max-configure");
+ if (opt && atoi(opt) > 0)
+ conf_ccp_max_configure = atoi(opt);
}
static void ccp_init(void)
diff --git a/accel-pppd/ppp/ppp_ccp.h b/accel-pppd/ppp/ppp_ccp.h
index 2c2dc6dd..11c8a221 100644
--- a/accel-pppd/ppp/ppp_ccp.h
+++ b/accel-pppd/ppp/ppp_ccp.h
@@ -84,7 +84,8 @@ struct ppp_ccp_t
int ropt_len;
int conf_req_len;
- int passive;
+ int passive:1;
+ int starting:1;
int started:1;
int need_req:1;
};
@@ -92,5 +93,8 @@ struct ppp_ccp_t
int ccp_option_register(struct ccp_option_handler_t *h);
struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h);
+struct ppp_ccp_t *ccp_find_layer_data(struct ppp_t *ppp);
+int ccp_ipcp_started(struct ppp_t *ppp);
+
#endif
diff --git a/accel-pppd/ppp/ppp_fsm.c b/accel-pppd/ppp/ppp_fsm.c
index 180b30e9..33f82375 100644
--- a/accel-pppd/ppp/ppp_fsm.c
+++ b/accel-pppd/ppp/ppp_fsm.c
@@ -97,7 +97,7 @@ int ppp_fsm_open(struct ppp_fsm_t *layer)
switch(layer->fsm_state)
{
case FSM_Initial:
- if (layer->layer_started) layer->layer_started(layer);
+ //if (layer->layer_started) layer->layer_started(layer);
layer->fsm_state=FSM_Starting;
break;
case FSM_Starting:
@@ -215,6 +215,12 @@ void ppp_fsm_recv_conf_req_ack(struct ppp_fsm_t *layer)
--layer->restart_counter;
if (layer->send_conf_req) layer->send_conf_req(layer);
case FSM_Req_Sent:
+ if (layer->send_conf_ack) layer->send_conf_ack(layer);
+ init_req_counter(layer,layer->max_configure);
+ --layer->restart_counter;
+ if (layer->send_conf_req) layer->send_conf_req(layer);
+ layer->fsm_state=FSM_Ack_Sent;
+ break;
case FSM_Ack_Sent:
if (layer->send_conf_ack) layer->send_conf_ack(layer);
layer->fsm_state=FSM_Ack_Sent;