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;
}
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");
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);
}
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_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_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE;
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;
// Physical communication protocol
StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol);
// Protocol details
StrCpy(st->ProtocolDetails, sizeof(st->ProtocolDetails), s->ProtocolDetails);
Trim(st->ProtocolDetails);
// UDP acceleration function
if (s->IpcSessionShared != NULL && IsEmptyStr(s->IpcSessionShared->ProtocolDetails) == false)
{
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
Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
// Policy

View File

@ -341,6 +341,7 @@ struct RPC_CLIENT_GET_CONNECTION_STATUS
bool UseCompress; // Use of compression
bool IsRUDPSession; // R-UDP session
char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol details
bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled
bool IsUsingUdpAcceleration; // Using the UDP acceleration function
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);
}
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_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;
c->CurrentSendQueueSize -= b->Size;
Free(new_buf);
}
FreeBlock(b);
@ -2682,6 +2684,8 @@ BLOCK *NewBlock(void *data, UINT size, int compress)
b = MallocFast(sizeof(BLOCK));
b->RawFlagRetUdpAccel = 0;
b->IsFlooding = false;
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 Param1; // Parameter 1
bool IsFlooding; // Is flooding packet
UCHAR RawFlagRetUdpAccel; // Raw flag returned by UDP accel
};
// Connection structure

View File

@ -5913,7 +5913,7 @@ void IntoTrafficLimiter(TRAFFIC_LIMITER *tr, PKT *p)
}
// Value increase
tr->Value += p->PacketSize * (UINT64)8;
tr->Value += (UINT64)p->PacketSize * (UINT64)8;
}
// 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;
BUF *b;
UCHAR mschap_v2_server_response_20[20];
UINT64 u64;
// Validate arguments
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);
u64 = PackGetInt64(p, "IpcSessionSharedBuffer");
ipc->IpcSessionSharedBuffer = (SHARED_BUFFER *)u64;
ipc->IpcSessionShared = ipc->IpcSessionSharedBuffer->Data;
FreePack(p);
ReleaseSock(a);
@ -591,6 +596,8 @@ void FreeIPC(IPC *ipc)
ReleaseQueue(ipc->IPv4ReceivedQueue);
ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer);
Free(ipc);
}

View File

@ -43,6 +43,14 @@ struct IPC_DHCP_RELEASE_QUEUE
UCHAR MacAddress[6];
};
// IPC_SESSION_SHARED_BUFFER_DATA
struct IPC_SESSION_SHARED_BUFFER_DATA
{
char ProtocolDetails[256];
bool EnableUdpAccel;
bool UsingUdpAccel;
};
// IPC_PARAM
struct IPC_PARAM
{
@ -106,6 +114,8 @@ struct IPC
TUBE_FLUSH_LIST *FlushList; // Tube Flush List
UCHAR MsChapV2_ServerResponse[20]; // Server response
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;
};

View File

