1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2026-03-10 18:29:18 +03:00

Compare commits

..

5 Commits

13 changed files with 407 additions and 480 deletions

View File

@ -4,7 +4,6 @@ name: Coverity
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
contents: read
@ -12,7 +11,7 @@ permissions:
jobs:
scan:
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'SoftEtherVPN' || github.event_name == 'workflow_dispatch' }}
if: ${{ github.repository_owner == 'SoftEtherVPN' }}
steps:
- uses: actions/checkout@v2
with:

2
.gitignore vendored
View File

@ -210,3 +210,5 @@ developer_tools/stbchecker/**/*.binlog
developer_tools/stbchecker/**/*.nvuser
developer_tools/stbchecker/**/.mfractor/
/vcpkg_installed
_codeql_build_dir/
_codeql_detected_source_root

View File

@ -87,10 +87,6 @@ into it. So that is what will be described below.
- x86-on-x64
Cross compile x86 executables with 64-bit compiler
- arm64-on-x64
Cross compile arm64 executables with x64t compiler
On 64-bit Windows, all four configurations can be used. 32-bit platforms can only use 32-bit compiler.

View File

@ -1,52 +0,0 @@
# How to build and install SoftEther VPN on Windows ARM64
This document describes how to build SoftEther VPN for Windows ARM64 and how to install the VPN Client and Neo6 virtual network adapter on Windows on ARM devices.
## Requirements
- Build host: Windows x64
- Target device: Windows 10 / Windows 11 ARM64
## Building
**Notes before building**: ARM64 builds are cross-compiled from an x64 Windows host. An existing x64-native build is required to generate hamcore.se2.
1. Follow [BUILD_WINDOWS.md](BUILD_WINDOWS.md##Building)
1. Build x64 (Native): From the build menu, select x64-on-x64. Complete the build successfully. This build is required to generate shared resources
1. Build ARM64 (Cross-Compiled): From the same build menu, select arm64-on-x64.
Build the ARM64 version of SoftEther VPN.
1. Building the Neo6 Virtual Network Adapter (ARM64)
Open the following project in Visual Studio:
```
.\src\Neo6\Neo6.vcxproj
```
SoftEther VPN Client uses the Neo6 virtual network adapter.
Driver Output Files
The ARM64 driver package includes:
```
Neo6_arm64_VPN.sys
Neo6_arm64_VPN.inf
```
Driver Signing and Installation (Windows ARM64)
```
Enable test-signing mode: bcdedit /set testsigning on
Reboot the system.
Testing signing:
Install the Neo6 ARM64 driver.
```
# Summary
SoftEther VPN can be cross-compiled for Windows ARM64 on an x64 host
VPN Client works natively on Windows on ARM
Neo6 ARM64 driver requires Microsoft signing for production use
Test-signing is suitable for local development only

View File

@ -2562,16 +2562,9 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
Debug("OpenVPN Channel %u Failed.\n", j);
OvsLog(s, se, c, "LO_CHANNEL_FAILED");
if ((se->IpcAsync->ErrorCode == ERR_AUTHTYPE_NOT_SUPPORTED) ||
(se->IpcAsync->ErrorCode == ERR_AUTH_FAILED) ||
(se->IpcAsync->ErrorCode == ERR_PROXY_AUTH_FAILED) ||
(se->IpcAsync->ErrorCode == ERR_USER_AUTHTYPE_NOT_PASSWORD) ||
(se->IpcAsync->ErrorCode == ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE))
{
// Return the AUTH_FAILED
str = "AUTH_FAILED";
WriteFifo(c->SslPipe->SslInOut->SendFifo, str, StrSize(str));
}
// Return the AUTH_FAILED
str = "AUTH_FAILED";
WriteFifo(c->SslPipe->SslInOut->SendFifo, str, StrSize(str));
s->SessionEstablishedCount++;

View File

@ -1190,6 +1190,67 @@ void NnIpSendForInternet(NATIVE_NAT *t, UCHAR ip_protocol, UCHAR ttl, UINT src_i
}
}
// Host IP address cache TTL in milliseconds (60 seconds)
#define HOST_IP_CACHE_TTL_MS 60000
// Check if destination IP is one of the host's own IP addresses
// Uses caching to avoid frequent system calls
// Returns true if dest_ip matches any of the host's IPs
bool IsDestinationHostOwnIP(VH *v, UINT dest_ip)
{
bool is_host_ip = false;
UINT64 now;
LIST *new_list = NULL;
// Validate arguments
if (v == NULL)
{
return false;
}
now = Tick64();
Lock(v->HostIPCacheLock);
{
// Check if cache needs refresh (every 60 seconds or if not initialized)
if (v->HostIPAddressCache == NULL || now >= v->HostIPCacheExpires)
{
// Get new list while holding the lock to prevent multiple threads from refreshing
new_list = GetHostIPAddressList();
// Free old cache
if (v->HostIPAddressCache != NULL)
{
FreeHostIPAddressList(v->HostIPAddressCache);
}
// Set new cache with TTL
v->HostIPAddressCache = new_list;
v->HostIPCacheExpires = now + HOST_IP_CACHE_TTL_MS;
}
// Check if dest_ip matches any cached host IP
if (v->HostIPAddressCache != NULL)
{
UINT i;
IP dest_ip_obj;
UINTToIP(&dest_ip_obj, dest_ip);
for (i = 0; i < LIST_NUM(v->HostIPAddressCache); i++)
{
IP *host_ip = LIST_DATA(v->HostIPAddressCache, i);
if (IsIP4(host_ip) && CmpIpAddr(&dest_ip_obj, host_ip) == 0)
{
is_host_ip = true;
break;
}
}
}
}
Unlock(v->HostIPCacheLock);
return is_host_ip;
}
// Communication of ICMP towards the Internet
void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size)
{
@ -1209,6 +1270,15 @@ void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UIN
return;
}
// Check if destination is the host's own IP address
// When Native NAT tries to send packets to the host's own IP, the OS routing
// may fail or behave unexpectedly. Drop such packets to avoid issues.
if (IsDestinationHostOwnIP(v, dest_ip))
{
// Destination is the host's own IP - drop the packet
return;
}
t = v->NativeNat;
old_icmp_header = (ICMP_HEADER *)icmp_data;
@ -1351,6 +1421,15 @@ void NnUdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT
return;
}
// Check if destination is the host's own IP address
// When Native NAT tries to send packets to the host's own IP, the OS routing
// may fail or behave unexpectedly. Drop such packets to avoid issues.
if (IsDestinationHostOwnIP(v, dest_ip))
{
// Destination is the host's own IP - drop the packet
return;
}
t = v->NativeNat;
// Search whether there is an existing session
@ -1449,6 +1528,15 @@ void NnTcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT
return;
}
// Check if destination is the host's own IP address
// When Native NAT tries to send packets to the host's own IP, the OS routing
// may fail or behave unexpectedly. Drop such packets to avoid issues.
if (IsDestinationHostOwnIP(v, dest_ip))
{
// Destination is the host's own IP - drop the packet
return;
}
t = v->NativeNat;
// Search whether there is an existing session
@ -10193,6 +10281,13 @@ void Virtual_Free(VH *v)
LockVirtual(v);
{
// Free host IP cache
if (v->HostIPAddressCache != NULL)
{
FreeHostIPAddressList(v->HostIPAddressCache);
v->HostIPAddressCache = NULL;
}
// Release the IP combining list
FreeIpCombineList(v);
@ -10227,6 +10322,9 @@ void Virtual_Free(VH *v)
}
UnlockVirtual(v);
// Release the host IP cache lock
DeleteLock(v->HostIPCacheLock);
// Release the logger
FreeLog(v->Logger);
}
@ -10357,6 +10455,11 @@ VH *NewVirtualHostEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *auth, VH_
v->nat = nat;
// Initialize host IP cache for Native NAT
v->HostIPAddressCache = NULL;
v->HostIPCacheExpires = 0;
v->HostIPCacheLock = NewLock();
// Examine whether ICMP Raw Socket can be created
s = NewUDP4(MAKE_SPECIAL_PORT(IP_PROTO_ICMPV4), NULL);
if (s != NULL)

