// SoftEther VPN Source Code - Developer Edition Master Branch // Mayaqua Kernel // // SoftEther VPN Server, Client and Bridge are free software under GPLv2. // // Copyright (c) Daiyuu Nobori. // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan. // Copyright (c) SoftEther Corporation. // // All Rights Reserved. // // http://www.softether.org/ // // Author: Daiyuu Nobori, Ph.D. // Comments: Tetsuo Sugiyama, Ph.D. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License version 2 // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE // AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE. // // // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, // UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, // MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS // SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS // SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER // CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL // DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING, // MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR // SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO // EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, // JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION // AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN // THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE. // // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS // YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY // CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS // SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE // SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO // COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING // PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR // CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE // NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ // COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE // WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY // COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE // COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE // SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR // COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO // RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT // JUST A STATEMENT FOR WARNING AND DISCLAIMER. // // // SOURCE CODE CONTRIBUTION // ------------------------ // // Your contribution to SoftEther VPN Project is much appreciated. // Please send patches to us through GitHub. // Read the SoftEther VPN Patch Acceptance Policy in advance: // http://www.softether.org/5-download/src/9.patch // // // DEAR SECURITY EXPERTS // --------------------- // // If you find a bug or a security vulnerability please kindly inform us // about the problem immediately so that we can fix the security problem // to protect a lot of users around the world as soon as possible. // // Our e-mail address for security reports is: // softether-vpn-security [at] softether.org // // Please note that the above e-mail address is not a technical support // inquiry address. If you need technical assistance, please visit // http://www.softether.org/ and ask your question on the users forum. // // Thank you for your cooperation. // // // NO MEMORY OR RESOURCE LEAKS // --------------------------- // // The memory-leaks and resource-leaks verification under the stress // test has been passed before release this source code. // Mayaqua.h // Mayaqua Kernel header file #ifndef MAYAQUA_H #define MAYAQUA_H // PenCore.dll related #define PENCORE_DLL_NAME "|PenCore.dll" // #define PENCORE_DLL_NAME_X64 "|PenCore_x64.dll" // commonized to x86 // #define PENCORE_DLL_NAME_IA64 "|PenCore_ia64.dll" // commonized to x86 //#define USE_PROBE // Use Probe // Macro for the release flag #ifdef VPN_SPEED #define DONT_USE_KERNEL_STATUS // Do not update the kernel status #define WIN32_USE_HEAP_API_FOR_MEMORY // Use the heap API to allocate memory #define WIN32_NO_DEBUG_HELP_DLL // Do not call the DLL for debugging #define DONT_CHECK_HEAP // Do not check the status of the heap #define DONT_ALLOW_RUN_ON_DEBUGGER // Do not allow running on the debugger #endif // VPN_SPEED void InitProcessCallOnce(); #ifdef VPN_EXE // To build the executable file #ifdef WIN32 #include #include "../PenCore/resource.h" int main(int argc, char *argv[]); int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, char *CmdLine, int CmdShow) { char *argv[] = { CmdLine, }; InitProcessCallOnce(); return main(1, argv); } #endif // WIN32 #endif // VPN_EXE // Constant #define DEFAULT_TABLE_FILE_NAME "|strtable.stb" // Default string table //#define DEFAULT_TABLE_FILE_NAME "@hamcore_zh/strtable.stb" // Test for Chinese #define STRTABLE_ID "SE_VPN_20121007" // String table identifier // Determining the OS #ifdef WIN32 #define OS_WIN32 // Microsoft Windows #else #define OS_UNIX // UNIX #endif // WIN32 // Directory separator #ifdef OS_WIN32 #define PATH_BACKSLASH // Backslash (\) #else // WIN32 #define PATH_SLASH // Slash (/) #endif // WIN32 // Character code #ifdef OS_WIN32 #define CODE_SHIFTJIS // Shift_JIS code #else // WIN32 #define CODE_EUC // euc-jp code #endif // WIN32 // Endian #define IsBigEndian() (g_little_endian ? false : true) #define IsLittleEndian() (g_little_endian) #ifdef OS_WIN32 // Replace the snprintf function #define snprintf _snprintf #endif // OS_WIN32 // Compiler dependent #ifndef OS_WIN32 // Gcc compiler #define GCC_PACKED __attribute__ ((__packed__)) #else // OS_WIN32 // VC++ compiler #define GCC_PACKED #endif // OS_WIN32 // Macro that displays the current file name and line number #define WHERE if (IsDebug()){printf("%s: %u\n", __FILE__, __LINE__); SleepThread(10);} #define WHERE32 if (IsDebug()){ \ char tmp[128]; sprintf(tmp, "%s: %u", __FILE__, __LINE__); Win32DebugAlert(tmp); \ } #define TIMECHECK if (IsDebug()){printf("%-12s:%5u", __FILE__, __LINE__);TimeCheck();} // Probe related #ifdef USE_PROBE #define PROBE_WHERE WriteProbe(__FILE__, __LINE__, ""); #define PROBE_STR(str) WriteProbe(__FILE__, __LINE__, (str)); #define PROBE_DATA2(str, data, size) WriteProbeData(__FILE__, __LINE__, (str), (data), (size)); #define PROBE_DATA(data, size) WriteProbeData(__FILE__, __LINE__, "", (data), (size)); #else // USE_PROBE #define PROBE_WHERE #define PROBE_STR(str) #define PROBE_DATA2(str, data, size) #define PROBE_DATA(data, size) #endif // USE_PROBE // Determine the performance / memory strategy #if (defined(CPU_X86) || defined(CPU_X64) || defined(CPU_X86_X64) || defined(CPU_SPARC) || defined(CPU_SPARC64) || defined(OS_WIN32) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__ia64__) || defined(__IA64__) || defined(_IA64)) #define USE_STRATEGY_PERFORMACE #else #define USE_STRATEGY_LOW_MEMORY #endif // Macro that displays the current time #ifdef WIN32 #define WHEN if (IsDebug()){WHERE; MsPrintTick();} #else // WIN32 #define WHEN #endif // WIN32 #ifdef OS_UNIX #ifndef UNIX_SOLARIS #ifndef CPU_SH4 // Getifaddrs system call is supported on UNIX other than Solaris. // However, it is not supported also by the Linux on SH4 CPU #define MAYAQUA_SUPPORTS_GETIFADDRS #endif // CPU_SH4 #endif // UNIX_SOLARIS #endif // OS_UNIX #ifdef OS_UNIX // Header only needed in UNIX OS #include #include #include #include #ifdef UNIX_LINUX #include #elif UNIX_BSD #include #include #endif #ifdef UNIX_SOLARIS #include #define USE_STATVFS #endif // UNIX_SOLARIS #include #include #include #include #include #include #include #ifdef UNIX_SOLARIS #include #endif // UNIX_SOLARIS #include #include #include #ifdef UNIX_LINUX #include #endif // UNIX_LINUX #include #include #include #include //#include #include #include #include #include #include //#include #ifdef MAYAQUA_SUPPORTS_GETIFADDRS #include #endif // MAYAQUA_SUPPORTS_GETIFADDRS #ifdef UNIX_LINUX typedef void *iconv_t; iconv_t iconv_open (__const char *__tocode, __const char *__fromcode); size_t iconv (iconv_t __cd, char **__restrict __inbuf, size_t *__restrict __inbytesleft, char **__restrict __outbuf, size_t *__restrict __outbytesleft); int iconv_close (iconv_t __cd); #else // UNIX_LINUX #include #endif // UNIX_LINUX #ifdef UNIX_LINUX #include #include #include #endif // UNIX_LINUX #ifdef UNIX_SOLARIS #include #include #include #endif // UNIX_SOLARIS #ifndef NO_VLAN #include #endif // NO_VLAN #define closesocket(s) close(s) #else // Win32 only #include #endif // OS_UNIX // IPv6 support flag #ifndef WIN32 #ifndef AF_INET6 #define NO_IPV6 #endif // AF_INET6 #endif // WIN32 // Basic type declaration #include // Object management #include // Object tracking #include // File I/O #include // Memory management #include // String processing #include // Internationalized string processing #include // Encryption processing #include // Secure token #include // Kernel #include // Package #include // Configuration file #include // String table #include // Network communication #include // TCP/IP #include // 64 bit real-time clock #include // OS-dependent code #include // Code for Microsoft Windows #include // Global variables extern bool g_memcheck; extern bool g_debug; extern char *cmdline; extern wchar_t *uni_cmdline; extern bool g_little_endian; extern LOCK *tick_manual_lock; // Kernel state #define NUM_KERNEL_STATUS 128 extern UINT64 kernel_status[NUM_KERNEL_STATUS]; extern UINT64 kernel_status_max[NUM_KERNEL_STATUS]; extern LOCK *kernel_status_lock[NUM_KERNEL_STATUS]; extern BOOL kernel_status_inited; // Kernel state operation macro #define KS_LOCK(id) LockKernelStatus(id) #define KS_UNLOCK(id) UnlockKernelStatus(id) #define KS_GET64(id) (kernel_status[id]) #define KS_GET(id) ((UINT)KS_GET64(id)) #define KS_GETMAX64(id) (kernel_status_max[id]) #define KS_GETMAX(id) ((UINT)KS_GETMAX64(id)) #ifdef DONT_USE_KERNEL_STATUS // Disable operations of the kernel status #define KS_INC(id) #define KS_DEC(id) #define KS_ADD(id, n) #define KS_SUB(id, n) #else // DONT_USE_KERNEL_STATUS // Enable operations of the kernel status #define KS_INC(id) \ if (kernel_status_inited) { \ KS_LOCK(id); \ kernel_status[id]++; \ kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]); \ KS_UNLOCK(id); \ } #define KS_DEC(id) \ if (kernel_status_inited) { \ KS_LOCK(id); \ kernel_status[id]--; \ kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]); \ KS_UNLOCK(id); \ } #define KS_ADD(id, n) \ if (kernel_status_inited) { \ KS_LOCK(id); \ kernel_status[id] += n; \ kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]); \ KS_UNLOCK(id); \ } #define KS_SUB(id, n) \ if (kernel_status_inited) { \ KS_LOCK(id); \ kernel_status[id] -= n; \ kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]); \ KS_UNLOCK(id); \ } #endif // DONT_USE_KERNEL_STATUS // Kernel status // String related #define KS_STRCPY_COUNT 0 // number of calls StrCpy #define KS_STRLEN_COUNT 1 // number of calls StrLen #define KS_STRCHECK_COUNT 2 // number of calls StrCheck #define KS_STRCAT_COUNT 3 // number of calls StrCat #define KS_FORMAT_COUNT 4 // number of calls Format // Memory related #define KS_MALLOC_COUNT 5 // Number of calls Malloc #define KS_REALLOC_COUNT 6 // Number of calls ReAlloc #define KS_FREE_COUNT 7 // number of calls Free #define KS_TOTAL_MEM_SIZE 8 // The total size of the memory that was allocated so far #define KS_CURRENT_MEM_COUNT 9 // Number of memory blocks that are currently reserved #define KS_TOTAL_MEM_COUNT 10 // The total number of memory blocks that ware allocated so far #define KS_ZERO_COUNT 11 // Number of calls Zero #define KS_COPY_COUNT 12 // Number of calls Copy // Lock related #define KS_NEWLOCK_COUNT 13 // Number of calls NewLock #define KS_DELETELOCK_COUNT 14 // Number of calls DeleteLock #define KS_LOCK_COUNT 15 // Number of calls Lock #define KS_UNLOCK_COUNT 16 // Number of calls Unlock #define KS_CURRENT_LOCK_COUNT 17 // Current number of LOCK objects #define KS_CURRENT_LOCKED_COUNT 18 // Current number of locked LOCK objects // Counter information #define KS_NEW_COUNTER_COUNT 19 // Number of calls NewCounter #define KS_DELETE_COUNTER_COUNT 20 // Number of calls DeleteCounter #define KS_INC_COUNT 21 // Number of calls Inc #define KS_DEC_COUNT 22 // Number of calls Dec #define KS_CURRENT_COUNT 23 // Current total number of counts // Reference counter information #define KS_NEWREF_COUNT 24 // Number of calls NewRef #define KS_FREEREF_COUNT 72 // Number of times REF objects are deleted #define KS_ADDREF_COUNT 25 // Number of calls AddRef #define KS_RELEASE_COUNT 26 // Number of calls Release #define KS_CURRENT_REF_COUNT 27 // Current number of REF objects #define KS_CURRENT_REFED_COUNT 28 // The sum of the current number of references // Buffer information #define KS_NEWBUF_COUNT 29 // Number of calls NewBuf #define KS_FREEBUF_COUNT 30 // NNumber of calls FreeBuf #define KS_CURRENT_BUF_COUNT 31 // Current number of objects in the BUF #define KS_READ_BUF_COUNT 32 // Number of calls ReadBuf #define KS_WRITE_BUF_COUNT 33 // Number of calls WriteBuf #define KS_ADJUST_BUFSIZE_COUNT 34 // Number of times to adjust the buffer size #define KS_SEEK_BUF_COUNT 35 // Number of calls SeekBuf // FIFO information #define KS_NEWFIFO_COUNT 36 // Number of calls NewFifo #define KS_FREEFIFO_COUNT 37 // Number of times the FIFO object is deleted #define KS_READ_FIFO_COUNT 38 // Number of calls ReadFifo #define KS_WRITE_FIFO_COUNT 39 // Number of calls WriteFifo #define KS_PEEK_FIFO_COUNT 40 // Number of calls PeekFifo // List related #define KS_NEWLIST_COUNT 41 // Number of calls NewList #define KS_FREELIST_COUNT 42 // Number of times the object LIST was deleted #define KS_INSERT_COUNT 43 // Number of calls Add #define KS_DELETE_COUNT 44 // Number of calls Delete #define KS_SORT_COUNT 45 // Number of calls Sort #define KS_SEARCH_COUNT 46 // Number of calls Search #define KS_TOARRAY_COUNT 47 // Number of calls ToArray // Queue related #define KS_NEWQUEUE_COUNT 48 // Number of calls NewQueue #define KS_FREEQUEUE_COUNT 49 // Number of times you delete the object QUEUE #define KS_PUSH_COUNT 50 // Number of calls Push #define KS_POP_COUNT 51 // Number of calls POP // Stack related #define KS_NEWSK_COUNT 52 // Number of calls NewSk #define KS_FREESK_COUNT 53 // Number of times you delete the object SK #define KS_INSERT_QUEUE_COUNT 54 // Number of calls InsertQueue #define KS_GETNEXT_COUNT 55 // Number of calls GetNext // Kernel related #define KS_GETTIME_COUNT 56 // Number of times to get the time #define KS_GETTICK_COUNT 57 // Number of times to get the system timer #define KS_NEWTHREAD_COUNT 58 // Number of calls NewThread #define KS_FREETHREAD_COUNT 59 // Number of times you delete the object THREAD #define KS_WAITFORTHREAD_COUNT 60 // Number of calls WaitForThread #define KS_NEWEVENT_COUNT 61 // Number of calls NewEvent #define KS_FREEEVENT_COUNT 62 // Number of times which EVENT object is deleted #define KS_WAIT_COUNT 63 // Number of calls Wait #define KS_SLEEPTHREAD_COUNT 64 // Number of calls SleepThread // About IO #define KS_IO_OPEN_COUNT 65 // Number of times to open the file #define KS_IO_CREATE_COUNT 66 // Number of times that the file was created #define KS_IO_CLOSE_COUNT 67 // Number of times to close the file #define KS_IO_READ_COUNT 68 // Number of times to read from the file #define KS_IO_WRITE_COUNT 69 // Number of times to write to a file #define KS_IO_TOTAL_READ_SIZE 70 // Total number of bytes read from the file #define KS_IO_TOTAL_WRITE_SIZE 71 // The total number of bytes written to the file // Memory pool related #define KS_MEMPOOL_MALLOC_COUNT 75 // Number of times to allocate the memory pool #define KS_MEMPOOL_FREE_COUNT 73 // Number of times you release the memory pool #define KS_MEMPOOL_CURRENT_NUM 74 // Current number of the memory pool #define KS_MEMPOOL_REALLOC_COUNT 76 // Number of times you have realloc the memory pool // Macro #define IsDebug() (g_debug) // A debug mode #define IsMemCheck() (g_memcheck) // Memory check mode // Function prototype void InitMayaqua(bool memcheck, bool debug, int argc, char **argv); void FreeMayaqua(); bool IsNt(); bool IsUnicode(); void MayaquaDotNetMode(); bool MayaquaIsDotNetMode(); void MayaquaMinimalMode(); bool MayaquaIsMinimalMode(); bool Is64(); bool Is32(); bool IsIA64(); bool IsX64(); void InitKernelStatus(); void FreeKernelStatus(); void PrintDebugInformation(); void LockKernelStatus(UINT id); void UnlockKernelStatus(UINT id); void PrintKernelStatus(); void InitCommandLineStr(int argc, char **argv); void FreeCommandLineStr(); void SetCommandLineStr(char *str); void SetCommandLineUniStr(wchar_t *str); char *GetCommandLineStr(); wchar_t *GetCommandLineUniStr(); void ParseCommandLineTokens(); void FreeCommandLineTokens(); TOKEN_LIST *GetCommandLineToken(); UNI_TOKEN_LIST *GetCommandLineUniToken(); void InitOsInfo(); void FreeOsInfo(); void Alert(char *msg, char *caption); void AlertW(wchar_t *msg, wchar_t *caption); OS_INFO *GetOsInfo(); UINT GetOsType(); void PrintOsInfo(OS_INFO *info); void CheckEndian(); void CheckUnixTempDir(); void TimeCheck(); void SetHamMode(); bool IsHamMode(); void InitProbe(); void FreeProbe(); void EnableProbe(bool enable); bool IsProbeEnabled(); void WriteProbe(char *filename, UINT line, char *str); void WriteProbeData(char *filename, UINT line, char *str, void *data, UINT size); USHORT CalcChecksum16(void *buf, UINT size); #ifdef OS_WIN32 // Import library (for Win32) #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "winmm.lib") #pragma comment(lib, "kernel32.lib") #pragma comment(lib, "user32.lib") #pragma comment(lib, "gdi32.lib") #pragma comment(lib, "shell32.lib") #pragma comment(lib, "comctl32.lib") #pragma comment(lib, "dbghelp.lib") #pragma comment(lib, "Iphlpapi.lib") #pragma comment(lib, "setupapi.lib") #pragma comment(lib, "version.lib") #pragma comment(lib, "Netapi32.lib") #pragma comment(lib, "shlwapi.lib") #pragma comment(lib, "crypt32.lib") #pragma warning( disable : 4099 ) #endif // OS_WIN32 // For Debugging #ifndef ENCRYPT_C //#define Disconnect(s) {Debug("Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);} #endif #endif // MAYAQUA_H