diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index f5e6ef56..c9714de5 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -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); diff --git a/src/Cedar/CM.c b/src/Cedar/CM.c index c908f30d..63555550 100644 --- a/src/Cedar/CM.c +++ b/src/Cedar/CM.c @@ -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"))); diff --git a/src/Cedar/CedarType.h b/src/Cedar/CedarType.h index 8b821996..6b0972dd 100644 --- a/src/Cedar/CedarType.h +++ b/src/Cedar/CedarType.h @@ -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; // ============================================================== diff --git a/src/Cedar/Client.c b/src/Cedar/Client.c index d587d6e3..007b4ad1 100644 --- a/src/Cedar/Client.c +++ b/src/Cedar/Client.c @@ -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 - st->IsUdpAccelerationEnabled = s->UseUdpAcceleration; - st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration; + 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 diff --git a/src/Cedar/Client.h b/src/Cedar/Client.h index 013ddbfb..c5dde36f 100644 --- a/src/Cedar/Client.h +++ b/src/Cedar/Client.h @@ -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 diff --git a/src/Cedar/Command.c b/src/Cedar/Command.c index 23dc9481..78dbf300 100644 --- a/src/Cedar/Command.c +++ b/src/Cedar/Command.c @@ -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"))); diff --git a/src/Cedar/Connection.c b/src/Cedar/Connection.c index ae8ddde4..045ccfb8 100644 --- a/src/Cedar/Connection.c +++ b/src/Cedar/Connection.c @@ -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; diff --git a/src/Cedar/Connection.h b/src/Cedar/Connection.h index a134b1ed..2f39edf1 100644 --- a/src/Cedar/Connection.h +++ b/src/Cedar/Connection.h @@ -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 diff --git a/src/Cedar/Hub.c b/src/Cedar/Hub.c index 02f2de14..0a37f8e0 100644 --- a/src/Cedar/Hub.c +++ b/src/Cedar/Hub.c @@ -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 diff --git a/src/Cedar/IPC.c b/src/Cedar/IPC.c index 9263e903..377b5d59 100644 --- a/src/Cedar/IPC.c +++ b/src/Cedar/IPC.c @@ -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); } diff --git a/src/Cedar/IPC.h b/src/Cedar/IPC.h index 60d54400..0aa25b4a 100644 --- a/src/Cedar/IPC.h +++ b/src/Cedar/IPC.h @@ -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; }; diff --git a/src/Cedar/Logging.c b/src/Cedar/Logging.c index c172e6bf..1df57ce4 100644 --- a/src/Cedar/Logging.c +++ b/src/Cedar/Logging.c @@ -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; } diff --git a/src/Cedar/Proto_IKE.c b/src/Cedar/Proto_IKE.c index a5faa34d..c35468c2 100644 --- a/src/Cedar/Proto_IKE.c +++ b/src/Cedar/Proto_IKE.c @@ -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)) diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c index 71ab6a33..e3e386bc 100644 --- a/src/Cedar/Proto_PPP.c +++ b/src/Cedar/Proto_PPP.c @@ -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) diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index b1498441..fce8b428 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -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,46 +4884,62 @@ REDIRECTED: 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"); - UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie"); - bool encryption = PackGetBool(p, "udp_acceleration_use_encryption"); + IP remote_ip; - 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, - &udp_acceleration_server_ip, udp_acceleration_server_port, - server_cookie, client_cookie, &remote_ip) == false) - { - Debug("UdpAccelInitClient failed.\n"); - } - else - { - sess->UseUdpAcceleration = true; + AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), "UDPAccel_Ver", sess->UdpAccel->Version); - sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect; + AddProtocolDetailsStr(sess->ProtocolDetails, sizeof(sess->ProtocolDetails), sess->UdpAccel->Version > 1 ? "ChaCha20-Poly1305" : "RC4"); - sess->UdpAccel->PlainTextMode = !encryption; - - sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration"); - - if (sess->UseHMacOnUdpAcceleration) - { - sess->UdpAccel->UseHMac = true; - } - } + 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); - PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE); - PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE); + 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, ""); } } diff --git a/src/Cedar/Radius.c b/src/Cedar/Radius.c index 864e3a0e..39cd4e9b 100644 --- a/src/Cedar/Radius.c +++ b/src/Cedar/Radius.c @@ -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); diff --git a/src/Cedar/Session.c b/src/Cedar/Session.c index 88e96f2d..e9d11125 100644 --- a/src/Cedar/Session.c +++ b/src/Cedar/Session.c @@ -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); } diff --git a/src/Cedar/Session.h b/src/Cedar/Session.h index 2c980248..3ae3b01b 100644 --- a/src/Cedar/Session.h +++ b/src/Cedar/Session.h @@ -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 diff --git a/src/Cedar/UdpAccel.c b/src/Cedar/UdpAccel.c index 1e2e943b..5915c4b6 100644 --- a/src/Cedar/UdpAccel.c +++ b/src/Cedar/UdpAccel.c @@ -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; - } + 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); - FreeCrypt(c); + 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; + } - // Next Iv - Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE); + 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); + + 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,36 +575,54 @@ 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) { - 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; - buf += UDP_ACCELERATION_PACKET_IV_SIZE; - size -= UDP_ACCELERATION_PACKET_IV_SIZE; - - // Calculate the key - UdpAccelCalcKey(key, a->YourKey, iv); - - if (false) + else { - 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); - } + UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1]; + CRYPT *c; - // Decryption - c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); - Encrypt(c, buf, buf, size); - FreeCrypt(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 @@ -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; } - compress_flag = *((UCHAR *)buf); + 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,26 +698,29 @@ 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) { - return false; - } - pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE; - buf += pad_size; - size -= pad_size; + UINT pad_size; - // verify - if (size != UDP_ACCELERATION_PACKET_IV_SIZE) - { - return NULL; - } + if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1) + { + return false; + } - 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) - { - return NULL; + if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1) + { + 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) { - 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); } - diff --git a/src/Cedar/UdpAccel.h b/src/Cedar/UdpAccel.h index 35e787c4..b9d88c0e 100644 --- a/src/Cedar/UdpAccel.h +++ b/src/Cedar/UdpAccel.h @@ -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); diff --git a/src/Mayaqua/MayaType.h b/src/Mayaqua/MayaType.h index b2ea200c..d7390a08 100644 --- a/src/Mayaqua/MayaType.h +++ b/src/Mayaqua/MayaType.h @@ -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 diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index ce9cf798..6e5bddaf 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -2397,65 +2397,109 @@ 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; } - padding_size = Rand32() % 31 + 1; - - 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++) + if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2) { - 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 - 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); + padding_size = Rand32() % 31 + 1; - // IV - Copy(buf + SHA1_SIZE, iv, SHA1_SIZE); + size = sizeof(UINT64) + data_size + padding_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); + // 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 { - 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 - Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE); + padding_size = Rand32() % 31 + 1; + + 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) { @@ -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,40 +2636,71 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, } // Verification signature (bulk packet) - if (se->UseHMac == false) + if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2) { - Copy(sign, p, SHA1_SIZE); - Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); - Sha1(sign2, p, recv_size); - Copy(p, sign, SHA1_SIZE); + UCHAR *iv = p; + CIPHER *c; - 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; } } - 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; } // 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,15 +2718,85 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, return false; } - // Validate the signature - if (se->UseHMac == false) + if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2) { - Copy(sign, p, SHA1_SIZE); - Copy(p, se->BulkRecvKey->Data, SHA1_SIZE); - Sha1(sign2, p, recv_size); - Copy(p, sign, SHA1_SIZE); + UINT ret; + CIPHER *c; - 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); @@ -2655,61 +2804,45 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, { 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; } - } + iv = p; + p += SHA1_SIZE; + size -= SHA1_SIZE; - p += SHA1_SIZE; - size -= SHA1_SIZE; + // Decrypt + 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 - if (size < SHA1_SIZE) - { - return false; - } - iv = p; - p += SHA1_SIZE; - size -= SHA1_SIZE; + c = NewCrypt(key, sizeof(key)); + Encrypt(c, p, p, size); + FreeCrypt(c); - // Decrypt - if (size < 1) - { - return false; + // padlen + padlen = p[size - 1]; + if (padlen == 0) + { + 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 = 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), ¤t_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; } diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 06dbc6fd..44351d5c 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -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);