diff options
author | Kozlov Dmitry <dima@server> | 2010-09-03 18:58:53 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-09-03 18:58:53 +0400 |
commit | e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e (patch) | |
tree | 17a99610798630e83fc1032c82ee51c404ce19fe /accel-pptpd/ppp/ppp_fsm.c | |
parent | a22573e91dac7971aa4c9b1d874d6751e8502d16 (diff) | |
download | accel-ppp-e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e.tar.gz accel-ppp-e8aa3a1457295f70f8ccc9cd7f2f9073f01a5e2e.zip |
project restructured
Diffstat (limited to 'accel-pptpd/ppp/ppp_fsm.c')
-rw-r--r-- | accel-pptpd/ppp/ppp_fsm.c | 534 |
1 files changed, 534 insertions, 0 deletions
diff --git a/accel-pptpd/ppp/ppp_fsm.c b/accel-pptpd/ppp/ppp_fsm.c new file mode 100644 index 00000000..85cf15a2 --- /dev/null +++ b/accel-pptpd/ppp/ppp_fsm.c @@ -0,0 +1,534 @@ +#include <arpa/inet.h> +#include <stdlib.h> + +#include "triton.h" + +#include "ppp.h" +#include "ppp_fsm.h" +#include "ppp_lcp.h" +#include "log.h" + +static int conf_max_terminate = 2; +static int conf_max_configure = 5; +static int conf_max_failure = 5; +static int conf_timeout = 3; + +void send_term_req(struct ppp_fsm_t *layer); +void send_term_ack(struct ppp_fsm_t *layer); +void send_echo_reply(struct ppp_fsm_t *layer); + +static void init_req_counter(struct ppp_fsm_t *layer,int timeout); +static void zero_req_counter(struct ppp_fsm_t *layer); +static void restart_timer_func(struct triton_timer_t *t); +static void stop_timer(struct ppp_fsm_t *fsm); + +void ppp_fsm_init(struct ppp_fsm_t *layer) +{ + layer->fsm_state = FSM_Initial; + layer->restart_timer.expire = restart_timer_func; + layer->restart_counter = 0; + + layer->max_terminate = conf_max_terminate; + layer->max_configure = conf_max_configure; + layer->max_failure = conf_max_failure; + layer->timeout = conf_timeout; +} +void ppp_fsm_free(struct ppp_fsm_t *layer) +{ + stop_timer(layer); +} + +void ppp_fsm_lower_up(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Initial: + layer->fsm_state=FSM_Closed; + break; + case FSM_Starting: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_lower_down(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + case FSM_Closing: + layer->fsm_state=FSM_Initial; + break; + case FSM_Stopped: + if (layer->layer_started) layer->layer_started(layer); + layer->fsm_state=FSM_Starting; + break; + case FSM_Stopping: + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + case FSM_Ack_Sent: + layer->fsm_state=FSM_Starting; + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + layer->fsm_state=FSM_Starting; + break; + default: + break; + } +} + +void ppp_fsm_open(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Initial: + if (layer->layer_started) layer->layer_started(layer); + layer->fsm_state=FSM_Starting; + break; + case FSM_Starting: + break; + case FSM_Closed: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Closing: + case FSM_Stopping: + case FSM_Stopped: + case FSM_Opened: + ppp_fsm_lower_down(layer); + ppp_fsm_lower_up(layer); + break; + default: + break; + } +} + +void ppp_fsm_close(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Starting: + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Initial; + break; + case FSM_Stopped: + layer->fsm_state=FSM_Closed; + break; + case FSM_Stopping: + layer->fsm_state=FSM_Closing; + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + 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->fsm_state=FSM_Closing; + break; + default: + break; + } +} + +void ppp_fsm_timeout0(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closing: + case FSM_Stopping: + send_term_req(layer); + break; + case FSM_Ack_Rcvd: + layer->fsm_state=FSM_Req_Sent; + case FSM_Req_Sent: + case FSM_Ack_Sent: + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + break; + default: + break; + } +} + +void ppp_fsm_timeout1(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closing: + stop_timer(layer); + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Closed; + break; + case FSM_Stopping: + stop_timer(layer); + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Stopped; + break; + case FSM_Ack_Rcvd: + case FSM_Req_Sent: + case FSM_Ack_Sent: + stop_timer(layer); + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Stopped; + break; + default: + break; + } +} + +void ppp_fsm_recv_conf_req_ack(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + send_term_ack(layer); + break; + case FSM_Stopped: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + case FSM_Req_Sent: + case FSM_Ack_Sent: + if (layer->send_conf_ack) layer->send_conf_ack(layer); + layer->fsm_state=FSM_Ack_Sent; + break; + case FSM_Ack_Rcvd: + if (layer->send_conf_ack) layer->send_conf_ack(layer); + stop_timer(layer); + if (layer->layer_up) layer->layer_up(layer); + layer->fsm_state=FSM_Opened; + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + if (layer->send_conf_ack) layer->send_conf_ack(layer); + layer->fsm_state=FSM_Ack_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_conf_req_nak(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + send_term_ack(layer); + break; + case FSM_Stopped: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + case FSM_Ack_Sent: + if (layer->send_conf_nak) layer->send_conf_nak(layer); + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + if (layer->send_conf_nak) layer->send_conf_nak(layer); + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + if (layer->send_conf_nak) layer->send_conf_nak(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + send_term_ack(layer); + break; + case FSM_Stopped: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + case FSM_Ack_Sent: + if (layer->send_conf_rej) layer->send_conf_rej(layer); + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + if (layer->send_conf_rej) layer->send_conf_rej(layer); + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + if (layer->send_conf_rej) layer->send_conf_rej(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + case FSM_Stopped: + send_term_ack(layer); + break; + case FSM_Req_Sent: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + layer->fsm_state=FSM_Ack_Rcvd; + break; + case FSM_Ack_Rcvd: + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Ack_Sent: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + //init_req_counter(layer,layer->max_configure); + //tlu + stop_timer(layer); + if (layer->layer_up) layer->layer_up(layer); + layer->fsm_state=FSM_Opened; + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + default: + break; + } +} + +void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closed: + case FSM_Stopped: + send_term_ack(layer); + break; + case FSM_Req_Sent: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_failure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + break; + case FSM_Ack_Rcvd: + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Ack_Sent: + //if (layer->init_req_cnt) layer->init_req_cnt(layer); + init_req_counter(layer,layer->max_configure); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + send_term_req(layer); + send_term_ack(layer); + //if (layer->zero_req_cnt) layer->zero_req_cnt(layer); + zero_req_counter(layer); + layer->fsm_state=FSM_Stopping; + break; + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + case FSM_Ack_Sent: + send_term_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + send_term_req(layer); + break; + } +} + +void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Closing: + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Closed; + break; + case FSM_Stopping: + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Stopped; + break; + case FSM_Ack_Rcvd: + layer->fsm_state=FSM_Req_Sent; + break; + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + --layer->restart_counter; + if (layer->send_conf_req) layer->send_conf_req(layer); + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_unk(struct ppp_fsm_t *layer) +{ + if (layer->send_conf_rej) layer->send_conf_rej(layer); +} + +void ppp_fsm_recv_code_rej_perm(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Ack_Rcvd: + layer->fsm_state=FSM_Req_Sent; + break; + default: + break; + } +} + +void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer) +{ + switch(layer->fsm_state) + { + case FSM_Opened: + if (layer->layer_down) layer->layer_down(layer); + send_term_req(layer); + layer->fsm_state=FSM_Stopping; + break; + case FSM_Closing: + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Closed; + break; + case FSM_Stopping: + case FSM_Req_Sent: + case FSM_Ack_Rcvd: + case FSM_Ack_Sent: + if (layer->layer_finished) layer->layer_finished(layer); + layer->fsm_state=FSM_Stopped; + break; + default: + break; + } +} + +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_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_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.period) { + fsm->restart_timer.period = 0; + triton_timer_del(&fsm->restart_timer); + } +} +static void init_req_counter(struct ppp_fsm_t *layer,int timeout) +{ + layer->restart_timer.expire_tv.tv_sec=0; + layer->restart_counter = timeout; + + if (!layer->restart_timer.period) { + layer->restart_timer.period = layer->timeout * 1000; + triton_timer_add(layer->ppp->ctrl->ctx, &layer->restart_timer, 0); + } +} +static void zero_req_counter(struct ppp_fsm_t *layer) +{ + layer->restart_timer.expire_tv.tv_sec=0; + layer->restart_counter=0; +} + +static void restart_timer_func(struct triton_timer_t *t) +{ + struct ppp_fsm_t *layer = container_of(t, typeof(*layer), restart_timer); + + if (layer->restart_counter>0) + ppp_fsm_timeout0(layer); + else + ppp_fsm_timeout1(layer); +} + +void __init fsm_init(void) +{ + char *opt; + + opt = conf_get_opt("lcp", "max-terminate"); + if (opt && atoi(opt) > 0) + conf_max_terminate = atoi(opt); + + opt = conf_get_opt("lcp", "max-configure"); + if (opt && atoi(opt) > 0) + conf_max_configure = atoi(opt); + + opt = conf_get_opt("lcp", "max-failure"); + if (opt && atoi(opt) > 0) + conf_max_failure = atoi(opt); + + opt = conf_get_opt("lcp", "timeout"); + if (opt && atoi(opt) > 0) + conf_timeout = atoi(opt); +} |