提交 23a958de 编写于 作者: K Kozlov Dmitry

ppp: better handling for lost last acknowledge packet

上级 d2cb3998
...@@ -133,7 +133,7 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o ...@@ -133,7 +133,7 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o
if (ipaddr_opt->ip->peer_addr == opt32->val) { if (ipaddr_opt->ip->peer_addr == opt32->val) {
ipcp->ppp->ipaddr = ipaddr_opt->ip->addr; ipcp->ppp->ipaddr = ipaddr_opt->ip->addr;
ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr; ipcp->ppp->peer_ipaddr = ipaddr_opt->ip->peer_addr;
ipcp->delay_ack = 1; ipcp->delay_ack = !ipcp->started;
return IPCP_OPT_ACK; return IPCP_OPT_ACK;
} }
...@@ -191,8 +191,6 @@ static void if_up(struct ppp_t *ppp) ...@@ -191,8 +191,6 @@ static void if_up(struct ppp_t *ppp)
if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np))
log_ppp_error("ipcp: failed to set NP mode: %s\n", strerror(errno)); log_ppp_error("ipcp: failed to set NP mode: %s\n", strerror(errno));
ipcp_send_ack(ppp);
} }
static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr) static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr)
......
...@@ -609,7 +609,7 @@ static void ccp_recv(struct ppp_handler_t*h) ...@@ -609,7 +609,7 @@ static void ccp_recv(struct ppp_handler_t*h)
struct ppp_ccp_t *ccp = container_of(h, typeof(*ccp), hnd); struct ppp_ccp_t *ccp = container_of(h, typeof(*ccp), hnd);
int r; int r;
if (ccp->fsm.fsm_state == FSM_Initial || ccp->fsm.fsm_state == FSM_Closed || ccp->fsm.fsm_state == FSM_Opened || ccp->ppp->terminating) { if (ccp->fsm.fsm_state == FSM_Initial || ccp->fsm.fsm_state == FSM_Closed || ccp->ppp->terminating) {
if (conf_ppp_verbose) if (conf_ppp_verbose)
log_ppp_warn("CCP: discarding packet\n"); log_ppp_warn("CCP: discarding packet\n");
if (ccp->fsm.fsm_state == FSM_Closed || !conf_ccp) if (ccp->fsm.fsm_state == FSM_Closed || !conf_ccp)
...@@ -636,16 +636,23 @@ static void ccp_recv(struct ppp_handler_t*h) ...@@ -636,16 +636,23 @@ static void ccp_recv(struct ppp_handler_t*h)
switch(hdr->code) { switch(hdr->code) {
case CONFREQ: case CONFREQ:
r = ccp_recv_conf_req(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN); r = ccp_recv_conf_req(ccp, (uint8_t*)(hdr + 1), ntohs(hdr->len) - PPP_HDRLEN);
switch(r) { if (ccp->started) {
case CCP_OPT_ACK: if (r == CCP_OPT_ACK)
ppp_fsm_recv_conf_req_ack(&ccp->fsm); send_conf_ack(&ccp->fsm);
break; else
case CCP_OPT_NAK: r = CCP_OPT_FAIL;
ppp_fsm_recv_conf_req_nak(&ccp->fsm); } else {
break; switch(r) {
case CCP_OPT_REJ: case CCP_OPT_ACK:
ppp_fsm_recv_conf_req_rej(&ccp->fsm); ppp_fsm_recv_conf_req_ack(&ccp->fsm);
break; break;
case CCP_OPT_NAK:
ppp_fsm_recv_conf_req_nak(&ccp->fsm);
break;
case CCP_OPT_REJ:
ppp_fsm_recv_conf_req_rej(&ccp->fsm);
break;
}
} }
ccp_free_conf_req(ccp); ccp_free_conf_req(ccp);
......
...@@ -61,9 +61,6 @@ static void ipcp_options_free(struct ppp_ipcp_t *ipcp) ...@@ -61,9 +61,6 @@ static void ipcp_options_free(struct ppp_ipcp_t *ipcp)
list_del(&lopt->entry); list_del(&lopt->entry);
lopt->h->free(ipcp, lopt); lopt->h->free(ipcp, lopt);
} }
if (ipcp->buf)
_free(ipcp->buf);
} }
static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp) static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp)
...@@ -226,10 +223,7 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) ...@@ -226,10 +223,7 @@ static void send_conf_ack(struct ppp_fsm_t *fsm)
struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf; struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf;
if (ipcp->delay_ack) { if (ipcp->delay_ack) {
if (!ipcp->buf) { send_term_ack(fsm);
ipcp->buf = _malloc(ntohs(hdr->len) + 2);
memcpy(ipcp->buf, ipcp->ppp->buf, ntohs(hdr->len) + 2);
}
return; return;
} }
...@@ -241,19 +235,6 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) ...@@ -241,19 +235,6 @@ static void send_conf_ack(struct ppp_fsm_t *fsm)
ppp_unit_send(ipcp->ppp, hdr, ntohs(hdr->len) + 2); ppp_unit_send(ipcp->ppp, hdr, ntohs(hdr->len) + 2);
} }
void ipcp_send_ack(struct ppp_t *ppp)
{
struct ppp_ipcp_t *ipcp = container_of(ppp_find_layer_data(ppp, &ipcp_layer), typeof(*ipcp), ld);
struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->buf;
hdr->code = CONFACK;
if (conf_ppp_verbose)
log_ppp_info2("send [IPCP ConfAck id=%x]\n", ipcp->fsm.recv_id);
ppp_unit_send(ipcp->ppp, hdr, ntohs(hdr->len) + 2);
}
static void send_conf_nak(struct ppp_fsm_t *fsm) static void send_conf_nak(struct ppp_fsm_t *fsm)
{ {
struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm); struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm);
...@@ -583,7 +564,7 @@ static void ipcp_recv(struct ppp_handler_t*h) ...@@ -583,7 +564,7 @@ static void ipcp_recv(struct ppp_handler_t*h)
struct ppp_ipcp_t *ipcp = container_of(h, typeof(*ipcp), hnd); struct ppp_ipcp_t *ipcp = container_of(h, typeof(*ipcp), hnd);
int r; int r;
if (ipcp->fsm.fsm_state == FSM_Initial || ipcp->fsm.fsm_state == FSM_Closed || ipcp->fsm.fsm_state == FSM_Opened || ipcp->ppp->terminating) { if (ipcp->fsm.fsm_state == FSM_Initial || ipcp->fsm.fsm_state == FSM_Closed || ipcp->ppp->terminating) {
if (conf_ppp_verbose) if (conf_ppp_verbose)
log_ppp_warn("IPCP: discarding packet\n"); log_ppp_warn("IPCP: discarding packet\n");
return; return;
...@@ -612,16 +593,23 @@ static void ipcp_recv(struct ppp_handler_t*h) ...@@ -612,16 +593,23 @@ static void ipcp_recv(struct ppp_handler_t*h)
ipcp_free_conf_req(ipcp); ipcp_free_conf_req(ipcp);
return; return;
} }
switch(r) { if (ipcp->started) {
case IPCP_OPT_ACK: if (r == IPCP_OPT_ACK)
ppp_fsm_recv_conf_req_ack(&ipcp->fsm); send_conf_ack(&ipcp->fsm);
break; else
case IPCP_OPT_NAK: r = IPCP_OPT_FAIL;
ppp_fsm_recv_conf_req_nak(&ipcp->fsm); } else {
break; switch(r) {
case IPCP_OPT_REJ: case IPCP_OPT_ACK:
ppp_fsm_recv_conf_req_rej(&ipcp->fsm); ppp_fsm_recv_conf_req_ack(&ipcp->fsm);
break; break;
case IPCP_OPT_NAK:
ppp_fsm_recv_conf_req_nak(&ipcp->fsm);
break;
case IPCP_OPT_REJ:
ppp_fsm_recv_conf_req_rej(&ipcp->fsm);
break;
}
} }
ipcp_free_conf_req(ipcp); ipcp_free_conf_req(ipcp);
if (r == IPCP_OPT_FAIL) if (r == IPCP_OPT_FAIL)
......
...@@ -82,7 +82,6 @@ struct ppp_ipcp_t ...@@ -82,7 +82,6 @@ struct ppp_ipcp_t
struct ppp_fsm_t fsm; struct ppp_fsm_t fsm;
struct ppp_t *ppp; struct ppp_t *ppp;
struct list_head options; struct list_head options;
void *buf;
struct list_head ropt_list; // last received ConfReq struct list_head ropt_list; // last received ConfReq
int ropt_len; int ropt_len;
...@@ -94,7 +93,6 @@ struct ppp_ipcp_t ...@@ -94,7 +93,6 @@ struct ppp_ipcp_t
int ipcp_option_register(struct ipcp_option_handler_t *h); int ipcp_option_register(struct ipcp_option_handler_t *h);
struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h); struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h);
void ipcp_send_ack(struct ppp_t *);
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册