@ -2181,7 +2181,7 @@ void MakeLogFileNameStringFromTick(LOG *g, char *str, UINT size, UINT64 tick, UI
break;
default: // Without switching
snprintf(str, size, "%s");
StrCpy(str, size, "");
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
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->ExpiresSoftTick = ike->Now + span;
//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);
if (payload == NULL)
{
return false;
break;
}
if (CompareBuf(payload->Payload.VendorId.Data, buf))

View File

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

View File

@ -1077,12 +1077,17 @@ bool ServerAccept(CONNECTION *c)
bool half_connection;
UINT adjust_mss;
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_udp_accel_fast_disconnect_detect;
bool use_hmac_on_udp_acceleration = false;
bool supress_return_pack_error = false;
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;
bool admin_mode = false;
UINT direction;
@ -1144,6 +1149,7 @@ bool ServerAccept(CONNECTION *c)
Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip));
udp_acceleration_client_port = 0;
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));
@ -1453,6 +1459,16 @@ bool ServerAccept(CONNECTION *c)
client_id = PackGetInt(p, "client_id");
adjust_mss = PackGetInt(p, "adjust_mss");
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_udp_accel_fast_disconnect_detect = PackGetBool(p, "support_udp_accel_fast_disconnect_detect");
support_bulk_on_rudp = PackGetBool(p, "support_bulk_on_rudp");
@ -1479,8 +1495,8 @@ bool ServerAccept(CONNECTION *c)
{
if (IsEmptyStr(c->InProcPrefix) == false)
{
Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol),
SOCK_UNDERLAY_INPROC_EX, c->InProcPrefix);
Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol), 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 &&
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
enable_bulk_on_rudp = true;
@ -1537,9 +1553,11 @@ bool ServerAccept(CONNECTION *c)
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
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)
if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false)
{
use_udp_acceleration_client = false;
}
@ -2807,7 +2825,8 @@ bool ServerAccept(CONNECTION *c)
// R-UDP session
s->IsRUDPSession = true;
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)
@ -2821,6 +2840,8 @@ bool ServerAccept(CONNECTION *c)
StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), c->FirstSock->UnderlayProtocol);
AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), c->FirstSock->ProtocolDetails);
if (server != NULL)
{
s->NoSendSignature = server->NoSendSignature;
@ -2849,6 +2870,22 @@ bool ServerAccept(CONNECTION *c)
s->UseUdpAcceleration = true;
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)
@ -2872,6 +2909,7 @@ bool ServerAccept(CONNECTION *c)
Debug("UseUdpAcceleration = %u\n", s->UseUdpAcceleration);
Debug("UseHMacOnUdpAcceleration = %u\n", s->UseHMacOnUdpAcceleration);
Debug("UdpAccelerationVersion = %u\n", s->UdpAccelerationVersion);
if (s->UseUdpAcceleration)
{
@ -2887,8 +2925,11 @@ bool ServerAccept(CONNECTION *c)
}
else
{
if (UdpAccelInitServer(s->UdpAccel, udp_acceleration_client_key, &udp_acceleration_client_ip, udp_acceleration_client_port,
&c->FirstSock->RemoteIP) == false)
s->UdpAccel->Version = udp_acceleration_version;
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");
s->UseUdpAcceleration = false;
@ -2902,6 +2943,12 @@ bool ServerAccept(CONNECTION *c)
}
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)
{
Debug("AdjustMSS: %u\n", s->AdjustMss);
AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails), "AdjustMSS", s->AdjustMss);
}
s->IsBridgeMode = (policy->NoBridge == false) || (policy->NoRouting == false);
@ -2957,8 +3005,7 @@ bool ServerAccept(CONNECTION *c)
{
char ip[128];
IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP);
HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort,
c->FirstSock->UnderlayProtocol);
HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort, c->FirstSock->UnderlayProtocol, c->FirstSock->ProtocolDetails);
}
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)
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);
SetTimeout(sock, CONNECTING_TIMEOUT);
direction = TCP_BOTH;
@ -3981,6 +4041,19 @@ bool ClientAdditionalConnect(CONNECTION *c, THREAD *t)
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
// Add to the TcpSockList of the connection
ts = NewTcpSock(s);
@ -4704,9 +4777,13 @@ REDIRECTED:
// Physical communication protocol
StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), s->UnderlayProtocol);
AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), s->ProtocolDetails);
if (c->Session->IsAzureSession)
{
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)
@ -4725,22 +4802,44 @@ REDIRECTED:
sess->EnableBulkOnRUDP = 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
sess->EnableHMacOnBulkOfRUDP = PackGetBool(p, "enable_hmac_on_bulk_of_rudp");
sess->BulkOnRUDPVersion = PackGetInt(p, "rudp_bulk_version");
if (PackGetBool(p, "enable_bulk_on_rudp"))
{
// Receive the key
UCHAR key_send[SHA1_SIZE];
UCHAR key_recv[SHA1_SIZE];
UCHAR key_send[RUDP_BULK_KEY_SIZE_MAX];
UCHAR key_recv[RUDP_BULK_KEY_SIZE_MAX];
if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, SHA1_SIZE) &&
PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, SHA1_SIZE))
UINT key_size = 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;
Copy(s->BulkSendKey->Data, key_send, SHA1_SIZE);
Copy(s->BulkRecvKey->Data, key_recv, SHA1_SIZE);
Copy(s->BulkSendKey->Data, key_send, key_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("EnableHMacOnBulkOfRUDP = %u\n", sess->EnableHMacOnBulkOfRUDP);
Debug("EnableUdpRecovery = %u\n", sess->EnableUdpRecovery);
Debug("BulkOnRUDPVersion = %u\n", sess->BulkOnRUDPVersion);
sess->UseUdpAcceleration = false;
sess->IsUsingUdpAcceleration = false;
@ -4763,8 +4863,14 @@ REDIRECTED:
if (PackGetBool(p, "use_udp_acceleration"))
{
UINT udp_acceleration_version = PackGetInt(p, "udp_acceleration_version");
IP udp_acceleration_server_ip;
if (udp_acceleration_version == 0)
{
udp_acceleration_version = 1;
}
sess->UdpAccelFastDisconnectDetect = PackGetBool(p, "udp_accel_fast_disconnect_detect");
if (PackGetIp(p, "udp_acceleration_server_ip", &udp_acceleration_server_ip))
@ -4778,14 +4884,18 @@ REDIRECTED:
if (udp_acceleration_server_port != 0)
{
UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE];
if (PackGetData2(p, "udp_acceleration_server_key", 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");
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)
{
IP remote_ip;
@ -4797,7 +4907,14 @@ REDIRECTED:
Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP));
}
if (UdpAccelInitClient(sess->UdpAccel, udp_acceleration_server_key,
sess->UdpAccel->Version = 1;
if (udp_acceleration_version == 2)
{
sess->UdpAccel->Version = 2;
}
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)
{
@ -4817,7 +4934,12 @@ REDIRECTED:
{
sess->UdpAccel->UseHMac = true;
}
}
AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "UDPAccel_Ver", sess->UdpAccel->Version);
AddProtocolDetailsStr(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), sess->UdpAccel->Version > 1 ? "ChaCha20-Poly1305" : "RC4");
AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "UDPAccel_MSS", UdpAccelCalcMss(sess->UdpAccel));
}
}
}
@ -5044,15 +5166,25 @@ PACK *PackWelcome(SESSION *s)
// Virtual 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)
{
// UDP acceleration function
PackAddBool(p, "use_udp_acceleration", true);
PackAddInt(p, "udp_acceleration_version", s->UdpAccel->Version);
PackAddIp(p, "udp_acceleration_server_ip", &s->UdpAccel->MyIp);
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_client_cookie", s->UdpAccel->YourCookie);
PackAddBool(p, "udp_acceleration_use_encryption", !s->UdpAccel->PlainTextMode);
@ -5065,9 +5197,35 @@ PACK *PackWelcome(SESSION *s)
// Allow bulk transfer on R-UDP
PackAddBool(p, "enable_bulk_on_rudp", true);
PackAddBool(p, "enable_hmac_on_bulk_of_rudp", s->EnableHMacOnBulkOfRUDP);
PackAddInt(p, "rudp_bulk_version", s->BulkOnRUDPVersion);
if (s->BulkOnRUDPVersion == 2)
{
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)
@ -5442,6 +5600,8 @@ bool ClientUploadAuth(CONNECTION *c)
PackAddBool(p, "use_udp_acceleration", true);
PackAddInt(p, "udp_acceleration_version", c->Session->UdpAccel->Version);
Copy(&my_ip, &c->Session->UdpAccel->MyIp, sizeof(IP));
if (IsLocalHostIP(&my_ip))
{
@ -5457,11 +5617,15 @@ bool ClientUploadAuth(CONNECTION *c)
PackAddIp(p, "udp_acceleration_client_ip", &my_ip);
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_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
{
char *branded_ctos = _SS("BRANDED_C_TO_S");
@ -5767,14 +5931,31 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
else
{
if (StrCmpi(h->Target, "/") == 0)
{
// Root directory
BUF *b = NULL;
*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, "");
}
}

View File

@ -221,7 +221,7 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size)
EAP_PEAP *send_peap_message;
UINT sz;
sz = ReadBuf(buf, tmp, 200);
sz = ReadBuf(buf, tmp, sizeof(tmp));
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));
// 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
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
ui = Endian32(5);

