ipcp: try to re-send CHAP ack on timeout
If it was lost, some clients (e.g. pppd) may not try to re-send their CHAP reply.
This commit is contained in:
parent
b3b052a483
commit
366faaea76
3 changed files with 24 additions and 10 deletions
7
l2tpns.c
7
l2tpns.c
|
|
@ -5488,6 +5488,11 @@ static void regular_cleanups(double period)
|
||||||
if (sess_local[s].ipcp.conf_sent < config->ppp_max_configure)
|
if (sess_local[s].ipcp.conf_sent < config->ppp_max_configure)
|
||||||
{
|
{
|
||||||
LOG(3, s, session[s].tunnel, "No ACK for IPCP ConfigReq... resending\n");
|
LOG(3, s, session[s].tunnel, "No ACK for IPCP ConfigReq... resending\n");
|
||||||
|
if (sess_local[s].lcp_authtype == AUTHCHAP && sess_local[s].ipcp.conf_sent % 3 == 2)
|
||||||
|
{
|
||||||
|
LOG(3, s, session[s].tunnel, "Trying to re-send CHAP ack\n");
|
||||||
|
resendchapack(s, session[s].tunnel, sess_local[s].auth_id);
|
||||||
|
}
|
||||||
sendipcp(s, session[s].tunnel);
|
sendipcp(s, session[s].tunnel);
|
||||||
change_state(s, ipcp, next_state);
|
change_state(s, ipcp, next_state);
|
||||||
}
|
}
|
||||||
|
|
@ -7780,7 +7785,7 @@ int sessionsetup(sessionidt s, tunnelidt t)
|
||||||
// Add the route for this session.
|
// Add the route for this session.
|
||||||
routesset(s, &session[s], 1);
|
routesset(s, &session[s], 1);
|
||||||
|
|
||||||
sess_local[s].lcp_authtype = 0; // RADIUS authentication complete
|
sess_local[s].lcp_authdone = 1; // RADIUS authentication complete
|
||||||
lcp_open(s, t); // transition to Network phase and send initial IPCP
|
lcp_open(s, t); // transition to Network phase and send initial IPCP
|
||||||
|
|
||||||
// Run the plugin's against this new session.
|
// Run the plugin's against this new session.
|
||||||
|
|
|
||||||
3
l2tpns.h
3
l2tpns.h
|
|
@ -419,6 +419,8 @@ typedef struct
|
||||||
|
|
||||||
// authentication to use
|
// authentication to use
|
||||||
int lcp_authtype;
|
int lcp_authtype;
|
||||||
|
// whether authentication is over
|
||||||
|
int lcp_authdone;
|
||||||
|
|
||||||
// Last Received LCP ConfReq and its length
|
// Last Received LCP ConfReq and its length
|
||||||
uint8_t lcp_last_received_confreq[MAXLCPLENGTH];
|
uint8_t lcp_last_received_confreq[MAXLCPLENGTH];
|
||||||
|
|
@ -998,6 +1000,7 @@ void processmpframe(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l, uint8_t e
|
||||||
void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
|
void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
|
||||||
void processccp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
|
void processccp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
|
||||||
void sendchap(sessionidt s, tunnelidt t);
|
void sendchap(sessionidt s, tunnelidt t);
|
||||||
|
void resendchapack(sessionidt s, tunnelidt t, uint16_t auth_id);
|
||||||
uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits);
|
uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits);
|
||||||
uint8_t *opt_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits);
|
uint8_t *opt_makeppp(uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype, uint8_t prio, bundleidt bid, uint8_t mp_bits);
|
||||||
void sendlcp(sessionidt s, tunnelidt t);
|
void sendlcp(sessionidt s, tunnelidt t);
|
||||||
|
|
|
||||||
24
ppp.c
24
ppp.c
|
|
@ -170,6 +170,19 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-send a CHAP ack, in case it was previously lost
|
||||||
|
void resendchapack(sessionidt s, tunnelidt t, uint16_t auth_id)
|
||||||
|
{
|
||||||
|
uint8_t b[MAXETHER];
|
||||||
|
uint8_t *p;
|
||||||
|
p = makeppp(b, sizeof(b), 0, 0, s, t, PPPCHAP, 0, 0, 0);
|
||||||
|
if (!p) return;
|
||||||
|
*p = 3; // ack
|
||||||
|
p[1] = auth_id;
|
||||||
|
*(uint16_t *) (p + 2) = ntohs(4); // no message
|
||||||
|
tunnelsend(b, (p - b) + 4, t); // send it
|
||||||
|
}
|
||||||
|
|
||||||
// Process CHAP messages
|
// Process CHAP messages
|
||||||
void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
|
|
@ -209,15 +222,8 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
{
|
{
|
||||||
if (session[s].ppp.phase == Network)
|
if (session[s].ppp.phase == Network)
|
||||||
{
|
{
|
||||||
uint8_t b[MAXETHER];
|
|
||||||
uint8_t *p2;
|
|
||||||
LOG(2, s, t, "CHAP in Network phase, peer probably missed our ack, confirming it\n");
|
LOG(2, s, t, "CHAP in Network phase, peer probably missed our ack, confirming it\n");
|
||||||
p2 = makeppp(b, sizeof(b), 0, 0, s, t, PPPCHAP, 0, 0, 0);
|
resendchapack(s, t, p[1]);
|
||||||
if (!p2) return;
|
|
||||||
*p2 = 3; // ack
|
|
||||||
p2[1] = p[1];
|
|
||||||
*(uint16_t *) (p2 + 2) = ntohs(4); // no message
|
|
||||||
tunnelsend(b, (p2 - b) + 4, t); // send it
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG(2, s, t, "CHAP ignored in %s phase\n", ppp_phase(session[s].ppp.phase));
|
LOG(2, s, t, "CHAP ignored in %s phase\n", ppp_phase(session[s].ppp.phase));
|
||||||
|
|
@ -405,7 +411,7 @@ static void dumplcp(uint8_t *p, int l)
|
||||||
void lcp_open(sessionidt s, tunnelidt t)
|
void lcp_open(sessionidt s, tunnelidt t)
|
||||||
{
|
{
|
||||||
// transition to Authentication or Network phase:
|
// transition to Authentication or Network phase:
|
||||||
session[s].ppp.phase = sess_local[s].lcp_authtype ? Authenticate : Network;
|
session[s].ppp.phase = sess_local[s].lcp_authtype && !sess_local[s].lcp_authdone ? Authenticate : Network;
|
||||||
|
|
||||||
LOG(3, s, t, "LCP: Opened, phase %s\n", ppp_phase(session[s].ppp.phase));
|
LOG(3, s, t, "LCP: Opened, phase %s\n", ppp_phase(session[s].ppp.phase));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue