summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-08-20 17:50:13 +0400
committerKozlov Dmitry <dima@server>2010-08-20 17:50:13 +0400
commit1dbf2a2820c428b8ba8b04d6ec30c78f642cbfb3 (patch)
treeb688869cf739aa1c20ddc83335c59ca7fdddf472
parent128961dd4ccfae1fc6c973be704d55a27932a280 (diff)
downloadaccel-ppp-xebd-1dbf2a2820c428b8ba8b04d6ec30c78f642cbfb3.tar.gz
accel-ppp-xebd-1dbf2a2820c428b8ba8b04d6ec30c78f642cbfb3.zip
using dynamic ppp layers instead of hard coded, but signal transition/handling (up,down,open,close) not fully elaborated
-rw-r--r--accel-pptpd/CMakeLists.txt2
-rw-r--r--accel-pptpd/auth_pap.c10
-rw-r--r--accel-pptpd/ppp.c368
-rw-r--r--accel-pptpd/ppp.h79
-rw-r--r--accel-pptpd/ppp_auth.c131
-rw-r--r--accel-pptpd/ppp_fsm.c6
-rw-r--r--accel-pptpd/ppp_lcp.c71
-rw-r--r--accel-pptpd/ppp_lcp.h1
-rw-r--r--accel-pptpd/pptp.c (renamed from accel-pptpd/ctrl.c)85
9 files changed, 524 insertions, 229 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt
index 3279141..2a038f1 100644
--- a/accel-pptpd/CMakeLists.txt
+++ b/accel-pptpd/CMakeLists.txt
@@ -7,7 +7,7 @@ ADD_SUBDIRECTORY(triton)
ADD_EXECUTABLE(pptpd
pptpd.c
- ctrl.c
+ pptp.c
log.c
ppp.c
ppp_fsm.c
diff --git a/accel-pptpd/auth_pap.c b/accel-pptpd/auth_pap.c
index 95d5b1e..e92f253 100644
--- a/accel-pptpd/auth_pap.c
+++ b/accel-pptpd/auth_pap.c
@@ -84,7 +84,7 @@ static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth)
d->h.proto=PPP_PAP;
d->h.recv=pap_recv;
- ppp_register_handler(ppp,&d->h);
+ ppp_register_chan_handler(ppp,&d->h);
return 0;
}
@@ -120,7 +120,7 @@ static void pap_send_ack(struct pap_auth_data_t *p, int id)
log_debug("send [PAP AuthAck id=%x \"%s\"]\n",id,MSG_SUCCESSED);
- ppp_send(p->ppp,msg,ntohs(msg->hdr.len)+2);
+ ppp_chan_send(p->ppp,msg,ntohs(msg->hdr.len)+2);
}
static void pap_send_nak(struct pap_auth_data_t *p,int id)
@@ -136,7 +136,7 @@ static void pap_send_nak(struct pap_auth_data_t *p,int id)
log_debug("send [PAP AuthNak id=%x \"%s\"]\n",id,MSG_FAILED);
- ppp_send(p->ppp,msg,ntohs(msg->hdr.len)+2);
+ ppp_chan_send(p->ppp,msg,ntohs(msg->hdr.len)+2);
}
static int pap_recv_req(struct pap_auth_data_t *p,struct pap_hdr_t *hdr)
@@ -190,9 +190,9 @@ static int pap_recv_req(struct pap_auth_data_t *p,struct pap_hdr_t *hdr)
static void pap_recv(struct ppp_handler_t *h)
{
struct pap_auth_data_t *d=container_of(h,typeof(*d),h);
- struct pap_hdr_t *hdr=(struct pap_hdr_t *)d->ppp->in_buf;
+ struct pap_hdr_t *hdr=(struct pap_hdr_t *)d->ppp->chan_buf;
- if (d->ppp->in_buf_size<sizeof(*hdr) || ntohs(hdr->len)<HDR_LEN || ntohs(hdr->len)<d->ppp->in_buf_size-2)
+ if (d->ppp->chan_buf_size<sizeof(*hdr) || ntohs(hdr->len)<HDR_LEN || ntohs(hdr->len)<d->ppp->chan_buf_size-2)
{
log_warn("PAP: short packet received\n");
return;
diff --git a/accel-pptpd/ppp.c b/accel-pptpd/ppp.c
index b032b06..58f99dc 100644
--- a/accel-pptpd/ppp.c
+++ b/accel-pptpd/ppp.c
@@ -17,21 +17,33 @@
#include "log.h"
#include "events.h"
-static void ppp_read(struct triton_md_handler_t*);
-static void ppp_write(struct triton_md_handler_t*);
-static void ppp_timeout(struct triton_md_handler_t*);
+static LIST_HEAD(layers);
-struct ppp_t *alloc_ppp(void)
+struct layer_node_t
+{
+ struct list_head entry;
+ int order;
+ struct list_head items;
+};
+
+static void ppp_chan_read(struct triton_md_handler_t*);
+static void ppp_unit_read(struct triton_md_handler_t*);
+static void init_layers(struct ppp_t *);
+static void start_first_layer(struct ppp_t *);
+
+struct ppp_t *init_ppp(void)
{
struct ppp_t *ppp=malloc(sizeof(*ppp));
memset(ppp,0,sizeof(*ppp));
- ppp->out_buf=malloc(PPP_MTU+PPP_HDRLEN);
- ppp->in_buf=malloc(PPP_MRU+PPP_HDRLEN);
- ppp->mtu=PPP_MTU;
- ppp->mru=PPP_MRU;
return ppp;
}
+static void free_ppp(struct ppp_t *ppp)
+{
+ free(ppp->chan_buf);
+ free(ppp->unit_buf);
+}
+
int establish_ppp(struct ppp_t *ppp)
{
/* Open an instance of /dev/ppp and connect the channel to it */
@@ -65,42 +77,75 @@ int establish_ppp(struct ppp_t *ppp)
if (ioctl(ppp->unit_fd, PPPIOCNEWUNIT, &ppp->unit_idx)<0)
{
log_error("Couldn't create new ppp unit\n");
- goto exit_clodse_unit;
+ goto exit_close_unit;
}
if (ioctl(ppp->chan_fd, PPPIOCCONNECT, &ppp->unit_idx)<0)
{
log_error("Couldn't attach to PPP unit %d\n", ppp->unit_idx);
- goto exit_clodse_unit;
+ goto exit_close_unit;
}
log_info("connect: ppp%i <--> pptp(%s)\n",ppp->unit_idx,ppp->chan_name);
+
+ ppp->chan_buf=malloc(PPP_MRU);
+ ppp->unit_buf=malloc(PPP_MRU);
- ppp->h=malloc(sizeof(*ppp->h));
- memset(ppp->h,0,sizeof(*ppp->h));
- ppp->h->pd=ppp;
- ppp->h->fd=ppp->chan_fd;
- ppp->h->read=ppp_read;
- ppp->h->write=ppp_write;
- ppp->h->timeout=ppp_timeout;
- ppp->h->twait=-1;
- triton_md_register_handler(ppp->h);
- triton_md_enable_handler(ppp->h,MD_MODE_READ);
- INIT_LIST_HEAD(&ppp->handlers);
-
- ppp->cur_layer=PPP_LAYER_LCP;
+ INIT_LIST_HEAD(&ppp->chan_handlers);
+ INIT_LIST_HEAD(&ppp->unit_handlers);
- lcp_start(ppp);
+ init_layers(ppp);
+
+ if (list_empty(&ppp->layers))
+ {
+ log_error("no layers to start\n");
+ goto exit_close_unit;
+ }
+
+ ppp->chan_hnd.fd=ppp->chan_fd;
+ ppp->chan_hnd.read=ppp_chan_read;
+ ppp->chan_hnd.twait=-1;
+ ppp->unit_hnd.fd=ppp->unit_fd;
+ ppp->unit_hnd.read=ppp_unit_read;
+ ppp->unit_hnd.twait=-1;
+ triton_md_register_handler(&ppp->chan_hnd);
+ triton_md_register_handler(&ppp->unit_hnd);
+
+ triton_md_enable_handler(&ppp->chan_hnd,MD_MODE_READ);
+ triton_md_enable_handler(&ppp->unit_hnd,MD_MODE_READ);
+
+ log_debug("ppp established\n");
+
+ start_first_layer(ppp);
return 0;
-exit_clodse_unit:
+exit_close_unit:
close(ppp->unit_fd);
exit_close_chan:
close(ppp->chan_fd);
+
+ free_ppp(ppp);
+
return -1;
}
+void destablish_ppp(struct ppp_t *ppp)
+{
+ triton_md_unregister_handler(&ppp->chan_hnd);
+ triton_md_unregister_handler(&ppp->unit_hnd);
+
+ close(ppp->unit_fd);
+ close(ppp->chan_fd);
+
+ free(ppp->unit_buf);
+ free(ppp->chan_buf);
+
+ log_debug("ppp destablished\n");
+
+ if (ppp->events.finished) ppp->events.finished(ppp);
+}
+
void print_buf(uint8_t *buf,int size)
{
int i;
@@ -109,41 +154,51 @@ void print_buf(uint8_t *buf,int size)
printf("\n");
}
-int ppp_send(struct ppp_t *ppp, void *data, int size)
+int ppp_chan_send(struct ppp_t *ppp, void *data, int size)
{
int n;
- if (ppp->out_buf_size) return -1;
- if (size>PPP_MTU+PPP_HDRLEN) return -1;
+ printf("ppp_chan_send: ");
+ print_buf((uint8_t*)data,size);
+
+ n=write(ppp->chan_fd,data,size);
+ if (n<size)
+ log_error("ppp_chan_send: short write %i, excpected %i\n",n,size);
+ return n;
+}
- printf("ppp: send: ");
+int ppp_unit_send(struct ppp_t *ppp, void *data, int size)
+{
+ int n;
+
+ printf("ppp_unit_send: ");
print_buf((uint8_t*)data,size);
n=write(ppp->unit_fd,data,size);
- /*if (n>=0)
- {
- if (n!=ppp->out_buf_size-ppp->out_buf_pos)
- {
- ppp->out_buf_pos+=n;
- triton_md_enable_handler(ppp->h,MD_MODE_WRITE);
- }
- }*/
+ if (n<size)
+ log_error("ppp_unit_send: short write %i, excpected %i\n",n,size);
return n;
}
-static void ppp_read(struct triton_md_handler_t*h)
+static void ppp_chan_read(struct triton_md_handler_t*h)
{
- struct ppp_t *ppp=(struct ppp_t *)h->pd;
- struct ppp_handler_t *ppp_h=NULL;
+ struct ppp_t *ppp=container_of(h,typeof(*ppp),chan_hnd);
+ struct ppp_handler_t *ppp_h;
uint16_t proto;
- ppp->in_buf_size=read(h->fd,ppp->in_buf,PPP_MRU+PPP_HDRLEN);
+ ppp->chan_buf_size=read(h->fd,ppp->chan_buf,PPP_MRU);
+
+ printf("ppp_chan_read: ");
+ print_buf(ppp->chan_buf,ppp->chan_buf_size);
- printf("ppp: recv: ");
- print_buf(ppp->in_buf,ppp->in_buf_size);
+ if (ppp->chan_buf_size<2)
+ {
+ log_error("ppp_chan_read: short read %i\n",ppp->chan_buf_size);
+ return;
+ }
- proto=ntohs(*(uint16_t*)ppp->in_buf);
- list_for_each_entry(ppp_h,&ppp->handlers,entry)
+ proto=ntohs(*(uint16_t*)ppp->chan_buf);
+ list_for_each_entry(ppp_h,&ppp->chan_handlers,entry)
{
if (ppp_h->proto==proto)
{
@@ -152,75 +207,212 @@ static void ppp_read(struct triton_md_handler_t*h)
}
}
- log_warn("discarding unknown packet %x\n",proto);
+ log_warn("ppp_chan_read: discarding unknown packet %x\n",proto);
}
-static void ppp_write(struct triton_md_handler_t*h)
+
+static void ppp_unit_read(struct triton_md_handler_t*h)
{
- struct ppp_t *ppp=(struct ppp_t *)h->pd;
+ struct ppp_t *ppp=container_of(h,typeof(*ppp),unit_hnd);
+ struct ppp_handler_t *ppp_h;
+ uint16_t proto;
- int n=write(ppp->unit_fd,ppp->out_buf+ppp->out_buf_pos,ppp->out_buf_size-ppp->out_buf_pos);
- if (n>=0)
+ ppp->unit_buf_size=read(h->fd,ppp->unit_buf,PPP_MRU);
+
+ printf("ppp_unit_read: ");
+ print_buf(ppp->unit_buf,ppp->unit_buf_size);
+
+ if (ppp->unit_buf_size<2)
{
- ppp->out_buf_pos+=n;
- if (ppp->out_buf_pos==ppp->out_buf_size)
+ log_error("ppp_chan_read: short read %i\n",ppp->unit_buf_size);
+ return;
+ }
+
+ proto=ntohs(*(uint16_t*)ppp->unit_buf);
+ list_for_each_entry(ppp_h,&ppp->unit_handlers,entry)
+ {
+ if (ppp_h->proto==proto)
{
- triton_md_disable_handler(ppp->h,MD_MODE_WRITE);
- ppp->out_buf_pos=0;
- ppp->out_buf_size=0;
+ ppp_h->recv(ppp_h);
+ return;
}
}
+
+ log_warn("ppp_chan_read: discarding unknown packet %x\n",proto);
}
-static void ppp_timeout(struct triton_md_handler_t*h)
+
+void ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d)
{
+ struct layer_node_t *n=d->node;
+
+ d->started=1;
+
+ list_for_each_entry(d,&n->items,entry)
+ if (!d->started) return;
+ if (n->entry.next==&ppp->layers)
+ {
+ if (ppp->events.started) ppp->events.started(ppp);
+ }else
+ {
+ n=list_entry(n->entry.next,typeof(*n),entry);
+ list_for_each_entry(d,&n->items,entry)
+ d->layer->start(d);
+ }
}
-void ppp_layer_started(struct ppp_t *ppp)
+void ppp_layer_finished(struct ppp_t *ppp, struct ppp_layer_data_t *d)
{
- switch(ppp->cur_layer)
+ struct layer_node_t *n=d->node;
+
+ d->started=0;
+
+ list_for_each_entry(d,&n->items,entry)
+ if (d->started) return;
+
+ if (n->entry.prev==&ppp->layers) destablish_ppp(ppp);
+ else
{
- case PPP_LAYER_LCP:
- ppp->cur_layer++;
- if (auth_start(ppp))
- break;
- case PPP_LAYER_AUTH:
- ppp->cur_layer++;
- if (ccp_start(ppp))
- break;
- case PPP_LAYER_CCP:
- ppp->cur_layer++;
- if (ipcp_start(ppp))
- break;
- case PPP_LAYER_IPCP:
- break;
+ n=list_entry(n->entry.prev,typeof(*n),entry);
+ list_for_each_entry(d,&n->items,entry)
+ if (d->started) d->layer->finish(d);
}
}
+
void ppp_terminate(struct ppp_t *ppp)
{
- switch(ppp->cur_layer)
+ struct layer_node_t *n;
+ struct list_head *p;
+ struct ppp_layer_data_t *d;
+ int s=0;
+
+ log_debug("ppp_terminate\n");
+
+ list_for_each_prev(p,&ppp->layers)
{
- case PPP_LAYER_IPCP:
- ppp->cur_layer--;
- ipcp_finish(ppp);
- case PPP_LAYER_CCP:
- ppp->cur_layer--;
- ccp_finish(ppp);
- case PPP_LAYER_AUTH:
- ppp->cur_layer--;
- auth_finish(ppp);
- case PPP_LAYER_LCP:
- ppp->cur_layer--;
- lcp_finish(ppp);
+ list_for_each_entry(d,&n->items,entry)
+ {
+ if (d->started)
+ {
+ s=1;
+ d->layer->finish(d);
+ }
+ }
+ if (s) return;
}
+ destablish_ppp(ppp);
}
-
-void ppp_register_handler(struct ppp_t *ppp,struct ppp_handler_t *h)
+void ppp_register_chan_handler(struct ppp_t *ppp,struct ppp_handler_t *h)
+{
+ list_add_tail(&h->entry,&ppp->chan_handlers);
+}
+void ppp_register_unit_handler(struct ppp_t *ppp,struct ppp_handler_t *h)
{
- list_add_tail(&h->entry,&ppp->handlers);
+ list_add_tail(&h->entry,&ppp->unit_handlers);
}
void ppp_unregister_handler(struct ppp_t *ppp,struct ppp_handler_t *h)
{
list_del(&h->entry);
}
+static int get_layer_order(const char *name)
+{
+ if (!strcmp(name,"lcp")) return 0;
+ if (!strcmp(name,"auth")) return 1;
+ if (!strcmp(name,"ipcp")) return 2;
+ if (!strcmp(name,"ccp")) return 2;
+ return -1;
+}
+
+int ppp_register_layer(const char *name, struct ppp_layer_t *layer)
+{
+ int order;
+ struct layer_node_t *n,*n1;
+
+ order=get_layer_order(name);
+
+ if (order<0)
+ return order;
+
+ list_for_each_entry(n,&layers,entry)
+ {
+ if (order>n->order)
+ continue;
+ if (order<n->order)
+ {
+ n1=malloc(sizeof(*n1));
+ memset(n1,0,sizeof(*n1));
+ n1->order=order;
+ INIT_LIST_HEAD(&n1->items);
+ list_add_tail(&n1->entry,&n->entry);
+ n=n1;
+ }
+ goto insert;
+ }
+ n1=malloc(sizeof(*n1));
+ memset(n1,0,sizeof(*n1));
+ n1->order=order;
+ INIT_LIST_HEAD(&n1->items);
+ list_add_tail(&n1->entry,&layers);
+ n=n1;
+insert:
+ list_add_tail(&layer->entry,&n->items);
+
+ return 0;
+}
+void ppp_unregister_layer(struct ppp_layer_t *layer)
+{
+ list_del(&layer->entry);
+}
+
+static void init_layers(struct ppp_t *ppp)
+{
+ struct layer_node_t *n,*n1;
+ struct ppp_layer_t *l;
+ struct ppp_layer_data_t *d;
+
+ INIT_LIST_HEAD(&ppp->layers);
+
+ list_for_each_entry(n,&layers,entry)
+ {
+ n1=(struct layer_node_t*)malloc(sizeof(*n1));
+ memset(n1,0,sizeof(*n1));
+ INIT_LIST_HEAD(&n1->items);
+ list_add_tail(&n1->entry,&ppp->layers);
+ list_for_each_entry(l,&n->items,entry)
+ {
+ d=l->init(ppp);
+ d->layer=l;
+ d->started=0;
+ d->node=n1;
+ list_add_tail(&d->entry,&n1->items);
+ }
+ }
+}
+
+static void start_first_layer(struct ppp_t *ppp)
+{
+ struct layer_node_t *n;
+ struct ppp_layer_data_t *d;
+
+ n=list_entry(ppp->layers.next,typeof(*n),entry);
+ list_for_each_entry(d,&n->items,entry)
+ d->layer->start(d);
+}
+
+struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *ppp, struct ppp_layer_t *layer)
+{
+ struct layer_node_t *n;
+ struct ppp_layer_data_t *d;
+
+ list_for_each_entry(n,&ppp->layers,entry)
+ {
+ list_for_each_entry(d,&n->items,entry)
+ {
+ if (d->layer==layer)
+ return d;
+ }
+ }
+
+ return NULL;
+}
diff --git a/accel-pptpd/ppp.h b/accel-pptpd/ppp.h
index 83ad8ed..9d8cdf1 100644
--- a/accel-pptpd/ppp.h
+++ b/accel-pptpd/ppp.h
@@ -2,6 +2,8 @@
#define PPP_H
#include <sys/types.h>
+
+#include "triton/triton.h"
#include "list.h"
/*
@@ -48,11 +50,18 @@
#define AUTH_MAX 3
-struct ppp_lcp_t;
+struct ppp_t;
+
+struct ppp_events_t
+{
+ void (*started)(struct ppp_t*);
+ void (*finished)(struct ppp_t*);
+};
struct ppp_t
{
- struct triton_md_handler_t *h;
+ struct triton_md_handler_t chan_hnd;
+ struct triton_md_handler_t unit_hnd;
int fd;
int chan_fd;
int unit_fd;
@@ -62,28 +71,42 @@ struct ppp_t
char *chan_name;
- //options
- int mtu,mru;
- int accomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled
- int pcomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled
- int auth[AUTH_MAX];
- //
-
+ struct ppp_events_t events;
+
int log:1;
- void *out_buf;
- int out_buf_size;
- int out_buf_pos;
+ void *chan_buf;
+ int chan_buf_size;
+ void *unit_buf;
+ int unit_buf_size;
- void *in_buf;
- int in_buf_size;
+ struct list_head chan_handlers;
+ struct list_head unit_handlers;
- struct list_head handlers;
+ struct list_head layers;
- int cur_layer;
struct ppp_lcp_t *lcp;
};
+struct ppp_layer_t;
+struct layer_node_t;
+struct ppp_layer_data_t
+{
+ struct list_head entry;
+ struct ppp_layer_t *layer;
+ struct layer_node_t *node;
+ int started:1;
+};
+
+struct ppp_layer_t
+{
+ struct list_head entry;
+ struct ppp_layer_data_t *(*init)(struct ppp_t *);
+ void (*start)(struct ppp_layer_data_t*);
+ void (*finish)(struct ppp_layer_data_t*);
+ void (*free)(struct ppp_layer_data_t *);
+};
+
struct ppp_handler_t
{
struct list_head entry;
@@ -93,25 +116,23 @@ struct ppp_handler_t
struct ppp_t *alloc_ppp(void);
int establish_ppp(struct ppp_t *ppp);
-int ppp_send(struct ppp_t *ppp, void *data, int size);
+int ppp_chan_send(struct ppp_t *ppp, void *data, int size);
+int ppp_unit_send(struct ppp_t *ppp, void *data, int size);
void ppp_init(void);
struct ppp_fsm_t* ppp_lcp_init(struct ppp_t *ppp);
-void ppp_layer_started(struct ppp_t *ppp);
+void ppp_layer_started(struct ppp_t *ppp,struct ppp_layer_data_t*);
+void ppp_layer_finished(struct ppp_t *ppp,struct ppp_layer_data_t*);
void ppp_terminate(struct ppp_t *ppp);
-void ppp_register_handler(struct ppp_t*,struct ppp_handler_t*);
-void ppp_unregister_handler(struct ppp_t*,struct ppp_handler_t*);
-
-void lcp_start(struct ppp_t*);
-void lcp_finish(struct ppp_t*);
-int auth_start(struct ppp_t*);
-void auth_finish(struct ppp_t*);
-int ccp_start(struct ppp_t*);
-void ccp_finish(struct ppp_t*);
-int ipcp_start(struct ppp_t*);
-void ipcp_finish(struct ppp_t*);
+void ppp_register_chan_handler(struct ppp_t *, struct ppp_handler_t *);
+void ppp_register_unit_handler(struct ppp_t * ,struct ppp_handler_t *);
+void ppp_unregister_handler(struct ppp_t *, struct ppp_handler_t *);
+
+int ppp_register_layer(const char *name, struct ppp_layer_t *);
+void ppp_unregister_layer(struct ppp_layer_t *);
+struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *, struct ppp_layer_t *);
#define __init __attribute__((constructor))
diff --git a/accel-pptpd/ppp_auth.c b/accel-pptpd/ppp_auth.c
index 6fc4801..ee173a7 100644
--- a/accel-pptpd/ppp_auth.c
+++ b/accel-pptpd/ppp_auth.c
@@ -21,6 +21,11 @@ static int auth_recv_conf_rej(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, u
static int auth_recv_conf_ack(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr);
static void auth_print(void (*print)(const char *fmt,...),struct lcp_option_t*, uint8_t *ptr);
+static struct ppp_layer_data_t *auth_layer_init(struct ppp_t*);
+static void auth_layer_start(struct ppp_layer_data_t *);
+static void auth_layer_finish(struct ppp_layer_data_t *);
+static void auth_layer_free(struct ppp_layer_data_t *);
+
struct auth_option_t
{
struct lcp_option_t opt;
@@ -29,6 +34,13 @@ struct auth_option_t
struct auth_data_t *peer_auth;
};
+struct auth_layer_data_t
+{
+ struct ppp_layer_data_t ld;
+ struct auth_option_t auth_opt;
+ struct ppp_t *ppp;
+};
+
static struct lcp_option_handler_t auth_opt_hnd=
{
.init=auth_init,
@@ -42,25 +54,35 @@ static struct lcp_option_handler_t auth_opt_hnd=
.print=auth_print,
};
+static struct ppp_layer_t auth_layer=
+{
+ .init=auth_layer_init,
+ .start=auth_layer_start,
+ .finish=auth_layer_finish,
+ .free=auth_layer_free,
+};
+
static struct lcp_option_t *auth_init(struct ppp_lcp_t *lcp)
{
struct ppp_auth_handler_t *h;
struct auth_data_t *d;
- struct auth_option_t *auth_opt=malloc(sizeof(*auth_opt));
- memset(auth_opt,0,sizeof(*auth_opt));
- auth_opt->opt.id=CI_AUTH;
- auth_opt->opt.len=4+extra_opt_len;
+ struct auth_layer_data_t *ad;
- INIT_LIST_HEAD(&auth_opt->auth_list);
+ ad=container_of(ppp_find_layer_data(lcp->ppp,&auth_layer),typeof(*ad),ld);
+
+ ad->auth_opt.opt.id=CI_AUTH;
+ ad->auth_opt.opt.len=4+extra_opt_len;
+
+ INIT_LIST_HEAD(&ad->auth_opt.auth_list);
list_for_each_entry(h,&auth_handlers,entry)
{
d=h->init(lcp->ppp);
d->h=h;
- list_add_tail(&d->entry,&auth_opt->auth_list);
+ list_add_tail(&d->entry,&ad->auth_opt.auth_list);
}
- return &auth_opt->opt;
+ return &ad->auth_opt.opt;
}
static void auth_free(struct ppp_lcp_t *lcp, struct lcp_option_t *opt)
@@ -74,8 +96,6 @@ static void auth_free(struct ppp_lcp_t *lcp, struct lcp_option_t *opt)
list_del(&d->entry);
d->h->free(lcp->ppp,d);
}
-
- free(auth_opt);
}
static int auth_send_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr)
@@ -206,66 +226,61 @@ print_d:
print("<auth %s>",d->h->name);
}
-int ppp_auth_register_handler(struct ppp_auth_handler_t *h)
+static struct ppp_layer_data_t *auth_layer_init(struct ppp_t *ppp)
{
- list_add_tail(&h->entry,&auth_handlers);
- return 0;
-}
-
-static void __init auth_opt_init()
-{
- lcp_option_register(&auth_opt_hnd);
-}
-
-
-
-
+ struct auth_layer_data_t *ad=(struct auth_layer_data_t*)malloc(sizeof(*ad));
+ log_debug("auth_layer_init\n");
+
+ memset(ad,0,sizeof(*ad));
+ ad->ppp=ppp;
+ return &ad->ld;
+}
-int auth_start(struct ppp_t *ppp)
+static void auth_layer_start(struct ppp_layer_data_t *ld)
{
- struct lcp_option_t *opt;
- struct auth_option_t *auth_opt;
-
- list_for_each_entry(opt,&ppp->lcp->options,entry)
+ struct auth_layer_data_t *ad=container_of(ld,typeof(*ad),ld);
+
+ log_debug("auth_layer_start\n");
+
+ if (ad->auth_opt.auth)
+ ad->auth_opt.auth->h->start(ad->ppp,ad->auth_opt.auth);
+ else
{
- if (opt->id==CI_AUTH)
- {
- auth_opt=container_of(opt,typeof(*auth_opt),opt);
- if (auth_opt->auth)
- {
- auth_opt->auth->h->start(ppp,auth_opt->auth);
- return 1;
- }
- break;
- }
+ log_debug("auth_layer_started\n");
+ ppp_layer_started(ad->ppp,ld);
}
+}
- return 0;
+static void auth_layer_finish(struct ppp_layer_data_t *ld)
+{
+ struct auth_layer_data_t *ad=container_of(ld,typeof(*ad),ld);
+
+ log_debug("auth_layer_finish\n");
+
+ if (ad->auth_opt.auth)
+ ad->auth_opt.auth->h->finish(ad->ppp,ad->auth_opt.auth);
+
+ log_debug("auth_layer_finished\n");
+ ppp_layer_finished(ad->ppp,ld);
}
-void auth_finish(struct ppp_t *ppp)
+static void auth_layer_free(struct ppp_layer_data_t *ld)
{
- struct lcp_option_t *opt;
- struct auth_option_t *auth_opt;
+ struct auth_layer_data_t *ad=container_of(ld,typeof(*ad),ld);
- list_for_each_entry(opt,&ppp->lcp->options,entry)
- {
- if (opt->id==CI_AUTH)
- {
- auth_opt=container_of(opt,typeof(*auth_opt),opt);
- if (auth_opt->auth)
- auth_opt->auth->h->finish(ppp,auth_opt->auth);
- break;
- }
- }
+ log_debug("auth_layer_free\n");
+
+ free(ad);
}
void auth_successed(struct ppp_t *ppp)
{
- ppp_layer_started(ppp);
+ struct auth_layer_data_t *ad=container_of(ppp_find_layer_data(ppp,&auth_layer),typeof(*ad),ld);
+ log_debug("auth_layer_started\n");
+ ppp_layer_started(ppp,&ad->ld);
}
void auth_failed(struct ppp_t *ppp)
@@ -273,3 +288,15 @@ void auth_failed(struct ppp_t *ppp)
ppp_terminate(ppp);
}
+int ppp_auth_register_handler(struct ppp_auth_handler_t *h)
+{
+ list_add_tail(&h->entry,&auth_handlers);
+ return 0;
+}
+
+static void __init ppp_auth_init()
+{
+ ppp_register_layer("auth",&auth_layer);
+ lcp_option_register(&auth_opt_hnd);
+}
+
diff --git a/accel-pptpd/ppp_fsm.c b/accel-pptpd/ppp_fsm.c
index b68b63f..41436eb 100644
--- a/accel-pptpd/ppp_fsm.c
+++ b/accel-pptpd/ppp_fsm.c
@@ -10,6 +10,8 @@
*
*/
+#include <arpa/inet.h>
+
#include "triton/triton.h"
#include "ppp.h"
#include "ppp_fsm.h"
@@ -441,7 +443,7 @@ void send_term_req(struct ppp_fsm_t *layer)
log_debug("send [LCP TermReq id=%i \"\"]\n",hdr.id);
- ppp_send(layer->ppp,&hdr,6);
+ ppp_chan_send(layer->ppp,&hdr,6);
}
void send_term_ack(struct ppp_fsm_t *layer)
{
@@ -454,7 +456,7 @@ void send_term_ack(struct ppp_fsm_t *layer)
log_debug("send [LCP TermAck id=%i \"\"]\n",hdr.id);
- ppp_send(layer->ppp,&hdr,6);
+ ppp_chan_send(layer->ppp,&hdr,6);
}
static void init_req_counter(struct ppp_fsm_t *layer,int timeout)
diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c
index 21b7fb2..bfc9917 100644
--- a/accel-pptpd/ppp_lcp.c
+++ b/accel-pptpd/ppp_lcp.c
@@ -62,10 +62,12 @@ static void lcp_options_free(struct ppp_lcp_t *lcp)
}
}
-void lcp_start(struct ppp_t *ppp)
+static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp)
{
struct ppp_lcp_t *lcp=malloc(sizeof(*lcp));
memset(lcp,0,sizeof(*lcp));
+
+ log_debug("lcp_layer_init\n");
lcp->ppp=ppp;
lcp->fsm.ppp=ppp;
@@ -73,46 +75,65 @@ void lcp_start(struct ppp_t *ppp)
lcp->hnd.proto=PPP_LCP;
lcp->hnd.recv=lcp_recv;
- ppp_register_handler(ppp,&lcp->hnd);
+ ppp_register_chan_handler(ppp,&lcp->hnd);
ppp_fsm_init(&lcp->fsm);
lcp->fsm.layer_up=lcp_layer_up;
- lcp->fsm.layer_down=lcp_layer_down;
+ lcp->fsm.layer_finished=lcp_layer_down;
lcp->fsm.send_conf_req=send_conf_req;
lcp->fsm.send_conf_ack=send_conf_ack;
lcp->fsm.send_conf_nak=send_conf_nak;
lcp->fsm.send_conf_rej=send_conf_rej;
- lcp_options_init(lcp);
INIT_LIST_HEAD(&lcp->ropt_list);
+ return &lcp->ld;
+}
+
+void lcp_layer_start(struct ppp_layer_data_t *ld)
+{
+ struct ppp_lcp_t *lcp=container_of(ld,typeof(*lcp),ld);
+
+ log_debug("lcp_layer_start\n");
+
+ lcp_options_init(lcp);
ppp_fsm_lower_up(&lcp->fsm);
ppp_fsm_open(&lcp->fsm);
-
- ppp->lcp=lcp;
}
-void lcp_finish(struct ppp_t *ppp)
+void lcp_layer_finish(struct ppp_layer_data_t *ld)
{
- struct ppp_lcp_t *lcp=ppp->lcp;
+ struct ppp_lcp_t *lcp=container_of(ld,typeof(*lcp),ld);
+
+ log_debug("lcp_layer_finish\n");
- ppp_unregister_handler(ppp,&lcp->hnd);
+ ppp_unregister_handler(lcp->ppp,&lcp->hnd);
lcp_options_free(lcp);
+}
+
+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");
+
free(lcp);
}
static void lcp_layer_up(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
- ppp_layer_started(lcp->ppp);
+ log_debug("lcp_layer_started\n");
+ ppp_layer_started(lcp->ppp,&lcp->ld);
}
static void lcp_layer_down(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
- ppp_terminate(lcp->ppp);
+ log_debug("lcp_layer_finished\n");
+ ppp_layer_finished(lcp->ppp,&lcp->ld);
}
static void print_ropt(struct recv_opt_t *ropt)
@@ -159,18 +180,18 @@ static void send_conf_req(struct ppp_fsm_t *fsm)
log_debug("]\n");
lcp_hdr->len=htons((ptr-buf)-2);
- ppp_send(lcp->ppp,lcp_hdr,ptr-buf);
+ ppp_chan_send(lcp->ppp,lcp_hdr,ptr-buf);
}
static void send_conf_ack(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
- struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)lcp->ppp->in_buf;
+ struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)lcp->ppp->chan_buf;
hdr->code=CONFACK;
log_debug("send [LCP ConfAck id=%x ]\n",lcp->fsm.recv_id);
- ppp_send(lcp->ppp,hdr,ntohs(hdr->len)+2);
+ ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2);
}
static void send_conf_nak(struct ppp_fsm_t *fsm)
@@ -202,7 +223,7 @@ static void send_conf_nak(struct ppp_fsm_t *fsm)
log_debug("]\n");
lcp_hdr->len=htons((ptr-buf)-2);
- ppp_send(lcp->ppp,lcp_hdr,ptr-buf);
+ ppp_chan_send(lcp->ppp,lcp_hdr,ptr-buf);
}
static void send_conf_rej(struct ppp_fsm_t *fsm)
@@ -236,7 +257,7 @@ static void send_conf_rej(struct ppp_fsm_t *fsm)
log_debug("]\n");
lcp_hdr->len=htons((ptr-buf)-2);
- ppp_send(lcp->ppp,lcp_hdr,ptr-buf);
+ ppp_chan_send(lcp->ppp,lcp_hdr,ptr-buf);
}
static int lcp_recv_conf_req(struct ppp_lcp_t *lcp,uint8_t *data,int size)
@@ -438,7 +459,7 @@ void send_echo_reply(struct ppp_lcp_t *lcp)
.magic.val=0,
};
- ppp_send(lcp->ppp,&msg,ntohs(msg.hdr.len)+2);
+ ppp_chan_send(lcp->ppp,&msg,ntohs(msg.hdr.len)+2);
}
static void lcp_recv(struct ppp_handler_t*h)
@@ -448,13 +469,13 @@ static void lcp_recv(struct ppp_handler_t*h)
int r;
char *term_msg;
- if (lcp->ppp->in_buf_size<PPP_HEADERLEN+2)
+ if (lcp->ppp->chan_buf_size<PPP_HEADERLEN+2)
{
log_warn("LCP: short packet received\n");
return;
}
- hdr=(struct lcp_hdr_t *)lcp->ppp->in_buf;
+ hdr=(struct lcp_hdr_t *)lcp->ppp->chan_buf;
if (ntohs(hdr->len)<PPP_HEADERLEN)
{
log_warn("LCP: short packet received\n");
@@ -535,3 +556,15 @@ int lcp_option_register(struct lcp_option_handler_t *h)
return 0;
}
+static struct ppp_layer_t lcp_layer=
+{
+ .init=lcp_layer_init,
+ .start=lcp_layer_start,
+ .finish=lcp_layer_finish,
+ .free=lcp_layer_free,
+};
+
+static void __init lcp_init(void)
+{
+ ppp_register_layer("lcp",&lcp_layer);
+}
diff --git a/accel-pptpd/ppp_lcp.h b/accel-pptpd/ppp_lcp.h
index 54235c4..d241de6 100644
--- a/accel-pptpd/ppp_lcp.h
+++ b/accel-pptpd/ppp_lcp.h
@@ -110,6 +110,7 @@ struct lcp_option_handler_t
struct ppp_lcp_t
{
+ struct ppp_layer_data_t ld;
struct ppp_handler_t hnd;
struct ppp_fsm_t fsm;
struct ppp_t *ppp;
diff --git a/accel-pptpd/ctrl.c b/accel-pptpd/pptp.c
index 3fbc6e8..6d24460 100644
--- a/accel-pptpd/ctrl.c
+++ b/accel-pptpd/pptp.c
@@ -33,11 +33,12 @@
#define STATE_IDLE 0
#define STATE_ESTB 1
+#define STATE_PPP 2
#define STATE_FIN 10
struct pptp_conn_t
{
- struct triton_md_handler_t *h;
+ struct triton_md_handler_t hnd;
int state;
u_int8_t *in_buf;
@@ -46,16 +47,17 @@ struct pptp_conn_t
int out_size;
int out_pos;
- struct ppp_t *ppp;
+ struct ppp_t ppp;
};
static void pptp_read(struct triton_md_handler_t *h);
static void pptp_write(struct triton_md_handler_t *h);
static void pptp_timeout(struct triton_md_handler_t *h);
+static void ppp_started(struct ppp_t *);
+static void ppp_finished(struct ppp_t *);
static void ctrl_read(struct triton_md_handler_t *h)
{
- struct triton_md_handler_t *hc;
struct pptp_conn_t *conn;
int fd;
@@ -70,22 +72,14 @@ static void ctrl_read(struct triton_md_handler_t *h)
memset(conn,0,sizeof(*conn));
conn->in_buf=malloc(PPTP_CTRL_SIZE_MAX);
conn->out_buf=malloc(PPTP_CTRL_SIZE_MAX);
-
- hc=malloc(sizeof(*hc));
- memset(hc,0,sizeof(*hc));
- hc->fd=fd;
- hc->twait=TIMEOUT;
- hc->read=pptp_read;
- hc->write=pptp_write;
- hc->timeout=pptp_timeout;
-
- hc->pd=conn;
- conn->h=hc;
-
- conn->ppp=alloc_ppp();
-
- triton_md_register_handler(hc);
- triton_md_enable_handler(hc,MD_MODE_READ);
+ conn->hnd.fd=fd;
+ conn->hnd.twait=TIMEOUT;
+ conn->hnd.read=pptp_read;
+ conn->hnd.write=pptp_write;
+ conn->hnd.timeout=pptp_timeout;
+
+ triton_md_register_handler(&conn->hnd);
+ triton_md_enable_handler(&conn->hnd,MD_MODE_READ);
}
int ctrl_init(struct ctrl_thread_t*ctrl)
@@ -103,9 +97,8 @@ int ctrl_init(struct ctrl_thread_t*ctrl)
static void disconnect(struct pptp_conn_t *conn)
{
- close(conn->h->fd);
- triton_md_unregister_handler(conn->h);
- free(conn->h);
+ close(conn->hnd.fd);
+ triton_md_unregister_handler(&conn->hnd);
free(conn);
}
@@ -118,7 +111,7 @@ static int post_msg(struct pptp_conn_t *conn,void *buf,int size)
return -1;
}
- n=write(conn->h->fd,buf,size);
+ n=write(conn->hnd.fd,buf,size);
if (n<0)
{
if (errno==EINTR) n=0;
@@ -132,7 +125,7 @@ static int post_msg(struct pptp_conn_t *conn,void *buf,int size)
if (n<size)
{
memcpy(conn->out_buf,buf+n,size-n);
- triton_md_enable_handler(conn->h,MD_MODE_WRITE);
+ triton_md_enable_handler(&conn->hnd,MD_MODE_WRITE);
}
return 0;
@@ -164,8 +157,11 @@ static int pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn)
struct pptp_stop_ctrl_conn *msg=(struct pptp_stop_ctrl_conn *)conn->in_buf;
log_info("PPTP_STOP_CTRL_CONN_RQST reason=%i error_code=%i\n",msg->reason_result,msg->error_code);
+ if (conn->state==STATE_PPP)
+ ppp_terminate(&conn->ppp);
+
conn->state=STATE_FIN;
- conn->h->twait=1000;
+ conn->hnd.twait=1000;
return send_pptp_stop_ctrl_conn_rply(conn,PPTP_CONN_STOP_OK,0);
}
@@ -262,13 +258,13 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn)
src_addr.sa_family=AF_PPPOX;
src_addr.sa_protocol=PX_PROTO_PPTP;
src_addr.sa_addr.pptp.call_id=0;
- addrlen=sizeof(addr); getsockname(conn->h->fd,(struct sockaddr*)&addr,&addrlen);
+ addrlen=sizeof(addr); getsockname(conn->hnd.fd,(struct sockaddr*)&addr,&addrlen);
src_addr.sa_addr.pptp.sin_addr=addr.sin_addr;
dst_addr.sa_family=AF_PPPOX;
dst_addr.sa_protocol=PX_PROTO_PPTP;
dst_addr.sa_addr.pptp.call_id=htons(msg->call_id);
- addrlen=sizeof(addr); getpeername(conn->h->fd,(struct sockaddr*)&addr,&addrlen);
+ addrlen=sizeof(addr); getpeername(conn->hnd.fd,(struct sockaddr*)&addr,&addrlen);
dst_addr.sa_addr.pptp.sin_addr=addr.sin_addr;
pptp_sock=socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_PPTP);
@@ -296,9 +292,17 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn)
if (send_pptp_out_call_rply(conn,msg,src_addr.sa_addr.pptp.call_id,PPTP_CALL_RES_OK,0))
return -1;
- conn->ppp->fd=pptp_sock;
- conn->ppp->chan_name=strdup(inet_ntoa(dst_addr.sa_addr.pptp.sin_addr));
- establish_ppp(conn->ppp);
+ conn->ppp.fd=pptp_sock;
+ conn->ppp.chan_name=strdup(inet_ntoa(dst_addr.sa_addr.pptp.sin_addr));
+ conn->ppp.events.started=ppp_started;
+ conn->ppp.events.finished=ppp_finished;
+ if (establish_ppp(&conn->ppp))
+ {
+ close(pptp_sock);
+ send_pptp_stop_ctrl_conn_rqst(conn,0,0);
+ conn->state=STATE_FIN;
+ conn->hnd.twait=1000;
+ }else conn->state=STATE_PPP;
return 0;
}
@@ -320,14 +324,14 @@ static int process_packet(struct pptp_conn_t *conn)
static void pptp_read(struct triton_md_handler_t *h)
{
- struct pptp_conn_t *conn=(struct pptp_conn_t *)h->pd;
+ struct pptp_conn_t *conn=container_of(h,typeof(*conn),hnd);
struct pptp_header *hdr=(struct pptp_header *)conn->in_buf;
int n;
n=read(h->fd,conn->in_buf,PPTP_CTRL_SIZE_MAX-conn->in_size);
if (n<=0)
{
- if (errno==EINTR) return;
+ if (errno==EAGAIN) return;
disconnect(conn);
return;
}
@@ -352,7 +356,7 @@ drop:
}
static void pptp_write(struct triton_md_handler_t *h)
{
- struct pptp_conn_t *conn=(struct pptp_conn_t *)h->pd;
+ struct pptp_conn_t *conn=container_of(h,typeof(*conn),hnd);
int n=write(h->fd,conn->out_buf+conn->out_pos,conn->out_size-conn->out_pos);
if (n<0)
@@ -378,3 +382,18 @@ static void pptp_write(struct triton_md_handler_t *h)
static void pptp_timeout(struct triton_md_handler_t *h)
{
}
+
+static void ppp_started(struct ppp_t *ppp)
+{
+ log_msg("ppp_started\n");
+}
+static void ppp_finished(struct ppp_t *ppp)
+{
+ struct pptp_conn_t *conn=container_of(ppp,typeof(*conn),ppp);
+
+ log_msg("ppp_finished\n");
+ close(conn->ppp.fd);
+ send_pptp_stop_ctrl_conn_rqst(conn,0,0);
+ conn->state=STATE_FIN;
+ conn->hnd.twait=1000;
+}