View File

@ -103,7 +103,7 @@ void SessionMain(SESSION *s)
s->LastCommTime = Tick64();
if (s->ServerMode == false)
{
s->NextConnectionTime = Tick64() + s->ClientOption->AdditionalConnectionInterval * (UINT64)1000;
s->NextConnectionTime = Tick64() + (UINT64)((UINT64)s->ClientOption->AdditionalConnectionInterval * (UINT64)1000);
}
s->NumConnectionsEstablished++;
@ -900,7 +900,7 @@ void ClientAdditionalConnectChance(SESSION *s)
(s->NextConnectionTime <= now))
{
// 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);
}
else
@ -1293,6 +1293,8 @@ void CleanupSession(SESSION *s)
DeleteCounter(s->LoggingRecordCount);
ReleaseSharedBuffer(s->IpcSessionSharedBuffer);
Free(s);
}

View File

@ -157,6 +157,7 @@ struct SESSION
UINT NumDisconnected; // Number of socket disconnection
bool NoReconnectToSession; // Disable to reconnect to the session
char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol details
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection
UINT64 CurrentConnectionEstablishTime; // Completion time of this connection
@ -167,10 +168,12 @@ struct SESSION
bool IsRUDPSession; // Whether R-UDP session
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
UINT BulkOnRUDPVersion; // RUDP Bulk version
bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session
bool EnableUdpRecovery; // Enable the R-UDP recovery
bool UseUdpAcceleration; // Use of UDP acceleration mode
UINT UdpAccelerationVersion; // UDP acceleration version
bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode
UDP_ACCEL *UdpAccel; // UDP acceleration
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
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
UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time
UINT CurrentNumPackets; // Current number of packets
@ -219,6 +227,9 @@ struct SESSION
UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash
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

