1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Merge PR #1039: Port latest improvements from stable repository

This commit is contained in:
Davide Beatrici 2019-11-23 06:41:57 +01:00 committed by GitHub
commit 876ca4ef3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 921 additions and 400 deletions

View File

@ -9696,6 +9696,15 @@ UINT StSetFarmSetting(ADMIN *a, RPC_FARM *t)
return ERR_NOT_SUPPORTED; return ERR_NOT_SUPPORTED;
} }
if (IsZero(t->MemberPassword, sizeof(t->MemberPassword)))
{
if (IsEmptyStr(t->MemberPasswordPlaintext) == false)
{
// For JSON-RPC
HashAdminPassword(t->MemberPassword, t->MemberPasswordPlaintext);
}
}
ALog(a, NULL, "LA_SET_FARM_SETTING"); ALog(a, NULL, "LA_SET_FARM_SETTING");
IncrementServerConfigRevision(a->Server); IncrementServerConfigRevision(a->Server);

View File

@ -9655,6 +9655,12 @@ void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
} }
if (IsEmptyStr(s->ProtocolDetails) == false)
{
StrToUni(tmp, sizeof(tmp), s->ProtocolDetails);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_PROTOCOL_DETAILS"), tmp);
}
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));

View File

@ -576,6 +576,7 @@ typedef struct IPC_ASYNC IPC_ASYNC;
typedef struct IPC_PARAM IPC_PARAM; typedef struct IPC_PARAM IPC_PARAM;
typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE; typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE;
typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO; typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO;
typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA;
// ============================================================== // ==============================================================

View File

@ -5818,9 +5818,26 @@ void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
st->IsRUDPSession = s->IsRUDPSession; st->IsRUDPSession = s->IsRUDPSession;
// Physical communication protocol // Physical communication protocol
StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol); StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol);
// Protocol details
StrCpy(st->ProtocolDetails, sizeof(st->ProtocolDetails), s->ProtocolDetails);
Trim(st->ProtocolDetails);
// UDP acceleration function // UDP acceleration function
st->IsUdpAccelerationEnabled = s->UseUdpAcceleration; if (s->IpcSessionShared != NULL && IsEmptyStr(s->IpcSessionShared->ProtocolDetails) == false)
st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration; {
char tmp[sizeof(s->IpcSessionShared->ProtocolDetails)];
StrCpy(tmp, sizeof(tmp), s->IpcSessionShared->ProtocolDetails);
Trim(tmp);
StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), " ");
StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), tmp);
st->IsUdpAccelerationEnabled = s->IpcSessionShared->EnableUdpAccel;
st->IsUsingUdpAcceleration = s->IpcSessionShared->UsingUdpAccel;
}
else
{
st->IsUdpAccelerationEnabled = s->UseUdpAcceleration;
st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration;
}
// Session key // Session key
Copy(st->SessionKey, s->SessionKey, SHA1_SIZE); Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
// Policy // Policy

View File

@ -341,6 +341,7 @@ struct RPC_CLIENT_GET_CONNECTION_STATUS
bool UseCompress; // Use of compression bool UseCompress; // Use of compression
bool IsRUDPSession; // R-UDP session bool IsRUDPSession; // R-UDP session
char UnderlayProtocol[64]; // Physical communication protocol char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol details
bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled
bool IsUsingUdpAcceleration; // Using the UDP acceleration function bool IsUsingUdpAcceleration; // Using the UDP acceleration function
char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name

View File

@ -15155,6 +15155,12 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo
CtInsert(ct, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); CtInsert(ct, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
} }
if (IsEmptyStr(s->ProtocolDetails) == false)
{
StrToUni(tmp, sizeof(tmp), s->ProtocolDetails);
CtInsert(ct, _UU("CM_ST_PROTOCOL_DETAILS"), tmp);
}
CtInsert(ct, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); CtInsert(ct, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
CtInsert(ct, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); CtInsert(ct, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));

View File

@ -1160,6 +1160,8 @@ void ConnectionSend(CONNECTION *c, UINT64 now)
s->TotalSendSizeReal += b->Size; s->TotalSendSizeReal += b->Size;
c->CurrentSendQueueSize -= b->Size; c->CurrentSendQueueSize -= b->Size;
Free(new_buf);
} }
FreeBlock(b); FreeBlock(b);
@ -2682,6 +2684,8 @@ BLOCK *NewBlock(void *data, UINT size, int compress)
b = MallocFast(sizeof(BLOCK)); b = MallocFast(sizeof(BLOCK));
b->RawFlagRetUdpAccel = 0;
b->IsFlooding = false; b->IsFlooding = false;
b->PriorityQoS = b->Ttl = b->Param1 = 0; b->PriorityQoS = b->Ttl = b->Param1 = 0;

View File

@ -155,6 +155,7 @@ struct BLOCK
UINT Ttl; // TTL value (Used only in ICMP NAT of Virtual.c) UINT Ttl; // TTL value (Used only in ICMP NAT of Virtual.c)
UINT Param1; // Parameter 1 UINT Param1; // Parameter 1
bool IsFlooding; // Is flooding packet bool IsFlooding; // Is flooding packet
UCHAR RawFlagRetUdpAccel; // Raw flag returned by UDP accel
}; };
// Connection structure // Connection structure

View File

@ -5913,7 +5913,7 @@ void IntoTrafficLimiter(TRAFFIC_LIMITER *tr, PKT *p)
} }
// Value increase // Value increase
tr->Value += p->PacketSize * (UINT64)8; tr->Value += (UINT64)p->PacketSize * (UINT64)8;
} }
// The bandwidth reduction by traffic limiter // The bandwidth reduction by traffic limiter

View File

@ -242,6 +242,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
NODE_INFO info; NODE_INFO info;
BUF *b; BUF *b;
UCHAR mschap_v2_server_response_20[20]; UCHAR mschap_v2_server_response_20[20];
UINT64 u64;
// Validate arguments // Validate arguments
if (cedar == NULL || username == NULL || password == NULL || client_hostname == NULL) if (cedar == NULL || username == NULL || password == NULL || client_hostname == NULL)
{ {
@ -457,6 +458,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr); Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr);
u64 = PackGetInt64(p, "IpcSessionSharedBuffer");
ipc->IpcSessionSharedBuffer = (SHARED_BUFFER *)u64;
ipc->IpcSessionShared = ipc->IpcSessionSharedBuffer->Data;
FreePack(p); FreePack(p);
ReleaseSock(a); ReleaseSock(a);
@ -591,6 +596,8 @@ void FreeIPC(IPC *ipc)
ReleaseQueue(ipc->IPv4ReceivedQueue); ReleaseQueue(ipc->IPv4ReceivedQueue);
ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer);
Free(ipc); Free(ipc);
} }

View File

@ -43,6 +43,14 @@ struct IPC_DHCP_RELEASE_QUEUE
UCHAR MacAddress[6]; UCHAR MacAddress[6];
}; };
// IPC_SESSION_SHARED_BUFFER_DATA
struct IPC_SESSION_SHARED_BUFFER_DATA
{
char ProtocolDetails[256];
bool EnableUdpAccel;
bool UsingUdpAccel;
};
// IPC_PARAM // IPC_PARAM
struct IPC_PARAM struct IPC_PARAM
{ {
@ -106,6 +114,8 @@ struct IPC
TUBE_FLUSH_LIST *FlushList; // Tube Flush List TUBE_FLUSH_LIST *FlushList; // Tube Flush List
UCHAR MsChapV2_ServerResponse[20]; // Server response UCHAR MsChapV2_ServerResponse[20]; // Server response
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session
IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // Shared data between IPC and Session
UINT Layer; UINT Layer;
}; };

View File

@ -2181,7 +2181,7 @@ void MakeLogFileNameStringFromTick(LOG *g, char *str, UINT size, UINT64 tick, UI
break; break;
default: // Without switching default: // Without switching
snprintf(str, size, "%s"); StrCpy(str, size, "");
break; break;
} }

View File

