summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-03 16:06:42 +0400
committerKozlov Dmitry <dima@server>2010-09-03 16:06:42 +0400
commitd00c2d1e3afc883683b3c40b6fbb116c3746b8d0 (patch)
tree918c9cbe47a114ce691175e66ccd0f90a5f5fa3a /accel-pptpd
parenta8ebd78892b99cad6aa055d1e0024df485536c17 (diff)
downloadaccel-ppp-xebd-d00c2d1e3afc883683b3c40b6fbb116c3746b8d0.tar.gz
accel-ppp-xebd-d00c2d1e3afc883683b3c40b6fbb116c3746b8d0.zip
lcp: implemented echo request/reply
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/accel-pptpd.conf12
-rw-r--r--accel-pptpd/lcp_opt_magic.c2
-rw-r--r--accel-pptpd/ppp_lcp.c91
-rw-r--r--accel-pptpd/ppp_lcp.h6
-rw-r--r--accel-pptpd/triton/conf_file.c4
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);