diff options
author | Kozlov Dmitry <dima@server> | 2010-09-03 16:06:42 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-03 16:06:42 +0400 |
commit | d00c2d1e3afc883683b3c40b6fbb116c3746b8d0 (patch) | |
tree | 918c9cbe47a114ce691175e66ccd0f90a5f5fa3a | |
parent | a8ebd78892b99cad6aa055d1e0024df485536c17 (diff) | |
download | accel-ppp-xebd-d00c2d1e3afc883683b3c40b6fbb116c3746b8d0.tar.gz accel-ppp-xebd-d00c2d1e3afc883683b3c40b6fbb116c3746b8d0.zip |
lcp: implemented echo request/reply
-rw-r--r-- | accel-pptpd/accel-pptpd.conf | 12 | ||||
-rw-r--r-- | accel-pptpd/lcp_opt_magic.c | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 91 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.h | 6 | ||||
-rw-r--r-- | accel-pptpd/triton/conf_file.c | 4 |
5 files changed, 101 insertions, 14 deletions
diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf new file mode 100644 index 0000000..a0c5fdb --- /dev/null +++ b/accel-pptpd/accel-pptpd.conf @@ -0,0 +1,12 @@ +[modules] +libpap.so +libmschap-v1.so +libmschap-v2.so + + +[core] +log-error=/dev/stderr + +[lcp] +echo-interval=3 +echo-failure=3 diff --git a/accel-pptpd/lcp_opt_magic.c b/accel-pptpd/lcp_opt_magic.c index 53438b9..dc94ac6 100644 --- a/accel-pptpd/lcp_opt_magic.c +++ b/accel-pptpd/lcp_opt_magic.c @@ -35,6 +35,8 @@ static struct lcp_option_t *magic_init(struct ppp_lcp_t *lcp) magic_opt->opt.id=CI_MAGIC; magic_opt->opt.len=6; + lcp->magic = magic_opt->magic; + return &magic_opt->opt; } diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c index ac885c7..d1c8707 100644 --- a/accel-pptpd/ppp_lcp.c +++ b/accel-pptpd/ppp_lcp.c @@ -29,6 +29,8 @@ static void send_conf_ack(struct ppp_fsm_t*); static void send_conf_nak(struct ppp_fsm_t*); static void send_conf_rej(struct ppp_fsm_t*); static void lcp_recv(struct ppp_handler_t*); +static void start_echo(struct ppp_lcp_t *lcp); +static void stop_echo(struct ppp_lcp_t *lcp); static void lcp_options_init(struct ppp_lcp_t *lcp) { @@ -106,6 +108,9 @@ void lcp_layer_finish(struct ppp_layer_data_t *ld) struct ppp_lcp_t *lcp=container_of(ld,typeof(*lcp),ld); log_debug("lcp_layer_finish\n"); + + stop_echo(lcp); + ppp_fsm_close(&lcp->fsm); } @@ -114,7 +119,8 @@ void lcp_layer_free(struct ppp_layer_data_t *ld) struct ppp_lcp_t *lcp=container_of(ld,typeof(*lcp),ld); log_debug("lcp_layer_free\n"); - + + stop_echo(lcp); ppp_unregister_handler(lcp->ppp,&lcp->hnd); lcp_options_free(lcp); @@ -126,12 +132,15 @@ static void lcp_layer_up(struct ppp_fsm_t *fsm) struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); log_debug("lcp_layer_started\n"); ppp_layer_started(lcp->ppp,&lcp->ld); + + start_echo(lcp); } static void lcp_layer_down(struct ppp_fsm_t *fsm) { struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); log_debug("lcp_layer_finished\n"); + stop_echo(lcp); ppp_layer_finished(lcp->ppp,&lcp->ld); } @@ -453,25 +462,83 @@ static int lcp_recv_conf_ack(struct ppp_lcp_t *lcp,uint8_t *data,int size) static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp,uint8_t *data,int size) { + uint32_t magic = *(uint32_t *)data; + + if (size != 4) { + log_error("lcp:echo: magic number size mismatch\n"); + ppp_terminate(lcp->ppp, 0); + } + + log_debug("recv [LCP EchoRep id=%x <magic %x>]\n",lcp->fsm.recv_id,magic); + if (magic == lcp->magic) { + log_error("lcp:echo: loop-back detected\n"); + ppp_terminate(lcp->ppp, 0); + } + + lcp->echo_sent = 0; } -void send_echo_reply(struct ppp_lcp_t *lcp) +static void send_echo_reply(struct ppp_lcp_t *lcp) +{ + struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)lcp->ppp->chan_buf; + uint32_t magic = *(uint32_t *)(hdr+1); + + hdr->code=ECHOREP; + log_debug("send [LCP EchoRep id=%x <magic %x>]\n", hdr->id, magic); + + ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2); +} +static void send_echo_request(struct triton_timer_t *t) { - struct lcp_echo_reply_t + struct ppp_lcp_t *lcp = container_of(t, typeof(*lcp), echo_timer); + struct lcp_echo_req_t { struct lcp_hdr_t hdr; - struct lcp_opt32_t magic; - } __attribute__((packed)) msg = - { - .hdr.proto=htons(PPP_LCP), - .hdr.code=ECHOREP, - .hdr.id=lcp->fsm.recv_id, - .hdr.len=htons(8), - .magic.val=0, + uint32_t magic; + } __attribute__((packed)) msg = { + .hdr.proto = htons(PPP_LCP), + .hdr.code = ECHOREQ, + .hdr.id = ++lcp->fsm.id, + .hdr.len = htons(8), + .magic = lcp->magic, }; - ppp_chan_send(lcp->ppp,&msg,ntohs(msg.hdr.len)+2); + if (++lcp->echo_sent > lcp->echo_failure) { + log_warn("lcp: no echo reply\n"); + ppp_terminate(lcp->ppp, 0); + } else { + log_debug("send [LCP EchoReq id=%x <magic %x>]\n", msg.hdr.id, msg.magic); + ppp_chan_send(lcp->ppp,&msg,ntohs(msg.hdr.len)+2); + } +} + +static void start_echo(struct ppp_lcp_t *lcp) +{ + char *opt; + + opt = conf_get_opt("lcp","echo-failure"); + if (!opt || atoi(opt) <= 0) + return; + + lcp->echo_failure = atoi(opt); + + opt = conf_get_opt("lcp","echo-interval"); + if (!opt || atoi(opt) <= 0) + return; + + lcp->echo_interval = atoi(opt); + + lcp->echo_timer.period = lcp->echo_interval * 1000; + lcp->echo_timer.expire = send_echo_request; + triton_timer_add(lcp->ppp->ctrl->ctx, &lcp->echo_timer, 0); +} +static void stop_echo(struct ppp_lcp_t *lcp) +{ + if (lcp->echo_interval) { + triton_timer_del(&lcp->echo_timer); + lcp->echo_interval = 0; + } } static void lcp_recv(struct ppp_handler_t*h) diff --git a/accel-pptpd/ppp_lcp.h b/accel-pptpd/ppp_lcp.h index d241de6..7110db2 100644 --- a/accel-pptpd/ppp_lcp.h +++ b/accel-pptpd/ppp_lcp.h @@ -116,6 +116,12 @@ struct ppp_lcp_t struct ppp_t *ppp; struct list_head options; + struct triton_timer_t echo_timer; + int echo_interval; + int echo_failure; + int echo_sent; + int magic; + struct list_head ropt_list; // last received ConfReq int ropt_len; diff --git a/accel-pptpd/triton/conf_file.c b/accel-pptpd/triton/conf_file.c index e99afaa..c6ba745 100644 --- a/accel-pptpd/triton/conf_file.c +++ b/accel-pptpd/triton/conf_file.c @@ -164,12 +164,12 @@ static struct conf_option_t *find_item(struct conf_sect_t *sect, const char *nam return NULL; } -struct conf_sect_t * conf_get_section(const char *name) +__export struct conf_sect_t * conf_get_section(const char *name) { return find_sect(name); } -char * conf_get_opt(const char *sect, const char *name) +__export char * conf_get_opt(const char *sect, const char *name) { struct conf_option_t *opt; struct conf_sect_t *s = conf_get_section(sect); |