diff options
author | Kozlov Dmitry <dima@server> | 2010-08-20 17:50:13 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-08-20 17:50:13 +0400 |
commit | 1dbf2a2820c428b8ba8b04d6ec30c78f642cbfb3 (patch) | |
tree | b688869cf739aa1c20ddc83335c59ca7fdddf472 | |
parent | 128961dd4ccfae1fc6c973be704d55a27932a280 (diff) | |
download | accel-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.txt | 2 | ||||
-rw-r--r-- | accel-pptpd/auth_pap.c | 10 | ||||
-rw-r--r-- | accel-pptpd/ppp.c | 368 | ||||
-rw-r--r-- | accel-pptpd/ppp.h | 79 | ||||
-rw-r--r-- | accel-pptpd/ppp_auth.c | 131 | ||||
-rw-r--r-- | accel-pptpd/ppp_fsm.c | 6 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 71 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.h | 1 | ||||
-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; +} |