l2tplac: Delay considering the tunnel to LNS open until SCCCN ack

We are not really supposed to send ICRQ until we got our SCCCN acked, so better
wait for it.
This commit is contained in:
Samuel Thibault 2025-03-09 17:48:28 +01:00
parent 6f04a5c390
commit b48dfb2697
2 changed files with 18 additions and 5 deletions

View file

@ -3483,14 +3483,15 @@ static void controlnull(tunnelidt t)
}
// add a control message to a tunnel, and send if within window
static void controladd(controlt *c, sessionidt far, tunnelidt t)
static uint16_t controladd(controlt *c, sessionidt far, tunnelidt t)
{
uint16_t *pint16 = (uint16_t *) (c->buf + 2);
uint16_t ns;
pint16[0] = htons(c->length); // length
pint16[1] = htons(tunnel[t].far); // tunnel
pint16[2] = htons(far); // session
pint16[3] = htons(tunnel[t].ns); // sequence
tunnel[t].ns++; // advance sequence
ns = tunnel[t].ns++; // advance sequence
pint16[3] = htons(ns); // sequence
// link in message in to queue
if (tunnel[t].controlc)
tunnel[t].controle->next = c;
@ -3506,6 +3507,7 @@ static void controladd(controlt *c, sessionidt far, tunnelidt t)
tunnel[t].try = 0; // first send
tunnelsend(c->buf, c->length, t);
}
return ns;
}
//
@ -3904,6 +3906,7 @@ static void tunnelclear(tunnelidt t)
tunn_local[t].l2tp_fd = -1;
tunnel[t].state = TUNNELFREE;
tunn_local[t].scccn = -1;
}
static void bundleclear(bundleidt b)
@ -4279,6 +4282,15 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
if (!tunnel[t].controlc)
tunnel[t].retry = 0; // caught up
}
{
// Handle ack (possibly just a ZLB)
if (tunn_local[t].scccn >= 0 && ((uint16_t) tunn_local[t].scccn) - nr >= 0x8000u)
{
LOG(3, s, t, "REMOTE LNS acked our SCCCN %d\n", tunn_local[t].scccn);
tunn_local[t].scccn = -1;
tunnel[t].state = TUNNELOPEN;
}
}
if (l)
{ // if not a null message
int result = 0;
@ -4750,7 +4762,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
}
break;
case 2: // SCCRP
tunnel[t].state = TUNNELOPEN;
tunnel[t].lastrec = time_now;
LOG(3, s, t, "Received SCCRP\n");
if (main_quit != QUIT_SHUTDOWN)
@ -4772,7 +4783,8 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexu
control32(c, 3, 3, 1); // framing Capabilities
if (sendchalresponse) controlb(c, 13, sendchalresponse, 16, 1); // Challenge response
control16(c, 9, t, 1); // assigned tunnel
controladd(c, 0, t); // send
tunn_local[t].scccn = controladd(c, 0, t); // send
LOG(3, s, t, "sent SCCCN as %d\n", tunn_local[t].scccn);
}
else
{

View file

@ -517,6 +517,7 @@ tunnelt;
typedef struct
{
int32_t scccn; // seq number of last sccn waiting for an ack (-1 if none)
controlt *controlr; // queue of OoO-received messages
int l2tp_fd; // kernel acceleration UDP socket
}