mirror of
				https://github.com/xjasonlyu/tun2socks.git
				synced 2025-11-01 04:22:44 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			224 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include "lwip/opt.h"
 | |
| #include "lwip/sys.h"
 | |
| 
 | |
| #ifdef _WIN32
 | |
|   // defines both win32 and win64
 | |
|   #ifdef _MSC_VER
 | |
|   #pragma warning (push, 3)
 | |
|   #endif
 | |
|   #include <windows.h>
 | |
|   #ifdef _MSC_VER
 | |
|   #pragma warning (pop)
 | |
|   #endif
 | |
|   #include <time.h>
 | |
|   
 | |
|   #include <lwip/arch.h>
 | |
|   #include <lwip/stats.h>
 | |
|   #include <lwip/debug.h>
 | |
|   #include <lwip/tcpip.h>
 | |
|   
 | |
|   /** Set this to 1 to enable assertion checks that SYS_ARCH_PROTECT() is only
 | |
|    * called once in a call stack (calling it nested might cause trouble in some
 | |
|    * implementations, so let's avoid this in core code as long as we can).
 | |
|    */
 | |
|   #ifndef LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
 | |
|   #define LWIP_SYS_ARCH_CHECK_NESTED_PROTECT 1
 | |
|   #endif
 | |
|   
 | |
|   /** Set this to 1 to enable assertion checks that SYS_ARCH_PROTECT() is *not*
 | |
|    * called before functions potentiolly involving the OS scheduler.
 | |
|    *
 | |
|    * This scheme is currently broken only for non-core-locking when waking up
 | |
|    * threads waiting on a socket via select/poll.
 | |
|    */
 | |
|   #ifndef LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED
 | |
|   #define LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED LWIP_TCPIP_CORE_LOCKING
 | |
|   #endif
 | |
|   
 | |
|   #define LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER (LWIP_SYS_ARCH_CHECK_NESTED_PROTECT || LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED)
 | |
|   
 | |
|   /* These functions are used from NO_SYS also, for precise timer triggering */
 | |
|   static LARGE_INTEGER freq, sys_start_time;
 | |
|   #define SYS_INITIALIZED() (freq.QuadPart != 0)
 | |
|   
 | |
|   static DWORD netconn_sem_tls_index;
 | |
|   
 | |
|   static HCRYPTPROV hcrypt;
 | |
|   
 | |
|   u32_t
 | |
|   sys_win_rand(void)
 | |
|   {
 | |
|     u32_t ret;
 | |
|     if (CryptGenRandom(hcrypt, sizeof(ret), (BYTE*)&ret)) {
 | |
|       return ret;
 | |
|     }
 | |
|     LWIP_ASSERT("CryptGenRandom failed", 0);
 | |
|     return 0;
 | |
|   }
 | |
|   
 | |
|   static void
 | |
|   sys_win_rand_init(void)
 | |