@ -2688,7 +2688,7 @@ IPSECSA *NewIPsecSa(IKE_SERVER *ike, IKE_CLIENT *c, IKE_SA *ike_sa, bool initiat
// Set the expiration time // Set the expiration time
if (setting->LifeSeconds != 0) if (setting->LifeSeconds != 0)
{ {
UINT64 span = setting->LifeSeconds * (UINT64)1000 + (UINT64)IKE_SOFT_EXPIRES_MARGIN; const UINT64 span = (UINT64)((UINT64)setting->LifeSeconds * (UINT64)1000) + (UINT64)IKE_SOFT_EXPIRES_MARGIN;
sa->ExpiresHardTick = ike->Now + span; sa->ExpiresHardTick = ike->Now + span;
sa->ExpiresSoftTick = ike->Now + span; sa->ExpiresSoftTick = ike->Now + span;
//sa->ExpiresSoftTick = ike->Now + (UINT64)5000; //sa->ExpiresSoftTick = ike->Now + (UINT64)5000;
@ -3740,7 +3740,7 @@ bool IkeIsVendorIdExists(IKE_PACKET *p, char *str)
IKE_PACKET_PAYLOAD *payload = IkeGetPayload(p->PayloadList, IKE_PAYLOAD_VENDOR_ID, i); IKE_PACKET_PAYLOAD *payload = IkeGetPayload(p->PayloadList, IKE_PAYLOAD_VENDOR_ID, i);
if (payload == NULL) if (payload == NULL)
{ {
return false; break;
} }
if (CompareBuf(payload->Payload.VendorId.Data, buf)) if (CompareBuf(payload->Payload.VendorId.Data, buf))

View File

@ -1215,7 +1215,7 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
t = 1; t = 1;
} }
p->DhcpRenewInterval = t * (UINT64)1000; p->DhcpRenewInterval = (UINT64)t * (UINT64)1000;
p->DhcpNextRenewTime = Tick64() + p->DhcpRenewInterval; p->DhcpNextRenewTime = Tick64() + p->DhcpRenewInterval;
if (true) if (true)

View File

@ -1077,12 +1077,17 @@ bool ServerAccept(CONNECTION *c)
bool half_connection; bool half_connection;
UINT adjust_mss; UINT adjust_mss;
bool use_udp_acceleration_client; bool use_udp_acceleration_client;
UINT client_udp_acceleration_max_version = 1;
UINT udp_acceleration_version = 1;
UINT client_rudp_bulk_max_version = 1;
UINT rudp_bulk_version = 1;
bool support_hmac_on_udp_acceleration_client = false; bool support_hmac_on_udp_acceleration_client = false;
bool support_udp_accel_fast_disconnect_detect; bool support_udp_accel_fast_disconnect_detect;
bool use_hmac_on_udp_acceleration = false; bool use_hmac_on_udp_acceleration = false;
bool supress_return_pack_error = false; bool supress_return_pack_error = false;
IP udp_acceleration_client_ip; IP udp_acceleration_client_ip;
UCHAR udp_acceleration_client_key[UDP_ACCELERATION_COMMON_KEY_SIZE]; UCHAR udp_acceleration_client_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1];
UCHAR udp_acceleration_client_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2];
UINT udp_acceleration_client_port; UINT udp_acceleration_client_port;
bool admin_mode = false; bool admin_mode = false;
UINT direction; UINT direction;
@ -1144,6 +1149,7 @@ bool ServerAccept(CONNECTION *c)
Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip)); Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip));
udp_acceleration_client_port = 0; udp_acceleration_client_port = 0;
Zero(udp_acceleration_client_key, sizeof(udp_acceleration_client_key)); Zero(udp_acceleration_client_key, sizeof(udp_acceleration_client_key));
Zero(udp_acceleration_client_key_v2, sizeof(udp_acceleration_client_key_v2));
Zero(&winver, sizeof(winver)); Zero(&winver, sizeof(winver));
@ -1453,6 +1459,16 @@ bool ServerAccept(CONNECTION *c)
client_id = PackGetInt(p, "client_id"); client_id = PackGetInt(p, "client_id");
adjust_mss = PackGetInt(p, "adjust_mss"); adjust_mss = PackGetInt(p, "adjust_mss");
use_udp_acceleration_client = PackGetBool(p, "use_udp_acceleration"); use_udp_acceleration_client = PackGetBool(p, "use_udp_acceleration");
client_udp_acceleration_max_version = PackGetInt(p, "udp_acceleration_max_version");
if (client_udp_acceleration_max_version == 0)
{
client_udp_acceleration_max_version = 1;
}
client_rudp_bulk_max_version = PackGetInt(p, "rudp_bulk_max_version");
if (client_rudp_bulk_max_version == 0)
{
client_rudp_bulk_max_version = 1;
}
support_hmac_on_udp_acceleration_client = PackGetBool(p, "support_hmac_on_udp_acceleration"); support_hmac_on_udp_acceleration_client = PackGetBool(p, "support_hmac_on_udp_acceleration");
support_udp_accel_fast_disconnect_detect = PackGetBool(p, "support_udp_accel_fast_disconnect_detect"); support_udp_accel_fast_disconnect_detect = PackGetBool(p, "support_udp_accel_fast_disconnect_detect");
support_bulk_on_rudp = PackGetBool(p, "support_bulk_on_rudp"); support_bulk_on_rudp = PackGetBool(p, "support_bulk_on_rudp");
@ -1479,8 +1495,8 @@ bool ServerAccept(CONNECTION *c)
{ {
if (IsEmptyStr(c->InProcPrefix) == false) if (IsEmptyStr(c->InProcPrefix) == false)
{ {
Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol), Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol), SOCK_UNDERLAY_INPROC_EX, c->InProcPrefix);
SOCK_UNDERLAY_INPROC_EX, c->InProcPrefix); AddProtocolDetailsStr(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol), c->InProcPrefix);
} }
} }
@ -1522,7 +1538,7 @@ bool ServerAccept(CONNECTION *c)
if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket && if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket &&
c->FirstSock->BulkRecvKey != NULL && c->FirstSock->BulkSendKey != NULL) c->FirstSock->BulkRecvKey != NULL && c->FirstSock->BulkSendKey != NULL)
{ {
// RAllow UDP bulk transfer if the client side supports // Allow UDP bulk transfer if the client side supports
// in the case of using R-UDP Socket // in the case of using R-UDP Socket
enable_bulk_on_rudp = true; enable_bulk_on_rudp = true;
@ -1537,9 +1553,11 @@ bool ServerAccept(CONNECTION *c)
if (use_udp_acceleration_client) if (use_udp_acceleration_client)
{ {
PackGetData2(p, "udp_acceleration_client_key", udp_acceleration_client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
PackGetData2(p, "udp_acceleration_client_key_v2", udp_acceleration_client_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
// Get the parameters for the UDP acceleration function // Get the parameters for the UDP acceleration function
if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false || if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false)
PackGetData2(p, "udp_acceleration_client_key", udp_acceleration_client_key, UDP_ACCELERATION_COMMON_KEY_SIZE) == false)
{ {
use_udp_acceleration_client = false; use_udp_acceleration_client = false;
} }
@ -2807,7 +2825,8 @@ bool ServerAccept(CONNECTION *c)
// R-UDP session // R-UDP session
s->IsRUDPSession = true; s->IsRUDPSession = true;
s->RUdpMss = c->FirstSock->RUDP_OptimizedMss; s->RUdpMss = c->FirstSock->RUDP_OptimizedMss;
Debug("Optimized MSS Value for R-UDP: %u\n", s->RUdpMss); Debug("ServerAccept(): Optimized MSS Value for R-UDP: %u\n", s->RUdpMss);
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "RUDP_MSS", s->RUdpMss);
} }
if (enable_bulk_on_rudp) if (enable_bulk_on_rudp)
@ -2821,6 +2840,8 @@ bool ServerAccept(CONNECTION *c)
StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), c->FirstSock->UnderlayProtocol); StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), c->FirstSock->UnderlayProtocol);
AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), c->FirstSock->ProtocolDetails);
if (server != NULL) if (server != NULL)
{ {
s->NoSendSignature = server->NoSendSignature; s->NoSendSignature = server->NoSendSignature;
@ -2849,6 +2870,22 @@ bool ServerAccept(CONNECTION *c)
s->UseUdpAcceleration = true; s->UseUdpAcceleration = true;
s->UdpAccelFastDisconnectDetect = support_udp_accel_fast_disconnect_detect; s->UdpAccelFastDisconnectDetect = support_udp_accel_fast_disconnect_detect;
udp_acceleration_version = 1;
if (client_udp_acceleration_max_version >= 2)
{
udp_acceleration_version = 2;
}
}
if (client_rudp_bulk_max_version >= 2)
{
rudp_bulk_version = 2;
}
if (s->EnableBulkOnRUDP)
{
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "RUDP_Bulk_Ver", s->BulkOnRUDPVersion);
} }
if (hub->Option != NULL && hub->Option->DisableUdpAcceleration) if (hub->Option != NULL && hub->Option->DisableUdpAcceleration)
@ -2872,6 +2909,7 @@ bool ServerAccept(CONNECTION *c)
Debug("UseUdpAcceleration = %u\n", s->UseUdpAcceleration); Debug("UseUdpAcceleration = %u\n", s->UseUdpAcceleration);
Debug("UseHMacOnUdpAcceleration = %u\n", s->UseHMacOnUdpAcceleration); Debug("UseHMacOnUdpAcceleration = %u\n", s->UseHMacOnUdpAcceleration);
Debug("UdpAccelerationVersion = %u\n", s->UdpAccelerationVersion);
if (s->UseUdpAcceleration) if (s->UseUdpAcceleration)
{ {
@ -2887,8 +2925,11 @@ bool ServerAccept(CONNECTION *c)
} }
else else
{ {
if (UdpAccelInitServer(s->UdpAccel, udp_acceleration_client_key, &udp_acceleration_client_ip, udp_acceleration_client_port, s->UdpAccel->Version = udp_acceleration_version;
&c->FirstSock->RemoteIP) == false)
if (UdpAccelInitServer(s->UdpAccel,
s->UdpAccel->Version == 2 ? udp_acceleration_client_key_v2 : udp_acceleration_client_key,
&udp_acceleration_client_ip, udp_acceleration_client_port, &c->FirstSock->RemoteIP) == false)
{ {
Debug("UdpAccelInitServer Failed.\n"); Debug("UdpAccelInitServer Failed.\n");
s->UseUdpAcceleration = false; s->UseUdpAcceleration = false;
@ -2902,6 +2943,12 @@ bool ServerAccept(CONNECTION *c)
} }
s->UdpAccel->UseHMac = s->UseHMacOnUdpAcceleration; s->UdpAccel->UseHMac = s->UseHMacOnUdpAcceleration;
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "UDPAccel_Ver", s->UdpAccel->Version);
AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), s->UdpAccel->Version > 1 ? "ChaCha20-Poly1305" : "RC4");
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "UDPAccel_MSS", UdpAccelCalcMss(s->UdpAccel));
} }
} }
@ -2912,6 +2959,7 @@ bool ServerAccept(CONNECTION *c)
if (s->AdjustMss != 0) if (s->AdjustMss != 0)
{ {
Debug("AdjustMSS: %u\n", s->AdjustMss); Debug("AdjustMSS: %u\n", s->AdjustMss);
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "AdjustMSS", s->AdjustMss);
} }
s->IsBridgeMode = (policy->NoBridge == false) || (policy->NoRouting == false); s->IsBridgeMode = (policy->NoBridge == false) || (policy->NoRouting == false);
@ -2957,8 +3005,7 @@ bool ServerAccept(CONNECTION *c)
{ {
char ip[128]; char ip[128];
IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP); IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP);
HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort, HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort, c->FirstSock->UnderlayProtocol, c->FirstSock->ProtocolDetails);
c->FirstSock->UnderlayProtocol);
} }
c->Session = s; c->Session = s;
@ -3334,6 +3381,19 @@ bool ServerAccept(CONNECTION *c)
// Add the socket of this connection to the connection list of the session (TCP) // Add the socket of this connection to the connection list of the session (TCP)
sock = c->FirstSock; sock = c->FirstSock;
if (sock->IsRUDPSocket && sock->BulkRecvKey != NULL && sock->BulkSendKey != NULL)
{
if (s->BulkRecvKeySize != 0 && s->BulkSendKeySize != 0)
{
// Restore R-UDP bulk send/recv keys for additional connections
Copy(sock->BulkRecvKey->Data, s->BulkRecvKey, s->BulkRecvKeySize);
sock->BulkRecvKey->Size = s->BulkRecvKeySize;
Copy(sock->BulkSendKey->Data, s->BulkSendKey, s->BulkSendKeySize);
sock->BulkSendKey->Size = s->BulkSendKeySize;
}
}
ts = NewTcpSock(sock); ts = NewTcpSock(sock);
SetTimeout(sock, CONNECTING_TIMEOUT); SetTimeout(sock, CONNECTING_TIMEOUT);
direction = TCP_BOTH; direction = TCP_BOTH;
@ -3981,6 +4041,19 @@ bool ClientAdditionalConnect(CONNECTION *c, THREAD *t)
Debug("Additional Connect Succeed!\n"); Debug("Additional Connect Succeed!\n");
if (s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
{
// Restore R-UDP bulk send/recv keys for additional connections
if (c->Session->BulkRecvKeySize != 0 && c->Session->BulkSendKeySize != 0)
{
Copy(s->BulkRecvKey->Data, c->Session->BulkRecvKey, c->Session->BulkRecvKeySize);
s->BulkRecvKey->Size = c->Session->BulkRecvKeySize;
Copy(s->BulkSendKey->Data, c->Session->BulkSendKey, c->Session->BulkSendKeySize);
s->BulkSendKey->Size = c->Session->BulkSendKeySize;
}
}
// Success the additional connection // Success the additional connection
// Add to the TcpSockList of the connection // Add to the TcpSockList of the connection
ts = NewTcpSock(s); ts = NewTcpSock(s);
@ -4704,9 +4777,13 @@ REDIRECTED:
// Physical communication protocol // Physical communication protocol
StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), s->UnderlayProtocol); StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), s->UnderlayProtocol);
AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), s->ProtocolDetails);
if (c->Session->IsAzureSession) if (c->Session->IsAzureSession)
{ {
StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), SOCK_UNDERLAY_AZURE); StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), "VPN Azure");
} }
if (c->Protocol == CONNECTION_UDP) if (c->Protocol == CONNECTION_UDP)
@ -4725,22 +4802,44 @@ REDIRECTED:
sess->EnableBulkOnRUDP = false; sess->EnableBulkOnRUDP = false;
sess->EnableHMacOnBulkOfRUDP = false; sess->EnableHMacOnBulkOfRUDP = false;
if (s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL) if (s != NULL && s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
{ {
// Bulk transfer on R-UDP // Bulk transfer on R-UDP
sess->EnableHMacOnBulkOfRUDP = PackGetBool(p, "enable_hmac_on_bulk_of_rudp");
sess->BulkOnRUDPVersion = PackGetInt(p, "rudp_bulk_version");
if (PackGetBool(p, "enable_bulk_on_rudp")) if (PackGetBool(p, "enable_bulk_on_rudp"))
{ {
// Receive the key // Receive the key
UCHAR key_send[SHA1_SIZE]; UCHAR key_send[RUDP_BULK_KEY_SIZE_MAX];
UCHAR key_recv[SHA1_SIZE]; UCHAR key_recv[RUDP_BULK_KEY_SIZE_MAX];
if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, SHA1_SIZE) && UINT key_size = SHA1_SIZE;
PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, SHA1_SIZE))
if (sess->BulkOnRUDPVersion == 2)
{
key_size = RUDP_BULK_KEY_SIZE_V2;
}
if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, key_size) &&
PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, key_size))
{ {
sess->EnableBulkOnRUDP = true; sess->EnableBulkOnRUDP = true;
Copy(s->BulkSendKey->Data, key_send, SHA1_SIZE); Copy(s->BulkSendKey->Data, key_send, key_size);
Copy(s->BulkRecvKey->Data, key_recv, SHA1_SIZE); Copy(s->BulkRecvKey->Data, key_recv, key_size);
s->BulkSendKey->Size = key_size;
s->BulkRecvKey->Size = key_size;
// Backup R-UDP bulk send/recv keys for additional connections
Copy(sess->BulkSendKey, s->BulkSendKey->Data, s->BulkSendKey->Size);
sess->BulkSendKeySize = s->BulkSendKey->Size;
Copy(sess->BulkRecvKey, s->BulkRecvKey->Data, s->BulkRecvKey->Size);
sess->BulkRecvKeySize = s->BulkRecvKey->Size;
AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "RUDP_Bulk_Ver", sess->BulkOnRUDPVersion);
} }
} }
@ -4750,6 +4849,7 @@ REDIRECTED:
Debug("EnableBulkOnRUDP = %u\n", sess->EnableBulkOnRUDP); Debug("EnableBulkOnRUDP = %u\n", sess->EnableBulkOnRUDP);
Debug("EnableHMacOnBulkOfRUDP = %u\n", sess->EnableHMacOnBulkOfRUDP); Debug("EnableHMacOnBulkOfRUDP = %u\n", sess->EnableHMacOnBulkOfRUDP);
Debug("EnableUdpRecovery = %u\n", sess->EnableUdpRecovery); Debug("EnableUdpRecovery = %u\n", sess->EnableUdpRecovery);
Debug("BulkOnRUDPVersion = %u\n", sess->BulkOnRUDPVersion);
sess->UseUdpAcceleration = false; sess->UseUdpAcceleration = false;
sess->IsUsingUdpAcceleration = false; sess->IsUsingUdpAcceleration = false;
@ -4763,8 +4863,14 @@ REDIRECTED:
if (PackGetBool(p, "use_udp_acceleration")) if (PackGetBool(p, "use_udp_acceleration"))
{ {
UINT udp_acceleration_version = PackGetInt(p, "udp_acceleration_version");
IP udp_acceleration_server_ip; IP udp_acceleration_server_ip;
if (udp_acceleration_version == 0)
{
udp_acceleration_version = 1;
}
sess->UdpAccelFastDisconnectDetect = PackGetBool(p, "udp_accel_fast_disconnect_detect"); sess->UdpAccelFastDisconnectDetect = PackGetBool(p, "udp_accel_fast_disconnect_detect");
if (PackGetIp(p, "udp_acceleration_server_ip", &udp_acceleration_server_ip)) if (PackGetIp(p, "udp_acceleration_server_ip", &udp_acceleration_server_ip))
@ -4778,46 +4884,62 @@ REDIRECTED:
if (udp_acceleration_server_port != 0) if (udp_acceleration_server_port != 0)
{ {
UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE]; UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1];
UCHAR udp_acceleration_server_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2];
UINT server_cookie = PackGetInt(p, "udp_acceleration_server_cookie");
UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie");
bool encryption = PackGetBool(p, "udp_acceleration_use_encryption");
if (PackGetData2(p, "udp_acceleration_server_key", udp_acceleration_server_key, UDP_ACCELERATION_COMMON_KEY_SIZE)) Zero(udp_acceleration_server_key, sizeof(udp_acceleration_server_key));
Zero(udp_acceleration_server_key_v2, sizeof(udp_acceleration_server_key_v2));
PackGetData2(p, "udp_acceleration_server_key", udp_acceleration_server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
PackGetData2(p, "udp_acceleration_server_key_v2", udp_acceleration_server_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
if (server_cookie != 0 && client_cookie != 0)
{ {
UINT server_cookie = PackGetInt(p, "udp_acceleration_server_cookie"); IP remote_ip;
UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie");
bool encryption = PackGetBool(p, "udp_acceleration_use_encryption");
if (server_cookie != 0 && client_cookie != 0) Copy(&remote_ip, &s->RemoteIP, sizeof(IP));
if (IsZeroIp(&c->Session->AzureRealServerGlobalIp) == false)
{ {
IP remote_ip; Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP));
}
Copy(&remote_ip, &s->RemoteIP, sizeof(IP)); sess->UdpAccel->Version = 1;
if (udp_acceleration_version == 2)
{
sess->UdpAccel->Version = 2;
}
if (IsZeroIp(&c->Session->AzureRealServerGlobalIp) == false) if (UdpAccelInitClient(sess->UdpAccel,
sess->UdpAccel->Version == 2 ? udp_acceleration_server_key_v2 : udp_acceleration_server_key,
&udp_acceleration_server_ip, udp_acceleration_server_port,
server_cookie, client_cookie, &remote_ip) == false)
{
Debug("UdpAccelInitClient failed.\n");
}
else
{
sess->UseUdpAcceleration = true;
sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect;
sess->UdpAccel->PlainTextMode = !encryption;
sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration");
if (sess->UseHMacOnUdpAcceleration)
{ {
Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP)); sess->UdpAccel->UseHMac = true;
} }
if (UdpAccelInitClient(sess->UdpAccel, udp_acceleration_server_key, AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "UDPAccel_Ver", sess->UdpAccel->Version);
&udp_acceleration_server_ip, udp_acceleration_server_port,
server_cookie, client_cookie, &remote_ip) == false)
{
Debug("UdpAccelInitClient failed.\n");
}
else
{
sess->UseUdpAcceleration = true;
sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect; AddProtocolDetailsStr(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), sess->UdpAccel->Version > 1 ? "ChaCha20-Poly1305" : "RC4");
sess->UdpAccel->PlainTextMode = !encryption; AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "UDPAccel_MSS", UdpAccelCalcMss(sess->UdpAccel));
sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration");
if (sess->UseHMacOnUdpAcceleration)
{
sess->UdpAccel->UseHMac = true;
}
}
} }
} }
} }
@ -5044,15 +5166,25 @@ PACK *PackWelcome(SESSION *s)
// Virtual HUB name // Virtual HUB name
PackAddStr(p, "IpcHubName", s->Hub->Name); PackAddStr(p, "IpcHubName", s->Hub->Name);
// Shared Buffer
s->IpcSessionSharedBuffer = NewSharedBuffer(NULL, sizeof(IPC_SESSION_SHARED_BUFFER_DATA));
AddRef(s->IpcSessionSharedBuffer->Ref);
s->IpcSessionShared = s->IpcSessionSharedBuffer->Data;
PackAddInt64(p, "IpcSessionSharedBuffer", (UINT64)s->IpcSessionSharedBuffer);
} }
if (s->UdpAccel != NULL) if (s->UdpAccel != NULL)
{ {
// UDP acceleration function // UDP acceleration function
PackAddBool(p, "use_udp_acceleration", true); PackAddBool(p, "use_udp_acceleration", true);
PackAddInt(p, "udp_acceleration_version", s->UdpAccel->Version);
PackAddIp(p, "udp_acceleration_server_ip", &s->UdpAccel->MyIp); PackAddIp(p, "udp_acceleration_server_ip", &s->UdpAccel->MyIp);
PackAddInt(p, "udp_acceleration_server_port", s->UdpAccel->MyPort); PackAddInt(p, "udp_acceleration_server_port", s->UdpAccel->MyPort);
PackAddData(p, "udp_acceleration_server_key", s->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE); PackAddData(p, "udp_acceleration_server_key", s->UdpAccel->MyKey, sizeof(s->UdpAccel->MyKey));
PackAddData(p, "udp_acceleration_server_key_v2", s->UdpAccel->MyKey_V2, sizeof(s->UdpAccel->MyKey_V2));
PackAddInt(p, "udp_acceleration_server_cookie", s->UdpAccel->MyCookie); PackAddInt(p, "udp_acceleration_server_cookie", s->UdpAccel->MyCookie);
PackAddInt(p, "udp_acceleration_client_cookie", s->UdpAccel->YourCookie); PackAddInt(p, "udp_acceleration_client_cookie", s->UdpAccel->YourCookie);
PackAddBool(p, "udp_acceleration_use_encryption", !s->UdpAccel->PlainTextMode); PackAddBool(p, "udp_acceleration_use_encryption", !s->UdpAccel->PlainTextMode);
@ -5065,9 +5197,35 @@ PACK *PackWelcome(SESSION *s)
// Allow bulk transfer on R-UDP // Allow bulk transfer on R-UDP
PackAddBool(p, "enable_bulk_on_rudp", true); PackAddBool(p, "enable_bulk_on_rudp", true);
PackAddBool(p, "enable_hmac_on_bulk_of_rudp", s->EnableHMacOnBulkOfRUDP); PackAddBool(p, "enable_hmac_on_bulk_of_rudp", s->EnableHMacOnBulkOfRUDP);
PackAddInt(p, "rudp_bulk_version", s->BulkOnRUDPVersion);
PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE); if (s->BulkOnRUDPVersion == 2)
PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE); {
PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, RUDP_BULK_KEY_SIZE_V2);
s->Connection->FirstSock->BulkRecvKey->Size = RUDP_BULK_KEY_SIZE_V2;
PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, RUDP_BULK_KEY_SIZE_V2);
s->Connection->FirstSock->BulkSendKey->Size = RUDP_BULK_KEY_SIZE_V2;
}
else
{
PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE);
s->Connection->FirstSock->BulkRecvKey->Size = SHA1_SIZE;
PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE);
s->Connection->FirstSock->BulkSendKey->Size = SHA1_SIZE;
}
// Backup R-UDP bulk send/recv keys for additional connections
Copy(s->BulkSendKey, s->Connection->FirstSock->BulkSendKey->Data,
s->Connection->FirstSock->BulkSendKey->Size);
s->BulkSendKeySize = s->Connection->FirstSock->BulkSendKey->Size;
Copy(s->BulkRecvKey, s->Connection->FirstSock->BulkRecvKey->Data,
s->Connection->FirstSock->BulkRecvKey->Size);
s->BulkRecvKeySize = s->Connection->FirstSock->BulkRecvKey->Size;
} }
if (s->IsAzureSession) if (s->IsAzureSession)
@ -5442,6 +5600,8 @@ bool ClientUploadAuth(CONNECTION *c)
PackAddBool(p, "use_udp_acceleration", true); PackAddBool(p, "use_udp_acceleration", true);
PackAddInt(p, "udp_acceleration_version", c->Session->UdpAccel->Version);
Copy(&my_ip, &c->Session->UdpAccel->MyIp, sizeof(IP)); Copy(&my_ip, &c->Session->UdpAccel->MyIp, sizeof(IP));
if (IsLocalHostIP(&my_ip)) if (IsLocalHostIP(&my_ip))
{ {
@ -5457,11 +5617,15 @@ bool ClientUploadAuth(CONNECTION *c)
PackAddIp(p, "udp_acceleration_client_ip", &my_ip); PackAddIp(p, "udp_acceleration_client_ip", &my_ip);
PackAddInt(p, "udp_acceleration_client_port", c->Session->UdpAccel->MyPort); PackAddInt(p, "udp_acceleration_client_port", c->Session->UdpAccel->MyPort);
PackAddData(p, "udp_acceleration_client_key", c->Session->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE); PackAddData(p, "udp_acceleration_client_key", c->Session->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
PackAddData(p, "udp_acceleration_client_key_v2", c->Session->UdpAccel->MyKey_V2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
PackAddBool(p, "support_hmac_on_udp_acceleration", true); PackAddBool(p, "support_hmac_on_udp_acceleration", true);
PackAddBool(p, "support_udp_accel_fast_disconnect_detect", true); PackAddBool(p, "support_udp_accel_fast_disconnect_detect", true);
PackAddInt(p, "udp_acceleration_max_version", 2);
} }
PackAddInt(p, "rudp_bulk_max_version", 2);
// Brand string for the connection limit // Brand string for the connection limit
{ {
char *branded_ctos = _SS("BRANDED_C_TO_S"); char *branded_ctos = _SS("BRANDED_C_TO_S");
@ -5767,14 +5931,31 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
} }
else else
{ {
if (StrCmpi(h->Target, "/") == 0) if (StrCmpi(h->Target, "/") == 0)
{ {
// Root directory // Root directory
BUF *b = NULL;
*error_detail_str = "HTTP_ROOT"; *error_detail_str = "HTTP_ROOT";
if (server->DisableJsonRpcWebApi == false)
{
b = ReadDump("|wwwroot\\index.html");
}
if (b != NULL)
{
FreeHttpHeader(h);
h = NewHttpHeader("HTTP/1.1", "202", "OK");
AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE4));
AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
PostHttp(c->FirstSock, h, b->Buf, b->Size);
FreeBuf(b);
}
else
{ {
// Other than free version
HttpSendForbidden(c->FirstSock, h->Target, ""); HttpSendForbidden(c->FirstSock, h->Target, "");
} }
} }

View File

@ -221,7 +221,7 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size)
EAP_PEAP *send_peap_message; EAP_PEAP *send_peap_message;
UINT sz; UINT sz;
sz = ReadBuf(buf, tmp, 200); sz = ReadBuf(buf, tmp, sizeof(tmp));
if (sz == 0) if (sz == 0)
{ {
@ -1856,10 +1856,11 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui));
// MS-RAS-Vendor // MS-RAS-Vendor
RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_VERSION, ms_ras_version, StrLen(ms_ras_version)); ui = Endian32(RADIUS_VENDOR_MICROSOFT);
RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_VENDOR, &ui, sizeof(ui));
// MS-RAS-Version // MS-RAS-Version
RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_VERSION, ms_ras_version, StrLen(ms_ras_version));
// NAS-Port-Type // NAS-Port-Type
ui = Endian32(5); ui = Endian32(5);

