diff options
-rw-r--r-- | accel-pptpd/accel-pptpd.conf | 5 | ||||
-rw-r--r-- | accel-pptpd/pptp.c | 101 | ||||
-rw-r--r-- | accel-pptpd/pptp_prot.h | 170 |
3 files changed, 179 insertions, 97 deletions
diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index a0c5fdb..736f71a 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -8,5 +8,8 @@ libmschap-v2.so log-error=/dev/stderr [lcp] -echo-interval=3 +echo-interval=10 echo-failure=3 + +[pptp] +echo-interval=3 diff --git a/accel-pptpd/pptp.c b/accel-pptpd/pptp.c index 3104e60..2d69a6e 100644 --- a/accel-pptpd/pptp.c +++ b/accel-pptpd/pptp.c @@ -20,8 +20,6 @@ #include "ppp.h" -#define TIMEOUT 10000 - #define STATE_IDLE 0 #define STATE_ESTB 1 #define STATE_PPP 2 @@ -35,6 +33,7 @@ struct pptp_conn_t struct triton_timer_t timeout_timer; struct triton_timer_t echo_timer; int state; + int echo_sent; uint8_t *in_buf; int in_size; @@ -46,9 +45,12 @@ struct pptp_conn_t struct ppp_t ppp; }; +static int conf_timeout = 3; +static int conf_echo_interval = 0; + static int pptp_read(struct triton_md_handler_t *h); static int pptp_write(struct triton_md_handler_t *h); -static void pptp_timeout(struct triton_md_handler_t *h); +static void pptp_timeout(struct triton_timer_t *); static void ppp_started(struct ppp_t *); static void ppp_finished(struct ppp_t *); @@ -57,6 +59,16 @@ static void disconnect(struct pptp_conn_t *conn) triton_md_unregister_handler(&conn->hnd); close(conn->hnd.fd); + if (conn->timeout_timer.period) { + triton_timer_del(&conn->timeout_timer); + conn->timeout_timer.period = 0; + } + + if (conn->echo_timer.period) { + triton_timer_del(&conn->echo_timer); + conn->echo_timer.period = 0; + } + if (conn->state == STATE_PPP) { conn->state = STATE_CLOSE; ppp_terminate(&conn->ppp, 1); @@ -127,8 +139,6 @@ static int pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn) ppp_terminate(&conn->ppp, 0); } - //conn->hnd.twait=1000; - send_pptp_stop_ctrl_conn_rply(conn, PPTP_CONN_STOP_OK, 0); return -1; } @@ -180,6 +190,8 @@ static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn) if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_SUCCESS, 0)) return -1; + triton_timer_mod(&conn->timeout_timer, 0); + conn->state = STATE_ESTB; return 0; @@ -212,7 +224,7 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) int pptp_sock; if (conn->state != STATE_ESTB) { - log_info("unexpected PPTP_OUT_CALL_RQST\n"); + log_error("unexpected PPTP_OUT_CALL_RQST\n"); if (send_pptp_out_call_rply(conn, msg, 0, PPTP_CALL_RES_GE, PPTP_GE_NOCONN)) return -1; return 0; @@ -263,15 +275,63 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) if (establish_ppp(&conn->ppp)) { close(pptp_sock); //if (send_pptp_stop_ctrl_conn_rqst(conn, 0, 0)) - // return -1; conn->state = STATE_FIN; - //conn->hnd.twait=1000; return -1; - } else - conn->state = STATE_PPP; + } + conn->state = STATE_PPP; + + triton_timer_del(&conn->timeout_timer); + conn->timeout_timer.period = 0; + + if (conf_echo_interval) { + conn->echo_timer.period = conf_echo_interval * 1000; + triton_timer_add(&conn->ctx, &conn->echo_timer, 0); + } + + return 0; +} + +static int pptp_echo_rqst(struct pptp_conn_t *conn) +{ + struct pptp_echo_rqst *in_msg = (struct pptp_echo_rqst *)conn->in_buf; + struct pptp_echo_rply out_msg = { + .header = PPTP_HEADER_CTRL(PPTP_ECHO_RQST), + .identifier = in_msg->identifier, + .result_code = 1, + }; + + return post_msg(conn, &out_msg, sizeof(out_msg)); +} +static int pptp_echo_rply(struct pptp_conn_t *conn) +{ + struct pptp_echo_rply *msg = (struct pptp_echo_rply *)conn->in_buf; + if (msg->identifier != conn->echo_sent) { + log_error("pptp:echo: identifier mismatch\n"); + return -1; + } + conn->echo_sent = 0; return 0; } +static void pptp_send_echo(struct triton_timer_t *t) +{ + struct pptp_conn_t *conn = container_of(t, typeof(*conn), echo_timer); + struct pptp_echo_rqst msg = { + .header = PPTP_HEADER_CTRL(PPTP_ECHO_RQST), + }; + + if (conn->echo_sent) { + log_warn("pptp: no echo reply\n"); + disconnect(conn); + return; + } + + conn->echo_sent = random(); + msg.identifier = conn->echo_sent; + + if (post_msg(conn, &msg, sizeof(msg))) + disconnect(conn); +} static int process_packet(struct pptp_conn_t *conn) { @@ -284,6 +344,10 @@ static int process_packet(struct pptp_conn_t *conn) return pptp_stop_ctrl_conn_rqst(conn); case PPTP_OUT_CALL_RQST: return pptp_out_call_rqst(conn); + case PPTP_ECHO_RQST: + return pptp_echo_rqst(conn); + case PPTP_ECHO_RPLY: + return pptp_echo_rply(conn); } return 0; } @@ -357,8 +421,10 @@ static int pptp_write(struct triton_md_handler_t *h) } } } -static void pptp_timeout(struct triton_md_handler_t *h) +static void pptp_timeout(struct triton_timer_t *t) { + struct pptp_conn_t *conn = container_of(t, typeof(*conn), timeout_timer); + disconnect(conn); } static void pptp_close(struct triton_ctx_t *ctx) { @@ -426,10 +492,14 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ctx.close = pptp_close; conn->in_buf = malloc(PPTP_CTRL_SIZE_MAX); conn->out_buf = malloc(PPTP_CTRL_SIZE_MAX); + conn->timeout_timer.expire = pptp_timeout; + conn->timeout_timer.period = conf_timeout * 1000; + conn->echo_timer.expire = pptp_send_echo; triton_register_ctx(&conn->ctx); triton_md_register_handler(&conn->ctx, &conn->hnd); triton_md_enable_handler(&conn->hnd,MD_MODE_READ); + triton_timer_add(&conn->ctx, &conn->timeout_timer, 0); } return 0; } @@ -449,6 +519,7 @@ static struct pptp_serv_t serv= static void __init pptp_init(void) { struct sockaddr_in addr; + char *opt; serv.hnd.fd = socket (PF_INET, SOCK_STREAM, 0); if (serv.hnd.fd < 0) { @@ -480,5 +551,13 @@ static void __init pptp_init(void) triton_register_ctx(&serv.ctx); triton_md_register_handler(&serv.ctx, &serv.hnd); triton_md_enable_handler(&serv.hnd, MD_MODE_READ); + + opt = conf_get_opt("pptp", "timeout"); + if (opt && atoi(opt) > 0) + conf_timeout = atoi(opt); + + opt = conf_get_opt("pptp", "echo-interval"); + if (opt && atoi(opt) > 0) + conf_echo_interval = atoi(opt); } diff --git a/accel-pptpd/pptp_prot.h b/accel-pptpd/pptp_prot.h index cee250b..7e3ebdd 100644 --- a/accel-pptpd/pptp_prot.h +++ b/accel-pptpd/pptp_prot.h @@ -93,159 +93,159 @@ struct pptp_header { - u_int16_t length; /* message length in octets, including header */ - u_int16_t pptp_type; /* PPTP message type. 1 for control message. */ - u_int32_t magic; /* this should be PPTP_MAGIC. */ - u_int16_t ctrl_type; /* Control message type (0-15) */ - u_int16_t reserved0; /* reserved. MUST BE ZERO. */ + uint16_t length; /* message length in octets, including header */ + uint16_t pptp_type; /* PPTP message type. 1 for control message. */ + uint32_t magic; /* this should be PPTP_MAGIC. */ + uint16_t ctrl_type; /* Control message type (0-15) */ + uint16_t reserved0; /* reserved. MUST BE ZERO. */ }__attribute__((packed)); struct pptp_start_ctrl_conn /* for control message types 1 and 2 */ { struct pptp_header header; - u_int16_t version; /* PPTP protocol version. = PPTP_VERSION */ - u_int8_t result_code; /* these two fields should be zero on rqst msg*/ - u_int8_t error_code; /* 0 unless result_code==2 (General Error) */ - u_int32_t framing_cap; /* Framing capabilities */ - u_int32_t bearer_cap; /* Bearer Capabilities */ - u_int16_t max_channels; /* Maximum Channels (=0 for PNS, PAC ignores) */ - u_int16_t firmware_rev; /* Firmware or Software Revision */ - u_int8_t hostname[64]; /* Host Name (64 octets, zero terminated) */ - u_int8_t vendor[64]; /* Vendor string (64 octets, zero term.) */ + uint16_t version; /* PPTP protocol version. = PPTP_VERSION */ + uint8_t result_code; /* these two fields should be zero on rqst msg*/ + uint8_t error_code; /* 0 unless result_code==2 (General Error) */ + uint32_t framing_cap; /* Framing capabilities */ + uint32_t bearer_cap; /* Bearer Capabilities */ + uint16_t max_channels; /* Maximum Channels (=0 for PNS, PAC ignores) */ + uint16_t firmware_rev; /* Firmware or Software Revision */ + uint8_t hostname[64]; /* Host Name (64 octets, zero terminated) */ + uint8_t vendor[64]; /* Vendor string (64 octets, zero term.) */ }__attribute__((packed)); struct pptp_stop_ctrl_conn /* for control message types 3 and 4 */ { struct pptp_header header; - u_int8_t reason_result; /* reason for rqst, result for rply */ - u_int8_t error_code; /* MUST be 0, unless rply result==2 (general err)*/ - u_int16_t reserved1; /* MUST be 0 */ + uint8_t reason_result; /* reason for rqst, result for rply */ + uint8_t error_code; /* MUST be 0, unless rply result==2 (general err)*/ + uint16_t reserved1; /* MUST be 0 */ }__attribute__((packed)); struct pptp_echo_rqst /* for control message type 5 */ { struct pptp_header header; - u_int32_t identifier; /* arbitrary value set by sender which is used */ + uint32_t identifier; /* arbitrary value set by sender which is used */ /* to match up reply and request */ }__attribute__((packed)); struct pptp_echo_rply /* for control message type 6 */ { struct pptp_header header; - u_int32_t identifier; /* should correspond to id of rqst */ - u_int8_t result_code; - u_int8_t error_code; /* =0, unless result_code==2 (general error) */ - u_int16_t reserved1; /* MUST BE ZERO */ + uint32_t identifier; /* should correspond to id of rqst */ + uint8_t result_code; + uint8_t error_code; /* =0, unless result_code==2 (general error) */ + uint16_t reserved1; /* MUST BE ZERO */ }__attribute__((packed)); struct pptp_out_call_rqst /* for control message type 7 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (unique id used to multiplex data) */ - u_int16_t call_sernum; /* Call Serial Number (used for logging) */ - u_int32_t bps_min; /* Minimum BPS (lowest acceptable line speed) */ - u_int32_t bps_max; /* Maximum BPS (highest acceptable line speed) */ - u_int32_t bearer; /* Bearer type */ - u_int32_t framing; /* Framing type */ - u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - u_int16_t phone_len; /* Phone Number Length (num. of valid digits) */ - u_int16_t reserved1; /* MUST BE ZERO */ - u_int8_t phone_num[64]; /* Phone Number (64 octets, null term.) */ - u_int8_t subaddress[64]; /* Subaddress (64 octets, null term.) */ + uint16_t call_id; /* Call ID (unique id used to multiplex data) */ + uint16_t call_sernum; /* Call Serial Number (used for logging) */ + uint32_t bps_min; /* Minimum BPS (lowest acceptable line speed) */ + uint32_t bps_max; /* Maximum BPS (highest acceptable line speed) */ + uint32_t bearer; /* Bearer type */ + uint32_t framing; /* Framing type */ + uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ + uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ + uint16_t phone_len; /* Phone Number Length (num. of valid digits) */ + uint16_t reserved1; /* MUST BE ZERO */ + uint8_t phone_num[64]; /* Phone Number (64 octets, null term.) */ + uint8_t subaddress[64]; /* Subaddress (64 octets, null term.) */ }__attribute__((packed)); struct pptp_out_call_rply /* for control message type 8 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - u_int8_t result_code; /* Result Code (1 is no errors) */ - u_int8_t error_code; /* Error Code (=0 unless result_code==2) */ - u_int16_t cause_code; /* Cause Code (addt'l failure information) */ - u_int32_t speed; /* Connect Speed (in BPS) */ - u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - u_int32_t channel; /* Physical Channel ID (for logging) */ + uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ + uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ + uint8_t result_code; /* Result Code (1 is no errors) */ + uint8_t error_code; /* Error Code (=0 unless result_code==2) */ + uint16_t cause_code; /* Cause Code (addt'l failure information) */ + uint32_t speed; /* Connect Speed (in BPS) */ + uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ + uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ + uint32_t channel; /* Physical Channel ID (for logging) */ }__attribute__((packed)); struct pptp_in_call_rqst /* for control message type 9 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (unique id used to multiplex data) */ - u_int16_t call_sernum; /* Call Serial Number (used for logging) */ - u_int32_t bearer; /* Bearer type */ - u_int32_t channel; /* Physical Channel ID (for logging) */ - u_int16_t dialed_len; /* Dialed Number Length (# of valid digits) */ - u_int16_t dialing_len; /* Dialing Number Length (# of valid digits) */ - u_int8_t dialed_num[64]; /* Dialed Number (64 octets, zero term.) */ - u_int8_t dialing_num[64]; /* Dialing Number (64 octets, zero term.) */ - u_int8_t subaddress[64]; /* Subaddress (64 octets, zero term.) */ + uint16_t call_id; /* Call ID (unique id used to multiplex data) */ + uint16_t call_sernum; /* Call Serial Number (used for logging) */ + uint32_t bearer; /* Bearer type */ + uint32_t channel; /* Physical Channel ID (for logging) */ + uint16_t dialed_len; /* Dialed Number Length (# of valid digits) */ + uint16_t dialing_len; /* Dialing Number Length (# of valid digits) */ + uint8_t dialed_num[64]; /* Dialed Number (64 octets, zero term.) */ + uint8_t dialing_num[64]; /* Dialing Number (64 octets, zero term.) */ + uint8_t subaddress[64]; /* Subaddress (64 octets, zero term.) */ }__attribute__((packed)); struct pptp_in_call_rply /* for control message type 10 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - u_int8_t result_code; /* Result Code (1 is no errors) */ - u_int8_t error_code; /* Error Code (=0 unless result_code==2) */ - u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - u_int16_t reserved1; /* MUST BE ZERO */ + uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ + uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ + uint8_t result_code; /* Result Code (1 is no errors) */ + uint8_t error_code; /* Error Code (=0 unless result_code==2) */ + uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ + uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ + uint16_t reserved1; /* MUST BE ZERO */ }__attribute__((packed)); struct pptp_in_call_connect /* for control message type 11 */ { struct pptp_header header; - u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - u_int16_t reserved1; /* MUST BE ZERO */ - u_int32_t speed; /* Connect Speed (in BPS) */ - u_int16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ - u_int16_t delay; /* Packet Processing Delay (in 1/10 sec) */ - u_int32_t framing; /* Framing type */ + uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ + uint16_t reserved1; /* MUST BE ZERO */ + uint32_t speed; /* Connect Speed (in BPS) */ + uint16_t recv_size; /* Recv. Window Size (no. of buffered packets) */ + uint16_t delay; /* Packet Processing Delay (in 1/10 sec) */ + uint32_t framing; /* Framing type */ }__attribute__((packed)); struct pptp_call_clear_rqst /* for control message type 12 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - u_int16_t reserved1; /* MUST BE ZERO */ + uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ + uint16_t reserved1; /* MUST BE ZERO */ }__attribute__((packed)); struct pptp_call_clear_ntfy /* for control message type 13 */ { struct pptp_header header; - u_int16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ - u_int8_t result_code; /* Result Code */ - u_int8_t error_code; /* Error Code (=0 unless result_code==2) */ - u_int16_t cause_code; /* Cause Code (for ISDN, is Q.931 cause code) */ - u_int16_t reserved1; /* MUST BE ZERO */ - u_int8_t call_stats[128]; /* Call Statistics: 128 octets, ascii, 0-term */ + uint16_t call_id; /* Call ID (used to multiplex data over tunnel)*/ + uint8_t result_code; /* Result Code */ + uint8_t error_code; /* Error Code (=0 unless result_code==2) */ + uint16_t cause_code; /* Cause Code (for ISDN, is Q.931 cause code) */ + uint16_t reserved1; /* MUST BE ZERO */ + uint8_t call_stats[128]; /* Call Statistics: 128 octets, ascii, 0-term */ }__attribute__((packed)); struct pptp_wan_err_ntfy /* for control message type 14 */ { struct pptp_header header; - u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ - u_int16_t reserved1; /* MUST BE ZERO */ - u_int32_t crc_errors; /* CRC errors */ - u_int32_t frame_errors; /* Framing errors */ - u_int32_t hard_errors; /* Hardware overruns */ - u_int32_t buff_errors; /* Buffer overruns */ - u_int32_t time_errors; /* Time-out errors */ - u_int32_t align_errors; /* Alignment errors */ + uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst)*/ + uint16_t reserved1; /* MUST BE ZERO */ + uint32_t crc_errors; /* CRC errors */ + uint32_t frame_errors; /* Framing errors */ + uint32_t hard_errors; /* Hardware overruns */ + uint32_t buff_errors; /* Buffer overruns */ + uint32_t time_errors; /* Time-out errors */ + uint32_t align_errors; /* Alignment errors */ }__attribute__((packed)); struct pptp_set_link_info /* for control message type 15 */ { struct pptp_header header; - u_int16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst) */ - u_int16_t reserved1; /* MUST BE ZERO */ - u_int32_t send_accm; /* Send ACCM (for PPP packets; default 0xFFFFFFFF)*/ - u_int32_t recv_accm; /* Receive ACCM (for PPP pack.;default 0xFFFFFFFF)*/ + uint16_t call_id_peer; /* Peer's Call ID (call_id of pptp_out_call_rqst) */ + uint16_t reserved1; /* MUST BE ZERO */ + uint32_t send_accm; /* Send ACCM (for PPP packets; default 0xFFFFFFFF)*/ + uint32_t recv_accm; /* Receive ACCM (for PPP pack.;default 0xFFFFFFFF)*/ }__attribute__((packed)); /* helpful #defines: -------------------------------------------- */ |