|   {
 | |
|     if (!CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, 0)) {
 | |
|       DWORD err = GetLastError();
 | |
|       LWIP_PLATFORM_DIAG(("CryptAcquireContext failed with error %d, trying to create NEWKEYSET", (int)err));
 | |
|       if(!CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
 | |
|         char errbuf[128];
 | |
|         err = GetLastError();
 | |
|         snprintf(errbuf, sizeof(errbuf), "CryptAcquireContext failed with error %d", (int)err);
 | |
|         LWIP_UNUSED_ARG(err);
 | |
|         LWIP_ASSERT(errbuf, 0);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   static void
 | |
|   sys_init_timing(void)
 | |
|   {
 | |
|     QueryPerformanceFrequency(&freq);
 | |
|     QueryPerformanceCounter(&sys_start_time);
 | |
|   }
 | |
|   
 | |
|   static LONGLONG
 | |
|   sys_get_ms_longlong(void)
 | |
|   {
 | |
|     LONGLONG ret;
 | |
|     LARGE_INTEGER now;
 | |
|   #if NO_SYS
 | |
|     if (!SYS_INITIALIZED()) {
 | |
|       sys_init();
 | |
|       LWIP_ASSERT("initialization failed", SYS_INITIALIZED());
 | |
|     }
 | |
|   #endif /* NO_SYS */
 | |
|     QueryPerformanceCounter(&now);
 | |
|     ret = now.QuadPart-sys_start_time.QuadPart;
 | |
|     return (u32_t)(((ret)*1000)/freq.QuadPart);
 | |
|   }
 | |
|   
 | |
|   u32_t
 | |
|   sys_jiffies(void)
 | |
|   {
 | |
|     return (u32_t)sys_get_ms_longlong();
 | |
|   }
 | |
|   
 | |
|   u32_t
 | |
|   sys_now(void)
 | |
|   {
 | |
|     return (u32_t)sys_get_ms_longlong();
 | |
|   }
 | |
|   
 | |
|   CRITICAL_SECTION critSec;
 | |
|   #if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
 | |
|   static int protection_depth;
 | |
|   #endif
 | |
|   
 | |
|   static void
 | |
|   InitSysArchProtect(void)
 | |
|   {
 | |
|     InitializeCriticalSection(&critSec);
 | |
|   }
 | |
|   
 | |
|   sys_prot_t
 | |
|   sys_arch_protect(void)
 | |
|   {
 | |
|   #if NO_SYS
 | |
|     if (!SYS_INITIALIZED()) {
 | |
|       sys_init();
 | |
|       LWIP_ASSERT("initialization failed", SYS_INITIALIZED());
 | |
|     }
 | |
|   #endif
 | |
|     EnterCriticalSection(&critSec);
 | |
|   #if LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
 | |
|     LWIP_ASSERT("nested SYS_ARCH_PROTECT", protection_depth == 0);
 | |
|   #endif
 | |
|   #if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
 | |
|     protection_depth++;
 | |
|   #endif
 | |
|     return 0;
 | |
|   }
 | |
|   
 | |
|   void
 | |
|   sys_arch_unprotect(sys_prot_t pval)
 | |
|   {
 | |
|     LWIP_UNUSED_ARG(pval);
 | |
|   #if LWIP_SYS_ARCH_CHECK_NESTED_PROTECT
 | |
|     LWIP_ASSERT("missing SYS_ARCH_PROTECT", protection_depth == 1);
 | |
|   #else
 | |
|     LWIP_ASSERT("missing SYS_ARCH_PROTECT", protection_depth > 0);
 | |
|   #endif
 | |
|   #if LWIP_WIN32_SYS_ARCH_ENABLE_PROTECT_COUNTER
 | |
|     protection_depth--;
 | |
|   #endif
 | |
|     LeaveCriticalSection(&critSec);
 | |
|   }
 | |
|   
 | |
|   #if LWIP_SYS_ARCH_CHECK_SCHEDULING_UNPROTECTED
 | |
|   /** This checks that SYS_ARCH_PROTECT() hasn't been called by protecting
 | |
|    * and then checking the level
 | |
|    */
 | |
|   static void
 | |
|   sys_arch_check_not_protected(void)
 | |
|   {
 | |
|     sys_arch_protect();
 | |
|     LWIP_ASSERT("SYS_ARCH_PROTECT before scheduling", protection_depth == 1);
 | |
|     sys_arch_unprotect(0);
 | |
|   }
 | |
|   #else
 | |
|   #define sys_arch_check_not_protected()
 | |
|   #endif
 | |
|   
 | |
|   static void
 | |
|   msvc_sys_init(void)
 | |
|   {
 | |
|     sys_win_rand_init();
 | |
|     sys_init_timing();
 | |
|     InitSysArchProtect();
 | |
|     netconn_sem_tls_index = TlsAlloc();
 | |
|     LWIP_ASSERT("TlsAlloc failed", netconn_sem_tls_index != TLS_OUT_OF_INDEXES);
 | |
|   }
 | |
|   
 | |
|   void
 | |
|   sys_init(void)
 | |
|   {
 | |
|     msvc_sys_init();
 | |
|   }
 | |
| 
 | |
|   #include <stdarg.h>
 | |
|   
 | |
|   /* This is an example implementation for LWIP_PLATFORM_DIAG:
 | |
|    * format a string and pass it to your output function.
 | |
|    */
 | |
|   void
 | |
|   lwip_win32_platform_diag(const char *format, ...)
 | |
|   {
 | |
|     va_list ap;
 | |
|     /* get the varargs */
 | |
|     va_start(ap, format);
 | |
|     /* print via varargs; to use another output function, you could use
 | |
|        vsnprintf here */
 | |
|     vprintf(format, ap);
 | |
|     va_end(ap);
 | |
|   }
 | |
| #elif __APPLE__
 | |
|     #include <mach/mach_time.h>
 | |
|     u32_t sys_now(void) {
 | |
|         uint64_t now = mach_absolute_time();
 | |
|         mach_timebase_info_data_t info;
 | |
|         mach_timebase_info(&info);
 | |
|         now = now * info.numer / info.denom / NSEC_PER_MSEC;
 | |
|         return (u32_t)(now);
 | |
|     }
 | |
| #elif __linux
 | |
|     #include <sys/time.h>
 | |
|     u32_t sys_now(void)
 | |
|     {
 | |
|         struct timeval te;
 | |
|         gettimeofday(&te, NULL);
 | |
|         return te.tv_sec*1000LL + te.tv_usec/1000;
 | |
|     }
 | |
| #elif __unix // all unices not caught above
 | |
|     // Unix
 | |
| #elif __posix
 | |
|     // POSIX
 | |
| #endif
 | 
