diff --git a/src/BuildUtil/UnixBuildSoftwares.cs b/src/BuildUtil/UnixBuildSoftwares.cs index f11063c3..b5ecebe7 100644 --- a/src/BuildUtil/UnixBuildSoftwares.cs +++ b/src/BuildUtil/UnixBuildSoftwares.cs @@ -143,6 +143,7 @@ namespace BuildUtil @"bin\BuiltHamcoreFiles", @"bin\hamcore", "Cedar", + "vpntest", "Mayaqua", "Neo", "vpnbridge", @@ -731,7 +732,7 @@ namespace BuildUtil { string[] programNames = { - "Ham", + "vpntest", "vpnserver", "vpnbridge", "vpnclient", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8842cab4..61905e3b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,6 +115,10 @@ get_target_property(VPNBRIDGE_RUNTIME_OUTPUT_DIRECTORY vpnbridge RUNTIME_OUTPUT_ add_subdirectory(vpncmd) get_target_property(VPNCMD_RUNTIME_OUTPUT_DIRECTORY vpncmd RUNTIME_OUTPUT_DIRECTORY) +# vpntest +add_subdirectory(vpntest) +get_target_property(VPNTEST_RUNTIME_OUTPUT_DIRECTORY vpntest RUNTIME_OUTPUT_DIRECTORY) + # hamcore.se2 archive file add_custom_target(hamcore-archive-build ALL @@ -148,6 +152,12 @@ add_custom_command(TARGET hamcore-archive-build COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/tmp/hamcore.se2 ${VPNCMD_RUNTIME_OUTPUT_DIRECTORY} ) +# Copy hamcore.se2 to vpntest's directory +add_custom_command(TARGET hamcore-archive-build + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/tmp/hamcore.se2 ${VPNTEST_RUNTIME_OUTPUT_DIRECTORY} +) + # Copy "vpnserver" directory to /usr/lib(exec)/softether/, install launch script and systemd service install(DIRECTORY ${VPNSERVER_RUNTIME_OUTPUT_DIRECTORY} COMPONENT "vpnserver" diff --git a/src/Cedar/WinUi.c b/src/Cedar/WinUi.c index 5ba696fc..7ea05e0c 100644 --- a/src/Cedar/WinUi.c +++ b/src/Cedar/WinUi.c @@ -1964,6 +1964,9 @@ void RegistWindowsFirewallAllEx(char *dir) MsRegistWindowsFirewallEx2(CEDAR_CUI_STR, "vpncmd.exe", dir); MsRegistWindowsFirewallEx2(CEDAR_CUI_STR, "vpncmd_x64.exe", dir); + + MsRegistWindowsFirewallEx2(CEDAR_PRODUCT_STR, "vpntest.exe", dir); + MsRegistWindowsFirewallEx2(CEDAR_PRODUCT_STR, "vpntest_x64.exe", dir); } // Check whether the notification service is already running diff --git a/src/Mayaqua/Mayaqua.c b/src/Mayaqua/Mayaqua.c index a452ac91..cd8708cb 100644 --- a/src/Mayaqua/Mayaqua.c +++ b/src/Mayaqua/Mayaqua.c @@ -1151,6 +1151,11 @@ void PrintKernelStatus() Print(" !!! MEMORY LEAKS DETECTED !!!\n\n"); if (g_memcheck == false) { + if (IsHamMode()) + { + Print(" Enable /memcheck startup option to see the leaking memory heap.\n"); + Print(" Press Enter key to exit the process.\n"); + } GetLine(NULL, 0); } } diff --git a/src/Mayaqua/Tracking.c b/src/Mayaqua/Tracking.c index 3dda6c0a..ae0bd1f6 100644 --- a/src/Mayaqua/Tracking.c +++ b/src/Mayaqua/Tracking.c @@ -157,7 +157,15 @@ void MemoryDebugMenu() TOKEN_LIST *t; char *cmd; Print("Mayaqua Kernel Memory Debug Tools\n" - "Copyright (c) SoftEther Corporation. All Rights Reserved.\n\n"); + "Copyright (c) SoftEther VPN Project. All Rights Reserved.\n\n"); + +#ifndef OS_WIN32 + Print("Unfortunately The call stack is not recorded on non-Windows systems\n"); + Print("since UnixGetCallStack() and UnixGetCallStackSymbolInfo() is not implemented.\n"); + Print("Therefore please use valgrind or other memory leak check tools\n"); + Print("to get the actual call stacks of memory leak causes.\n\n"); +#endif // OS_WIN32 + g_memcheck = false; while (true) { diff --git a/src/SEVPN.sln b/src/SEVPN.sln index 78ffc9da..fdf9b32f 100644 --- a/src/SEVPN.sln +++ b/src/SEVPN.sln @@ -90,6 +90,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cedar", "Cedar\Cedar.vcproj {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} = {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vpntest", "vpntest\vpntest.vcproj", "{1ED5782B-1734-4FC6-AA9E-F7181CDBA8A7}" + ProjectSection(ProjectDependencies) = postProject + {2928D768-DEC3-40D3-8E51-26E364497C9B} = {2928D768-DEC3-40D3-8E51-26E364497C9B} + {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} = {384815C3-333C-4CEC-9DCD-B6AB2602EBB9} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vpncmd", "vpncmd\vpncmd.vcproj", "{83438AC3-5329-4337-89BC-5B69EBAE4B6E}" ProjectSection(ProjectDependencies) = postProject {2928D768-DEC3-40D3-8E51-26E364497C9B} = {2928D768-DEC3-40D3-8E51-26E364497C9B} diff --git a/src/vpntest/CMakeLists.txt b/src/vpntest/CMakeLists.txt new file mode 100644 index 00000000..b8914254 --- /dev/null +++ b/src/vpntest/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(vpntest vpntest.c vpntest.h) + +set_target_properties(vpntest + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${BUILD_DIRECTORY}/vpntest" + LIBRARY_OUTPUT_DIRECTORY "${BUILD_DIRECTORY}/vpntest" + RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIRECTORY}/vpntest" +) + +target_link_libraries(vpntest cedar mayaqua) diff --git a/src/vpntest/resource.h b/src/vpntest/resource.h new file mode 100644 index 00000000..2f5bec73 --- /dev/null +++ b/src/vpntest/resource.h @@ -0,0 +1,19 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Ham.rc +// +#define IDR_TEST1 101 +#define IDI_ICON1 102 +#define IDI_CERT 102 +#define IDI_ICON2 103 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/vpntest/vpntest.c b/src/vpntest/vpntest.c new file mode 100644 index 00000000..7ba5ef67 --- /dev/null +++ b/src/vpntest/vpntest.c @@ -0,0 +1,243 @@ +// vpntest.c +// VPN Server / VPN Client / VPN Bridge test program + +#include +#define VPN_EXE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "vpntest.h" + + + +void client_test(UINT num, char **arg) +{ + Print("VPN Client Test. Press Enter key to stop the VPN Client .\n"); + CtStartClient(); + GetLine(NULL, 0); + CtStopClient(); +} + +void server_test(UINT num, char **arg) +{ + Print("VPN Server Test. Press Enter key to stop the VPN Server .\n"); + + StInit(); + + StStartServer(false); + + GetLine(NULL, 0); + + StStopServer(); + + StFree(); +} + +void bridge_test(UINT num, char **arg) +{ + Print("VPN Bridge Test. Press Enter key to stop the VPN Bridge .\n"); + + StInit(); + + StStartServer(true); + + GetLine(NULL, 0); + + StStopServer(); + + StFree(); +} + +void memory_leak_test(UINT num, char **arg) +{ + char *a = Malloc(1); + + Print("Hello, I am the great dictator of this kingdom!\n"); + Print("Just now I called Malloc(1) and never free! Ha ha ha !!\n"); +} + + +// The list of test functions +// Test function definition list +typedef void (TEST_PROC)(UINT num, char **arg); + +typedef struct TEST_LIST +{ + char *command_str; + TEST_PROC *proc; + char *help; +} TEST_LIST; + +TEST_LIST test_list[] = +{ + {"c", client_test, "VPN Client in Test Mode, enter key to graceful stop."}, + {"s", server_test, "VPN Server in Test Mode, enter key to graceful stop."}, + {"b", bridge_test, "VPN Bridge in Test Mode, enter key to graceful stop."}, + {"memory_leak", memory_leak_test, "Memory leak test: Try to leak one byte by malloc()."}, +}; + +// Test function +void TestMain(char *cmd) +{ + char tmp[MAX_SIZE]; + bool first = true; + bool exit_now = false; + + Print("SoftEther VPN Project\n"); + Print("vpntest: VPN Server / VPN Client / VPN Bridge test program\n"); + Print("Usage: vpntest [/memcheck] [command]\n\n"); + Print("Enter '?' or 'help' to show the command list.\n"); + Print("Enter 'q' or 'exit' to exit the process.\n\n"); + Print(" - In Jurassic Park: \"It's a UNIX system! I know this!\"\n\n"); + +#ifdef OS_WIN32 + MsSetEnableMinidump(false); +#endif // OS_WIN32 + + while (true) + { + Print("TEST>"); + if (first && StrLen(cmd) != 0 && g_memcheck == false) + { + first = false; + StrCpy(tmp, sizeof(tmp), cmd); + exit_now = true; + Print("%s\n", cmd); + } + else + { + GetLine(tmp, sizeof(tmp)); + } + Trim(tmp); + if (StrLen(tmp) != 0) + { + UINT i, num; + bool b = false; + TOKEN_LIST *token = ParseCmdLine(tmp); + char *cmd = token->Token[0]; + if (!StrCmpi(cmd, "exit") || !StrCmpi(cmd, "quit") || !StrCmpi(cmd, "q")) + { + FreeToken(token); + break; + } + else if (StrCmpi(cmd, "?") == 0 || StrCmpi(cmd, "help") == 0) + { + UINT max_len = 0; + Print("Available commands:\n\n"); + num = sizeof(test_list) / sizeof(TEST_LIST); + for (i = 0;i < num;i++) + { + TEST_LIST *t = &test_list[i]; + max_len = MAX(max_len, StrLen(t->command_str)); + } + for (i = 0;i < num;i++) + { + TEST_LIST *t = &test_list[i]; + UINT len = StrLen(t->command_str); + char *pad = NULL; + if (len < max_len) + { + UINT padlen = max_len - len; + pad = MakeCharArray(' ', padlen); + } + Print(" '%s'%s : %s\n", t->command_str, pad == NULL ? "" : pad, t->help); + if (pad != NULL) + { + Free(pad); + } + } + Print("\n"); + } + else if (StartWith(tmp, "vpncmd")) + { + wchar_t *s = CopyStrToUni(tmp); + CommandMain(s); + Free(s); + } + else + { + num = sizeof(test_list) / sizeof(TEST_LIST); + for (i = 0;i < num;i++) + { + if (!StrCmpi(test_list[i].command_str, cmd)) + { + char **arg = Malloc(sizeof(char *) * (token->NumTokens - 1)); + UINT j; + for (j = 0;j < token->NumTokens - 1;j++) + { + arg[j] = CopyStr(token->Token[j + 1]); + } + test_list[i].proc(token->NumTokens - 1, arg); + for (j = 0;j < token->NumTokens - 1;j++) + { + Free(arg[j]); + } + Free(arg); + b = true; + Print("\n"); + break; + } + } + if (b == false) + { + Print("Invalid Command: %s\n\n", cmd); + } + } + FreeToken(token); + + if (exit_now) + { + break; + } + } + } + Print("Exiting...\n\n"); +} + +// Main function +int main(int argc, char *argv[]) +{ + bool memchk = false; + UINT i; + char cmd[MAX_SIZE]; + char *s; + + InitProcessCallOnce(); + + cmd[0] = 0; + if (argc >= 2) + { + for (i = 1;i < (UINT)argc;i++) + { + s = argv[i]; + if (s[0] == '/') + { + if (!StrCmpi(s, "/memcheck")) + { + memchk = true; + } + } + else + { + StrCpy(cmd, sizeof(cmd), &s[0]); + } + } + } + + InitMayaqua(memchk, true, argc, argv); + EnableProbe(true); + InitCedar(); + SetHamMode(); + TestMain(cmdline); + FreeCedar(); + FreeMayaqua(); + + return 0; +} + diff --git a/src/vpntest/vpntest.h b/src/vpntest/vpntest.h new file mode 100644 index 00000000..d3f5a12f --- /dev/null +++ b/src/vpntest/vpntest.h @@ -0,0 +1 @@ + diff --git a/src/vpntest/vpntest.ico b/src/vpntest/vpntest.ico new file mode 100644 index 00000000..0310b265 Binary files /dev/null and b/src/vpntest/vpntest.ico differ diff --git a/src/vpntest/vpntest.rc b/src/vpntest/vpntest.rc new file mode 100644 index 00000000..6d048626 --- /dev/null +++ b/src/vpntest/vpntest.rc @@ -0,0 +1,72 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Japanese resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +#ifdef _WIN32 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +#pragma code_page(932) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON2 ICON "vpntest.ico" +#endif // Japanese resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/vpntest/vpntest.vcproj b/src/vpntest/vpntest.vcproj new file mode 100644 index 00000000..e8533dc5 --- /dev/null +++ b/src/vpntest/vpntest.vcproj @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +