diff options
Diffstat (limited to 'accel-pptpd')
29 files changed, 459 insertions, 111 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index 3de0072d..9254e7e9 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -12,7 +12,7 @@ ADD_SUBDIRECTORY(radius) ADD_SUBDIRECTORY(logs) ADD_SUBDIRECTORY(extra) -ADD_EXECUTABLE(pptpd +ADD_EXECUTABLE(accel-pptpd ppp/ppp.c ppp/ppp_fsm.c ppp/ppp_lcp.c @@ -39,5 +39,5 @@ ADD_EXECUTABLE(pptpd main.c memdebug.c ) -TARGET_LINK_LIBRARIES(pptpd triton rt pthread ssl) +TARGET_LINK_LIBRARIES(accel-pptpd triton rt pthread ssl) diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index 40413bbc..e3f0eaa7 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -1,6 +1,6 @@ [modules] log_file -log_pgsql +#log_pgsql pptp auth_pap auth_chap_md5 @@ -36,10 +36,11 @@ dm_coa_secret=testing123 verbose=1 [client-ip-range] -192.168.10.20-20 +192.168.10.20-30 192.168.10.6/32 192.168.10.1/32 192.168.11.0/24 +192.168.0.0/24 [ip-pool] gw-ip-address=192.168.100.1 @@ -53,7 +54,7 @@ gw-ip-address=192.168.100.1 [log] log-file=general.log log-emerg=/dev/stderr -log-debug=debug.log +log-debug=/dev/stdout copy=1 #color=1 #per-user-dir=per_user diff --git a/accel-pptpd/ctrl/pptp.c b/accel-pptpd/ctrl/pptp.c index f4cd9d3a..fddd00fa 100644 --- a/accel-pptpd/ctrl/pptp.c +++ b/accel-pptpd/ctrl/pptp.c @@ -117,12 +117,11 @@ static int post_msg(struct pptp_conn_t *conn, void *buf, int size) 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) { 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)); @@ -143,12 +142,13 @@ 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_ppp_info("PPTP_STOP_CTRL_CONN_RQST reason=%i error_code=%i\n",msg->reason_result, msg->error_code); - if (conn->state == STATE_PPP) { - conn->state = STATE_FIN; - ppp_terminate(&conn->ppp, 0); - } - send_pptp_stop_ctrl_conn_rply(conn, PPTP_CONN_STOP_OK, 0); + + return -1; +} + +static int pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn) +{ return -1; } @@ -173,6 +173,7 @@ static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn, int res_code 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; @@ -190,12 +191,12 @@ static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn) return -1; return 0; } - if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) { + /*if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) { log_ppp_warn("connection does not supports sync mode\n"); 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)) return -1; @@ -350,6 +351,8 @@ static int process_packet(struct pptp_conn_t *conn) return pptp_start_ctrl_conn_rqst(conn); case PPTP_STOP_CTRL_CONN_RQST: return pptp_stop_ctrl_conn_rqst(conn); + case PPTP_STOP_CTRL_CONN_RPLY: + return pptp_stop_ctrl_conn_rply(conn); case PPTP_OUT_CALL_RQST: return pptp_out_call_rqst(conn); case PPTP_ECHO_RQST: @@ -438,10 +441,18 @@ static void pptp_close(struct triton_context_t *ctx) { struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx); if (conn->state == STATE_PPP) { - conn->state = STATE_FIN; + conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, 0); - } else - disconnect(conn); + } else { + if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) + triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); + else { + if (conn->timeout_timer.tpd) + triton_timer_mod(&conn->timeout_timer, 0); + else + triton_timer_add(ctx, &conn->timeout_timer, 0); + } + } } static void ppp_started(struct ppp_t *ppp) { @@ -451,11 +462,18 @@ static void ppp_finished(struct ppp_t *ppp) { struct pptp_conn_t *conn = container_of(ppp, typeof(*conn), ppp); - //send_pptp_stop_ctrl_conn_rqst(conn, 0, 0); if (conn->state != STATE_CLOSE) { log_ppp_debug("ppp_finished\n"); conn->state = STATE_CLOSE; - triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); + + if (send_pptp_stop_ctrl_conn_rqst(conn, 0)) + triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn); + else { + if (conn->timeout_timer.tpd) + triton_timer_mod(&conn->timeout_timer, 0); + else + triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); + } } } @@ -540,6 +558,7 @@ static void pptp_serv_close(struct triton_context_t *ctx) struct pptp_serv_t *s=container_of(ctx,typeof(*s),ctx); triton_md_unregister_handler(&s->hnd); close(s->hnd.fd); + triton_context_unregister(ctx); } static struct pptp_serv_t serv= @@ -561,6 +580,8 @@ static void __init pptp_init(void) addr.sin_family = AF_INET; addr.sin_port = htons (PPTP_PORT); addr.sin_addr.s_addr = htonl (INADDR_ANY); + + setsockopt(serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv.hnd.fd, 4); if (bind (serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { log_emerg("pptp: failed to bind socket: %s\n", strerror(errno)); close(serv.hnd.fd); diff --git a/accel-pptpd/include/ppp_fsm.h b/accel-pptpd/include/ppp_fsm.h index 5c6b7f47..77f983d3 120000..100644 --- a/accel-pptpd/include/ppp_fsm.h +++ b/accel-pptpd/include/ppp_fsm.h @@ -1 +1,69 @@ -../ppp/ppp_fsm.h
\ No newline at end of file +#ifndef PPP_FSM_H +#define PPP_FSM_H + +typedef enum {FSM_Initial=0,FSM_Starting,FSM_Closed,FSM_Stopped,FSM_Closing,FSM_Stopping,FSM_Req_Sent,FSM_Ack_Rcvd,FSM_Ack_Sent,FSM_Opened} FSM_STATE; +/* + * CP (LCP, IPCP, etc.) codes. + */ +#define CONFREQ 1 /* Configuration Request */ +#define CONFACK 2 /* Configuration Ack */ +#define CONFNAK 3 /* Configuration Nak */ +#define CONFREJ 4 /* Configuration Reject */ +#define TERMREQ 5 /* Termination Request */ +#define TERMACK 6 /* Termination Ack */ +#define CODEREJ 7 /* Code Reject */ +#define PROTOREJ 8 /* Code Reject */ +#define ECHOREQ 9 /* Echo Request */ +#define ECHOREP 10 /* Echo Reply */ + +struct ppp_t; + +struct ppp_fsm_t +{ + struct ppp_t *ppp; + FSM_STATE fsm_state; + uint16_t proto; + + struct triton_timer_t restart_timer; + int restart_counter; + int max_terminate; + int max_configure; + int max_failure; + int timeout; + int conf_failure; + + int id; + int recv_id; + + //fsm handling + void (*layer_up)(struct ppp_fsm_t*); + void (*layer_down)(struct ppp_fsm_t*); + void (*layer_started)(struct ppp_fsm_t*); + void (*layer_finished)(struct ppp_fsm_t*); + int (*send_conf_req)(struct ppp_fsm_t*); + void (*send_conf_ack)(struct ppp_fsm_t*); + void (*send_conf_nak)(struct ppp_fsm_t*); + void (*send_conf_rej)(struct ppp_fsm_t*); + void (*send_code_rej)(struct ppp_fsm_t*); +}; + +void ppp_fsm_init(struct ppp_fsm_t*); +void ppp_fsm_free(struct ppp_fsm_t*); + +int ppp_fsm_lower_up(struct ppp_fsm_t*); +void ppp_fsm_lower_down(struct ppp_fsm_t*); +int ppp_fsm_open(struct ppp_fsm_t*); +void ppp_fsm_close(struct ppp_fsm_t*); +void ppp_fsm_timeout0(struct ppp_fsm_t *layer); +void ppp_fsm_timeout1(struct ppp_fsm_t *layer); +void ppp_fsm_recv_conf_req_ack(struct ppp_fsm_t *layer); +void ppp_fsm_recv_conf_req_nak(struct ppp_fsm_t *layer); +void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer); +void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer); +void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer); +void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer); +void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer); +void ppp_fsm_recv_unk(struct ppp_fsm_t *layer); +void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer); + +#endif diff --git a/accel-pptpd/log.c b/accel-pptpd/log.c index fee1b548..e942686b 100644 --- a/accel-pptpd/log.c +++ b/accel-pptpd/log.c @@ -5,6 +5,7 @@ #include <errno.h> #include <string.h> #include <stdint.h> +#include <signal.h> #include <sys/time.h> #include "triton/mempool.h" @@ -402,14 +403,27 @@ void __export log_switch(struct triton_context_t *ctx, void *arg) cur_ppp = (struct ppp_t *)arg; } + void __export log_register_target(struct log_target_t *t) { list_add_tail(&t->entry, &targets); } +static void sighup(int n) +{ + struct log_target_t *t; + + list_for_each_entry(t, &targets, entry) + if (t->reopen) + t->reopen(); +} + static void __init log_init(void) { char *opt; + struct sigaction sa = { + .sa_handler = sighup, + }; opt = conf_get_opt("log", "log-emerg"); if (opt) { @@ -428,4 +442,7 @@ static void __init log_init(void) msg_pool = mempool_create(sizeof(struct log_msg_t)); _msg_pool = mempool_create(sizeof(struct _log_msg_t)); chunk_pool = mempool_create(sizeof(struct log_chunk_t) + LOG_CHUNK_SIZE + 1); + + sigaction(SIGHUP, &sa, NULL); } + diff --git a/accel-pptpd/log.h b/accel-pptpd/log.h index 97894597..140dad1d 100644 --- a/accel-pptpd/log.h +++ b/accel-pptpd/log.h @@ -40,6 +40,7 @@ struct log_target_t struct list_head entry; void (*log)(struct log_msg_t *, struct ppp_t *ppp); + void (*reopen)(void); }; void log_free_msg(struct log_msg_t *msg); diff --git a/accel-pptpd/logs/log_file.c b/accel-pptpd/logs/log_file.c index 79af4c68..1c1538ca 100644 --- a/accel-pptpd/logs/log_file.c +++ b/accel-pptpd/logs/log_file.c @@ -34,8 +34,8 @@ struct log_file_t struct log_file_pd_t *lpd; int fd; + int new_fd; off_t offset; - int cnt; uint64_t magic; }; @@ -72,18 +72,17 @@ static LIST_HEAD(lf_queue); static spinlock_t lf_queue_lock = SPINLOCK_INITIALIZER; static int lf_queue_sleeping = 1; -static uint64_t temp_seq; +static unsigned long temp_seq; static void send_next_chunk(); -#define MAGIC 0x9988776655443322llu static void log_file_init(struct log_file_t *lf) { spinlock_init(&lf->lock); INIT_LIST_HEAD(&lf->msgs); lf->fd = -1; - lf->magic = MAGIC; + lf->new_fd = -1; } static int log_file_open(struct log_file_t *lf, const char *fname) @@ -201,11 +200,16 @@ static void send_next_chunk(void) spin_unlock(&lf_queue_lock); + if (lf->new_fd != -1) { + close(lf->fd); + lf->fd = lf->new_fd; + lf->new_fd = -1; + } + aiocb.aio_fildes = lf->fd; aiocb.aio_offset = lf->offset; aiocb.aio_sigevent.sigev_value.sival_ptr = lf; aiocb.aio_nbytes = dequeue_log(lf); - __sync_add_and_fetch(&lf->cnt, 1); if (aio_write(&aiocb)) log_emerg("log_file: aio_write: %s\n", strerror(errno)); @@ -323,6 +327,17 @@ static void per_session_log(struct log_msg_t *msg, struct ppp_t *ppp) queue_log(&lpd->lf, msg); } +static void general_reopen(void) +{ + char *fname = conf_get_opt("log", "log-file"); + int fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + log_emerg("log_file: open '%s': %s\n", fname, strerror(errno)); + return; + } + log_file->new_fd = fd; +} + static void free_lpd(struct log_file_pd_t *lpd) { struct log_msg_t *msg; @@ -515,6 +530,7 @@ out_err: static struct log_target_t general_target = { .log = general_log, + .reopen = general_reopen, }; static struct log_target_t per_user_target = diff --git a/accel-pptpd/logs/log_pgsql.c b/accel-pptpd/logs/log_pgsql.c index 351fc064..0eed2431 100644 --- a/accel-pptpd/logs/log_pgsql.c +++ b/accel-pptpd/logs/log_pgsql.c @@ -19,8 +19,11 @@ static char *conf_query; static void start_connect(void); static void start_connect_timer(struct triton_timer_t *); +static void pgsql_close(struct triton_context_t *ctx); -static struct triton_context_t pgsql_ctx; +static struct triton_context_t pgsql_ctx = { + .close = pgsql_close, +}; static struct triton_md_handler_t pgsql_hnd; static struct triton_timer_t connect_timer = { .period = 5000, @@ -34,6 +37,7 @@ static int queue_size; static int sleeping = 0; static spinlock_t queue_lock = SPINLOCK_INITIALIZER; static char *log_buf; +static int need_close; static void unpack_msg(struct log_msg_t *msg) { @@ -80,6 +84,12 @@ static void write_next_msg(void) if (list_empty(&msg_queue)) { sleeping = 1; spin_unlock(&queue_lock); + if (need_close) { + triton_md_unregister_handler(&pgsql_hnd); + PQfinish(conn); + conn = NULL; + triton_context_unregister(&pgsql_ctx); + } return; } @@ -162,6 +172,11 @@ static void queue_log(struct log_msg_t *msg) { int r = 0, f = 0; spin_lock(&queue_lock); + if (!conn) { + log_free_msg(msg); + spin_unlock(&queue_lock); + return; + } if (queue_size < conf_queue_max) { list_add_tail(&msg->entry, &msg_queue); ++queue_size; @@ -247,6 +262,19 @@ static void start_connect_timer(struct triton_timer_t *t) start_connect(); } +static void pgsql_close(struct triton_context_t *ctx) +{ + spin_lock(&queue_lock); + if (sleeping) { + triton_md_unregister_handler(&pgsql_hnd); + PQfinish(conn); + conn = NULL; + triton_context_unregister(&pgsql_ctx); + } else + need_close = 1; + spin_unlock(&queue_lock); +} + static struct log_target_t target = { .log = general_log, }; diff --git a/accel-pptpd/main.c b/accel-pptpd/main.c index afd6b588..b543f0d8 100644 --- a/accel-pptpd/main.c +++ b/accel-pptpd/main.c @@ -109,7 +109,7 @@ int main(int argc, char **argv) } if (pid_file) { - FILE *f = fopen("pid_file", "w"); + FILE *f = fopen(pid_file, "w"); if (f) { fprintf(f, "%i", getpid()); fclose(f); @@ -128,10 +128,11 @@ int main(int argc, char **argv) sigdelset(&set, SIGFPE); sigdelset(&set, SIGILL); sigdelset(&set, SIGBUS); - sigdelset(&set, 35); - sigdelset(&set, 36); + sigdelset(&set, SIGHUP); sigdelset(&set, SIGIO); sigdelset(&set, SIGINT); + sigdelset(&set, 35); + sigdelset(&set, 36); pthread_sigmask(SIG_SETMASK, &set, NULL); sigemptyset(&set); diff --git a/accel-pptpd/ppp/ipcp_opt_dns.c b/accel-pptpd/ppp/ipcp_opt_dns.c index 16ef7af4..b0365da2 100644 --- a/accel-pptpd/ppp/ipcp_opt_dns.c +++ b/accel-pptpd/ppp/ipcp_opt_dns.c @@ -9,6 +9,9 @@ #include "memdebug.h" +static in_addr_t conf_dns1; +static in_addr_t conf_dns2; + static struct ipcp_option_t *dns1_init(struct ppp_ipcp_t *ipcp); static struct ipcp_option_t *dns2_init(struct ppp_ipcp_t *ipcp); static void dns_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt); @@ -100,8 +103,8 @@ static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, if (!dns_opt->addr) { - if (dns_opt->opt.id==CI_DNS1) dns_opt->addr=inet_addr("10.0.0.1"); - else dns_opt->addr=inet_addr("10.0.0.2"); + if (dns_opt->opt.id == CI_DNS1 && conf_dns1) dns_opt->addr=conf_dns1; + else if (dns_opt->opt.id == CI_DNS2 && conf_dns2) dns_opt->addr=conf_dns2; if (!dns_opt->addr) { @@ -142,7 +145,16 @@ static void dns2_print(void (*print)(const char *fmt,...),struct ipcp_option_t * static void __init dns_opt_init() { + char *opt; + + opt = conf_get_opt("dns", "dns1"); + if (opt) + conf_dns1 = inet_addr(opt); + + opt = conf_get_opt("dns", "dns2"); + if (opt) + conf_dns2 = inet_addr(opt); + ipcp_option_register(&dns1_opt_hnd); ipcp_option_register(&dns2_opt_hnd); } - diff --git a/accel-pptpd/ppp/lcp_opt_accomp.c b/accel-pptpd/ppp/lcp_opt_accomp.c index 8545f9d7..94fa1281 100644 --- a/accel-pptpd/ppp/lcp_opt_accomp.c +++ b/accel-pptpd/ppp/lcp_opt_accomp.c @@ -19,6 +19,7 @@ struct accomp_option_t { struct lcp_option_t opt; int accomp; // 0 - disabled, 1 - enabled, 2 - allow,disabled, 3 - allow,enabled + int require; }; static struct lcp_option_handler_t accomp_opt_hnd= @@ -75,6 +76,13 @@ static int accomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, { struct accomp_option_t *accomp_opt=container_of(opt,typeof(*accomp_opt),opt); + if (!ptr) { + if (accomp_opt->require) + return LCP_OPT_NAK; + accomp_opt->accomp=0; + return LCP_OPT_ACK; + } + if (accomp_opt->accomp>0) { accomp_opt->accomp=1; diff --git a/accel-pptpd/ppp/lcp_opt_magic.c b/accel-pptpd/ppp/lcp_opt_magic.c index cec40ce4..166c85c4 100644 --- a/accel-pptpd/ppp/lcp_opt_magic.c +++ b/accel-pptpd/ppp/lcp_opt_magic.c @@ -64,6 +64,9 @@ static int magic_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, struct magic_option_t *magic_opt=container_of(opt,typeof(*magic_opt),opt); struct lcp_opt32_t *opt32=(struct lcp_opt32_t*)ptr; + if (!ptr) + return LCP_OPT_NAK; + if (magic_opt->magic==ntohl(opt32->val)) { log_ppp_error("loop detected"); diff --git a/accel-pptpd/ppp/lcp_opt_mru.c b/accel-pptpd/ppp/lcp_opt_mru.c index f13b0148..096c0d58 100644 --- a/accel-pptpd/ppp/lcp_opt_mru.c +++ b/accel-pptpd/ppp/lcp_opt_mru.c @@ -86,6 +86,9 @@ static int mru_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, ui struct mru_option_t *mru_opt = container_of(opt,typeof(*mru_opt),opt); struct lcp_opt16_t *opt16 = (struct lcp_opt16_t*)ptr; + if (!ptr) + return LCP_OPT_NAK; + if (ntohs(opt16->val) < conf_min_mtu || ntohs(opt16->val) > lcp->ppp->ctrl->max_mtu) return LCP_OPT_NAK; diff --git a/accel-pptpd/ppp/lcp_opt_pcomp.c b/accel-pptpd/ppp/lcp_opt_pcomp.c index 0ff4d11f..a1ceb8e8 100644 --- a/accel-pptpd/ppp/lcp_opt_pcomp.c +++ b/accel-pptpd/ppp/lcp_opt_pcomp.c @@ -19,6 +19,7 @@ struct pcomp_option_t { struct lcp_option_t opt; int pcomp; // 0 - disabled, 1 - enabled, 2 - allow,disabled, 3 - allow,enabled + int require; }; static struct lcp_option_handler_t pcomp_opt_hnd= @@ -75,6 +76,13 @@ static int pcomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, { struct pcomp_option_t *pcomp_opt=container_of(opt,typeof(*pcomp_opt),opt); + if (!ptr) { + if (pcomp_opt->require) + return LCP_OPT_NAK; + pcomp_opt->pcomp=0; + return LCP_OPT_ACK; + } + if (pcomp_opt->pcomp>0) { pcomp_opt->pcomp=1; diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c index dfe5bbe0..03a8db08 100644 --- a/accel-pptpd/ppp/ppp.c +++ b/accel-pptpd/ppp/ppp.c @@ -351,15 +351,15 @@ void __export ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d) void __export ppp_layer_finished(struct ppp_t *ppp, struct ppp_layer_data_t *d) { struct layer_node_t *n=d->node; - - d->starting=0; - d->started=0; + + d->finished = 1; + d->starting = 0; list_for_each_entry(n,&ppp->layers,entry) { list_for_each_entry(d,&n->items,entry) { - if (d->starting) + if (!d->finished) return; } } @@ -373,6 +373,14 @@ void __export ppp_terminate(struct ppp_t *ppp, int hard) struct ppp_layer_data_t *d; int s = 0; + if (ppp->terminating) { + if (hard) + destablish_ppp(ppp); + return; + } + + ppp->terminating = 1; + log_ppp_debug("ppp_terminate\n"); triton_event_fire(EV_PPP_FINISHING, ppp); diff --git a/accel-pptpd/ppp/ppp.h b/accel-pptpd/ppp/ppp.h index 5a8ac572..32615c2e 100644 --- a/accel-pptpd/ppp/ppp.h +++ b/accel-pptpd/ppp/ppp.h @@ -86,6 +86,7 @@ struct ppp_t struct ppp_ctrl_t *ctrl; int log:1; + int terminating:1; void *chan_buf; int chan_buf_size; @@ -111,6 +112,7 @@ struct ppp_layer_data_t struct layer_node_t *node; int starting:1; int started:1; + int finished:1; }; struct ppp_layer_t diff --git a/accel-pptpd/ppp/ppp_auth.c b/accel-pptpd/ppp/ppp_auth.c index d141b817..dfa54156 100644 --- a/accel-pptpd/ppp/ppp_auth.c +++ b/accel-pptpd/ppp/ppp_auth.c @@ -137,6 +137,10 @@ static int auth_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, u if (list_empty(&auth_opt->auth_list)) return LCP_OPT_REJ; + + if (!ptr) + return LCP_OPT_ACK; + list_for_each_entry(d,&auth_opt->auth_list,entry) { diff --git a/accel-pptpd/ppp/ppp_ccp.c b/accel-pptpd/ppp/ppp_ccp.c index 301c2385..477b6242 100644 --- a/accel-pptpd/ppp/ppp_ccp.c +++ b/accel-pptpd/ppp/ppp_ccp.c @@ -30,6 +30,8 @@ static int send_conf_req(struct ppp_fsm_t*); static void send_conf_ack(struct ppp_fsm_t*); static void send_conf_nak(struct ppp_fsm_t*); static void send_conf_rej(struct ppp_fsm_t*); +static void send_term_req(struct ppp_fsm_t *fsm); +static void send_term_ack(struct ppp_fsm_t *fsm); static void ccp_recv(struct ppp_handler_t*); static void ccp_options_init(struct ppp_ccp_t *ccp) @@ -78,6 +80,7 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) ppp_register_unit_handler(ppp,&ccp->hnd); + ccp->fsm.proto = PPP_CCP; ppp_fsm_init(&ccp->fsm); ccp->fsm.layer_up=ccp_layer_up; @@ -86,6 +89,8 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) ccp->fsm.send_conf_ack=send_conf_ack; ccp->fsm.send_conf_nak=send_conf_nak; ccp->fsm.send_conf_rej=send_conf_rej; + ccp->fsm.send_term_req=send_term_req; + ccp->fsm.send_term_ack=send_term_ack; INIT_LIST_HEAD(&ccp->options); INIT_LIST_HEAD(&ccp->ropt_list); @@ -134,6 +139,7 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm) { struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); log_ppp_debug("ccp_layer_started\n"); + ccp->started = 1; ppp_layer_started(ccp->ppp,&ccp->ld); } @@ -141,6 +147,9 @@ static void ccp_layer_down(struct ppp_fsm_t *fsm) { struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); log_ppp_debug("ccp_layer_finished\n"); + if (!ccp->started) + ppp_layer_started(ccp->ppp, &ccp->ld); + ccp->started = 0; ppp_layer_finished(ccp->ppp,&ccp->ld); } @@ -480,6 +489,36 @@ static int ccp_recv_conf_ack(struct ppp_ccp_t *ccp,uint8_t *data,int size) return res; } +static void send_term_req(struct ppp_fsm_t *fsm) +{ + struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); + struct ccp_hdr_t hdr = { + .proto = htons(PPP_CCP), + .code = TERMREQ, + .id = ++ccp->fsm.id, + .len = htons(4), + }; + + log_ppp_debug("send [CCP TermReq id=%i \"\"]\n",hdr.id); + + ppp_chan_send(ccp->ppp, &hdr, 6); +} + +static void send_term_ack(struct ppp_fsm_t *fsm) +{ + struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); + struct ccp_hdr_t hdr = { + .proto = htons(PPP_CCP), + .code = TERMACK, + .id = ccp->fsm.recv_id, + .len = htons(4), + }; + + log_ppp_debug("send [CCP TermAck id=%i \"\"]\n", hdr.id); + + ppp_chan_send(ccp->ppp, &hdr, 6); +} + static void ccp_recv(struct ppp_handler_t*h) { struct ccp_hdr_t *hdr; @@ -544,14 +583,14 @@ static void ccp_recv(struct ppp_handler_t*h) ppp_fsm_recv_conf_rej(&ccp->fsm); break; case TERMREQ: - term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len)); + term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4); log_ppp_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, 0); + ppp_fsm_close(&ccp->fsm); break; case TERMACK: - term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len)); + term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4); log_ppp_debug("recv [CCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg); _free(term_msg); ppp_fsm_recv_term_ack(&ccp->fsm); diff --git a/accel-pptpd/ppp/ppp_ccp.h b/accel-pptpd/ppp/ppp_ccp.h index 3e459697..23f44f0f 100644 --- a/accel-pptpd/ppp/ppp_ccp.h +++ b/accel-pptpd/ppp/ppp_ccp.h @@ -86,6 +86,7 @@ struct ppp_ccp_t int ropt_len; int conf_req_len; + int started:1; }; int ccp_option_register(struct ccp_option_handler_t *h); diff --git a/accel-pptpd/ppp/ppp_fsm.c b/accel-pptpd/ppp/ppp_fsm.c index 8f8e8558..4fc60c21 100644 --- a/accel-pptpd/ppp/ppp_fsm.c +++ b/accel-pptpd/ppp/ppp_fsm.c @@ -143,7 +143,7 @@ void ppp_fsm_close(struct ppp_fsm_t *layer) case FSM_Ack_Sent: //if (layer->init_req_cnt) layer->init_req_cnt(layer); init_req_counter(layer,layer->max_terminate); - send_term_req(layer); + layer->send_term_req(layer); layer->fsm_state=FSM_Closing; break; default: @@ -157,7 +157,7 @@ void ppp_fsm_timeout0(struct ppp_fsm_t *layer) { case FSM_Closing: case FSM_Stopping: - send_term_req(layer); + layer->send_term_req(layer); break; case FSM_Ack_Rcvd: layer->fsm_state=FSM_Req_Sent; @@ -202,7 +202,7 @@ void ppp_fsm_recv_conf_req_ack(struct ppp_fsm_t *layer) switch(layer->fsm_state) { case FSM_Closed: - send_term_ack(layer); + layer->send_term_ack(layer); break; case FSM_Stopped: //if (layer->init_req_cnt) layer->init_req_cnt(layer); @@ -237,7 +237,7 @@ void ppp_fsm_recv_conf_req_nak(struct ppp_fsm_t *layer) switch(layer->fsm_state) { case FSM_Closed: - send_term_ack(layer); + layer->send_term_ack(layer); break; case FSM_Stopped: //if (layer->init_req_cnt) layer->init_req_cnt(layer); @@ -269,7 +269,7 @@ void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer) switch(layer->fsm_state) { case FSM_Closed: - send_term_ack(layer); + layer->send_term_ack(layer); break; case FSM_Stopped: //if (layer->init_req_cnt) layer->init_req_cnt(layer); @@ -302,7 +302,7 @@ void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer) { case FSM_Closed: case FSM_Stopped: - send_term_ack(layer); + layer->send_term_ack(layer); break; case FSM_Req_Sent: //if (layer->init_req_cnt) layer->init_req_cnt(layer); @@ -338,9 +338,13 @@ void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer) { case FSM_Closed: case FSM_Stopped: - send_term_ack(layer); + layer->send_term_ack(layer); break; case FSM_Req_Sent: + if (++layer->conf_failure == layer->max_failure) { + ppp_terminate(layer->ppp, 0); + return; + } //if (layer->init_req_cnt) layer->init_req_cnt(layer); init_req_counter(layer,layer->max_failure); --layer->restart_counter; @@ -375,7 +379,7 @@ void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer) case FSM_Opened: if (layer->layer_down) layer->layer_down(layer); //send_term_req(layer); - send_term_ack(layer); + layer->send_term_ack(layer); //if (layer->zero_req_cnt) layer->zero_req_cnt(layer); zero_req_counter(layer); layer->fsm_state=FSM_Stopping; @@ -383,17 +387,18 @@ void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer) case FSM_Req_Sent: case FSM_Ack_Rcvd: case FSM_Ack_Sent: - send_term_ack(layer); + layer->send_term_ack(layer); layer->fsm_state=FSM_Req_Sent; break; default: - send_term_req(layer); + layer->send_term_req(layer); break; } } void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer) { + stop_timer(layer); switch(layer->fsm_state) { case FSM_Closing: @@ -420,7 +425,7 @@ void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer) void ppp_fsm_recv_unk(struct ppp_fsm_t *layer) { - if (layer->send_conf_rej) layer->send_conf_rej(layer); + if (layer->send_code_rej) layer->send_code_rej(layer); } void ppp_fsm_recv_code_rej_perm(struct ppp_fsm_t *layer) @@ -441,7 +446,7 @@ void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer) { case FSM_Opened: if (layer->layer_down) layer->layer_down(layer); - send_term_req(layer); + layer->send_term_req(layer); layer->fsm_state=FSM_Stopping; break; case FSM_Closing: @@ -460,34 +465,6 @@ void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer) } } -void send_term_req(struct ppp_fsm_t *layer) -{ - struct lcp_hdr_t hdr = { - .proto = htons(PPP_LCP), - .code = TERMREQ, - .id = ++layer->id, - .len = htons(4), - }; - - log_ppp_debug("send [LCP TermReq id=%i \"\"]\n",hdr.id); - - --layer->restart_counter; - ppp_chan_send(layer->ppp, &hdr, 6); -} -void send_term_ack(struct ppp_fsm_t *layer) -{ - struct lcp_hdr_t hdr = { - .proto = htons(PPP_LCP), - .code = TERMACK, - .id = layer->recv_id, - .len = htons(4), - }; - - log_ppp_debug("send [LCP TermAck id=%i \"\"]\n", hdr.id); - - ppp_chan_send(layer->ppp, &hdr, 6); -} - static void stop_timer(struct ppp_fsm_t *fsm) { if (fsm->restart_timer.tpd) @@ -510,6 +487,8 @@ static void restart_timer_func(struct triton_timer_t *t) { struct ppp_fsm_t *layer = container_of(t, typeof(*layer), restart_timer); + log_ppp_debug("fsm timeout\n"); + if (layer->restart_counter>0) ppp_fsm_timeout0(layer); else diff --git a/accel-pptpd/ppp/ppp_fsm.h b/accel-pptpd/ppp/ppp_fsm.h index 908936db..4252a557 100644 --- a/accel-pptpd/ppp/ppp_fsm.h +++ b/accel-pptpd/ppp/ppp_fsm.h @@ -12,6 +12,7 @@ typedef enum {FSM_Initial=0,FSM_Starting,FSM_Closed,FSM_Stopped,FSM_Closing,FSM_ #define TERMREQ 5 /* Termination Request */ #define TERMACK 6 /* Termination Ack */ #define CODEREJ 7 /* Code Reject */ +#define PROTOREJ 8 /* Code Reject */ #define ECHOREQ 9 /* Echo Request */ #define ECHOREP 10 /* Echo Reply */ @@ -21,6 +22,7 @@ struct ppp_fsm_t { struct ppp_t *ppp; FSM_STATE fsm_state; + uint16_t proto; struct triton_timer_t restart_timer; int restart_counter; @@ -28,6 +30,7 @@ struct ppp_fsm_t int max_configure; int max_failure; int timeout; + int conf_failure; int id; int recv_id; @@ -41,6 +44,9 @@ struct ppp_fsm_t void (*send_conf_ack)(struct ppp_fsm_t*); void (*send_conf_nak)(struct ppp_fsm_t*); void (*send_conf_rej)(struct ppp_fsm_t*); + void (*send_code_rej)(struct ppp_fsm_t*); + void (*send_term_req)(struct ppp_fsm_t*); + void (*send_term_ack)(struct ppp_fsm_t*); }; void ppp_fsm_init(struct ppp_fsm_t*); diff --git a/accel-pptpd/ppp/ppp_ipcp.c b/accel-pptpd/ppp/ppp_ipcp.c index f3c20a64..795cbc0e 100644 --- a/accel-pptpd/ppp/ppp_ipcp.c +++ b/accel-pptpd/ppp/ppp_ipcp.c @@ -31,6 +31,8 @@ static void send_conf_ack(struct ppp_fsm_t*); static void send_conf_nak(struct ppp_fsm_t*); static void send_conf_rej(struct ppp_fsm_t*); static void ipcp_recv(struct ppp_handler_t*); +static void send_term_req(struct ppp_fsm_t *fsm); +static void send_term_ack(struct ppp_fsm_t *fsm); static void ipcp_options_init(struct ppp_ipcp_t *ipcp) { @@ -77,7 +79,8 @@ static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp) ipcp->hnd.recv=ipcp_recv; ppp_register_unit_handler(ppp,&ipcp->hnd); - + + ipcp->fsm.proto = PPP_IPCP; ppp_fsm_init(&ipcp->fsm); ipcp->fsm.layer_up=ipcp_layer_up; @@ -86,6 +89,8 @@ static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp) ipcp->fsm.send_conf_ack=send_conf_ack; ipcp->fsm.send_conf_nak=send_conf_nak; ipcp->fsm.send_conf_rej=send_conf_rej; + ipcp->fsm.send_term_req=send_term_req; + ipcp->fsm.send_term_ack=send_term_ack; INIT_LIST_HEAD(&ipcp->options); INIT_LIST_HEAD(&ipcp->ropt_list); @@ -477,6 +482,36 @@ static int ipcp_recv_conf_ack(struct ppp_ipcp_t *ipcp,uint8_t *data,int size) return res; } +static void send_term_req(struct ppp_fsm_t *fsm) +{ + struct ppp_ipcp_t *ipcp=container_of(fsm,typeof(*ipcp),fsm); + struct ipcp_hdr_t hdr = { + .proto = htons(PPP_IPCP), + .code = TERMREQ, + .id = ++ipcp->fsm.id, + .len = htons(4), + }; + + log_ppp_debug("send [IPCP TermReq id=%i \"\"]\n",hdr.id); + + ppp_unit_send(ipcp->ppp, &hdr, 6); +} + +static void send_term_ack(struct ppp_fsm_t *fsm) +{ + struct ppp_ipcp_t *ipcp=container_of(fsm,typeof(*ipcp),fsm); + struct ipcp_hdr_t hdr = { + .proto = htons(PPP_IPCP), + .code = TERMACK, + .id = ipcp->fsm.recv_id, + .len = htons(4), + }; + + log_ppp_debug("send [IPCP TermAck id=%i \"\"]\n", hdr.id); + + ppp_unit_send(ipcp->ppp, &hdr, 6); +} + static void ipcp_recv(struct ppp_handler_t*h) { struct ipcp_hdr_t *hdr; @@ -541,17 +576,18 @@ static void ipcp_recv(struct ppp_handler_t*h) ppp_fsm_recv_conf_rej(&ipcp->fsm); break; case TERMREQ: - term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len)); + term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4); log_ppp_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, 0); break; case TERMACK: - term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len)); + term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4); log_ppp_debug("recv [IPCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg); _free(term_msg); ppp_fsm_recv_term_ack(&ipcp->fsm); + ppp_terminate(ipcp->ppp, 0); break; case CODEREJ: log_ppp_debug("recv [IPCP CodeRej id=%x]\n",hdr->id); diff --git a/accel-pptpd/ppp/ppp_lcp.c b/accel-pptpd/ppp/ppp_lcp.c index 7081cbb3..66d31da8 100644 --- a/accel-pptpd/ppp/ppp_lcp.c +++ b/accel-pptpd/ppp/ppp_lcp.c @@ -34,9 +34,12 @@ static int send_conf_req(struct ppp_fsm_t*); static void send_conf_ack(struct ppp_fsm_t*); static void send_conf_nak(struct ppp_fsm_t*); static void send_conf_rej(struct ppp_fsm_t*); -static void lcp_recv(struct ppp_handler_t*); +static void send_code_rej(struct ppp_fsm_t*); static void start_echo(struct ppp_lcp_t *lcp); static void stop_echo(struct ppp_lcp_t *lcp); +static void send_term_req(struct ppp_fsm_t *fsm); +static void send_term_ack(struct ppp_fsm_t *fsm); +static void lcp_recv(struct ppp_handler_t*); static void lcp_options_init(struct ppp_lcp_t *lcp) { @@ -85,7 +88,8 @@ static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp) lcp->hnd.recv=lcp_recv; ppp_register_chan_handler(ppp,&lcp->hnd); - + + lcp->fsm.proto = PPP_LCP; ppp_fsm_init(&lcp->fsm); lcp->fsm.layer_up=lcp_layer_up; @@ -95,6 +99,9 @@ static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp) lcp->fsm.send_conf_ack=send_conf_ack; lcp->fsm.send_conf_nak=send_conf_nak; lcp->fsm.send_conf_rej=send_conf_rej; + lcp->fsm.send_code_rej=send_code_rej; + lcp->fsm.send_term_req=send_term_req; + lcp->fsm.send_term_ack=send_term_ack; INIT_LIST_HEAD(&lcp->ropt_list); @@ -237,12 +244,23 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2); } +static void send_code_rej(struct ppp_fsm_t *fsm) +{ + struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); + struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)lcp->ppp->chan_buf; + + hdr->code=CONFACK; + log_ppp_debug("send [LCP CodeRej %x id=%x ]\n",hdr->code, lcp->fsm.recv_id); + + ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2); +} + static void send_conf_nak(struct ppp_fsm_t *fsm) { struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); uint8_t *buf=_malloc(lcp->conf_req_len), *ptr=buf; struct lcp_hdr_t *lcp_hdr=(struct lcp_hdr_t*)ptr; - struct recv_opt_t *ropt; + struct lcp_option_t *lopt; log_ppp_debug("send [LCP ConfNak id=%x",lcp->fsm.recv_id); @@ -253,13 +271,11 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) ptr+=sizeof(*lcp_hdr); - list_for_each_entry(ropt,&lcp->ropt_list,entry) - { - if (ropt->state==LCP_OPT_NAK) - { + list_for_each_entry(lopt, &lcp->options, entry) { + if (lopt->state == LCP_OPT_NAK) { log_ppp_debug(" "); - ropt->lopt->h->print(log_ppp_debug,ropt->lopt,NULL); - ptr+=ropt->lopt->h->send_conf_nak(lcp,ropt->lopt,ptr); + lopt->h->print(log_ppp_debug,lopt,NULL); + ptr+=lopt->h->send_conf_nak(lcp,lopt,ptr); } } @@ -362,7 +378,7 @@ static int lcp_recv_conf_req(struct ppp_lcp_t *lcp,uint8_t *data,int size) } log_ppp_debug("]\n"); - /*list_for_each_entry(lopt,&lcp->options,entry) + list_for_each_entry(lopt,&lcp->options,entry) { if (lopt->state==LCP_OPT_NONE) { @@ -370,7 +386,7 @@ static int lcp_recv_conf_req(struct ppp_lcp_t *lcp,uint8_t *data,int size) lopt->state=r; if (r<ret) ret=r; } - }*/ + } return ret; } @@ -570,6 +586,36 @@ static void stop_echo(struct ppp_lcp_t *lcp) triton_timer_del(&lcp->echo_timer); } +static void send_term_req(struct ppp_fsm_t *fsm) +{ + struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); + struct lcp_hdr_t hdr = { + .proto = htons(PPP_LCP), + .code = TERMREQ, + .id = ++lcp->fsm.id, + .len = htons(4), + }; + + log_ppp_debug("send [LCP TermReq id=%i \"\"]\n",hdr.id); + + ppp_chan_send(lcp->ppp, &hdr, 6); +} + +static void send_term_ack(struct ppp_fsm_t *fsm) +{ + struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm); + struct lcp_hdr_t hdr = { + .proto = htons(PPP_LCP), + .code = TERMACK, + .id = lcp->fsm.recv_id, + .len = htons(4), + }; + + log_ppp_debug("send [LCP TermAck id=%i \"\"]\n", hdr.id); + + ppp_chan_send(lcp->ppp, &hdr, 6); +} + static void lcp_recv(struct ppp_handler_t*h) { struct lcp_hdr_t *hdr; @@ -656,7 +702,11 @@ static void lcp_recv(struct ppp_handler_t*h) case ECHOREP: lcp_recv_echo_repl(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); break; + case PROTOREJ: + log_ppp_debug("recv [LCP ProtoRej id=%x <%x>]\n",hdr->code, hdr->id, *(uint16_t*)(hdr + 1)); + break; default: + log_ppp_debug("recv [LCP Unknown %x]\n",hdr->code); ppp_fsm_recv_unk(&lcp->fsm); break; } diff --git a/accel-pptpd/radius/auth.c b/accel-pptpd/radius/auth.c index ccb8fc03..9b61ecc6 100644 --- a/accel-pptpd/radius/auth.c +++ b/accel-pptpd/radius/auth.c @@ -173,7 +173,7 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar const uint8_t *nt_response = va_arg(args, const uint8_t *); int flags = va_arg(args, int); - req = rad_req_alloc(rpd, CODE_ACCESS_ACCEPT, username); + req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username); if (!req) return PWDB_DENIED; diff --git a/accel-pptpd/radius/dict/dictionary b/accel-pptpd/radius/dict/dictionary index 8d4a7979..64db18fe 100644 --- a/accel-pptpd/radius/dict/dictionary +++ b/accel-pptpd/radius/dict/dictionary @@ -74,3 +74,5 @@ $INCLUDE dictionary.rfc5176 $INCLUDE dictionary.microsoft + +ATTRIBUTE Traffic-Shape-in 231 integer diff --git a/accel-pptpd/radius/dm_coa.c b/accel-pptpd/radius/dm_coa.c index 32466bbb..d94596fc 100644 --- a/accel-pptpd/radius/dm_coa.c +++ b/accel-pptpd/radius/dm_coa.c @@ -235,6 +235,7 @@ static void dm_coa_close(struct triton_context_t *ctx) struct dm_coa_serv_t *serv = container_of(ctx, typeof(*serv), ctx); triton_md_unregister_handler(&serv->hnd); close(serv->hnd.fd); + triton_context_unregister(ctx); } static struct dm_coa_serv_t serv = { diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index 38ace958..42b39a5d 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -59,6 +59,8 @@ void rad_proc_attrs(struct rad_req_t *req) } } else if (!strcmp(attr->attr->name, "Acct-Interim-Interval")) req->rpd->acct_interim_interval = attr->val.integer; + else if (!strcmp(attr->attr->name, "Session-Timeout")) + req->rpd->session_timeout.expire_tv.tv_sec = attr->val.integer; } } @@ -105,6 +107,14 @@ static struct ipdb_item_t *get_ip(struct ppp_t *ppp) return NULL; } +static void session_timeout(struct triton_timer_t *t) +{ + struct radius_pd_t *rpd = container_of(t, typeof(*rpd), session_timeout); + + log_ppp_msg("radius: session timed out\n"); + ppp_terminate(rpd->ppp, 0); +} + static void ppp_starting(struct ppp_t *ppp) { struct radius_pd_t *rpd = mempool_alloc(rpd_pool); @@ -126,6 +136,11 @@ static void ppp_started(struct ppp_t *ppp) if (rad_acct_start(rpd)) ppp_terminate(rpd->ppp, 0); + + if (rpd->session_timeout.expire_tv.tv_sec) { + rpd->session_timeout.expire = session_timeout; + triton_timer_add(ppp->ctrl->ctx, &rpd->session_timeout, 0); + } } static void ppp_finishing(struct ppp_t *ppp) { @@ -149,6 +164,9 @@ static void ppp_finished(struct ppp_t *ppp) if (rpd->dm_coa_req) rad_packet_free(rpd->dm_coa_req); + if (rpd->session_timeout.tpd) + triton_timer_del(&rpd->session_timeout); + list_del(&rpd->pd.entry); mempool_free(rpd); @@ -302,6 +320,10 @@ static void __init radius_init(void) if (opt) conf_nas_ip_address = opt; + opt = conf_get_opt("radius", "nas-identifier"); + if (opt) + conf_nas_identifier = opt; + opt = conf_get_opt("radius", "gw-ip-address"); if (opt) conf_gw_ip_address = opt; diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h index ae442238..9537641b 100644 --- a/accel-pptpd/radius/radius_p.h +++ b/accel-pptpd/radius/radius_p.h @@ -23,6 +23,8 @@ struct radius_pd_t uint32_t acct_input_gigawords; uint32_t acct_output_gigawords; + struct triton_timer_t session_timeout; + struct rad_packet_t *dm_coa_req; struct sockaddr_in dm_coa_addr; diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index d7939041..c4205322 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -20,8 +20,8 @@ static LIST_HEAD(ctx_queue); static spinlock_t ctx_list_lock = SPINLOCK_INITIALIZER; static LIST_HEAD(ctx_list); -struct triton_context_t *default_ctx; static int terminate; +static int need_terminate; static mempool_t *ctx_pool; static mempool_t *call_pool; @@ -268,7 +268,7 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg) return 0; } -int __export triton_context_print() +void __export triton_context_print() { struct _triton_context_t *ctx; @@ -281,6 +281,7 @@ void __export triton_context_unregister(struct triton_context_t *ud) { struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; struct _triton_ctx_call_t *call; + struct _triton_thread_t *t; while (!list_empty(&ctx->pending_calls)) { call = list_entry(ctx->pending_calls.next, typeof(*call), entry); @@ -290,6 +291,12 @@ void __export triton_context_unregister(struct triton_context_t *ud) if (!list_empty(&ctx->handlers)) { triton_log_error("BUG:ctx:triton_unregister_ctx: handlers is not empty"); + { + struct _triton_md_handler_t *h; + list_for_each_entry(h, &ctx->handlers, entry) + if (h->ud) + printf("%p\n", h->ud); + } abort(); } if (!list_empty(&ctx->pending_handlers)) { @@ -308,9 +315,16 @@ void __export triton_context_unregister(struct triton_context_t *ud) ctx->need_free = 1; spin_lock(&ctx_list_lock); list_del(&ctx->entry); + if (need_terminate && list_empty(&ctx_list)) + terminate = 1; spin_unlock(&ctx_list_lock); __sync_fetch_and_sub(&triton_stat.context_count, 1); + + if (terminate) { + list_for_each_entry(t, &threads, entry) + triton_thread_wakeup(t); + } } void __export triton_context_schedule(struct triton_context_t *ud) { @@ -391,9 +405,6 @@ int __export triton_init(const char *conf_file) call_pool = mempool_create(sizeof(struct _triton_ctx_call_t)); ctx_stack_pool = mempool_create(CTX_STACK_SIZE); - default_ctx = _malloc(sizeof(*default_ctx)); - triton_context_register(default_ctx, NULL); - if (conf_load(conf_file)) return -1; @@ -446,27 +457,25 @@ void __export triton_terminate() { struct _triton_context_t *ctx; struct _triton_thread_t *t; - - md_terminate(); - timer_terminate(); - + int r; + + need_terminate = 1; + spin_lock(&ctx_list_lock); list_for_each_entry(ctx, &ctx_list, entry) { spin_lock(&ctx->lock); ctx->need_close = 1; - triton_queue_ctx(ctx); + r = triton_queue_ctx(ctx); + if (r) + triton_thread_wakeup(ctx->thread); spin_unlock(&ctx->lock); } spin_unlock(&ctx_list_lock); - spin_lock(&threads_lock); - terminate = 1; - spin_unlock(&threads_lock); - - list_for_each_entry(t, &threads, entry) - triton_thread_wakeup(t); - list_for_each_entry(t, &threads, entry) pthread_join(t->thread, NULL); + + md_terminate(); + timer_terminate(); } |