summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/CMakeLists.txt2
-rw-r--r--accel-pptpd/auth_chap_md5.c4
-rw-r--r--accel-pptpd/auth_mschap_v1.c4
-rw-r--r--accel-pptpd/auth_mschap_v2.c4
-rw-r--r--accel-pptpd/main.c10
-rw-r--r--accel-pptpd/ppp.c87
-rw-r--r--accel-pptpd/ppp.h2
-rw-r--r--accel-pptpd/ppp_auth.c2
-rw-r--r--accel-pptpd/ppp_ccp.c8
-rw-r--r--accel-pptpd/ppp_ipcp.c8
-rw-r--r--accel-pptpd/ppp_lcp.c8
-rw-r--r--accel-pptpd/pptp.c322
-rw-r--r--accel-pptpd/triton/CMakeLists.txt1
-rw-r--r--accel-pptpd/triton/md.c54
-rw-r--r--accel-pptpd/triton/mempool.c67
-rw-r--r--accel-pptpd/triton/timer.c60
-rw-r--r--accel-pptpd/triton/triton.c74
-rw-r--r--accel-pptpd/triton/triton.h63
-rw-r--r--accel-pptpd/triton/triton_p.h62
19 files changed, 522 insertions, 320 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt
index e22bdc6..fc6ac0e 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 f0a5368..5577794 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 88983d3..1cf5eb8 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 3b6bd13..502f368 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 31069f3..0503625 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 2ba41f1..7f15c8a 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 a0a6f0e..a766590 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 c7075fb..3208eda 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 4bceb5b..924df7d 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 ad552bd..4acf694 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 1f0431a..ac885c7 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 f932e0b..a8aef87 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 b11025d..fd6b518 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 c1aefcf..3cb47a6 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 0000000..973fec5
--- /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 5f7de93..f34c19d 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 121e695..8c8d5a3 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 2cc4edb..2543a23 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 385f355..24850bf 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,...);