summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2010-09-27 23:55:11 +0400
committerDmitry Kozlov <xeb@mail.ru>2010-09-27 23:55:11 +0400
commit2902ea733331c1a083487666dbdd847518a0f117 (patch)
treec0d9239c735a5ef14561af4e6e866f16c154c723 /accel-pptpd
parentf9bc7d57b20a0165862cfab7259f6147fcb15733 (diff)
parent0325cc5f07ac992414129b4f47ae4aae017dbd2b (diff)
downloadaccel-ppp-2902ea733331c1a083487666dbdd847518a0f117.tar.gz
accel-ppp-2902ea733331c1a083487666dbdd847518a0f117.zip
radius: implemented Session-Timeout attribute
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/CMakeLists.txt4
-rw-r--r--accel-pptpd/accel-pptpd.conf7
-rw-r--r--accel-pptpd/ctrl/pptp.c49
-rw-r--r--[l---------]accel-pptpd/include/ppp_fsm.h70
-rw-r--r--accel-pptpd/log.c17
-rw-r--r--accel-pptpd/log.h1
-rw-r--r--accel-pptpd/logs/log_file.c26
-rw-r--r--accel-pptpd/logs/log_pgsql.c30
-rw-r--r--accel-pptpd/main.c7
-rw-r--r--accel-pptpd/ppp/ipcp_opt_dns.c18
-rw-r--r--accel-pptpd/ppp/lcp_opt_accomp.c8
-rw-r--r--accel-pptpd/ppp/lcp_opt_magic.c3
-rw-r--r--accel-pptpd/ppp/lcp_opt_mru.c3
-rw-r--r--accel-pptpd/ppp/lcp_opt_pcomp.c8
-rw-r--r--accel-pptpd/ppp/ppp.c16
-rw-r--r--accel-pptpd/ppp/ppp.h2
-rw-r--r--accel-pptpd/ppp/ppp_auth.c4
-rw-r--r--accel-pptpd/ppp/ppp_ccp.c45
-rw-r--r--accel-pptpd/ppp/ppp_ccp.h1
-rw-r--r--accel-pptpd/ppp/ppp_fsm.c59
-rw-r--r--accel-pptpd/ppp/ppp_fsm.h6
-rw-r--r--accel-pptpd/ppp/ppp_ipcp.c42
-rw-r--r--accel-pptpd/ppp/ppp_lcp.c72
-rw-r--r--accel-pptpd/radius/auth.c2
-rw-r--r--accel-pptpd/radius/dict/dictionary2
-rw-r--r--accel-pptpd/radius/dm_coa.c1
-rw-r--r--accel-pptpd/radius/radius.c22
-rw-r--r--accel-pptpd/radius/radius_p.h2
-rw-r--r--accel-pptpd/triton/triton.c43
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();
}