From bfc338f17ebbadf377d59c51895f46f02a926fc8 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Wed, 13 Feb 2013 18:27:45 +0100 Subject: l2tp: Flush ack-ed messages from retransmission queue When several messages are sent consecutively, the peer can reply with a single ZLB to acknowledge all messages. In this case, removing only the first message from the retransmission queue isn't enough (acknowledged messages left in the queue will be retransmitted). This case can happen when replying to an outgoing call request, wich is handled by sending two messages in a row (an OCRP and an OCCN). This patch avoids useless retransmissions by removing all messages acknowledged by peer from the retransmission queue. Signed-off-by: Guillaume Nault --- accel-pppd/ctrl/l2tp/l2tp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index d1f0f3c3..69e5d143 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -2463,8 +2463,14 @@ static int l2tp_conn_read(struct triton_md_handler_t *h) } else { if (!list_empty(&pack->attrs)) conn->Nr++; - if (!list_empty(&conn->send_queue)) { - p = list_entry(conn->send_queue.next, typeof(*pack), entry); + while (!list_empty(&conn->send_queue)) { + /* Flush retransmission queue up + to the last acknowledged message */ + p = list_entry(conn->send_queue.next, + typeof(*pack), entry); + if (nsnr_cmp(ntohs(p->hdr.Ns), + ntohs(pack->hdr.Nr)) >= 0) + break; list_del(&p->entry); l2tp_packet_free(p); conn->retransmit = 0; -- cgit v1.2.3