mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
PPP, PPPoL2TP: properly ack receipt of duplicate packets
Managed to find the spirit behind the RFC. Looks like we need to send a ZLB packet with counters as is to the packet (ZLB or not) we previously sent to ack the message. Luckily we don't need more than received NS/NR counters to forge the resent ack. Signed-off-by: Sylvain Rochet <gradator@gradator.net>
This commit is contained in:
parent
738a2fe846
commit
f31160a6cb
@ -85,7 +85,7 @@ static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp);
|
|||||||
static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns);
|
static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns);
|
||||||
static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns);
|
static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns);
|
||||||
static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns);
|
static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns);
|
||||||
static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns);
|
static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr);
|
||||||
static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns);
|
static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns);
|
||||||
static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
||||||
static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb);
|
||||||
@ -499,9 +499,17 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, str
|
|||||||
if (ns != l2tp->peer_ns) {
|
if (ns != l2tp->peer_ns) {
|
||||||
PPPDEBUG(LOG_DEBUG, ("pppol2tp: drop unexpected packet: received NS=%d, expected NS=%d\n", ns, l2tp->peer_ns));
|
PPPDEBUG(LOG_DEBUG, ("pppol2tp: drop unexpected packet: received NS=%d, expected NS=%d\n", ns, l2tp->peer_ns));
|
||||||
/*
|
/*
|
||||||
* The RFC says we must send a ZLB ack for duplicate packets but preventing an endless
|
* In order to ensure that all messages are acknowledged properly
|
||||||
* ZLB packets loop came out wayyyy more complicated than just dropping the packet.
|
* (particularly in the case of a lost ZLB ACK message), receipt
|
||||||
|
* of duplicate messages MUST be acknowledged.
|
||||||
|
*
|
||||||
|
* In this very special case we Ack a packet we previously received.
|
||||||
|
* Therefore our NS is the NR we just received. And our NR is the
|
||||||
|
* NS we just received plus one.
|
||||||
*/
|
*/
|
||||||
|
if ((s16_t)(ns - l2tp->peer_ns) < 0) {
|
||||||
|
pppol2tp_send_zlb(l2tp, nr, ns+1);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +571,7 @@ static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, str
|
|||||||
break;
|
break;
|
||||||
/* Stop Control Connection Notification */
|
/* Stop Control Connection Notification */
|
||||||
case PPPOL2TP_MESSAGETYPE_STOPCCN:
|
case PPPOL2TP_MESSAGETYPE_STOPCCN:
|
||||||
pppol2tp_send_zlb(l2tp, l2tp->our_ns+1); /* Ack the StopCCN before we switch to down state */
|
pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns); /* Ack the StopCCN before we switch to down state */
|
||||||
if (l2tp->phase < PPPOL2TP_STATE_DATA) {
|
if (l2tp->phase < PPPOL2TP_STATE_DATA) {
|
||||||
pppol2tp_abort_connect(l2tp);
|
pppol2tp_abort_connect(l2tp);
|
||||||
} else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
|
} else if (l2tp->phase == PPPOL2TP_STATE_DATA) {
|
||||||
@ -714,7 +722,7 @@ nextavp:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
send_zlb:
|
send_zlb:
|
||||||
pppol2tp_send_zlb(l2tp, l2tp->our_ns+1);
|
pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns);
|
||||||
return;
|
return;
|
||||||
packet_too_short:
|
packet_too_short:
|
||||||
PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
|
PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len));
|
||||||
@ -1042,7 +1050,7 @@ static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send a ZLB ACK packet */
|
/* Send a ZLB ACK packet */
|
||||||
static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) {
|
static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr) {
|
||||||
struct pbuf *pb;
|
struct pbuf *pb;
|
||||||
u8_t *p;
|
u8_t *p;
|
||||||
u16_t len;
|
u16_t len;
|
||||||
@ -1065,7 +1073,7 @@ static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) {
|
|||||||
PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */
|
||||||
PUTSHORT(0, p); /* Session Id */
|
PUTSHORT(0, p); /* Session Id */
|
||||||
PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
PUTSHORT(ns, p); /* NS Sequence number - to peer */
|
||||||
PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */
|
PUTSHORT(nr, p); /* NR Sequence number - expected for peer */
|
||||||
|
|
||||||
return pppol2tp_udp_send(l2tp, pb);
|
return pppol2tp_udp_send(l2tp, pb);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user