View File

@ -103,7 +103,7 @@ void SessionMain(SESSION *s)
s->LastCommTime = Tick64(); s->LastCommTime = Tick64();
if (s->ServerMode == false) if (s->ServerMode == false)
{ {
s->NextConnectionTime = Tick64() + s->ClientOption->AdditionalConnectionInterval * (UINT64)1000; s->NextConnectionTime = Tick64() + (UINT64)((UINT64)s->ClientOption->AdditionalConnectionInterval * (UINT64)1000);
} }
s->NumConnectionsEstablished++; s->NumConnectionsEstablished++;
@ -900,7 +900,7 @@ void ClientAdditionalConnectChance(SESSION *s)
(s->NextConnectionTime <= now)) (s->NextConnectionTime <= now))
{ {
// Start the work to put an additional connection // Start the work to put an additional connection
s->NextConnectionTime = now + s->ClientOption->AdditionalConnectionInterval * (UINT64)1000U; s->NextConnectionTime = now + ((UINT64)s->ClientOption->AdditionalConnectionInterval * (UINT64)1000);
SessionAdditionalConnect(s); SessionAdditionalConnect(s);
} }
else else
@ -1293,6 +1293,8 @@ void CleanupSession(SESSION *s)
DeleteCounter(s->LoggingRecordCount); DeleteCounter(s->LoggingRecordCount);
ReleaseSharedBuffer(s->IpcSessionSharedBuffer);
Free(s); Free(s);
} }

