diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-07 20:55:02 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-07 20:55:02 +0300 |
| commit | c414f0a725a16cbd4c7063ff221dabb420b96df5 (patch) | |
| tree | 559eede0c019a22cbe33042b7ff2462042266002 /accel-pppd | |
| parent | 7e81fd4a4c5fb47f9ddfc6d99124ade83ca58940 (diff) | |
| parent | d84ba475fd0bd15faded9226866331fcadb34965 (diff) | |
| download | accel-ppp-c414f0a725a16cbd4c7063ff221dabb420b96df5.tar.gz accel-ppp-c414f0a725a16cbd4c7063ff221dabb420b96df5.zip | |
Merge pull request #359 from nuclearcat/ipcp-ccp-delay-ack
Ipcp ccp delay ack
Diffstat (limited to 'accel-pppd')
| -rw-r--r-- | accel-pppd/ppp/ppp_ccp.c | 12 | ||||
| -rw-r--r-- | accel-pppd/ppp/ppp_ipcp.c | 43 | ||||
| -rw-r--r-- | accel-pppd/ppp/ppp_ipcp.h | 3 | ||||
| -rw-r--r-- | accel-pppd/ppp/ppp_ipv6cp.c | 43 | ||||
| -rw-r--r-- | accel-pppd/ppp/ppp_ipv6cp.h | 3 |
5 files changed, 100 insertions, 4 deletions
diff --git a/accel-pppd/ppp/ppp_ccp.c b/accel-pppd/ppp/ppp_ccp.c index 2082ca3f..30ef97b9 100644 --- a/accel-pppd/ppp/ppp_ccp.c +++ b/accel-pppd/ppp/ppp_ccp.c @@ -13,6 +13,8 @@ #include "ppp.h" #include "ppp_ccp.h" +#include "ppp_ipcp.h" +#include "ppp_ipv6cp.h" #include "memdebug.h" @@ -202,6 +204,9 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm) return; } ppp_layer_started(ccp->ppp, &ccp->ld); + + ipcp_ccp_started(ccp->ppp); + ipv6cp_ccp_started(ccp->ppp); } } @@ -211,9 +216,12 @@ static void ccp_layer_finished(struct ppp_fsm_t *fsm) log_ppp_debug("ccp_layer_finished\n"); - if (!ccp->started) + if (!ccp->started) { ppp_layer_passive(ccp->ppp, &ccp->ld); - else if (!ccp->ppp->ses.terminating) + + ipcp_ccp_started(ccp->ppp); + ipv6cp_ccp_started(ccp->ppp); + } else if (!ccp->ppp->ses.terminating) ap_session_terminate(&ccp->ppp->ses, TERM_USER_ERROR, 0); fsm->fsm_state = FSM_Closed; diff --git a/accel-pppd/ppp/ppp_ipcp.c b/accel-pppd/ppp/ppp_ipcp.c index 2f75542a..1beccf8c 100644 --- a/accel-pppd/ppp/ppp_ipcp.c +++ b/accel-pppd/ppp/ppp_ipcp.c @@ -173,6 +173,9 @@ void ipcp_layer_free(struct ppp_layer_data_t *ld) if (ipcp->timeout.tpd) triton_timer_del(&ipcp->timeout); + if (ipcp->delay_ack_buf) + _free(ipcp->delay_ack_buf); + _free(ipcp); } @@ -292,7 +295,11 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf; if (ipcp->delay_ack) { - send_term_ack(fsm); + /* CCP is still negotiating, withhold the ack until it settles */ + if (ipcp->delay_ack_buf) + _free(ipcp->delay_ack_buf); + ipcp->delay_ack_buf = _malloc(ntohs(hdr->len) + 2); + memcpy(ipcp->delay_ack_buf, hdr, ntohs(hdr->len) + 2); return; } @@ -812,6 +819,40 @@ int ipcp_option_register(struct ipcp_option_handler_t *h) return 0; } +void ipcp_ccp_started(struct ppp_t *ppp) +{ + struct ppp_layer_data_t *ld = ppp_find_layer_data(ppp, &ipcp_layer); + struct ppp_ipcp_t *ipcp; + struct ipcp_hdr_t *hdr; + + if (!ld) + return; + + ipcp = container_of(ld, typeof(*ipcp), ld); + + if (!ipcp->delay_ack) + return; + + ipcp->delay_ack = 0; + + if (ipcp->fsm.fsm_state == FSM_Opened) + __ipcp_layer_up(ipcp); + + if (!ipcp->delay_ack_buf) + return; + + hdr = (struct ipcp_hdr_t *)ipcp->delay_ack_buf; + hdr->code = CONFACK; + + if (conf_ppp_verbose) + log_ppp_info2("send [IPCP ConfAck id=%x]\n", hdr->id); + + ppp_unit_send(ipcp->ppp, hdr, ntohs(hdr->len) + 2); + + _free(ipcp->delay_ack_buf); + ipcp->delay_ack_buf = NULL; +} + struct ipcp_option_t *ipcp_find_option(struct ppp_t *ppp, struct ipcp_option_handler_t *h) { struct ppp_ipcp_t *ipcp = container_of(ppp_find_layer_data(ppp, &ipcp_layer), typeof(*ipcp), ld); diff --git a/accel-pppd/ppp/ppp_ipcp.h b/accel-pppd/ppp/ppp_ipcp.h index 036f0a4d..8cd7790f 100644 --- a/accel-pppd/ppp/ppp_ipcp.h +++ b/accel-pppd/ppp/ppp_ipcp.h @@ -92,12 +92,15 @@ struct ppp_ipcp_t struct list_head ropt_list; // last received ConfReq int ropt_len; + void *delay_ack_buf; // ConfAck withheld until CCP finishes + int conf_req_len; unsigned int starting:1; unsigned int started:1; unsigned int delay_ack:1; }; +void ipcp_ccp_started(struct ppp_t *ppp); 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); diff --git a/accel-pppd/ppp/ppp_ipv6cp.c b/accel-pppd/ppp/ppp_ipv6cp.c index 370f1d55..3caa89a2 100644 --- a/accel-pppd/ppp/ppp_ipv6cp.c +++ b/accel-pppd/ppp/ppp_ipv6cp.c @@ -173,6 +173,9 @@ void ipv6cp_layer_free(struct ppp_layer_data_t *ld) if (ipv6cp->timeout.tpd) triton_timer_del(&ipv6cp->timeout); + if (ipv6cp->delay_ack_buf) + _free(ipv6cp->delay_ack_buf); + _free(ipv6cp); } @@ -296,7 +299,11 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) struct ipv6cp_hdr_t *hdr = (struct ipv6cp_hdr_t*)ipv6cp->ppp->buf; if (ipv6cp->delay_ack) { - send_term_ack(fsm); + /* CCP is still negotiating, withhold the ack until it settles */ + if (ipv6cp->delay_ack_buf) + _free(ipv6cp->delay_ack_buf); + ipv6cp->delay_ack_buf = _malloc(ntohs(hdr->len) + 2); + memcpy(ipv6cp->delay_ack_buf, hdr, ntohs(hdr->len) + 2); return; } @@ -821,6 +828,40 @@ int ipv6cp_option_register(struct ipv6cp_option_handler_t *h) return 0; } +void ipv6cp_ccp_started(struct ppp_t *ppp) +{ + struct ppp_layer_data_t *ld = ppp_find_layer_data(ppp, &ipv6cp_layer); + struct ppp_ipv6cp_t *ipv6cp; + struct ipv6cp_hdr_t *hdr; + + if (!ld) + return; + + ipv6cp = container_of(ld, typeof(*ipv6cp), ld); + + if (!ipv6cp->delay_ack) + return; + + ipv6cp->delay_ack = 0; + + if (ipv6cp->fsm.fsm_state == FSM_Opened) + __ipv6cp_layer_up(ipv6cp); + + if (!ipv6cp->delay_ack_buf) + return; + + hdr = (struct ipv6cp_hdr_t *)ipv6cp->delay_ack_buf; + hdr->code = CONFACK; + + if (conf_ppp_verbose) + log_ppp_info2("send [IPV6CP ConfAck id=%x]\n", hdr->id); + + ppp_unit_send(ipv6cp->ppp, hdr, ntohs(hdr->len) + 2); + + _free(ipv6cp->delay_ack_buf); + ipv6cp->delay_ack_buf = NULL; +} + struct ipv6cp_option_t *ipv6cp_find_option(struct ppp_t *ppp, struct ipv6cp_option_handler_t *h) { struct ppp_ipv6cp_t *ipv6cp = container_of(ppp_find_layer_data(ppp, &ipv6cp_layer), typeof(*ipv6cp), ld); diff --git a/accel-pppd/ppp/ppp_ipv6cp.h b/accel-pppd/ppp/ppp_ipv6cp.h index 6f1789ec..31bdccf6 100644 --- a/accel-pppd/ppp/ppp_ipv6cp.h +++ b/accel-pppd/ppp/ppp_ipv6cp.h @@ -98,12 +98,15 @@ struct ppp_ipv6cp_t struct list_head ropt_list; // last received ConfReq int ropt_len; + void *delay_ack_buf; // ConfAck withheld until CCP finishes + int conf_req_len; unsigned int starting:1; unsigned int started:1; unsigned int delay_ack:1; }; +void ipv6cp_ccp_started(struct ppp_t *ppp); int ipv6cp_option_register(struct ipv6cp_option_handler_t *h); #endif |
