summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-03 17:45:41 +0400
committerKozlov Dmitry <dima@server>2010-09-03 17:45:41 +0400
commita22573e91dac7971aa4c9b1d874d6751e8502d16 (patch)
tree76431aab698d2a05c195eecd3edc2c34cdc820a9 /accel-pptpd
parent9d6cabeeff53b574d9d3a9ceede962f452366747 (diff)
downloadaccel-ppp-xebd-a22573e91dac7971aa4c9b1d874d6751e8502d16.tar.gz
accel-ppp-xebd-a22573e91dac7971aa4c9b1d874d6751e8502d16.zip
pptp: implemented echo request/reply
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/accel-pptpd.conf5
-rw-r--r--accel-pptpd/pptp.c101
-rw-r--r--accel-pptpd/pptp_prot.h170
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: -------------------------------------------- */