View File

@ -313,6 +313,11 @@ struct VH
HUB_OPTION *HubOption; // Pointer to the Virtual HUB options
NATIVE_NAT *NativeNat; // Native NAT
// Host IP cache for Native NAT packet filtering
LIST *HostIPAddressCache; // Cached list of host IP addresses
UINT64 HostIPCacheExpires; // When the cache expires (tick64)
LOCK *HostIPCacheLock; // Lock for cache access
};
// Virtual host option

View File

@ -4761,7 +4761,7 @@ static void MY_SHA0_Transform(MY_SHA0_CTX* ctx) {
UCHAR* p = ctx->buf;
int t;
for(t = 0; t < 16; ++t) {
UINT tmp = (UINT)*p++ << 24;
UINT tmp = *p++ << 24;
tmp |= *p++ << 16;
tmp |= *p++ << 8;
tmp |= *p++;

View File

@ -63,7 +63,7 @@ static int ydays[] =
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};
static COUNTER *current_num_thread = NULL;
static UINT current_num_thread = 0;
static UINT cached_number_of_cpus = 0;
@ -776,7 +776,6 @@ void InitThreading()
{
thread_pool = NewSk();
thread_count = NewCounter();
current_num_thread = NewCounter();
}
// Release of thread pool
@ -822,9 +821,6 @@ void FreeThreading()
DeleteCounter(thread_count);
thread_count = NULL;
DeleteCounter(current_num_thread);
current_num_thread = NULL;
}
// Thread pool procedure
@ -1032,9 +1028,9 @@ THREAD *NewThreadNamed(THREAD_PROC *thread_proc, void *param, char *name)
Wait(pd->InitFinishEvent, INFINITE);
Inc(current_num_thread);
current_num_thread++;
// Debug("current_num_thread = %u\n", Count(current_num_thread));
// Debug("current_num_thread = %u\n", current_num_thread);
return ret;
}
@ -1059,8 +1055,8 @@ void CleanupThread(THREAD *t)
Free(t);
Dec(current_num_thread);
//Debug("current_num_thread = %u\n", Count(current_num_thread));
current_num_thread--;
//Debug("current_num_thread = %u\n", current_num_thread);
}
// Release thread (pool)

