mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Adding timeout propagation from user policy in PPP sessions (including L2TP and SSTP).
This commit is contained in:
parent
039cd8edf0
commit
1bdd9a92bc
@ -1995,6 +1995,7 @@ UINT CalcL2TPMss(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
|||||||
// Start the L2TP thread
|
// Start the L2TP thread
|
||||||
void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
||||||
{
|
{
|
||||||
|
PPP_SESSION* underlyingSession;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (l2tp == NULL || t == NULL || s == NULL)
|
if (l2tp == NULL || t == NULL || s == NULL)
|
||||||
{
|
{
|
||||||
@ -2023,9 +2024,11 @@ void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a PPP thread
|
// Create a PPP thread
|
||||||
s->Thread = NewPPPSession(l2tp->Cedar, &t->ClientIp, t->ClientPort, &t->ServerIp, t->ServerPort,
|
underlyingSession = NewPPPSession(l2tp->Cedar, &t->ClientIp, t->ClientPort, &t->ServerIp, t->ServerPort,
|
||||||
s->TubeSend, s->TubeRecv, L2TP_IPC_POSTFIX, tmp, t->HostName, l2tp->CryptName,
|
s->TubeSend, s->TubeRecv, L2TP_IPC_POSTFIX, tmp, t->HostName, l2tp->CryptName,
|
||||||
CalcL2TPMss(l2tp, t, s));
|
CalcL2TPMss(l2tp, t, s));
|
||||||
|
s->Thread = underlyingSession->SessionThread;
|
||||||
|
s->PPPSession = underlyingSession;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2122,8 +2125,21 @@ void L2TPProcessInterrupts(L2TP_SERVER *l2tp)
|
|||||||
{
|
{
|
||||||
L2TP_TUNNEL *t = LIST_DATA(l2tp->TunnelList, i);
|
L2TP_TUNNEL *t = LIST_DATA(l2tp->TunnelList, i);
|
||||||
LIST *delete_session_list = NULL;
|
LIST *delete_session_list = NULL;
|
||||||
|
UINT64 l2tpTimeout = L2TP_TUNNEL_TIMEOUT;
|
||||||
|
|
||||||
if ((l2tp->Now >= (t->LastRecvTick + (UINT64)L2TP_TUNNEL_TIMEOUT)) && t->Timedout == false)
|
// If we got on ANY session a higher timeout than the default L2TP tunnel timeout, increase it
|
||||||
|
for (i = 0; i < LIST_NUM(t->SessionList); i++)
|
||||||
|
{
|
||||||
|
L2TP_SESSION* s = LIST_DATA(t->SessionList, i);
|
||||||
|
|
||||||
|
if (s->PPPSession != NULL && s->PPPSession->DataTimeout > l2tpTimeout)
|
||||||
|
{
|
||||||
|
l2tpTimeout = s->PPPSession->DataTimeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((l2tp->Now >= (t->LastRecvTick + (UINT64)l2tpTimeout)) && t->Timedout == false)
|
||||||
{
|
{
|
||||||
// Disconnect the tunnel forcibly if data can not be received for a certain period of time
|
// Disconnect the tunnel forcibly if data can not be received for a certain period of time
|
||||||
t->Timedout = true;
|
t->Timedout = true;
|
||||||
|
@ -169,6 +169,7 @@ struct L2TP_SESSION
|
|||||||
UINT64 DisconnectTimeout; // Disconnection completion time-out
|
UINT64 DisconnectTimeout; // Disconnection completion time-out
|
||||||
bool HasThread; // Whether have a thread
|
bool HasThread; // Whether have a thread
|
||||||
THREAD *Thread; // Thread
|
THREAD *Thread; // Thread
|
||||||
|
PPP_SESSION* PPPSession; // Underlying PPP session
|
||||||
TUBE *TubeSend; // Tube of PPP to L2TP direction
|
TUBE *TubeSend; // Tube of PPP to L2TP direction
|
||||||
TUBE *TubeRecv; // Tube of L2TP to PPP direction
|
TUBE *TubeRecv; // Tube of L2TP to PPP direction
|
||||||
UINT PseudowireType; // Type of L2TPv3 virtual line
|
UINT PseudowireType; // Type of L2TPv3 virtual line
|
||||||
|
@ -386,13 +386,22 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Time-out inspection
|
// Time-out inspection
|
||||||
if ((p->LastRecvTime + (UINT64)PPP_DATA_TIMEOUT) <= now)
|
if ((p->LastRecvTime + (UINT64)p->DataTimeout) <= now)
|
||||||
{
|
{
|
||||||
// Communication time-out occurs
|
// Communication time-out occurs
|
||||||
PPPLog(p, "LP_DATA_TIMEOUT");
|
PPPLog(p, "LP_DATA_TIMEOUT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maximum PPP session time of the user reached inspection
|
||||||
|
if (p->UserConnectionTick != 0 && p->UserConnectionTimeout != 0 &&
|
||||||
|
p->UserConnectionTick + p->UserConnectionTimeout <= now)
|
||||||
|
{
|
||||||
|
// User connection time-out occurs
|
||||||
|
PPPLog(p, "LP_USER_TIMEOUT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Terminate if the PPP disconnected
|
// Terminate if the PPP disconnected
|
||||||
if (p->IsTerminateReceived)
|
if (p->IsTerminateReceived)
|
||||||
{
|
{
|
||||||
@ -444,7 +453,7 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
// Entry point
|
// Entry point
|
||||||
|
|
||||||
// Create a new PPP session
|
// Create a new PPP session
|
||||||
THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss)
|
PPP_SESSION *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss)
|
||||||
{
|
{
|
||||||
PPP_SESSION *p;
|
PPP_SESSION *p;
|
||||||
THREAD *t;
|
THREAD *t;
|
||||||
@ -474,6 +483,10 @@ THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_
|
|||||||
p->MsChapV2_ErrorCode = 691;
|
p->MsChapV2_ErrorCode = 691;
|
||||||
p->EapClient = NULL;
|
p->EapClient = NULL;
|
||||||
|
|
||||||
|
p->DataTimeout = PPP_DATA_TIMEOUT;
|
||||||
|
p->PacketRecvTimeout = PPP_PACKET_RECV_TIMEOUT;
|
||||||
|
p->UserConnectionTimeout = 0;
|
||||||
|
|
||||||
p->Cedar = cedar;
|
p->Cedar = cedar;
|
||||||
AddRef(cedar->ref);
|
AddRef(cedar->ref);
|
||||||
|
|
||||||
@ -510,7 +523,9 @@ THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_
|
|||||||
// Thread creation
|
// Thread creation
|
||||||
t = NewThread(PPPThread, p);
|
t = NewThread(PPPThread, p);
|
||||||
|
|
||||||
return t;
|
p->SessionThread = t;
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PPP processing functions
|
// PPP processing functions
|
||||||
@ -1292,6 +1307,13 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET* pp)
|
|||||||
if (ipc != NULL)
|
if (ipc != NULL)
|
||||||
{
|
{
|
||||||
p->Ipc = ipc;
|
p->Ipc = ipc;
|
||||||
|
|
||||||
|
// Setting user timeouts
|
||||||
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
|
p->UserConnectionTick = Tick64();
|
||||||
|
|
||||||
p->AuthOk = true;
|
p->AuthOk = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1889,7 +1911,7 @@ bool PPPSendAndRetransmitRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c)
|
|||||||
resend->Id = pp->Lcp->Id;
|
resend->Id = pp->Lcp->Id;
|
||||||
resend->Packet = pp;
|
resend->Packet = pp;
|
||||||
resend->ResendTime = now + PPP_PACKET_RESEND_INTERVAL;
|
resend->ResendTime = now + PPP_PACKET_RESEND_INTERVAL;
|
||||||
resend->TimeoutTime = now + PPP_PACKET_RECV_TIMEOUT;
|
resend->TimeoutTime = now + p->PacketRecvTimeout;
|
||||||
|
|
||||||
Add(p->SentReqPacketList, resend);
|
Add(p->SentReqPacketList, resend);
|
||||||
|
|
||||||
@ -1946,7 +1968,7 @@ LABEL_LOOP:
|
|||||||
|
|
||||||
if (async == false)
|
if (async == false)
|
||||||
{
|
{
|
||||||
d = TubeRecvSync(p->TubeRecv, PPP_PACKET_RECV_TIMEOUT);
|
d = TubeRecvSync(p->TubeRecv, p->PacketRecvTimeout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2499,9 +2521,17 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION* p, PPP_PACKET* pp)
|
|||||||
{
|
{
|
||||||
p->Ipc = ipc;
|
p->Ipc = ipc;
|
||||||
|
|
||||||
|
// Setting user timeouts
|
||||||
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
|
p->UserConnectionTick = Tick64();
|
||||||
|
|
||||||
Copy(p->MsChapV2_ServerResponse, ipc->MsChapV2_ServerResponse, 20);
|
Copy(p->MsChapV2_ServerResponse, ipc->MsChapV2_ServerResponse, 20);
|
||||||
|
|
||||||
ok = true;
|
ok = true;
|
||||||
|
|
||||||
|
p->AuthOk = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -32,11 +32,11 @@
|
|||||||
//// Constants
|
//// Constants
|
||||||
|
|
||||||
// Time-out value
|
// Time-out value
|
||||||
#define PPP_PACKET_RECV_TIMEOUT (30 * 1000) // Timeout until the next packet is received
|
#define PPP_PACKET_RECV_TIMEOUT (15 * 1000) // Timeout until the next packet is received (3/4 of default policy)
|
||||||
#define PPP_PACKET_RESEND_INTERVAL (5 * 1000) // Retransmission interval of the last packet
|
#define PPP_PACKET_RESEND_INTERVAL (3 * 1000) // Retransmission interval of the last packet
|
||||||
#define PPP_TERMINATE_TIMEOUT 2000 // Timeout value to complete disconnection after requesting to disconnect in the PPP
|
#define PPP_TERMINATE_TIMEOUT 2000 // Timeout value to complete disconnection after requesting to disconnect in the PPP
|
||||||
#define PPP_ECHO_SEND_INTERVAL 4792 // Transmission interval of PPP Echo Request
|
#define PPP_ECHO_SEND_INTERVAL 4792 // Transmission interval of PPP Echo Request
|
||||||
#define PPP_DATA_TIMEOUT (60 * 1000) // Communication time-out
|
#define PPP_DATA_TIMEOUT (20 * 1000) // Communication time-out (from default policy)
|
||||||
|
|
||||||
// MRU
|
// MRU
|
||||||
#define PPP_MRU_DEFAULT 1500 // Default value
|
#define PPP_MRU_DEFAULT 1500 // Default value
|
||||||
@ -238,6 +238,13 @@ struct PPP_SESSION
|
|||||||
|
|
||||||
PPP_PACKET *CurrentPacket;
|
PPP_PACKET *CurrentPacket;
|
||||||
LIST *DelayedPackets;
|
LIST *DelayedPackets;
|
||||||
|
|
||||||
|
UINT64 PacketRecvTimeout;
|
||||||
|
UINT64 DataTimeout;
|
||||||
|
UINT64 UserConnectionTimeout;
|
||||||
|
UINT64 UserConnectionTick;
|
||||||
|
|
||||||
|
THREAD* SessionThread; // Thread of the PPP session
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +255,7 @@ struct PPP_SESSION
|
|||||||
void PPPThread(THREAD *thread, void *param);
|
void PPPThread(THREAD *thread, void *param);
|
||||||
|
|
||||||
// Entry point
|
// Entry point
|
||||||
THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss);
|
PPP_SESSION *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss);
|
||||||
|
|
||||||
// PPP processing functions
|
// PPP processing functions
|
||||||
bool PPPRejectUnsupportedPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPRejectUnsupportedPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
|
@ -97,6 +97,8 @@ void SstpProcessControlPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
|||||||
// Process the SSTP received data packet
|
// Process the SSTP received data packet
|
||||||
void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
||||||
{
|
{
|
||||||
|
PPP_SESSION* underlyingSession;
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (s == NULL || p == NULL || p->IsControl)
|
if (s == NULL || p == NULL || p->IsControl)
|
||||||
{
|
{
|
||||||
@ -108,9 +110,11 @@ void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
|||||||
if (s->PPPThread == NULL)
|
if (s->PPPThread == NULL)
|
||||||
{
|
{
|
||||||
// Create a thread to initialize the new PPP module
|
// Create a thread to initialize the new PPP module
|
||||||
s->PPPThread = NewPPPSession(s->Cedar, &s->ClientIp, s->ClientPort, &s->ServerIp, s->ServerPort,
|
underlyingSession = NewPPPSession(s->Cedar, &s->ClientIp, s->ClientPort, &s->ServerIp, s->ServerPort,
|
||||||
s->TubeSend, s->TubeRecv, SSTP_IPC_POSTFIX, SSTP_IPC_CLIENT_NAME,
|
s->TubeSend, s->TubeRecv, SSTP_IPC_POSTFIX, SSTP_IPC_CLIENT_NAME,
|
||||||
s->ClientHostName, s->ClientCipherName, 0);
|
s->ClientHostName, s->ClientCipherName, 0);
|
||||||
|
s->PPPSession = underlyingSession;
|
||||||
|
s->PPPThread = underlyingSession->SessionThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the received data to the PPP module
|
// Pass the received data to the PPP module
|
||||||
@ -177,6 +181,7 @@ void SstpSendPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
|||||||
// Process the timer interrupt
|
// Process the timer interrupt
|
||||||
void SstpProcessInterrupt(SSTP_SERVER *s)
|
void SstpProcessInterrupt(SSTP_SERVER *s)
|
||||||
{
|
{
|
||||||
|
UINT64 sstpTimeout = SSTP_TIMEOUT;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
{
|
{
|
||||||
@ -261,7 +266,12 @@ void SstpProcessInterrupt(SSTP_SERVER *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s->LastRecvTick + (UINT64)SSTP_TIMEOUT) <= s->Now)
|
if (s->PPPSession != NULL && s->PPPSession->DataTimeout > sstpTimeout)
|
||||||
|
{
|
||||||
|
sstpTimeout = s->PPPSession->DataTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((s->LastRecvTick + sstpTimeout) <= s->Now)
|
||||||
{
|
{
|
||||||
// Disconnect the SSTP because a timeout occurred
|
// Disconnect the SSTP because a timeout occurred
|
||||||
SstpAbort(s);
|
SstpAbort(s);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define SSTP_IPC_POSTFIX "SSTP"
|
#define SSTP_IPC_POSTFIX "SSTP"
|
||||||
#define SSTP_ECHO_SEND_INTERVAL_MIN 2500 // Transmission interval of Echo Request (minimum)
|
#define SSTP_ECHO_SEND_INTERVAL_MIN 2500 // Transmission interval of Echo Request (minimum)
|
||||||
#define SSTP_ECHO_SEND_INTERVAL_MAX 4792 // Transmission interval of Echo Request (maximum)
|
#define SSTP_ECHO_SEND_INTERVAL_MAX 4792 // Transmission interval of Echo Request (maximum)
|
||||||
#define SSTP_TIMEOUT 10000 // Communication time-out of SSTP
|
#define SSTP_TIMEOUT 20 * 1000 // Communication time-out of SSTP (from default policy)
|
||||||
|
|
||||||
// SSTP Message Type
|
// SSTP Message Type
|
||||||
#define SSTP_MSG_CALL_CONNECT_REQUEST 0x0001
|
#define SSTP_MSG_CALL_CONNECT_REQUEST 0x0001
|
||||||
@ -116,6 +116,7 @@ struct SSTP_SERVER
|
|||||||
UINT64 LastRecvTick; // Tick when some data has received at the end
|
UINT64 LastRecvTick; // Tick when some data has received at the end
|
||||||
bool FlushRecvTube; // Flag whether to flush the reception tube
|
bool FlushRecvTube; // Flag whether to flush the reception tube
|
||||||
UINT EstablishedCount; // Number of session establishment
|
UINT EstablishedCount; // Number of session establishment
|
||||||
|
PPP_SESSION* PPPSession; // Underlying PPP Session
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user