View File

@ -157,6 +157,7 @@ struct SESSION
UINT NumDisconnected; // Number of socket disconnection UINT NumDisconnected; // Number of socket disconnection
bool NoReconnectToSession; // Disable to reconnect to the session bool NoReconnectToSession; // Disable to reconnect to the session
char UnderlayProtocol[64]; // Physical communication protocol char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol details
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */ /* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection
UINT64 CurrentConnectionEstablishTime; // Completion time of this connection UINT64 CurrentConnectionEstablishTime; // Completion time of this connection
@ -167,10 +168,12 @@ struct SESSION
bool IsRUDPSession; // Whether R-UDP session bool IsRUDPSession; // Whether R-UDP session
UINT RUdpMss; // The value of the MSS should be applied while the R-UDP is used UINT RUdpMss; // The value of the MSS should be applied while the R-UDP is used
bool EnableBulkOnRUDP; // Allow the bulk transfer in the R-UDP session bool EnableBulkOnRUDP; // Allow the bulk transfer in the R-UDP session
UINT BulkOnRUDPVersion; // RUDP Bulk version
bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session
bool EnableUdpRecovery; // Enable the R-UDP recovery bool EnableUdpRecovery; // Enable the R-UDP recovery
bool UseUdpAcceleration; // Use of UDP acceleration mode bool UseUdpAcceleration; // Use of UDP acceleration mode
UINT UdpAccelerationVersion; // UDP acceleration version
bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode
UDP_ACCEL *UdpAccel; // UDP acceleration UDP_ACCEL *UdpAccel; // UDP acceleration
bool IsUsingUdpAcceleration; // Flag of whether the UDP acceleration is used bool IsUsingUdpAcceleration; // Flag of whether the UDP acceleration is used
@ -210,6 +213,11 @@ struct SESSION
char FirstTimeHttpRedirectUrl[128]; // URL for redirection only the first time char FirstTimeHttpRedirectUrl[128]; // URL for redirection only the first time
UINT FirstTimeHttpAccessCheckIp; // IP address for access checking UINT FirstTimeHttpAccessCheckIp; // IP address for access checking
UCHAR BulkSendKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Send Key
UINT BulkSendKeySize; // RUDP Bulk Send Key size
UCHAR BulkRecvKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Recv Key
UINT BulkRecvKeySize; // RUDP Bulk Recv Key size
// To examine the maximum number of allowed logging target packets per minute // To examine the maximum number of allowed logging target packets per minute
UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time
UINT CurrentNumPackets; // Current number of packets UINT CurrentNumPackets; // Current number of packets
@ -219,6 +227,9 @@ struct SESSION
UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash
bool *NicDownOnDisconnect; // Pointer to client configuration parameter. NULL for non-clients. bool *NicDownOnDisconnect; // Pointer to client configuration parameter. NULL for non-clients.
SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session
IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // Shared data between IPC and Session
}; };
// Password dialog // Password dialog

View File

@ -253,7 +253,7 @@ void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b)
return; return;
} }
UdpAccelSend(a, b->Buf, b->Size, b->Compressed, a->MaxUdpPacketSize, b->PriorityQoS); UdpAccelSend(a, b->Buf, b->Size, b->Compressed ? 1 : 0, a->MaxUdpPacketSize, b->PriorityQoS);
} }
// Calculate the best MSS // Calculate the best MSS
@ -285,7 +285,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// IV // IV
ret -= UDP_ACCELERATION_PACKET_IV_SIZE; ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
} }
// Cookie // Cookie
@ -306,7 +306,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// Verify // Verify
ret -= UDP_ACCELERATION_PACKET_IV_SIZE; ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
} }
// Ethernet header (communication packets) // Ethernet header (communication packets)
@ -322,19 +322,13 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
} }
// Send // Send
void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority) void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority)
{ {
UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE]; UCHAR buffer[UDP_ACCELERATION_TMP_BUF_SIZE];
UCHAR *buf; UCHAR *buf = buffer;
UINT size; UINT size = 0;
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; UINT64 tmp;
UINT64 ui64; UINT ret;
USHORT us;
UCHAR c;
UINT current_size;
UINT ui32;
bool fatal_error = false;
UINT r;
// Validate arguments // Validate arguments
if (a == NULL || (data_size != 0 && data == NULL)) if (a == NULL || (data_size != 0 && data == NULL))
{ {
@ -345,171 +339,167 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
max_size = INFINITE; max_size = INFINITE;
} }
buf = tmp;
size = 0;
// IV
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// IV if (a->Version > 1)
Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE);
buf += UDP_ACCELERATION_PACKET_IV_SIZE;
size += UDP_ACCELERATION_PACKET_IV_SIZE;
// Calculate the key
UdpAccelCalcKey(key, a->MyKey, a->NextIv);
if (false)
{ {
char tmp1[256]; Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
char tmp2[256];
char tmp3[256]; buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey)); size += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); }
BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); else
Debug("My Key : %s\n" {
"IV : %s\n" Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
"Comm Key: %s\n",
tmp1, tmp2, tmp3); buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
} }
} }
// Cookie // Cookie
ui32 = Endian32(a->YourCookie); tmp = Endian32(a->YourCookie);
Copy(buf, &ui32, sizeof(UINT)); Copy(buf, &tmp, sizeof(UINT));
buf += sizeof(UINT); buf += sizeof(UINT);
size += sizeof(UINT); size += sizeof(UINT);
// My Tick // My tick
ui64 = Endian64(a->Now == 0 ? 1ULL : a->Now); tmp = Endian64(a->Now == 0 ? 1ULL : a->Now);
Copy(buf, &ui64, sizeof(UINT64)); Copy(buf, &tmp, sizeof(UINT64));
buf += sizeof(UINT64); buf += sizeof(UINT64);
size += sizeof(UINT64); size += sizeof(UINT64);
// Your Tick // Your tick
ui64 = Endian64(a->LastRecvYourTick); tmp = Endian64(a->LastRecvYourTick);
Copy(buf, &ui64, sizeof(UINT64)); Copy(buf, &tmp, sizeof(UINT64));
buf += sizeof(UINT64); buf += sizeof(UINT64);
size += sizeof(UINT64); size += sizeof(UINT64);
// Size // Size
us = Endian16(data_size); tmp = Endian16(data_size);
Copy(buf, &us, sizeof(USHORT)); Copy(buf, &tmp, sizeof(USHORT));
buf += sizeof(USHORT); buf += sizeof(USHORT);
size += sizeof(USHORT); size += sizeof(USHORT);
// Compress Flag // Flag
c = (compressed ? 1 : 0); Copy(buf, &flag, sizeof(UCHAR));
Copy(buf, &c, sizeof(UCHAR));
buf += sizeof(UCHAR); buf += sizeof(UCHAR);
size += sizeof(UCHAR); size += sizeof(UCHAR);
// Data // Data
if (data_size >= 1) Copy(buf, data, data_size);
{ buf += data_size;
Copy(buf, data, data_size); size += data_size;
buf += data_size;
size += data_size;
}
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0}; // Add padding to make protocol identification harder to accomplish
CRYPT *c; const UINT current_total_size = size + (a->Version > 1 ? UDP_ACCELERATION_PACKET_MAC_SIZE_V2 : UDP_ACCELERATION_PACKET_IV_SIZE_V1);
if (current_total_size < max_size)
current_size = UDP_ACCELERATION_PACKET_IV_SIZE + sizeof(UINT) + sizeof(UINT64) * 2 +
sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE;
if (current_size < max_size)
{ {
// Padding
UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE]; UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE); UINT pad_size = MIN(max_size - current_total_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
pad_size = rand() % pad_size; pad_size = rand() % pad_size;
Zero(pad, sizeof(pad)); Zero(pad, sizeof(pad));
Copy(buf, pad, pad_size); Copy(buf, pad, pad_size);
buf += pad_size; buf += pad_size;
size += pad_size; size += pad_size;
} }
// Verify if (a->Version > 1)
Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE); {
buf += UDP_ACCELERATION_PACKET_IV_SIZE; const UINT inner_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size += UDP_ACCELERATION_PACKET_IV_SIZE; UCHAR *inner = buffer + UDP_ACCELERATION_PACKET_IV_SIZE_V2;
// Encryption ret = CipherProcessAead(a->CipherEncrypt, a->NextIv_V2, inner + inner_size, UDP_ACCELERATION_PACKET_MAC_SIZE_V2, inner, inner, inner_size, NULL, 0);
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); if (ret == 0)
Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE); {
FreeCrypt(c); Debug("UdpAccelSend(): CipherProcessAead() failed!\n");
return;
}
// Next Iv Copy(a->NextIv_V2, inner, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE);
// Tag (appended to the buffer by CipherProcessAead())
size += UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
}
else
{
UCHAR *inner = buffer + UDP_ACCELERATION_PACKET_IV_SIZE_V1;
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
const UINT inner_size = size; // We don't have to subtract because we add below
CRYPT *c;
// Simple integrity check system: we fill some bytes with zeroes.
// The remote host verifies whether all the zeroes are present.
Zero(buf, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
UdpAccelCalcKeyV1(key, a->MyKey, a->NextIv);
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
Encrypt(c, inner, inner, inner_size);
FreeCrypt(c);
Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
}
} }
// Send
SetSockHighPriority(a->UdpSock, high_priority); SetSockHighPriority(a->UdpSock, high_priority);
r = SendTo(a->UdpSock, &a->YourIp, a->YourPort, tmp, size); ret = SendTo(a->UdpSock, &a->YourIp, a->YourPort, buffer, size);
if (r == 0 && a->UdpSock->IgnoreSendErr == false) if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
{
fatal_error = true;
Debug("Error: SendTo: %r %u %u\n", &a->YourIp, a->YourPort, size);
WHERE;
}
if (data_size == 0)
{
if (UdpAccelIsSendReady(a, true) == false)
{
if ((a->YourPortByNatTServer != 0) && (a->YourPort != a->YourPortByNatTServer))
{
r = SendTo(a->UdpSock, &a->YourIp, a->YourPortByNatTServer, tmp, size);
if (r == 0 && a->UdpSock->IgnoreSendErr == false)
{
fatal_error = true;
WHERE;
}
}
}
}
if (data_size == 0)
{
if (IsZeroIP(&a->YourIp2) == false && CmpIpAddr(&a->YourIp, &a->YourIp2) != 0)
{
if (UdpAccelIsSendReady(a, true) == false)
{
// When the KeepAlive, if the opponent may be behind a NAT,
// send the packet to the IP address of outside of the NAT
r = SendTo(a->UdpSock, &a->YourIp2, a->YourPort, tmp, size);
if (r == 0 && a->UdpSock->IgnoreSendErr == false)
{
fatal_error = true;
WHERE;
}
if ((a->YourPortByNatTServer != 0) && (a->YourPort != a->YourPortByNatTServer))
{
r = SendTo(a->UdpSock, &a->YourIp2, a->YourPortByNatTServer, tmp, size);
if (r == 0 && a->UdpSock->IgnoreSendErr == false)
{
fatal_error = true;
WHERE;
}
}
}
}
}
if (fatal_error)
{ {
a->FatalError = true; a->FatalError = true;
WHERE; Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPort, size);
return;
} }
//Debug("UDP Send: %u\n", size); if (data_size > 0 || UdpAccelIsSendReady(a, true))
{
return;
}
if (a->YourPortByNatTServer != 0 && a->YourPortByNatTServer != a->YourPort)
{
ret = SendTo(a->UdpSock, &a->YourIp, a->YourPortByNatTServer, buffer, size);
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
{
a->FatalError = true;
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPortByNatTServer, size);
return;
}
}
if (UdpAccelIsSendReady(a, true))
{
return;
}
if (IsZeroIP(&a->YourIp2) == false && CmpIpAddr(&a->YourIp, &a->YourIp2) != 0)
{
// We sent the packet, but the remote host didn't reply.
// It may be behind a NAT, let's try to send the packet to the alternative IP address.
ret = SendTo(a->UdpSock, &a->YourIp2, a->YourPort, buffer, size);
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
{
a->FatalError = true;
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp2, a->YourPort, size);
return;
}
if (a->YourPortByNatTServer != 0 && a->YourPortByNatTServer != a->YourPort)
{
ret = SendTo(a->UdpSock, &a->YourIp2, a->YourPortByNatTServer, buffer, size);
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
{
a->FatalError = true;
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp2, a->YourPortByNatTServer, size);
return;
}
}
}
} }
// Determine whether transmission is possible // Determine whether transmission is possible
@ -570,15 +560,11 @@ bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive)
// Process the received packet // Process the received packet
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port) BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port)
{ {
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE];
UCHAR *iv;
CRYPT *c;
UINT64 my_tick, your_tick; UINT64 my_tick, your_tick;
UINT inner_size; UINT inner_size;
UCHAR *inner_data = NULL; UCHAR *inner_data = NULL;
UINT pad_size;
UCHAR *verify;
bool compress_flag; bool compress_flag;
UCHAR raw_flag;
BLOCK *b = NULL; BLOCK *b = NULL;
UINT cookie; UINT cookie;
// Validate arguments // Validate arguments
@ -589,36 +575,54 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// IV UCHAR *iv = buf;
if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
if (a->Version > 1)
{ {
return NULL; UINT data_size;
if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2)
{
return NULL;
}
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2;
if (size < UDP_ACCELERATION_PACKET_MAC_SIZE_V2)
{
return NULL;
}
data_size = size - UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
if (CipherProcessAead(a->CipherDecrypt, iv, buf + data_size, UDP_ACCELERATION_PACKET_MAC_SIZE_V2, buf, buf, data_size, NULL, 0) == 0)
{
Debug("UdpAccelProcessRecvPacket(): CipherProcessAead() failed!\n");
return NULL;
}
size -= UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
} }
iv = buf; else
buf += UDP_ACCELERATION_PACKET_IV_SIZE;
size -= UDP_ACCELERATION_PACKET_IV_SIZE;
// Calculate the key
UdpAccelCalcKey(key, a->YourKey, iv);
if (false)
{ {
char tmp1[256]; UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
char tmp2[256]; CRYPT *c;
char tmp3[256];
BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey));
BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE);
BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
Debug("Your Key: %s\n"
"IV : %s\n"
"Comm Key: %s\n",
tmp1, tmp2, tmp3);
}
// Decryption if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); {
Encrypt(c, buf, buf, size); return NULL;
FreeCrypt(c); }
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
UdpAccelCalcKeyV1(key, a->YourKey, iv);
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
Encrypt(c, buf, buf, size);
FreeCrypt(c);
}
} }
// Cookie // Cookie
@ -635,7 +639,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return NULL; return NULL;
} }
// My Tick // My tick
if (size < sizeof(UINT64)) if (size < sizeof(UINT64))
{ {
return NULL; return NULL;
@ -644,7 +648,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(UINT64); buf += sizeof(UINT64);
size -= sizeof(UINT64); size -= sizeof(UINT64);
// Your Tick // Your tick
if (size < sizeof(UINT64)) if (size < sizeof(UINT64))
{ {
return NULL; return NULL;
@ -653,7 +657,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(UINT64); buf += sizeof(UINT64);
size -= sizeof(UINT64); size -= sizeof(UINT64);
// inner_size // Inner data size
if (size < sizeof(USHORT)) if (size < sizeof(USHORT))
{ {
return NULL; return NULL;
@ -662,12 +666,20 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(USHORT); buf += sizeof(USHORT);
size -= sizeof(USHORT); size -= sizeof(USHORT);
// compress_flag // Flag
if (size < sizeof(UCHAR)) if (size < sizeof(UCHAR))
{ {
return NULL; return NULL;
} }
compress_flag = *((UCHAR *)buf); if (a->ReadRawFlagMode == false)
{
compress_flag = *((UCHAR *)buf);
}
else
{
raw_flag = *((UCHAR *)buf);
}
buf += sizeof(UCHAR); buf += sizeof(UCHAR);
size -= sizeof(UCHAR); size -= sizeof(UCHAR);
@ -676,7 +688,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return NULL; return NULL;
} }
// inner_data // Inner_data
if (inner_size >= 1) if (inner_size >= 1)
{ {
inner_data = buf; inner_data = buf;
@ -686,26 +698,29 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// padding // Verify packet integrity
if (size < UDP_ACCELERATION_PACKET_IV_SIZE) if (a->Version == 1)
{ {
return false; UINT pad_size;
}
pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE;
buf += pad_size;
size -= pad_size;
// verify if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
if (size != UDP_ACCELERATION_PACKET_IV_SIZE) {
{ return false;
return NULL; }
}
verify = buf; pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1;
buf += pad_size;
size -= pad_size;
if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false) if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{ {
return NULL; return NULL;
}
if (IsZero(buf, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false)
{
return NULL;
}
} }
} }
@ -722,7 +737,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (inner_size >= 1) if (inner_size >= 1)
{ {
b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0); b = NewBlock(Clone(inner_data, inner_size), inner_size, a->ReadRawFlagMode == false ? (compress_flag ? -1 : 0) : 0);
if (a->ReadRawFlagMode)
{
b->RawFlagRetUdpAccel = raw_flag;
}
} }
if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick) if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick)
@ -751,18 +770,18 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return b; return b;
} }
// Calculate the key // Calculate V1 key
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv) void UdpAccelCalcKeyV1(UCHAR *key, UCHAR *common_key, UCHAR *iv)
{ {
UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE + UDP_ACCELERATION_PACKET_IV_SIZE]; UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE_V1 + UDP_ACCELERATION_PACKET_IV_SIZE_V1];
// Validate arguments // Validate arguments
if (key == NULL || common_key == NULL || iv == NULL) if (key == NULL || common_key == NULL || iv == NULL)
{ {
return; return;
} }
Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE); Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE, iv, UDP_ACCELERATION_PACKET_IV_SIZE); Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
Sha1(key, tmp, sizeof(tmp)); Sha1(key, tmp, sizeof(tmp));
} }
@ -790,15 +809,25 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
} }
IPToStr(tmp, sizeof(tmp), client_ip); IPToStr(tmp, sizeof(tmp), client_ip);
Debug("UdpAccelInitServer: client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, client_port, Debug("UdpAccelInitServer(): version: %u, client IP: %s, client port: %u, server cookie: %u, client cookie: %u\n", a->Version, tmp, client_port, a->MyCookie, a->YourCookie);
a->MyCookie, a->YourCookie);
if (IsIP6(client_ip) != a->IsIPv6) if (IsIP6(client_ip) != a->IsIPv6)
{ {
return false; return false;
} }
Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE); if (a->Version > 1)
{
a->CipherEncrypt = NewCipher("ChaCha20-Poly1305");
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
SetCipherKey(a->CipherDecrypt, client_key, false);
}
else
{
Copy(a->YourKey, client_key, sizeof(a->YourKey));
}
Copy(&a->YourIp, client_ip, sizeof(IP)); Copy(&a->YourIp, client_ip, sizeof(IP));
Copy(&a->YourIp2, client_ip_2, sizeof(IP)); Copy(&a->YourIp2, client_ip_2, sizeof(IP));
@ -822,14 +851,25 @@ bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT ser
} }
IPToStr(tmp, sizeof(tmp), server_ip); IPToStr(tmp, sizeof(tmp), server_ip);
Debug("UdpAccelInitClient: server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, server_port, server_cookie, client_cookie); Debug("UdpAccelInitClient(): version: %u, client IP: %s, client port: %u, server cookie: %u, client cookie: %u\n", a->Version, tmp, server_port, server_cookie, client_cookie);
if (IsIP6(server_ip) != a->IsIPv6) if (IsIP6(server_ip) != a->IsIPv6)
{ {
return false; return false;
} }
Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE); if (a->Version > 1)
{
a->CipherEncrypt = NewCipher("ChaCha20-Poly1305");
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
SetCipherKey(a->CipherDecrypt, server_key, false);
}
else
{
Copy(a->YourKey, server_key, sizeof(a->YourKey));
}
Copy(&a->YourIp, server_ip, sizeof(IP)); Copy(&a->YourIp, server_ip, sizeof(IP));
Copy(&a->YourIp2, server_ip_2, sizeof(IP)); Copy(&a->YourIp2, server_ip_2, sizeof(IP));
@ -911,6 +951,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->NoNatT = no_nat_t; a->NoNatT = no_nat_t;
a->Version = 1;
a->NatT_TranId = Rand64(); a->NatT_TranId = Rand64();
@ -922,8 +963,9 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->Now = Tick64(); a->Now = Tick64();
a->UdpSock = s; a->UdpSock = s;
Rand(a->MyKey, sizeof(a->MyKey)); Rand(a->MyKey, sizeof(a->MyKey));
Rand(a->YourKey, sizeof(a->YourKey)); Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
Copy(&a->MyIp, ip, sizeof(IP)); Copy(&a->MyIp, ip, sizeof(IP));
a->MyPort = s->LocalPort; a->MyPort = s->LocalPort;
@ -938,6 +980,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->RecvBlockQueue = NewQueue(); a->RecvBlockQueue = NewQueue();
Rand(a->NextIv, sizeof(a->NextIv)); Rand(a->NextIv, sizeof(a->NextIv));
Rand(a->NextIv_V2, sizeof(a->NextIv_V2));
do do
{ {
@ -1091,6 +1134,8 @@ void FreeUdpAccel(UDP_ACCEL *a)
ReleaseCedar(a->Cedar); ReleaseCedar(a->Cedar);
FreeCipher(a->CipherEncrypt);
FreeCipher(a->CipherDecrypt);
Free(a); Free(a);
} }

View File

@ -9,9 +9,14 @@
#define UDPACCEL_H #define UDPACCEL_H
// Constants // Constants
#define UDP_ACCELERATION_COMMON_KEY_SIZE 20 // Common key size #define UDP_ACCELERATION_COMMON_KEY_SIZE_V1 20 // V1: Common key size
#define UDP_ACCELERATION_PACKET_KEY_SIZE 20 // Key size for the packet #define UDP_ACCELERATION_PACKET_KEY_SIZE_V1 20 // V1: Key size for the packet
#define UDP_ACCELERATION_PACKET_IV_SIZE 20 // IV size for the packet #define UDP_ACCELERATION_PACKET_IV_SIZE_V1 20 // V1: IV size for the packet
#define UDP_ACCELERATION_COMMON_KEY_SIZE_V2 128 // V2: Common key size
#define UDP_ACCELERATION_PACKET_IV_SIZE_V2 12 // V2: IV size for the packet
#define UDP_ACCELERATION_PACKET_MAC_SIZE_V2 16 // V2: MAC size for the packet
#define UDP_ACCELERATION_TMP_BUF_SIZE 2048 // Temporary buffer size #define UDP_ACCELERATION_TMP_BUF_SIZE 2048 // Temporary buffer size
#define UDP_ACCELERATION_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds) #define UDP_ACCELERATION_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds)
@ -45,8 +50,10 @@ struct UDP_ACCEL
bool ClientMode; // Whether client mode bool ClientMode; // Whether client mode
bool IsInCedarPortList; // Whether included in the port list of the Cedar bool IsInCedarPortList; // Whether included in the port list of the Cedar
UINT64 Now; // Current time UINT64 Now; // Current time
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Submit-direction common key CIPHER *CipherEncrypt; // Encryption context
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Receiving-direction common key CIPHER *CipherDecrypt; // Decryption context
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Send-direction common key
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Receive-direction common key
SOCK *UdpSock; // UDP socket SOCK *UdpSock; // UDP socket
UINT MyPort; // My port number UINT MyPort; // My port number
UINT YourPort; // Port number of the other party UINT YourPort; // Port number of the other party
@ -63,7 +70,7 @@ struct UDP_ACCEL
UINT64 LastSetSrcIpAndPortTick; // Opponent's tick ??value at the time of storing the IP address and port number of the opponent at the end UINT64 LastSetSrcIpAndPortTick; // Opponent's tick ??value at the time of storing the IP address and port number of the opponent at the end
UINT64 LastRecvTick; // Tick when data has received at the end UINT64 LastRecvTick; // Tick when data has received at the end
UINT64 NextSendKeepAlive; // Next time to send a KeepAlive packet UINT64 NextSendKeepAlive; // Next time to send a KeepAlive packet
UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE]; // IV to be used next UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE_V1]; // IV to be used next
UINT MyCookie; // My cookie UINT MyCookie; // My cookie
UINT YourCookie; // Cookie of the other party UINT YourCookie; // Cookie of the other party
bool Inited; // Initialized flag bool Inited; // Initialized flag
@ -94,6 +101,10 @@ struct UDP_ACCEL
UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission) UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission)
UINT UdpIpQueryPacketSize; // Query packet data size (final transmission) UINT UdpIpQueryPacketSize; // Query packet data size (final transmission)
UCHAR UdpHostUniqueKey[SHA1_SIZE]; // Unique key for UDP self endpoint query UCHAR UdpHostUniqueKey[SHA1_SIZE]; // Unique key for UDP self endpoint query
UINT Version; // Version
UCHAR MyKey_V2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; // Send-direction common key (version 2)
UCHAR NextIv_V2[UDP_ACCELERATION_PACKET_IV_SIZE_V2]; // IV to be used next (version 2)
bool ReadRawFlagMode; // Read raw flag mode
}; };
// Function prototype // Function prototype
@ -104,9 +115,9 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
void UdpAccelPoll(UDP_ACCEL *a); void UdpAccelPoll(UDP_ACCEL *a);
void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64); void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64);
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port); BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port);
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv); void UdpAccelCalcKeyV1(UCHAR *key, UCHAR *common_key, UCHAR *iv);
bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive); bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive);
void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority); void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority);
void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b); void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b);
UINT UdpAccelCalcMss(UDP_ACCEL *a); UINT UdpAccelCalcMss(UDP_ACCEL *a);
void NatT_GetIpThread(THREAD *thread, void *param); void NatT_GetIpThread(THREAD *thread, void *param);

View File

@ -39,7 +39,7 @@ typedef struct x509_crl_st X509_CRL;
#define BUF_SIZE 512 #define BUF_SIZE 512
// Support Windows OS list // Support Windows OS list
#define SUPPORTED_WINDOWS_LIST "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016" #define SUPPORTED_WINDOWS_LIST "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016 / Server 2019"
// Infinite // Infinite
#ifndef WINDOWS_H #ifndef WINDOWS_H

View File

@ -2397,65 +2397,109 @@ void RUDPInterruptProc(RUDP_STACK *r)
void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size) void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
{ {
UCHAR *buf; UCHAR *buf;
UINT buf_size; UINT i, icmp_type, buf_size, padding_size;
UINT padding_size;
UINT i;
CRYPT *c;
UCHAR crypt_key_src[SHA1_SIZE * 2];
UCHAR crypt_key[SHA1_SIZE];
UINT icmp_type = 0;
UCHAR sign[SHA1_SIZE];
UCHAR iv[SHA1_SIZE + 1];
// Validate arguments // Validate arguments
if (r == NULL || se == NULL || (data == NULL && data_size != 0)) if (r == NULL || se == NULL || (data == NULL && data_size != 0))
{ {
return; return;
} }
padding_size = Rand32() % 31 + 1; if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
buf = Malloc(buf_size);
// SEQ NO
WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo);
se->BulkNextSeqNo++;
// Data
Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size);
// Padding
for (i = 0;i < padding_size;i++)
{ {
buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size; UCHAR *tmp, iv[RUDP_BULK_IV_SIZE_V2];
} UINT size;
CIPHER *c;
// Encryption padding_size = Rand32() % 31 + 1;
Copy(iv, se->BulkNextIv, SHA1_SIZE);
Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE);
Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE);
Sha1(crypt_key, crypt_key_src, SHA1_SIZE * 2);
c = NewCrypt(crypt_key, sizeof(crypt_key));
Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size);
FreeCrypt(c);
// IV size = sizeof(UINT64) + data_size + padding_size;
Copy(buf + SHA1_SIZE, iv, SHA1_SIZE);
// Sign // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
if (se->UseHMac == false) buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
{ buf = Malloc(buf_size);
Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE);
Sha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); // IV
Copy(buf + 0, sign, SHA1_SIZE); Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2);
Copy(buf, iv, RUDP_BULK_IV_SIZE_V2);
// SEQ NO
WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo);
se->BulkNextSeqNo++;
// Data
Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size);
// Padding
for (i = 0;i < padding_size;i++)
{
buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
}
size = sizeof(UINT64) + data_size + padding_size;
tmp = buf + RUDP_BULK_IV_SIZE_V2;
// Encryption
c = NewCipher("ChaCha20-Poly1305");
SetCipherKey(c, se->BulkSendKey->Data, true);
CipherProcessAead(c, iv, tmp + size, RUDP_BULK_MAC_SIZE_V2, tmp, tmp, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
FreeCipher(c);
// Next IV
Copy(se->BulkNextIv_V2, buf + sizeof(UINT64) + data_size + padding_size, RUDP_BULK_IV_SIZE_V2);
} }
else else
{ {
HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size); UCHAR crypt_key_src[SHA1_SIZE * 2];
} UCHAR crypt_key[SHA1_SIZE];
UCHAR sign[SHA1_SIZE];
UCHAR iv[SHA1_SIZE];
CRYPT *c;
// Next IV padding_size = Rand32() % 31 + 1;
Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
buf = Malloc(buf_size);
// SEQ NO
WRITE_UINT64(buf + SHA1_SIZE + SHA1_SIZE, se->BulkNextSeqNo);
se->BulkNextSeqNo++;
// Data
Copy(buf + SHA1_SIZE + SHA1_SIZE + sizeof(UINT64), data, data_size);
// Padding
for (i = 0;i < padding_size;i++)
{
buf[SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
}
// Encryption
Copy(iv, se->BulkNextIv, SHA1_SIZE);
Copy(crypt_key_src + 0, se->BulkSendKey->Data, SHA1_SIZE);
Copy(crypt_key_src + SHA1_SIZE, iv, SHA1_SIZE);
Sha1(crypt_key, crypt_key_src, SHA1_SIZE * 2);
c = NewCrypt(crypt_key, sizeof(crypt_key));
Encrypt(c, buf + SHA1_SIZE + SHA1_SIZE, buf + SHA1_SIZE + SHA1_SIZE, sizeof(UINT64) + data_size + padding_size);
FreeCrypt(c);
// IV
Copy(buf + SHA1_SIZE, iv, SHA1_SIZE);
// Sign
if (se->UseHMac == false)
{
Copy(buf + 0, se->BulkSendKey->Data, SHA1_SIZE);
Sha1(sign, buf, SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
Copy(buf + 0, sign, SHA1_SIZE);
}
else
{
HMacSha1(buf + 0, se->BulkSendKey->Data, SHA1_SIZE, buf + SHA1_SIZE, SHA1_SIZE + sizeof(UINT64) + data_size + padding_size);
}
// Next IV
Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
}
if (r->Protocol == RUDP_PROTOCOL_ICMP) if (r->Protocol == RUDP_PROTOCOL_ICMP)
{ {
@ -2465,6 +2509,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
{ {
icmp_type = se->Dns_TranId; icmp_type = se->Dns_TranId;
} }
RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type); RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
Free(buf); Free(buf);
@ -2528,14 +2573,17 @@ SOCK *AcceptRUDP(SOCK *s)
{ {
case RUDP_PROTOCOL_UDP: case RUDP_PROTOCOL_UDP:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/UDP");
break; break;
case RUDP_PROTOCOL_DNS: case RUDP_PROTOCOL_DNS:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/DNS");
break; break;
case RUDP_PROTOCOL_ICMP: case RUDP_PROTOCOL_ICMP:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/ICMP");
break; break;
} }
@ -2588,40 +2636,71 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
} }
// Verification signature (bulk packet) // Verification signature (bulk packet)
if (se->UseHMac == false) if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
{ {
Copy(sign, p, SHA1_SIZE); UCHAR *iv = p;
Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); CIPHER *c;
Sha1(sign2, p, recv_size);
Copy(p, sign, SHA1_SIZE);
if (Cmp(sign, sign2, SHA1_SIZE) == 0) // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
// IV
if (size < RUDP_BULK_IV_SIZE_V2)
{ {
return false;
}
iv = p;
p += RUDP_BULK_IV_SIZE_V2;
size -= RUDP_BULK_IV_SIZE_V2;
// Decrypt
if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
{
return false;
}
c = NewCipher("ChaCha20-Poly1305");
SetCipherKey(c, se->BulkRecvKey->Data, false);
size = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, r->TmpBuf, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
FreeCipher(c);
if (size == 0)
{
return false;
}
return true;
}
else
{
if (se->UseHMac == false)
{
Copy(sign, p, SHA1_SIZE);
Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
Sha1(sign2, p, recv_size);
Copy(p, sign, SHA1_SIZE);
if (Cmp(sign, sign2, SHA1_SIZE) == 0)
{
return true;
}
}
HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE);
if (Cmp(p, sign2, SHA1_SIZE) == 0)
{
se->UseHMac = true;
return true; return true;
} }
} }
HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, size - SHA1_SIZE);
if (Cmp(p, sign2, SHA1_SIZE) == 0)
{
se->UseHMac = true;
return true;
}
return false; return false;
} }
// Process the received packet (bulk) // Process the received packet (bulk)
bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size) bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
{ {
UCHAR sign[SHA1_SIZE];
UCHAR sign2[SHA1_SIZE];
UCHAR *p; UCHAR *p;
UCHAR *iv; UCHAR *iv;
UINT size; UINT size;
UCHAR keygen[SHA1_SIZE * 2];
UCHAR key[SHA1_SIZE];
CRYPT *c;
UCHAR padlen; UCHAR padlen;
UINT64 seq_no; UINT64 seq_no;
UCHAR *payload; UCHAR *payload;
@ -2639,15 +2718,85 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
return false; return false;
} }
// Validate the signature if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
if (se->UseHMac == false)
{ {
Copy(sign, p, SHA1_SIZE); UINT ret;
Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); CIPHER *c;
Sha1(sign2, p, recv_size);
Copy(p, sign, SHA1_SIZE);
if (Cmp(sign, sign2, SHA1_SIZE) != 0) // Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
// IV
if (size < RUDP_BULK_IV_SIZE_V2)
{
WHERE;
return false;
}
iv = p;
p += RUDP_BULK_IV_SIZE_V2;
size -= RUDP_BULK_IV_SIZE_V2;
// Decrypt
if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
{
WHERE;
return false;
}
c = NewCipher("ChaCha20-Poly1305");
SetCipherKey(c, se->BulkRecvKey->Data, false);
ret = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, p, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
FreeCipher(c);
if (ret == 0)
{
WHERE;
return false;
}
size -= RUDP_BULK_MAC_SIZE_V2;
// padlen
padlen = p[size - 1];
if (padlen == 0)
{
WHERE;
return false;
}
if (size < padlen)
{
WHERE;
return false;
}
size -= padlen;
}
else
{
CRYPT *c;
UCHAR sign[SHA1_SIZE], sign2[SHA1_SIZE];
UCHAR key[SHA1_SIZE], keygen[SHA1_SIZE * 2];
// Validate the signature
if (se->UseHMac == false)
{
Copy(sign, p, SHA1_SIZE);
Copy(p, se->BulkRecvKey->Data, SHA1_SIZE);
Sha1(sign2, p, recv_size);
Copy(p, sign, SHA1_SIZE);
if (Cmp(sign, sign2, SHA1_SIZE) != 0)
{
HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
if (Cmp(p, sign2, SHA1_SIZE) != 0)
{
return false;
}
else
{
se->UseHMac = true;
}
}
}
else
{ {
HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE); HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
@ -2655,61 +2804,45 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
{ {
return false; return false;
} }
else
{
se->UseHMac = true;
}
} }
else
{
}
}
else
{
HMacSha1(sign2, se->BulkRecvKey->Data, SHA1_SIZE, p + SHA1_SIZE, recv_size - SHA1_SIZE);
if (Cmp(p, sign2, SHA1_SIZE) != 0) p += SHA1_SIZE;
size -= SHA1_SIZE;
// IV
if (size < SHA1_SIZE)
{ {
return false; return false;
} }
} iv = p;
p += SHA1_SIZE;
size -= SHA1_SIZE;
p += SHA1_SIZE; // Decrypt
size -= SHA1_SIZE; if (size < 1)
{
return false;
}
Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE);
Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE);
Sha1(key, keygen, sizeof(keygen));
// IV c = NewCrypt(key, sizeof(key));
if (size < SHA1_SIZE) Encrypt(c, p, p, size);
{ FreeCrypt(c);
return false;
}
iv = p;
p += SHA1_SIZE;
size -= SHA1_SIZE;
// Decrypt // padlen
if (size < 1) padlen = p[size - 1];
{ if (padlen == 0)
return false; {
return false;
}
if (size < padlen)
{
return false;
}
size -= padlen;
} }
Copy(keygen + 0, se->BulkRecvKey->Data, SHA1_SIZE);
Copy(keygen + SHA1_SIZE, iv, SHA1_SIZE);
Sha1(key, keygen, sizeof(keygen));
c = NewCrypt(key, sizeof(key));
Encrypt(c, p, p, size);
FreeCrypt(c);
// padlen
padlen = p[size - 1];
if (padlen == 0)
{
return false;
}
if (size < padlen)
{
return false;
}
size -= padlen;
// SEQ NO // SEQ NO
seq_no = READ_UINT64(p); seq_no = READ_UINT64(p);
@ -3522,8 +3655,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your
RUDP_SESSION *se; RUDP_SESSION *se;
UCHAR key1[SHA1_SIZE]; UCHAR key1[SHA1_SIZE];
UCHAR key2[SHA1_SIZE]; UCHAR key2[SHA1_SIZE];
UCHAR bulk_send_key[SHA1_SIZE]; UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
UCHAR bulk_recv_key[SHA1_SIZE]; UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
BUF *b; BUF *b;
se = ZeroMalloc(sizeof(RUDP_SESSION)); se = ZeroMalloc(sizeof(RUDP_SESSION));
@ -3609,6 +3742,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your
se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key)); se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
Rand(se->BulkNextIv, sizeof(se->BulkNextIv)); Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
se->BulkNextSeqNo = 1; se->BulkNextSeqNo = 1;
return se; return se;
@ -12759,6 +12894,8 @@ SOCK *Accept(SOCK *sock)
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4");
return ret; return ret;
} }
@ -12869,6 +13006,8 @@ SOCK *Accept6(SOCK *sock)
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6");
return ret; return ret;
} }
@ -14070,6 +14209,7 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
if (nat_t_sock != NULL) if (nat_t_sock != NULL)
{ {
StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T); StrCpy(nat_t_sock->UnderlayProtocol, sizeof(nat_t_sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
AddProtocolDetailsStr(nat_t_sock->ProtocolDetails, sizeof(nat_t_sock->ProtocolDetails), "RUDP");
} }
Copy(ret_ip, &ip4, sizeof(IP)); Copy(ret_ip, &ip4, sizeof(IP));
@ -14294,8 +14434,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
Disconnect(p4.Result_Nat_T_Sock); Disconnect(p4.Result_Nat_T_Sock);
ReleaseSock(p4.Result_Nat_T_Sock); ReleaseSock(p4.Result_Nat_T_Sock);
StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
SOCK_UNDERLAY_NAT_T); AddProtocolDetailsStr(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/UDP");
Copy(ret_ip, &ip4, sizeof(IP)); Copy(ret_ip, &ip4, sizeof(IP));
@ -14308,8 +14448,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
Disconnect(p3.Result_Nat_T_Sock); Disconnect(p3.Result_Nat_T_Sock);
ReleaseSock(p3.Result_Nat_T_Sock); ReleaseSock(p3.Result_Nat_T_Sock);
StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_DNS);
SOCK_UNDERLAY_DNS); AddProtocolDetailsStr(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/DNS");
Copy(ret_ip, &ip4, sizeof(IP)); Copy(ret_ip, &ip4, sizeof(IP));
@ -14318,8 +14458,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
else if (p3.Ok) else if (p3.Ok)
{ {
// Use this if over ICMP success // Use this if over ICMP success
StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
SOCK_UNDERLAY_ICMP); AddProtocolDetailsStr(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), "RUDP/ICMP");
Copy(ret_ip, &ip4, sizeof(IP)); Copy(ret_ip, &ip4, sizeof(IP));
@ -14383,8 +14523,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
sock->Type = SOCK_TCP; sock->Type = SOCK_TCP;
sock->ServerMode = false; sock->ServerMode = false;
StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol), StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol), is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4);
(is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4)); AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails), is_ipv6 ? "IPv6" : "IPv4");
// Host name resolution // Host name resolution
if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), &current_ip) == false)) if (no_get_hostname || (GetHostName(tmp, sizeof(tmp), &current_ip) == false))
@ -14434,6 +14574,59 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
return sock; return sock;
} }
// Add a protocol details strings
void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str)
{
TOKEN_LIST *t1, *t2;
UINT i, j;
if (dst == NULL || str == NULL)
{
return;
}
t1 = ParseTokenWithoutNullStr(dst, " ");
t2 = ParseTokenWithoutNullStr(str, " ");
for (i = 0;i < t2->NumTokens;i++)
{
bool exists = false;
for (j = 0;j < t1->NumTokens;j++)
{
if (StrCmpi(t1->Token[j], t2->Token[i]) == 0)
{
exists = true;
break;
}
}
if (exists == false)
{
StrCat(dst, dst_size, t2->Token[i]);
StrCat(dst, dst_size, " ");
}
}
FreeToken(t1);
FreeToken(t2);
}
void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value)
{
char tmp[128];
StrCpy(tmp, sizeof(tmp), key);
StrCat(tmp, sizeof(tmp), "=");
StrCat(tmp, sizeof(tmp), value);
AddProtocolDetailsStr(dst, dst_size, tmp);
}
void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value)
{
char tmp[128];
ToStr(tmp, value);
AddProtocolDetailsKeyValueStr(dst, dst_size, key, tmp);
}
// Setting the buffer size of the socket // Setting the buffer size of the socket
bool SetSocketBufferSize(SOCKET s, bool send, UINT size) bool SetSocketBufferSize(SOCKET s, bool send, UINT size)
{ {
@ -19445,6 +19638,8 @@ SOCK *AcceptReverse(SOCK *s)
{ {
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPN Azure");
return ret; return ret;
} }
@ -19493,6 +19688,8 @@ SOCK *AcceptInProc(SOCK *s)
{ {
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC); StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc");
return ret; return ret;
} }

View File

@ -209,6 +209,7 @@ struct SOCK
UINT CurrentTtl; // Current TTL value UINT CurrentTtl; // Current TTL value
RUDP_STACK *R_UDP_Stack; // R-UDP stack RUDP_STACK *R_UDP_Stack; // R-UDP stack
char UnderlayProtocol[64]; // Underlying protocol char UnderlayProtocol[64]; // Underlying protocol
char ProtocolDetails[256]; // Protocol details
QUEUE *ReverseAcceptQueue; // Accept queue for the reverse socket QUEUE *ReverseAcceptQueue; // Accept queue for the reverse socket
EVENT *ReverseAcceptEvent; // Accept event for the reverse socket EVENT *ReverseAcceptEvent; // Accept event for the reverse socket
bool IsReverseAcceptedSocket; // Whether it is a reverse socket bool IsReverseAcceptedSocket; // Whether it is a reverse socket
@ -575,6 +576,12 @@ struct IPBLOCK
#define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication #define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication
#define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out #define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out
#define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size #define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size
#define RUDP_BULK_KEY_SIZE_MAX 128 // Bulk key size Max
#define RUDP_BULK_KEY_SIZE_V2 32 // V2: Bulk key size
#define RUDP_BULK_IV_SIZE_V2 12 // V2: Bulk IV size
#define RUDP_BULK_MAC_SIZE_V2 16 // V2: Bulk MAC size
// Maximum R-UDP packet size // Maximum R-UDP packet size
#define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255) #define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255)
#define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs #define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs
@ -663,6 +670,7 @@ struct RUDP_SESSION
UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send
bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube
UINT64 BulkRecvSeqNoMax; // Highest sequence number received UINT64 BulkRecvSeqNoMax; // Highest sequence number received
UCHAR BulkNextIv_V2[RUDP_BULK_IV_SIZE_V2]; // Next IV to the bulk send (version 2)
}; };
// NAT Traversal Server Information // NAT Traversal Server Information
@ -1238,6 +1246,9 @@ void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e);
void DebugPrintRoute(ROUTE_ENTRY *e); void DebugPrintRoute(ROUTE_ENTRY *e);
void DebugPrintRouteTable(ROUTE_TABLE *r); void DebugPrintRouteTable(ROUTE_TABLE *r);
bool IsIPv6LocalNetworkAddress(IP *ip); bool IsIPv6LocalNetworkAddress(IP *ip);
void AddProtocolDetailsStr(char *dst, UINT dst_size, char *str);
void AddProtocolDetailsKeyValueStr(char *dst, UINT dst_size, char *key, char *value);
void AddProtocolDetailsKeyValueInt(char *dst, UINT dst_size, char *key, UINT value);
#ifdef ENABLE_SSL_LOGGING #ifdef ENABLE_SSL_LOGGING
void SockEnableSslLogging(SOCK *s); void SockEnableSslLogging(SOCK *s);