View File

@ -72,26 +72,11 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, char *CmdLine, int CmdShow)
// Compiler dependent
#ifndef OS_WIN32
// GCC or Clang compiler
// Gcc compiler
#define GCC_PACKED __attribute__ ((__packed__))
// Clang compiler
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread")))
#endif // __has_feature(thread_sanitizer)
#endif // __has_feature
// GCC compiler
#if defined(__SANITIZE_THREAD__) && !defined(ATTRIBUTE_NO_TSAN)
#define ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread")))
#endif // __SANITIZE_THREAD__
// Other or older Clang/GCC compiler
#ifndef ATTRIBUTE_NO_TSAN
#define ATTRIBUTE_NO_TSAN
#endif // ATTRIBUTE_NO_TSAN
#else // OS_WIN32
// VC++ compiler
#define GCC_PACKED
#define ATTRIBUTE_NO_TSAN
#endif // OS_WIN32
// Macro that displays the current file name and line number

View File

@ -470,7 +470,6 @@ LIST *LoadLangList()
b = ReadDump(filename);
if (b == NULL)
{
FreeLangList(o);
return NULL;
}

View File

@ -2140,13 +2140,9 @@ void UnixMemoryFree(void *addr)
// SIGCHLD handler
void UnixSigChldHandler(int sig)
{
int old_errno = errno;
// Recall the zombie processes
while (waitpid(-1, NULL, WNOHANG) > 0);
signal(SIGCHLD, UnixSigChldHandler);
errno = old_errno;
}
// Disable core dump

File diff suppressed because it is too large Load Diff