View File

@ -253,7 +253,7 @@ void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b)
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
@ -285,7 +285,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false)
{
// IV
ret -= UDP_ACCELERATION_PACKET_IV_SIZE;
ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
}
// Cookie
@ -306,7 +306,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false)
{
// Verify
ret -= UDP_ACCELERATION_PACKET_IV_SIZE;
ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
}
// Ethernet header (communication packets)
@ -322,19 +322,13 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
}
// 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 *buf;
UINT size;
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE];
UINT64 ui64;
USHORT us;
UCHAR c;
UINT current_size;
UINT ui32;
bool fatal_error = false;
UINT r;
UCHAR buffer[UDP_ACCELERATION_TMP_BUF_SIZE];
UCHAR *buf = buffer;
UINT size = 0;
UINT64 tmp;
UINT ret;
// Validate arguments
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;
}
buf = tmp;
size = 0;
// IV
if (a->PlainTextMode == false)
{
// IV
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)
if (a->Version > 1)
{
char tmp1[256];
char tmp2[256];
char tmp3[256];
BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey));
BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE);
BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
Debug("My Key : %s\n"
"IV : %s\n"
"Comm Key: %s\n",
tmp1, tmp2, tmp3);
Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
}
else
{
Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
}
}
// Cookie
ui32 = Endian32(a->YourCookie);
Copy(buf, &ui32, sizeof(UINT));
tmp = Endian32(a->YourCookie);
Copy(buf, &tmp, sizeof(UINT));
buf += sizeof(UINT);
size += sizeof(UINT);
// My Tick
ui64 = Endian64(a->Now == 0 ? 1ULL : a->Now);
Copy(buf, &ui64, sizeof(UINT64));
// My tick
tmp = Endian64(a->Now == 0 ? 1ULL : a->Now);
Copy(buf, &tmp, sizeof(UINT64));
buf += sizeof(UINT64);
size += sizeof(UINT64);
// Your Tick
ui64 = Endian64(a->LastRecvYourTick);
Copy(buf, &ui64, sizeof(UINT64));
// Your tick
tmp = Endian64(a->LastRecvYourTick);
Copy(buf, &tmp, sizeof(UINT64));
buf += sizeof(UINT64);
size += sizeof(UINT64);
// Size
us = Endian16(data_size);
Copy(buf, &us, sizeof(USHORT));
tmp = Endian16(data_size);
Copy(buf, &tmp, sizeof(USHORT));
buf += sizeof(USHORT);
size += sizeof(USHORT);
// Compress Flag
c = (compressed ? 1 : 0);
Copy(buf, &c, sizeof(UCHAR));
// Flag
Copy(buf, &flag, sizeof(UCHAR));
buf += sizeof(UCHAR);
size += sizeof(UCHAR);
// Data
if (data_size >= 1)
{
Copy(buf, data, data_size);
buf += data_size;
size += data_size;
}
if (a->PlainTextMode == false)
{
static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0};
CRYPT *c;
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)
// Add padding to make protocol identification harder to accomplish
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)
{
// Padding
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;
Zero(pad, sizeof(pad));
Copy(buf, pad, pad_size);
buf += pad_size;
size += pad_size;
}
// Verify
Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE);
buf += UDP_ACCELERATION_PACKET_IV_SIZE;
size += UDP_ACCELERATION_PACKET_IV_SIZE;
if (a->Version > 1)
{
const UINT inner_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V2;
UCHAR *inner = buffer + UDP_ACCELERATION_PACKET_IV_SIZE_V2;
// Encryption
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE);
Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE);
ret = CipherProcessAead(a->CipherEncrypt, a->NextIv_V2, inner + inner_size, UDP_ACCELERATION_PACKET_MAC_SIZE_V2, inner, inner, inner_size, NULL, 0);
if (ret == 0)
{
Debug("UdpAccelSend(): CipherProcessAead() failed!\n");
return;
}
Copy(a->NextIv_V2, inner, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
// 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);
// Next Iv
Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE);
Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
}
}
// Send
SetSockHighPriority(a->UdpSock, high_priority);
r = SendTo(a->UdpSock, &a->YourIp, a->YourPort, tmp, size);
if (r == 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)
ret = SendTo(a->UdpSock, &a->YourIp, a->YourPort, buffer, size);
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
{
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
@ -570,15 +560,11 @@ bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive)
// Process the received packet
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;
UINT inner_size;
UCHAR *inner_data = NULL;
UINT pad_size;
UCHAR *verify;
bool compress_flag;
UCHAR raw_flag;
BLOCK *b = NULL;
UINT cookie;
// Validate arguments
@ -589,37 +575,55 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false)
{
// IV
if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
UCHAR *iv = buf;
if (a->Version > 1)
{
UINT data_size;
if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2)
{
return NULL;
}
iv = buf;
buf += UDP_ACCELERATION_PACKET_IV_SIZE;
size -= UDP_ACCELERATION_PACKET_IV_SIZE;
// Calculate the key
UdpAccelCalcKey(key, a->YourKey, iv);
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2;
if (false)
if (size < UDP_ACCELERATION_PACKET_MAC_SIZE_V2)
{
char tmp1[256];
char tmp2[256];
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);
return NULL;
}
// Decryption
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE);
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;
}
else
{
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
CRYPT *c;
if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{
return NULL;
}
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
if (size < sizeof(UINT))
@ -635,7 +639,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return NULL;
}
// My Tick
// My tick
if (size < sizeof(UINT64))
{
return NULL;
@ -644,7 +648,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(UINT64);
size -= sizeof(UINT64);
// Your Tick
// Your tick
if (size < sizeof(UINT64))
{
return NULL;
@ -653,7 +657,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(UINT64);
size -= sizeof(UINT64);
// inner_size
// Inner data size
if (size < sizeof(USHORT))
{
return NULL;
@ -662,12 +666,20 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(USHORT);
size -= sizeof(USHORT);
// compress_flag
// Flag
if (size < sizeof(UCHAR))
{
return NULL;
}
if (a->ReadRawFlagMode == false)
{
compress_flag = *((UCHAR *)buf);
}
else
{
raw_flag = *((UCHAR *)buf);
}
buf += sizeof(UCHAR);
size -= sizeof(UCHAR);
@ -676,7 +688,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return NULL;
}
// inner_data
// Inner_data
if (inner_size >= 1)
{
inner_data = buf;
@ -686,28 +698,31 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false)
{
// padding
if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
// Verify packet integrity
if (a->Version == 1)
{
UINT pad_size;
if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{
return false;
}
pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE;
pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1;
buf += pad_size;
size -= pad_size;
// verify
if (size != UDP_ACCELERATION_PACKET_IV_SIZE)
if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{
return NULL;
}
verify = buf;
if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false)
if (IsZero(buf, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false)
{
return NULL;
}
}
}
if (my_tick < a->LastRecvYourTick)
{
@ -722,7 +737,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
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)
@ -751,18 +770,18 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
return b;
}
// Calculate the key
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv)
// Calculate V1 key
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
if (key == NULL || common_key == NULL || iv == NULL)
{
return;
}
Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE);
Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE, iv, UDP_ACCELERATION_PACKET_IV_SIZE);
Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
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);
Debug("UdpAccelInitServer: client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, client_port,
a->MyCookie, a->YourCookie);
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);
if (IsIP6(client_ip) != a->IsIPv6)
{
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->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);
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)
{
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->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->Version = 1;
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->UdpSock = s;
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));
a->MyPort = s->LocalPort;
@ -938,6 +980,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->RecvBlockQueue = NewQueue();
Rand(a->NextIv, sizeof(a->NextIv));
Rand(a->NextIv_V2, sizeof(a->NextIv_V2));
do
{
@ -1091,6 +1134,8 @@ void FreeUdpAccel(UDP_ACCEL *a)
ReleaseCedar(a->Cedar);
FreeCipher(a->CipherEncrypt);
FreeCipher(a->CipherDecrypt);
Free(a);
}

View File

@ -9,9 +9,14 @@
#define UDPACCEL_H
// Constants
#define UDP_ACCELERATION_COMMON_KEY_SIZE 20 // Common key size
#define UDP_ACCELERATION_PACKET_KEY_SIZE 20 // Key size for the packet
#define UDP_ACCELERATION_PACKET_IV_SIZE 20 // IV size for the packet
#define UDP_ACCELERATION_COMMON_KEY_SIZE_V1 20 // V1: Common key size
#define UDP_ACCELERATION_PACKET_KEY_SIZE_V1 20 // V1: Key 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_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds)
@ -45,8 +50,10 @@ struct UDP_ACCEL
bool ClientMode; // Whether client mode
bool IsInCedarPortList; // Whether included in the port list of the Cedar
UINT64 Now; // Current time
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Submit-direction common key
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Receiving-direction common key
CIPHER *CipherEncrypt; // Encryption context
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
UINT MyPort; // My port number
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 LastRecvTick; // Tick when data has received at the end
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 YourCookie; // Cookie of the other party
bool Inited; // Initialized flag
@ -94,6 +101,10 @@ struct UDP_ACCEL
UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission)
UINT UdpIpQueryPacketSize; // Query packet data size (final transmission)
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
@ -104,9 +115,9 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
void UdpAccelPoll(UDP_ACCEL *a);
void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64);
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);
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);
UINT UdpAccelCalcMss(UDP_ACCEL *a);
void NatT_GetIpThread(THREAD *thread, void *param);

