diff options
author | Kozlov Dmitry <dima@server> | 2010-09-03 14:00:45 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-03 14:00:45 +0400 |
commit | 935c25b34dba5d22372de3f792dd806db6d729a8 (patch) | |
tree | 2d4916ec75b5750f8ee0b8f06dbb1fc55e9f6add | |
parent | b43d224c8a306ff54bbb913c5aab891f82541f6e (diff) | |
download | accel-ppp-935c25b34dba5d22372de3f792dd806db6d729a8.tar.gz accel-ppp-935c25b34dba5d22372de3f792dd806db6d729a8.zip |
rewrited triton library
-rw-r--r-- | accel-pptpd/CMakeLists.txt | 2 | ||||
-rw-r--r-- | accel-pptpd/auth_chap_md5.c | 4 | ||||
-rw-r--r-- | accel-pptpd/auth_mschap_v1.c | 4 | ||||
-rw-r--r-- | accel-pptpd/auth_mschap_v2.c | 4 | ||||
-rw-r--r-- | accel-pptpd/main.c | 10 | ||||
-rw-r--r-- | accel-pptpd/ppp.c | 87 | ||||
-rw-r--r-- | accel-pptpd/ppp.h | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp_auth.c | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp_ccp.c | 8 | ||||
-rw-r--r-- | accel-pptpd/ppp_ipcp.c | 8 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 8 | ||||
-rw-r--r-- | accel-pptpd/pptp.c | 322 | ||||
-rw-r--r-- | accel-pptpd/triton/CMakeLists.txt | 1 | ||||
-rw-r--r-- | accel-pptpd/triton/md.c | 54 | ||||
-rw-r--r-- | accel-pptpd/triton/mempool.c | 67 | ||||
-rw-r--r-- | accel-pptpd/triton/timer.c | 60 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.c | 74 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.h | 63 | ||||
-rw-r--r-- | accel-pptpd/triton/triton_p.h | 62 |
19 files changed, 522 insertions, 320 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index e22bdc69..fc6ac0ed 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -34,4 +34,4 @@ ADD_EXECUTABLE(pptpd main.c ) -TARGET_LINK_LIBRARIES(pptpd pthread triton ssl) +TARGET_LINK_LIBRARIES(pptpd pthread triton ssl rt) diff --git a/accel-pptpd/auth_chap_md5.c b/accel-pptpd/auth_chap_md5.c index f0a5368d..5577794f 100644 --- a/accel-pptpd/auth_chap_md5.c +++ b/accel-pptpd/auth_chap_md5.c @@ -210,14 +210,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h { log_error("chap-md5: id mismatch\n"); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } if (msg->val_size!=VALUE_SIZE) { log_error("chap-md5: value-size should be %i, expected %i\n",VALUE_SIZE,msg->val_size); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } name=strndup(msg->name,ntohs(msg->hdr.len)-sizeof(*msg)+2); diff --git a/accel-pptpd/auth_mschap_v1.c b/accel-pptpd/auth_mschap_v1.c index 88983d34..1cf5eb8b 100644 --- a/accel-pptpd/auth_mschap_v1.c +++ b/accel-pptpd/auth_mschap_v1.c @@ -222,14 +222,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h { log_error("mschap-v1: id mismatch\n"); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } if (msg->val_size!=RESPONSE_VALUE_SIZE) { log_error("mschap-v1: value-size should be %i, expected %i\n",RESPONSE_VALUE_SIZE,msg->val_size); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } if (chap_check_response(ad,msg)) diff --git a/accel-pptpd/auth_mschap_v2.c b/accel-pptpd/auth_mschap_v2.c index 3b6bd13f..502f3686 100644 --- a/accel-pptpd/auth_mschap_v2.c +++ b/accel-pptpd/auth_mschap_v2.c @@ -302,14 +302,14 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h { log_error("mschap-v2: id mismatch\n"); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } if (msg->val_size!=RESPONSE_VALUE_SIZE) { log_error("mschap-v2: value-size should be %i, expected %i\n",RESPONSE_VALUE_SIZE,msg->val_size); chap_send_failure(ad); - ppp_terminate(ad->ppp); + ppp_terminate(ad->ppp, 0); } if (chap_check_response(ad,msg)) diff --git a/accel-pptpd/main.c b/accel-pptpd/main.c index 31069f31..05036251 100644 --- a/accel-pptpd/main.c +++ b/accel-pptpd/main.c @@ -32,13 +32,14 @@ static int parse_cmdline(char ***argv) *argv = malloc(ARG_MAX * sizeof(void *)); memset(*argv, 0, ARG_MAX * sizeof(void *)); - for(i = 0; i < ARG_MAX; i++) - { + for(i = 0; i < ARG_MAX; i++) { len = 0; if (getdelim(&(*argv)[i], &len, 0, f) < 0) break; } + fclose(f); + return i; } static void __init __main(void) @@ -113,9 +114,12 @@ int main(int argc, char **argv) } } + signal(SIGTERM, sigterm); + signal(SIGPIPE, sigterm); + signal(SIGUSR1, sigterm); + triton_run(); - signal(SIGTERM, sigterm); sigfillset(&set); sigdelset(&set, SIGTERM); sigdelset(&set, SIGSEGV); diff --git a/accel-pptpd/ppp.c b/accel-pptpd/ppp.c index 2ba41f1b..7f15c8af 100644 --- a/accel-pptpd/ppp.c +++ b/accel-pptpd/ppp.c @@ -29,6 +29,7 @@ struct layer_node_t static int ppp_chan_read(struct triton_md_handler_t*); static int ppp_unit_read(struct triton_md_handler_t*); static void init_layers(struct ppp_t *); +static void free_layers(struct ppp_t *); static void start_first_layer(struct ppp_t *); struct ppp_t *init_ppp(void) @@ -112,16 +113,14 @@ int establish_ppp(struct ppp_t *ppp) goto exit_close_unit; } - ppp->chan_hnd.ctx=ppp->ctrl->ctx; ppp->chan_hnd.fd=ppp->chan_fd; ppp->chan_hnd.read=ppp_chan_read; //ppp->chan_hnd.twait=-1; - ppp->unit_hnd.ctx=ppp->ctrl->ctx; 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_register_handler(ppp->ctrl->ctx, &ppp->chan_hnd); + triton_md_register_handler(ppp->ctrl->ctx, &ppp->unit_hnd); triton_md_enable_handler(&ppp->chan_hnd,MD_MODE_READ); triton_md_enable_handler(&ppp->unit_hnd,MD_MODE_READ); @@ -150,8 +149,13 @@ void destablish_ppp(struct ppp_t *ppp) close(ppp->unit_fd); close(ppp->chan_fd); + ppp->unit_fd = -1; + ppp->chan_fd = -1; + free(ppp->unit_buf); free(ppp->chan_buf); + + free_layers(ppp); log_debug("ppp destablished\n"); @@ -222,6 +226,10 @@ cont: list_for_each_entry(ppp_h, &ppp->chan_handlers, entry) { if (ppp_h->proto == proto) { ppp_h->recv(ppp_h); + if (ppp->chan_fd == -1) { + ppp->ctrl->finished(ppp); + return 1; + } goto cont; } } @@ -260,11 +268,15 @@ cont: list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) { if (ppp_h->proto == proto) { ppp_h->recv(ppp_h); + if (ppp->unit_fd == -1) { + ppp->ctrl->finished(ppp); + return 1; + } goto cont; } } - log_warn("ppp_chan_read: discarding unknown packet %x\n",proto); + log_warn("ppp_unit_read: discarding unknown packet %x\n",proto); } } @@ -306,29 +318,33 @@ void ppp_layer_finished(struct ppp_t *ppp, struct ppp_layer_data_t *d) return; } } + destablish_ppp(ppp); } -void ppp_terminate(struct ppp_t *ppp) +void ppp_terminate(struct ppp_t *ppp, int hard) { struct layer_node_t *n; struct ppp_layer_data_t *d; - int s=0; + int s = 0; log_debug("ppp_terminate\n"); - list_for_each_entry(n,&ppp->layers,entry) - { - list_for_each_entry(d,&n->items,entry) - { - if (d->starting) - { - s=1; + if (hard) { + destablish_ppp(ppp); + return; + } + + list_for_each_entry(n,&ppp->layers,entry) { + list_for_each_entry(d,&n->items,entry) { + if (d->starting) { + s = 1; d->layer->finish(d); } } } - if (s) return; + if (s) + return; destablish_ppp(ppp); } @@ -397,26 +413,41 @@ void ppp_unregister_layer(struct ppp_layer_t *layer) static void init_layers(struct ppp_t *ppp) { - struct layer_node_t *n,*n1; + 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)); + 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); + 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 free_layers(struct ppp_t *ppp) +{ + struct layer_node_t *n; + struct ppp_layer_data_t *d; + + while (!list_empty(&ppp->layers)) { + n = list_entry(ppp->layers.next, typeof(*n), entry); + while (!list_empty(&n->items)) { + d = list_entry(n->items.next, typeof(*d), entry); + list_del(&d->entry); + d->layer->free(d); } + list_del(&n->entry); + free(n); } } diff --git a/accel-pptpd/ppp.h b/accel-pptpd/ppp.h index a0a6f0ed..a7665908 100644 --- a/accel-pptpd/ppp.h +++ b/accel-pptpd/ppp.h @@ -126,7 +126,7 @@ void ppp_init(void); struct ppp_fsm_t* ppp_lcp_init(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_terminate(struct ppp_t *ppp, int hard); void ppp_register_chan_handler(struct ppp_t *, struct ppp_handler_t *); void ppp_register_unit_handler(struct ppp_t * ,struct ppp_handler_t *); diff --git a/accel-pptpd/ppp_auth.c b/accel-pptpd/ppp_auth.c index c7075fb1..3208edac 100644 --- a/accel-pptpd/ppp_auth.c +++ b/accel-pptpd/ppp_auth.c @@ -303,7 +303,7 @@ void auth_successed(struct ppp_t *ppp) void auth_failed(struct ppp_t *ppp) { - ppp_terminate(ppp); + ppp_terminate(ppp, 0); } int ppp_auth_register_handler(struct ppp_auth_handler_t *h) diff --git a/accel-pptpd/ppp_ccp.c b/accel-pptpd/ppp_ccp.c index 4bceb5b2..924df7d2 100644 --- a/accel-pptpd/ppp_ccp.c +++ b/accel-pptpd/ppp_ccp.c @@ -509,11 +509,11 @@ static void ccp_recv(struct ppp_handler_t*h) } ccp_free_conf_req(ccp); if (r==CCP_OPT_FAIL) - ppp_terminate(ccp->ppp); + ppp_terminate(ccp->ppp, 0); break; case CONFACK: if (ccp_recv_conf_ack(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(ccp->ppp); + ppp_terminate(ccp->ppp, 0); else ppp_fsm_recv_conf_ack(&ccp->fsm); break; @@ -523,7 +523,7 @@ static void ccp_recv(struct ppp_handler_t*h) break; case CONFREJ: if (ccp_recv_conf_rej(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(ccp->ppp); + ppp_terminate(ccp->ppp, 0); else ppp_fsm_recv_conf_rej(&ccp->fsm); break; @@ -532,7 +532,7 @@ static void ccp_recv(struct ppp_handler_t*h) log_debug("recv [CCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg); free(term_msg); ppp_fsm_recv_term_req(&ccp->fsm); - ppp_terminate(ccp->ppp); + ppp_terminate(ccp->ppp, 0); break; case TERMACK: term_msg=strndup((char*)(hdr+1),ntohs(hdr->len)); diff --git a/accel-pptpd/ppp_ipcp.c b/accel-pptpd/ppp_ipcp.c index ad552bdd..4acf6947 100644 --- a/accel-pptpd/ppp_ipcp.c +++ b/accel-pptpd/ppp_ipcp.c @@ -500,11 +500,11 @@ static void ipcp_recv(struct ppp_handler_t*h) } ipcp_free_conf_req(ipcp); if (r==IPCP_OPT_FAIL) - ppp_terminate(ipcp->ppp); + ppp_terminate(ipcp->ppp, 0); break; case CONFACK: if (ipcp_recv_conf_ack(ipcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(ipcp->ppp); + ppp_terminate(ipcp->ppp, 0); else ppp_fsm_recv_conf_ack(&ipcp->fsm); break; @@ -514,7 +514,7 @@ static void ipcp_recv(struct ppp_handler_t*h) break; case CONFREJ: if (ipcp_recv_conf_rej(ipcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(ipcp->ppp); + ppp_terminate(ipcp->ppp, 0); else ppp_fsm_recv_conf_rej(&ipcp->fsm); break; @@ -523,7 +523,7 @@ static void ipcp_recv(struct ppp_handler_t*h) log_debug("recv [IPCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg); free(term_msg); ppp_fsm_recv_term_req(&ipcp->fsm); - ppp_terminate(ipcp->ppp); + ppp_terminate(ipcp->ppp, 0); break; case TERMACK: term_msg=strndup((char*)(hdr+1),ntohs(hdr->len)); diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c index 1f0431a7..ac885c77 100644 --- a/accel-pptpd/ppp_lcp.c +++ b/accel-pptpd/ppp_lcp.c @@ -513,11 +513,11 @@ static void lcp_recv(struct ppp_handler_t*h) } lcp_free_conf_req(lcp); if (r==LCP_OPT_FAIL) - ppp_terminate(lcp->ppp); + ppp_terminate(lcp->ppp, 0); break; case CONFACK: if (lcp_recv_conf_ack(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(lcp->ppp); + ppp_terminate(lcp->ppp, 0); else ppp_fsm_recv_conf_ack(&lcp->fsm); break; @@ -527,7 +527,7 @@ static void lcp_recv(struct ppp_handler_t*h) break; case CONFREJ: if (lcp_recv_conf_rej(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) - ppp_terminate(lcp->ppp); + ppp_terminate(lcp->ppp, 0); else ppp_fsm_recv_conf_rej(&lcp->fsm); break; @@ -536,7 +536,7 @@ static void lcp_recv(struct ppp_handler_t*h) log_debug("recv [LCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg); free(term_msg); ppp_fsm_recv_term_req(&lcp->fsm); - ppp_terminate(lcp->ppp); + ppp_terminate(lcp->ppp, 0); break; case TERMACK: term_msg=strndup((char*)(hdr+1),ntohs(hdr->len)); diff --git a/accel-pptpd/pptp.c b/accel-pptpd/pptp.c index f932e0b6..a8aef873 100644 --- a/accel-pptpd/pptp.c +++ b/accel-pptpd/pptp.c @@ -5,6 +5,7 @@ #include <errno.h> #include <string.h> #include <fcntl.h> +#include <time.h> #include <arpa/inet.h> #include <netinet/in.h> @@ -23,7 +24,8 @@ #define STATE_IDLE 0 #define STATE_ESTB 1 #define STATE_PPP 2 -#define STATE_FIN 10 +#define STATE_FIN 3 +#define STATE_CLOSE 4 struct pptp_conn_t { @@ -53,220 +55,226 @@ static void disconnect(struct pptp_conn_t *conn) { triton_md_unregister_handler(&conn->hnd); close(conn->hnd.fd); - conn->hnd.fd=-1; + + if (conn->state == STATE_PPP) { + conn->state = STATE_CLOSE; + ppp_terminate(&conn->ppp, 1); + } + triton_unregister_ctx(&conn->ctx); + + free(conn->in_buf); + free(conn->out_buf); + free(conn); } -static int post_msg(struct pptp_conn_t *conn,void *buf,int size) +static int post_msg(struct pptp_conn_t *conn, void *buf, int size) { int n; - if (conn->out_size) - { + if (conn->out_size) { log_debug("post_msg: buffer is not empty\n"); return -1; } - n=write(conn->hnd.fd,buf,size); - if (n<0) - { - if (errno==EINTR) n=0; - else - { - log_debug("post_msg: failed to write socket %i\n",errno); + n=write(conn->hnd.fd, buf, size); + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + n = 0; + else { + if (errno != EPIPE) + log_debug("post_msg: failed to write socket %i\n",errno); return -1; } } - if (n<size) - { - memcpy(conn->out_buf,buf+n,size-n); - triton_md_enable_handler(&conn->hnd,MD_MODE_WRITE); + if ( n<size ) { + memcpy(conn->out_buf, buf + n, size - n); + triton_md_enable_handler(&conn->hnd, MD_MODE_WRITE); } return 0; } -static int send_pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn,int reason,int err_code) +static int send_pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn, int reason, int err_code) { - struct pptp_stop_ctrl_conn msg={ - .header=PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RQST), - .reason_result=hton8(reason), - .error_code=hton8(err_code), + struct pptp_stop_ctrl_conn msg = { + .header = PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RQST), + .reason_result = hton8(reason), + .error_code = hton8(err_code), }; - return post_msg(conn,&msg,sizeof(msg)); + return post_msg(conn, &msg, sizeof(msg)); } -static int send_pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn,int reason,int err_code) +static int send_pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn, int reason, int err_code) { - struct pptp_stop_ctrl_conn msg={ - .header=PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY), - .reason_result=hton8(reason), - .error_code=hton8(err_code), + struct pptp_stop_ctrl_conn msg = { + .header = PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY), + .reason_result = hton8(reason), + .error_code = hton8(err_code), }; - return post_msg(conn,&msg,sizeof(msg)); + return post_msg(conn, &msg, sizeof(msg)); } 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); + 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); + if (conn->state == STATE_PPP) { + conn->state = STATE_FIN; + ppp_terminate(&conn->ppp, 0); + } - conn->state=STATE_FIN; //conn->hnd.twait=1000; - return send_pptp_stop_ctrl_conn_rply(conn,PPTP_CONN_STOP_OK,0); + send_pptp_stop_ctrl_conn_rply(conn, PPTP_CONN_STOP_OK, 0); + return -1; } -static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn,int res_code,int err_code) +static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn, int res_code, int err_code) { - struct pptp_start_ctrl_conn msg={ - .header=PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY), - .version=htons(PPTP_VERSION), - .result_code=res_code, - .error_code=err_code, - .framing_cap=htonl(PPTP_FRAME_SYNC), - .bearer_cap=htonl(0), - .max_channels=htons(1), - .firmware_rev=htons(PPTP_FIRMWARE_VERSION), + struct pptp_start_ctrl_conn msg = { + .header = PPTP_HEADER_CTRL(PPTP_START_CTRL_CONN_RPLY), + .version = htons(PPTP_VERSION), + .result_code = res_code, + .error_code = err_code, + .framing_cap = htonl(PPTP_FRAME_SYNC), + .bearer_cap = htonl(0), + .max_channels = htons(1), + .firmware_rev = htons(PPTP_FIRMWARE_VERSION), }; - memset(msg.hostname,0,sizeof(msg.hostname)); - strcpy((char*)msg.hostname,PPTP_HOSTNAME); + memset(msg.hostname, 0, sizeof(msg.hostname)); + strcpy((char*)msg.hostname, PPTP_HOSTNAME); - memset(msg.vendor,0,sizeof(msg.vendor)); - strcpy((char*)msg.vendor,PPTP_VENDOR); + memset(msg.vendor, 0, sizeof(msg.vendor)); + strcpy((char*)msg.vendor, PPTP_VENDOR); - return post_msg(conn,&msg,sizeof(msg)); + return post_msg(conn, &msg, sizeof(msg)); } static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn) { - struct pptp_start_ctrl_conn *msg=(struct pptp_start_ctrl_conn *)conn->in_buf; + struct pptp_start_ctrl_conn *msg = (struct pptp_start_ctrl_conn *)conn->in_buf; - if (conn->state!=STATE_IDLE) - { + if (conn->state != STATE_IDLE) { log_info("unexpected PPTP_START_CTRL_CONN_RQST\n"); - if (send_pptp_start_ctrl_conn_rply(conn,PPTP_CONN_RES_EXISTS,0)) + if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_EXISTS, 0)) return -1; return 0; } - if (msg->version!=htons(PPTP_VERSION)) - { - log_info("PPTP version mismatch: expecting %x, received %s\n",PPTP_VERSION,msg->version); - if (send_pptp_start_ctrl_conn_rply(conn,PPTP_CONN_RES_PROTOCOL,0)) + if (msg->version != htons(PPTP_VERSION)) { + log_info("PPTP version mismatch: expecting %x, received %s\n", PPTP_VERSION, msg->version); + if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_PROTOCOL, 0)) return -1; return 0; } - if (!(ntohl(msg->framing_cap)&PPTP_FRAME_SYNC)) - { + if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) { log_info("connection does not supports sync mode\n"); - if (send_pptp_start_ctrl_conn_rply(conn,PPTP_CONN_RES_GE,0)) + if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_GE, 0)) return -1; return 0; } - if (send_pptp_start_ctrl_conn_rply(conn,PPTP_CONN_RES_SUCCESS,0)) + if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_SUCCESS, 0)) return -1; - conn->state=STATE_ESTB; + conn->state = STATE_ESTB; return 0; } -static int send_pptp_out_call_rply(struct pptp_conn_t *conn,struct pptp_out_call_rqst *rqst,int call_id,int res_code,int err_code) +static int send_pptp_out_call_rply(struct pptp_conn_t *conn, struct pptp_out_call_rqst *rqst, int call_id, int res_code, int err_code) { - struct pptp_out_call_rply msg={ - .header=PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY), - .call_id=htons(call_id), - .call_id_peer=rqst->call_id, - .result_code=res_code, - .error_code=err_code, - .cause_code=0, - .speed=rqst->bps_max, - .recv_size=rqst->recv_size, - .delay=0, - .channel=0, + struct pptp_out_call_rply msg = { + .header = PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY), + .call_id = htons(call_id), + .call_id_peer = rqst->call_id, + .result_code = res_code, + .error_code = err_code, + .cause_code = 0, + .speed = rqst->bps_max, + .recv_size = rqst->recv_size, + .delay = 0, + .channel = 0, }; - return post_msg(conn,&msg,sizeof(msg)); + return post_msg(conn, &msg, sizeof(msg)); } static int pptp_out_call_rqst(struct pptp_conn_t *conn) { - struct pptp_out_call_rqst *msg=(struct pptp_out_call_rqst *)conn->in_buf; - struct sockaddr_pppox src_addr,dst_addr; + struct pptp_out_call_rqst *msg = (struct pptp_out_call_rqst *)conn->in_buf; + struct sockaddr_pppox src_addr, dst_addr; struct sockaddr_in addr; socklen_t addrlen; int pptp_sock; - if (conn->state!=STATE_ESTB) - { + if (conn->state != STATE_ESTB) { log_info("unexpected PPTP_OUT_CALL_RQST\n"); - if (send_pptp_out_call_rply(conn,msg,0,PPTP_CALL_RES_GE,PPTP_GE_NOCONN)) + if (send_pptp_out_call_rply(conn, msg, 0, PPTP_CALL_RES_GE, PPTP_GE_NOCONN)) return -1; return 0; } - 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->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->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); - if (pptp_sock<0) - { - log_error("failed to create PPTP socket (%s)\n",strerror(errno)); + 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->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->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); + if (pptp_sock < 0) { + log_error("failed to create PPTP socket (%s)\n", strerror(errno)); return -1; } - if (bind(pptp_sock,(struct sockaddr*)&src_addr,sizeof(src_addr))) - { - log_error("failed to bind PPTP socket (%s)\n",strerror(errno)); + if (bind(pptp_sock, (struct sockaddr*)&src_addr, sizeof(src_addr))) { + log_error("failed to bind PPTP socket (%s)\n", strerror(errno)); close(pptp_sock); return -1; } - addrlen=sizeof(src_addr); - getsockname(pptp_sock,(struct sockaddr*)&src_addr,&addrlen); + addrlen = sizeof(src_addr); + getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen); - if (connect(pptp_sock,(struct sockaddr*)&dst_addr,sizeof(dst_addr))) - { - log_error("failed to connect PPTP socket (%s)\n",strerror(errno)); + if (connect(pptp_sock, (struct sockaddr*)&dst_addr, sizeof(dst_addr))) { + log_error("failed to connect PPTP socket (%s)\n", strerror(errno)); close(pptp_sock); return -1; } - if (send_pptp_out_call_rply(conn,msg,src_addr.sa_addr.pptp.call_id,PPTP_CALL_RES_OK,0)) + 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)); - conn->ppp.ctrl=&conn->ctrl; - conn->ctrl.ctx=&conn->ctx; - conn->ctrl.started=ppp_started; - conn->ctrl.finished=ppp_finished; - if (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.ctrl = &conn->ctrl; + conn->ctrl.ctx = &conn->ctx; + conn->ctrl.started = ppp_started; + conn->ctrl.finished = ppp_finished; + if (establish_ppp(&conn->ppp)) { close(pptp_sock); - send_pptp_stop_ctrl_conn_rqst(conn,0,0); - conn->state=STATE_FIN; + //if (send_pptp_stop_ctrl_conn_rqst(conn, 0, 0)) + // return -1; + conn->state = STATE_FIN; //conn->hnd.twait=1000; - }else conn->state=STATE_PPP; + return -1; + } else + conn->state = STATE_PPP; return 0; } static int process_packet(struct pptp_conn_t *conn) { - struct pptp_header *hdr=(struct pptp_header *)conn->in_buf; + struct pptp_header *hdr = (struct pptp_header *)conn->in_buf; switch(ntohs(hdr->ctrl_type)) { case PPTP_START_CTRL_CONN_RQST: @@ -287,8 +295,7 @@ static int pptp_read(struct triton_md_handler_t *h) while(1) { n = read(h->fd,conn->in_buf,PPTP_CTRL_SIZE_MAX-conn->in_size); - if (n <= 0) - { + if (n < 0) { if (errno == EINTR) continue; if (errno == EAGAIN) @@ -296,6 +303,8 @@ static int pptp_read(struct triton_md_handler_t *h) log_error("pptp: read: %s\n",strerror(errno)); goto drop; } + if (n == 0) + goto drop; conn->in_size += n; if (conn->in_size >= sizeof(*hdr)) { if (hdr->magic != htonl(PPTP_MAGIC)) @@ -319,61 +328,61 @@ drop: } static int pptp_write(struct triton_md_handler_t *h) { - 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); + struct pptp_conn_t *conn = container_of(h, typeof(*conn), hnd); + int n; - if (n<0) - { - if (errno==EAGAIN) n=0; - else - { - log_debug("post_msg: failed to write socket %i\n",errno); - disconnect(conn); - return 1; + while (1) { + n = write(h->fd, conn->out_buf+conn->out_pos, conn->out_size-conn->out_pos); + + if (n < 0) { + if (errno == EINTR) + continue; + if (errno == EAGAIN) + n = 0; + else { + if (errno != EPIPE) + log_error("pptp:post_msg: %s\n", strerror(errno)); + disconnect(conn); + return 1; + } } - } - conn->out_pos+=n; - if (conn->out_pos==conn->out_size) - { - conn->out_pos=0; - conn->out_size=0; - triton_md_disable_handler(h,MD_MODE_WRITE); + conn->out_pos += n; + if (conn->out_pos == conn->out_size) { + conn->out_pos = 0; + conn->out_size = 0; + triton_md_disable_handler(h, MD_MODE_WRITE); + return 0; + } } - return 0; - //h->twait=TIMEOUT; } static void pptp_timeout(struct triton_md_handler_t *h) { } static void pptp_close(struct triton_ctx_t *ctx) { - struct pptp_conn_t *conn=container_of(ctx,typeof(*conn),ctx); - if (conn->state==STATE_PPP) - ppp_terminate(&conn->ppp); - else + struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); + if (conn->state == STATE_PPP) { + conn->state = STATE_FIN; + ppp_terminate(&conn->ppp, 0); + } else disconnect(conn); } -static void pptp_free(struct triton_ctx_t *ctx) -{ - struct pptp_conn_t *conn=container_of(ctx,typeof(*conn),ctx); - free(conn->in_buf); - free(conn->out_buf); - free(conn); -} 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); + 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; + //send_pptp_stop_ctrl_conn_rqst(conn, 0, 0); + if (conn->state != STATE_CLOSE) { + conn->state = STATE_CLOSE; + disconnect(conn); + } } //================================== @@ -414,13 +423,11 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->hnd.read = pptp_read; conn->hnd.write = pptp_write; conn->ctx.close = pptp_close; - conn->ctx.free = pptp_free; - conn->hnd.ctx = &conn->ctx; conn->in_buf = malloc(PPTP_CTRL_SIZE_MAX); conn->out_buf = malloc(PPTP_CTRL_SIZE_MAX); triton_register_ctx(&conn->ctx); - triton_md_register_handler(&conn->hnd); + triton_md_register_handler(&conn->ctx, &conn->hnd); triton_md_enable_handler(&conn->hnd,MD_MODE_READ); } return 0; @@ -436,7 +443,6 @@ static struct pptp_serv_t serv= { .hnd.read=pptp_connect, .ctx.close=pptp_serv_close, - .hnd.ctx=&serv.ctx, }; void __init pptp_init(void) @@ -471,7 +477,7 @@ void __init pptp_init(void) } triton_register_ctx(&serv.ctx); - triton_md_register_handler(&serv.hnd); + triton_md_register_handler(&serv.ctx, &serv.hnd); triton_md_enable_handler(&serv.hnd, MD_MODE_READ); } diff --git a/accel-pptpd/triton/CMakeLists.txt b/accel-pptpd/triton/CMakeLists.txt index b11025d8..fd6b5182 100644 --- a/accel-pptpd/triton/CMakeLists.txt +++ b/accel-pptpd/triton/CMakeLists.txt @@ -6,6 +6,7 @@ SET(sources_c conf_file.c loader.c log.c + mempool.c ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) ADD_DEFINITIONS("-DUSE_SPINLOCK") diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c index c1aefcf6..3cb47a6d 100644 --- a/accel-pptpd/triton/md.c +++ b/accel-pptpd/triton/md.c @@ -16,6 +16,8 @@ static struct epoll_event *epoll_events; static pthread_t md_thr; static void *md_thread(void *arg); +static mempool_t *md_pool; + int md_init(void) { epoll_fd = epoll_create(1); @@ -30,6 +32,8 @@ int md_init(void) return -1; } + md_pool = mempool_create(sizeof(struct _triton_md_handler_t)); + return 0; } void md_run(void) @@ -49,7 +53,7 @@ void md_terminate(void) static void *md_thread(void *arg) { int i,n,r; - struct triton_md_handler_t *h; + struct _triton_md_handler_t *h; while(1) { n = epoll_wait(epoll_fd, epoll_events, max_events, -1); @@ -61,13 +65,16 @@ static void *md_thread(void *arg) } for(i = 0; i < n; i++) { - h = (struct triton_md_handler_t *)epoll_events[i].data.ptr; + h = (struct _triton_md_handler_t *)epoll_events[i].data.ptr; spin_lock(&h->ctx->lock); - h->trig_epoll_events |= epoll_events[i].events; - if (!h->pending) { - list_add_tail(&h->entry2, &h->ctx->pending_handlers); - h->pending = 1; - r = triton_queue_ctx(h->ctx); + if (h->ud) { + h->trig_epoll_events |= epoll_events[i].events; + if (!h->pending) { + list_add_tail(&h->entry2, &h->ctx->pending_handlers); + h->pending = 1; + r = triton_queue_ctx(h->ctx); + } else + r = 0; } else r = 0; spin_unlock(&h->ctx->lock); @@ -79,25 +86,37 @@ static void *md_thread(void *arg) return NULL; } -void __export triton_md_register_handler(struct triton_md_handler_t *h) +void __export triton_md_register_handler(struct triton_ctx_t *ctx, struct triton_md_handler_t *ud) { + struct _triton_md_handler_t *h = mempool_alloc(md_pool); + memset(h, 0, sizeof(*h)); + h->ud = ud; h->epoll_event.data.ptr = h; - if (!h->ctx) - h->ctx = default_ctx; + if (ctx) + h->ctx = (struct _triton_ctx_t *)ctx->tpd; + else + h->ctx = (struct _triton_ctx_t *)default_ctx->tpd; + ud->tpd = h; spin_lock(&h->ctx->lock); list_add_tail(&h->entry, &h->ctx->handlers); spin_unlock(&h->ctx->lock); } -void __export triton_md_unregister_handler(struct triton_md_handler_t *h) +void __export triton_md_unregister_handler(struct triton_md_handler_t *ud) { + struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd; + triton_md_disable_handler(ud, MD_MODE_READ | MD_MODE_WRITE); spin_lock(&h->ctx->lock); list_del(&h->entry); if (h->pending) list_del(&h->entry2); + h->ud = NULL; spin_unlock(&h->ctx->lock); + sched_yield(); + mempool_free(h); } -int __export triton_md_enable_handler(struct triton_md_handler_t *h, int mode) +int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode) { + struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd; int r; int events = h->epoll_event.events; @@ -109,17 +128,18 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *h, int mode) h->epoll_event.events |= EPOLLET; if (events) - r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->fd, &h->epoll_event); + r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); else - r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->fd, &h->epoll_event); + r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->ud->fd, &h->epoll_event); if (r) triton_log_error("md:epoll_ctl: %s",strerror(errno)); return r; } -int __export triton_md_disable_handler(struct triton_md_handler_t *h,int mode) +int __export triton_md_disable_handler(struct triton_md_handler_t *ud,int mode) { + struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd; int r=0; if (!h->epoll_event.events) @@ -131,10 +151,10 @@ int __export triton_md_disable_handler(struct triton_md_handler_t *h,int mode) h->epoll_event.events &= ~EPOLLOUT; if (h->epoll_event.events & (EPOLLIN | EPOLLOUT)) - r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->fd, &h->epoll_event); + r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); else { h->epoll_event.events = 0; - r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->fd, NULL); + r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->ud->fd, NULL); } if (r) diff --git a/accel-pptpd/triton/mempool.c b/accel-pptpd/triton/mempool.c new file mode 100644 index 00000000..973fec53 --- /dev/null +++ b/accel-pptpd/triton/mempool.c @@ -0,0 +1,67 @@ +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "triton_p.h" + +struct _mempool_t +{ + int size; + struct list_head items; + spinlock_t lock; + uint64_t magic; +}; + +struct _item_t +{ + struct _mempool_t *owner; + struct list_head entry; + uint64_t magic; + char ptr[0]; +}; + +mempool_t *mempool_create(int size) +{ + struct _mempool_t *p = malloc(sizeof(*p)); + + memset(p, 0, sizeof(*p)); + INIT_LIST_HEAD(&p->items); + spinlock_init(&p->lock); + p->size = size; + p->magic = (uint64_t)random() * (uint64_t)random(); + + return (mempool_t *)p; +} + +void *mempool_alloc(mempool_t *pool) +{ + struct _mempool_t *p = (struct _mempool_t *)pool; + struct _item_t *it; + + spin_lock(&p->lock); + if (!list_empty(&p->items)) { + it = list_entry(p->items.next, typeof(*it), entry); + list_del(&it->entry); + spin_unlock(&p->lock); + return it->ptr; + } + spin_unlock(&p->lock); + it = malloc(sizeof(*it) + p->size); + it->owner = p; + it->magic = p->magic; + return it->ptr; +} + +void mempool_free(void *ptr) +{ + struct _item_t *it = container_of(ptr, typeof(*it), ptr); + + if (it->magic != it->owner->magic) { + triton_log_error("mempool: memory corruption detected"); + abort(); + } + spin_lock(&it->owner->lock); + list_add_tail(&it->entry,&it->owner->items); + spin_unlock(&it->owner->lock); +} + diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c index 5f7de93e..f34c19d1 100644 --- a/accel-pptpd/triton/timer.c +++ b/accel-pptpd/triton/timer.c @@ -16,6 +16,8 @@ static struct epoll_event *epoll_events; static pthread_t timer_thr; static void *timer_thread(void *arg); +static mempool_t *timer_pool; + int timer_init(void) { epoll_fd = epoll_create(1); @@ -30,6 +32,8 @@ int timer_init(void) return -1; } + timer_pool = mempool_create(sizeof(struct _triton_timer_t)); + return 0; } @@ -50,7 +54,7 @@ void timer_terminate(void) void *timer_thread(void *arg) { int i,n,r; - struct triton_timer_t *t; + struct _triton_timer_t *t; while(1) { n = epoll_wait(epoll_fd, epoll_events, max_events, -1); @@ -62,11 +66,17 @@ void *timer_thread(void *arg) } for(i = 0; i < n; i++) { - t = (struct triton_timer_t *)epoll_events[i].data.ptr; + t = (struct _triton_timer_t *)epoll_events[i].data.ptr; spin_lock(&t->ctx->lock); - list_add_tail(&t->entry2, &t->ctx->pending_timers); - t->pending = 1; - r=triton_queue_ctx(t->ctx); + if (t->ud) { + if (!t->pending) { + list_add_tail(&t->entry2, &t->ctx->pending_timers); + t->pending = 1; + r = triton_queue_ctx(t->ctx); + } else + r = 0; + } else + r = 0; spin_unlock(&t->ctx->lock); if (r) triton_thread_wakeup(t->ctx->thread); @@ -76,20 +86,30 @@ void *timer_thread(void *arg) return NULL; } -int __export triton_timer_add(struct triton_timer_t *t, int abs_time) +int __export triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t *ud, int abs_time) { + struct _triton_timer_t *t = mempool_alloc(timer_pool); + + memset(t, 0, sizeof(*t)); + t->ud = ud; t->epoll_event.data.ptr = t; t->epoll_event.events = EPOLLIN | EPOLLET; - if (!t->ctx) - t->ctx = default_ctx; + if (ctx) + t->ctx = (struct _triton_ctx_t *)ctx->tpd; + else + t->ctx = (struct _triton_ctx_t *)default_ctx->tpd; t->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if (t->fd < 0) { triton_log_error("timer:timerfd_create: %s" ,strerror(errno)); + mempool_free(t); return -1; } - if (triton_timer_mod(t, abs_time)) { + ud->tpd = t; + + if (triton_timer_mod(ud, abs_time)) { close(t->fd); + mempool_free(t); return -1; } @@ -100,24 +120,28 @@ int __export triton_timer_add(struct triton_timer_t *t, int abs_time) if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, t->fd, &t->epoll_event)) { triton_log_error("timer:epoll_ctl: %s", strerror(errno)); spin_lock(&t->ctx->lock); + t->ud = NULL; list_del(&t->entry); spin_unlock(&t->ctx->lock); close(t->fd); + mempool_free(t); + ud->tpd = NULL; return -1; } return 0; } -int __export triton_timer_mod(struct triton_timer_t *t,int abs_time) +int __export triton_timer_mod(struct triton_timer_t *ud,int abs_time) { + struct _triton_timer_t *t = (struct _triton_timer_t *)ud->tpd; struct itimerspec ts = { - .it_value.tv_sec = t->expire_tv.tv_sec, - .it_value.tv_nsec = t->expire_tv.tv_usec * 1000, - .it_interval.tv_sec = t->period / 1000, - .it_interval.tv_nsec = t->period % 1000 * 1000, + .it_value.tv_sec = ud->expire_tv.tv_sec, + .it_value.tv_nsec = ud->expire_tv.tv_usec * 1000, + .it_interval.tv_sec = ud->period / 1000, + .it_interval.tv_nsec = (ud->period % 1000) * 1000, }; - if (t->expire_tv.tv_sec == 0 && t->expire_tv.tv_usec == 0) + if (ud->expire_tv.tv_sec == 0 && ud->expire_tv.tv_usec == 0) ts.it_value = ts.it_interval; if (timerfd_settime(t->fd, abs_time ? TFD_TIMER_ABSTIME : 0, &ts, NULL)) { @@ -127,14 +151,18 @@ int __export triton_timer_mod(struct triton_timer_t *t,int abs_time) return 0; } -void __export triton_timer_del(struct triton_timer_t *t) +void __export triton_timer_del(struct triton_timer_t *ud) { + struct _triton_timer_t *t = (struct _triton_timer_t *)ud->tpd; epoll_ctl(epoll_fd, EPOLL_CTL_DEL, t->fd, &t->epoll_event); close(t->fd); spin_lock(&t->ctx->lock); list_del(&t->entry); if (t->pending) list_del(&t->entry2); + t->ud = NULL; spin_unlock(&t->ctx->lock); + sched_yield(); + mempool_free(t); } diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index 121e6957..8c8d5a38 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -22,17 +22,20 @@ static LIST_HEAD(ctx_list); struct triton_ctx_t *default_ctx; static int terminate; -void triton_thread_wakeup(struct triton_thread_t *thread) +static mempool_t *ctx_pool; + +void triton_thread_wakeup(struct _triton_thread_t *thread) { pthread_kill(thread->thread, SIGUSR1); } -static void* triton_thread(struct triton_thread_t *thread) +static void* triton_thread(struct _triton_thread_t *thread) { - struct triton_md_handler_t *h; - struct triton_timer_t *t; + struct _triton_md_handler_t *h; + struct _triton_timer_t *t; sigset_t set; int sig; + uint64_t tt; sigemptyset(&set); sigaddset(&set, SIGUSR1); @@ -43,7 +46,8 @@ static void* triton_thread(struct triton_thread_t *thread) cont: if (thread->ctx->need_close) { - thread->ctx->close(thread->ctx); + if (thread->ctx->ud->close) + thread->ctx->ud->close(thread->ctx->ud); thread->ctx->need_close = 0; } @@ -52,9 +56,10 @@ cont: if (!list_empty(&thread->ctx->pending_timers)) { t = list_entry(thread->ctx->pending_timers.next, typeof(*t), entry2); list_del(&t->entry2); + t->pending = 0; spin_unlock(&thread->ctx->lock); - if (t->expire(t)) - continue; + read(t->fd, &tt, sizeof(tt)); + t->ud->expire(t->ud); } if (!list_empty(&thread->ctx->pending_handlers)) { h = list_entry(thread->ctx->pending_handlers.next, typeof(*h), entry2); @@ -63,12 +68,12 @@ cont: spin_unlock(&thread->ctx->lock); if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP)) - if (h->read) - if (h->read(h)) + if (h->ud->read) + if (h->ud->read(h->ud)) continue; if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) - if (h->write) - if (h->write(h)) + if (h->ud->write) + if (h->ud->write(h->ud)) continue; h->trig_epoll_events = 0; continue; @@ -76,7 +81,7 @@ cont: thread->ctx->thread = NULL; spin_unlock(&thread->ctx->lock); if (thread->ctx->need_free) - thread->ctx->free(thread->ctx); + mempool_free(thread->ctx); thread->ctx = NULL; break; } @@ -101,9 +106,9 @@ cont: } } -struct triton_thread_t *create_thread() +struct _triton_thread_t *create_thread() { - struct triton_thread_t *thread = malloc(sizeof(*thread)); + struct _triton_thread_t *thread = malloc(sizeof(*thread)); if (!thread) return NULL; @@ -116,7 +121,7 @@ struct triton_thread_t *create_thread() return thread; } -int triton_queue_ctx(struct triton_ctx_t *ctx) +int triton_queue_ctx(struct _triton_ctx_t *ctx) { if (ctx->thread || ctx->queued) return 0; @@ -137,21 +142,46 @@ int triton_queue_ctx(struct triton_ctx_t *ctx) return 1; } -void __export triton_register_ctx(struct triton_ctx_t *ctx) +void __export triton_register_ctx(struct triton_ctx_t *ud) { + struct _triton_ctx_t *ctx = mempool_alloc(ctx_pool); + + memset(ctx, 0, sizeof(*ctx)); + ctx->ud = ud; spinlock_init(&ctx->lock); INIT_LIST_HEAD(&ctx->handlers); INIT_LIST_HEAD(&ctx->timers); INIT_LIST_HEAD(&ctx->pending_handlers); INIT_LIST_HEAD(&ctx->pending_timers); + ud->tpd = ctx; + spin_lock(&ctx_list_lock); list_add_tail(&ctx->entry, &ctx_list); spin_unlock(&ctx_list_lock); } -void __export triton_unregister_ctx(struct triton_ctx_t *ctx) +void __export triton_unregister_ctx(struct triton_ctx_t *ud) { + struct _triton_ctx_t *ctx = (struct _triton_ctx_t *)ud->tpd; + + if (!list_empty(&ctx->handlers)) { + triton_log_error("BUG:ctx:triton_unregister_ctx: handlers is not empty"); + abort(); + } + if (!list_empty(&ctx->pending_handlers)) { + triton_log_error("BUG:ctx:triton_unregister_ctx: pending_handlers is not empty"); + abort(); + } + if (!list_empty(&ctx->timers)) { + triton_log_error("BUG:ctx:triton_unregister_ctx: timers is not empty"); + abort(); + } + if (!list_empty(&ctx->pending_timers)) { + triton_log_error("BUG:ctx:triton_unregister_ctx: pending_timers is not empty"); + abort(); + } + ctx->need_free = 1; spin_lock(&ctx_list_lock); list_del(&ctx->entry); @@ -160,7 +190,9 @@ void __export triton_unregister_ctx(struct triton_ctx_t *ctx) int __export triton_init(const char *conf_file) { - default_ctx=malloc(sizeof(*default_ctx)); + ctx_pool = mempool_create(sizeof(struct _triton_ctx_t)); + + default_ctx = malloc(sizeof(*default_ctx)); if (!default_ctx) { fprintf(stderr,"cann't allocate memory\n"); return -1; @@ -184,7 +216,7 @@ int __export triton_init(const char *conf_file) void __export triton_run() { - struct triton_thread_t *t; + struct _triton_thread_t *t; int i; for(i = 0; i < thread_count; i++) { @@ -202,8 +234,8 @@ void __export triton_run() void __export triton_terminate() { - struct triton_ctx_t *ctx; - struct triton_thread_t *t; + struct _triton_ctx_t *ctx; + struct _triton_thread_t *t; md_terminate(); timer_terminate(); diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h index 2cc4edb4..2543a234 100644 --- a/accel-pptpd/triton/triton.h +++ b/accel-pptpd/triton/triton.h @@ -2,79 +2,35 @@ #define TRITON_H #include <sys/time.h> -#include <pthread.h> -#include <sys/epoll.h> #include "list.h" -#include "spinlock.h" - -struct triton_thread_t -{ - struct list_head entry; - struct list_head entry2; - pthread_t thread; - int terminate:1; - struct triton_ctx_t *ctx; -}; struct triton_ctx_t { - struct list_head entry; - struct list_head entry2; - spinlock_t lock; - struct list_head handlers; - struct list_head timers; - - struct triton_thread_t *thread; - struct list_head pending_handlers; - struct list_head pending_timers; - int queued:1; - int need_close:1; - int need_free:1; - + const void *tpd; // triton private data, don't touch! void (*close)(struct triton_ctx_t*); void (*free)(struct triton_ctx_t*); }; struct triton_md_handler_t { - //triton part - //========== - struct list_head entry; - struct list_head entry2; - struct triton_ctx_t *ctx; - struct epoll_event epoll_event; - uint32_t trig_epoll_events; - int pending:1; - //========= - - //user part - //========= + const void *tpd; // triton private data, don't touch! int fd; - int (*read)(struct triton_md_handler_t *); int (*write)(struct triton_md_handler_t *); - //========= }; struct triton_timer_t { - struct list_head entry; - struct list_head entry2; - struct epoll_event epoll_event; - struct triton_ctx_t *ctx; - int fd; - int pending:1; - + const void *tpd; // triton private data, don't touch! struct timeval expire_tv; int period; - int (*expire)(struct triton_timer_t *); + void (*expire)(struct triton_timer_t *); }; struct conf_option_t { struct list_head entry; - char *name; char *val; }; @@ -90,14 +46,14 @@ void triton_unregister_ctx(struct triton_ctx_t *); #define MD_MODE_READ 1 #define MD_MODE_WRITE 2 -void triton_md_register_handler(struct triton_md_handler_t *h); +void triton_md_register_handler(struct triton_ctx_t *, struct triton_md_handler_t *); void triton_md_unregister_handler(struct triton_md_handler_t *h); int triton_md_enable_handler(struct triton_md_handler_t *h, int mode); int triton_md_disable_handler(struct triton_md_handler_t *h,int mode); -int triton_timer_add(struct triton_timer_t*,int abs_time); -int triton_timer_mod(struct triton_timer_t*,int abs_time); -void triton_timer_del(struct triton_timer_t*); +int triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t*,int abs_time); +int triton_timer_mod(struct triton_timer_t *,int abs_time); +void triton_timer_del(struct triton_timer_t *); struct conf_sect_t *conf_get_section(const char *name); char *conf_get_opt(const char *sect, const char *name); @@ -117,6 +73,7 @@ void triton_terminate(void); #define __init __attribute__((constructor)) +#define __export __attribute__((visibility("default"))) #undef offsetof #ifdef __compiler_offsetof @@ -129,6 +86,4 @@ void triton_terminate(void); const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) -#define __export __attribute__((visibility("default"))) - #endif diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h index 385f3558..24850bfd 100644 --- a/accel-pptpd/triton/triton_p.h +++ b/accel-pptpd/triton/triton_p.h @@ -1,8 +1,66 @@ #ifndef TRITON_P_H #define TRITON_P_H +#include <pthread.h> +#include <sys/epoll.h> + #include "triton.h" #include "list.h" +#include "spinlock.h" + +struct _triton_thread_t +{ + struct list_head entry; + struct list_head entry2; + pthread_t thread; + int terminate:1; + struct _triton_ctx_t *ctx; +}; + +struct _triton_ctx_t +{ + struct list_head entry; + struct list_head entry2; + spinlock_t lock; + struct list_head handlers; + struct list_head timers; + + struct _triton_thread_t *thread; + struct list_head pending_handlers; + struct list_head pending_timers; + int queued:1; + int need_close:1; + int need_free:1; + + struct triton_ctx_t *ud; +}; + +struct _triton_md_handler_t +{ + struct list_head entry; + struct list_head entry2; + struct _triton_ctx_t *ctx; + struct epoll_event epoll_event; + uint32_t trig_epoll_events; + int pending:1; + struct triton_md_handler_t *ud; +}; + +struct _triton_timer_t +{ + struct list_head entry; + struct list_head entry2; + struct epoll_event epoll_event; + struct _triton_ctx_t *ctx; + int fd; + int pending:1; + struct triton_timer_t *ud; +}; + +typedef void * mempool_t; +mempool_t *mempool_create(int size); +void *mempool_alloc(mempool_t*); +void mempool_free(void*); int log_init(void); int md_init(); @@ -12,8 +70,8 @@ int timer_init(); void timer_run(); void timer_terminate(); struct triton_ctx_t *default_ctx; -int triton_queue_ctx(struct triton_ctx_t*); -void triton_thread_wakeup(struct triton_thread_t*); +int triton_queue_ctx(struct _triton_ctx_t*); +void triton_thread_wakeup(struct _triton_thread_t*); int conf_load(const char *fname); void triton_log_error(const char *fmt,...); void triton_log_debug(const char *fmt,...); |