View File

@ -39,7 +39,7 @@ typedef struct x509_crl_st X509_CRL;
#define BUF_SIZE 512
// 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
#ifndef WINDOWS_H

View File

@ -2397,21 +2397,64 @@ void RUDPInterruptProc(RUDP_STACK *r)
void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
{
UCHAR *buf;
UINT buf_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];
UINT i, icmp_type, buf_size, padding_size;
// Validate arguments
if (r == NULL || se == NULL || (data == NULL && data_size != 0))
{
return;
}
if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
{
UCHAR *tmp, iv[RUDP_BULK_IV_SIZE_V2];
UINT size;
CIPHER *c;
padding_size = Rand32() % 31 + 1;
size = sizeof(UINT64) + data_size + padding_size;
// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
buf = Malloc(buf_size);
// IV
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
{
UCHAR crypt_key_src[SHA1_SIZE * 2];
UCHAR crypt_key[SHA1_SIZE];
UCHAR sign[SHA1_SIZE];
UCHAR iv[SHA1_SIZE];
CRYPT *c;
padding_size = Rand32() % 31 + 1;
buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
@ -2456,6 +2499,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
// Next IV
Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
}
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;
}
RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
Free(buf);
@ -2528,14 +2573,17 @@ SOCK *AcceptRUDP(SOCK *s)
{
case RUDP_PROTOCOL_UDP:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/UDP");
break;
case RUDP_PROTOCOL_DNS:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_DNS);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/DNS");
break;
case RUDP_PROTOCOL_ICMP:
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_ICMP);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "RUDP/ICMP");
break;
}
@ -2588,6 +2636,41 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
}
// Verification signature (bulk packet)
if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
{
UCHAR *iv = p;
CIPHER *c;
// 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);
@ -2607,6 +2690,7 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
se->UseHMac = true;
return true;
}
}
return false;
}
@ -2614,14 +2698,9 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
// Process the received packet (bulk)
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 *iv;
UINT size;
UCHAR keygen[SHA1_SIZE * 2];
UCHAR key[SHA1_SIZE];
CRYPT *c;
UCHAR padlen;
UINT64 seq_no;
UCHAR *payload;
@ -2639,6 +2718,62 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
return false;
}
if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
{
UINT ret;
CIPHER *c;
// 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)
{
@ -2660,9 +2795,6 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
se->UseHMac = true;
}
}
else
{
}
}
else
{
@ -2710,6 +2842,7 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
return false;
}
size -= padlen;
}
// SEQ NO
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;
UCHAR key1[SHA1_SIZE];
UCHAR key2[SHA1_SIZE];
UCHAR bulk_send_key[SHA1_SIZE];
UCHAR bulk_recv_key[SHA1_SIZE];
UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
BUF *b;
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));
Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
se->BulkNextSeqNo = 1;
return se;
@ -12759,6 +12894,8 @@ SOCK *Accept(SOCK *sock)
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V4);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv4");
return ret;
}
@ -12869,6 +13006,8 @@ SOCK *Accept6(SOCK *sock)
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_NATIVE_V6);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "IPv6");
return ret;
}
@ -14070,6 +14209,7 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
if (nat_t_sock != NULL)
{
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));
@ -14294,8 +14434,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
Disconnect(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),
SOCK_UNDERLAY_NAT_T);
StrCpy(p2.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p2.Result_Nat_T_Sock->UnderlayProtocol), 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));
@ -14308,8 +14448,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
Disconnect(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),
SOCK_UNDERLAY_DNS);
StrCpy(p4.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p4.Result_Nat_T_Sock->UnderlayProtocol), 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));
@ -14318,8 +14458,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
else if (p3.Ok)
{
// Use this if over ICMP success
StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol),
SOCK_UNDERLAY_ICMP);
StrCpy(p3.Result_Nat_T_Sock->UnderlayProtocol, sizeof(p3.Result_Nat_T_Sock->UnderlayProtocol), 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));
@ -14383,8 +14523,8 @@ SOCK *ConnectEx4(char *hostname, UINT port, UINT timeout, bool *cancel_flag, cha
sock->Type = SOCK_TCP;
sock->ServerMode = false;
StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol),
(is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4));
StrCpy(sock->UnderlayProtocol, sizeof(sock->UnderlayProtocol), is_ipv6 ? SOCK_UNDERLAY_NATIVE_V6 : SOCK_UNDERLAY_NATIVE_V4);
AddProtocolDetailsStr(sock->ProtocolDetails, sizeof(sock->ProtocolDetails), is_ipv6 ? "IPv6" : "IPv4");
// Host name resolution
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;
}
// 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
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);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "VPN Azure");
return ret;
}
@ -19493,6 +19688,8 @@ SOCK *AcceptInProc(SOCK *s)
{
StrCpy(ret->UnderlayProtocol, sizeof(ret->UnderlayProtocol), SOCK_UNDERLAY_INPROC);
AddProtocolDetailsStr(ret->ProtocolDetails, sizeof(ret->ProtocolDetails), "InProc");
return ret;
}

View File

@ -209,6 +209,7 @@ struct SOCK
UINT CurrentTtl; // Current TTL value
RUDP_STACK *R_UDP_Stack; // R-UDP stack
char UnderlayProtocol[64]; // Underlying protocol
char ProtocolDetails[256]; // Protocol details
QUEUE *ReverseAcceptQueue; // Accept queue for the reverse socket
EVENT *ReverseAcceptEvent; // Accept event for the 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_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out
#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
#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
@ -663,6 +670,7 @@ struct RUDP_SESSION
UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send
bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube
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
@ -1238,6 +1246,9 @@ void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e);
void DebugPrintRoute(ROUTE_ENTRY *e);
void DebugPrintRouteTable(ROUTE_TABLE *r);
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
void SockEnableSslLogging(SOCK *s);