Test 1: Make WinTun work
This commit is contained in:
@@ -80,15 +80,6 @@ FetchContent_MakeAvailable(Sodium)
|
|||||||
FetchContent_MakeAvailable(asio)
|
FetchContent_MakeAvailable(asio)
|
||||||
FetchContent_MakeAvailable(cxxopts)
|
FetchContent_MakeAvailable(cxxopts)
|
||||||
|
|
||||||
# OpenSSL
|
|
||||||
find_package(OpenSSL REQUIRED)
|
|
||||||
if(OPENSSL_FOUND)
|
|
||||||
message(STATUS "Found OpenSSL version ${OPENSSL_VERSION}")
|
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "OpenSSL not found")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
# Output directories
|
# Output directories
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
@@ -108,7 +99,7 @@ endforeach()
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
file(GLOB_RECURSE COMMON_SRC CONFIGURE_DEPENDS src/common/*.cpp)
|
file(GLOB_RECURSE COMMON_SRC CONFIGURE_DEPENDS src/common/*.cpp)
|
||||||
add_library(common STATIC ${COMMON_SRC})
|
add_library(common STATIC ${COMMON_SRC})
|
||||||
target_link_libraries(common PUBLIC sodium OpenSSL::SSL OpenSSL::Crypto cxxopts::cxxopts)
|
target_link_libraries(common PUBLIC sodium cxxopts::cxxopts)
|
||||||
target_include_directories(common PUBLIC
|
target_include_directories(common PUBLIC
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
${sodium_SOURCE_DIR}/src/libsodium/include
|
${sodium_SOURCE_DIR}/src/libsodium/include
|
||||||
@@ -122,7 +113,7 @@ target_compile_definitions(common PUBLIC ASIO_STANDALONE)
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
file(GLOB_RECURSE CLIENT_SRC CONFIGURE_DEPENDS src/client/*.cpp)
|
file(GLOB_RECURSE CLIENT_SRC CONFIGURE_DEPENDS src/client/*.cpp)
|
||||||
add_executable(client ${CLIENT_SRC})
|
add_executable(client ${CLIENT_SRC})
|
||||||
target_link_libraries(client PRIVATE common sodium OpenSSL::SSL OpenSSL::Crypto cxxopts::cxxopts)
|
target_link_libraries(client PRIVATE common sodium cxxopts::cxxopts)
|
||||||
target_include_directories(client PRIVATE
|
target_include_directories(client PRIVATE
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
${sodium_SOURCE_DIR}/src/libsodium/include
|
${sodium_SOURCE_DIR}/src/libsodium/include
|
||||||
@@ -137,7 +128,7 @@ set_target_properties(client PROPERTIES OUTPUT_NAME "columnlynx_client")
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
file(GLOB_RECURSE SERVER_SRC CONFIGURE_DEPENDS src/server/*.cpp)
|
file(GLOB_RECURSE SERVER_SRC CONFIGURE_DEPENDS src/server/*.cpp)
|
||||||
add_executable(server ${SERVER_SRC})
|
add_executable(server ${SERVER_SRC})
|
||||||
target_link_libraries(server PRIVATE common sodium OpenSSL::SSL OpenSSL::Crypto cxxopts::cxxopts)
|
target_link_libraries(server PRIVATE common sodium cxxopts::cxxopts)
|
||||||
target_include_directories(server PRIVATE
|
target_include_directories(server PRIVATE
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
${sodium_SOURCE_DIR}/src/libsodium/include
|
${sodium_SOURCE_DIR}/src/libsodium/include
|
||||||
|
|||||||
@@ -28,11 +28,11 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
#include <wintun/wintun.h>
|
#include <wintun/wintun.h>
|
||||||
#pragma comment(lib, "advapi32.lib")
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ColumnLynx::Net {
|
namespace ColumnLynx::Net {
|
||||||
@@ -127,7 +127,9 @@ namespace ColumnLynx::Net {
|
|||||||
std::string mIfName;
|
std::string mIfName;
|
||||||
int mFd; // POSIX
|
int mFd; // POSIX
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
HANDLE mHandle; // Windows
|
WINTUN_ADAPTER_HANDLE mAdapter = nullptr;
|
||||||
|
WINTUN_SESSION_HANDLE mSession = nullptr;
|
||||||
|
HANDLE mHandle = nullptr;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,47 @@
|
|||||||
|
|
||||||
// This is all fucking voodoo dark magic.
|
// This is all fucking voodoo dark magic.
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
static HMODULE gWintun = nullptr;
|
||||||
|
|
||||||
|
static WintunOpenAdapterFn WintunOpenAdapter;
|
||||||
|
static WintunStartSessionFn WintunStartSession;
|
||||||
|
static WintunEndSessionFn WintunEndSession;
|
||||||
|
static WintunGetReadWaitEventFn WintunGetReadWaitEvent;
|
||||||
|
static WintunReceivePacketFn WintunReceivePacket;
|
||||||
|
static WintunReleaseReceivePacketFn WintunReleaseReceivePacket;
|
||||||
|
static WintunAllocateSendPacketFn WintunAllocateSendPacket;
|
||||||
|
static WintunSendPacketFn WintunSendPacket;
|
||||||
|
|
||||||
|
static void InitializeWintun()
|
||||||
|
{
|
||||||
|
if (gWintun)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gWintun = LoadLibraryExW(L"wintun.dll", nullptr,
|
||||||
|
LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
|
||||||
|
if (!gWintun)
|
||||||
|
throw std::runtime_error("Failed to load wintun.dll");
|
||||||
|
|
||||||
|
#define RESOLVE(name) \
|
||||||
|
name = (name##Fn)GetProcAddress(gWintun, #name); \
|
||||||
|
if (!name) throw std::runtime_error("Missing Wintun symbol: " #name);
|
||||||
|
|
||||||
|
RESOLVE(WintunOpenAdapter)
|
||||||
|
RESOLVE(WintunStartSession)
|
||||||
|
RESOLVE(WintunEndSession)
|
||||||
|
RESOLVE(WintunGetReadWaitEvent)
|
||||||
|
RESOLVE(WintunReceivePacket)
|
||||||
|
RESOLVE(WintunReleaseReceivePacket)
|
||||||
|
RESOLVE(WintunAllocateSendPacket)
|
||||||
|
RESOLVE(WintunSendPacket)
|
||||||
|
|
||||||
|
#undef RESOLVE
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
namespace ColumnLynx::Net {
|
namespace ColumnLynx::Net {
|
||||||
// ------------------------------ Constructor ------------------------------
|
// ------------------------------ Constructor ------------------------------
|
||||||
VirtualInterface::VirtualInterface(const std::string& ifName)
|
VirtualInterface::VirtualInterface(const std::string& ifName)
|
||||||
@@ -63,20 +104,23 @@ namespace ColumnLynx::Net {
|
|||||||
Utils::log("VirtualInterface: opened macOS UTUN: " + mIfName);
|
Utils::log("VirtualInterface: opened macOS UTUN: " + mIfName);
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
// ---- Windows: Wintun (WireGuard virtual adapter) ----
|
|
||||||
WINTUN_ADAPTER_HANDLE adapter =
|
|
||||||
WintunOpenAdapter(L"ColumnLynx", std::wstring(ifName.begin(), ifName.end()).c_str());
|
|
||||||
if (!adapter)
|
|
||||||
throw std::runtime_error("Wintun adapter not found or not installed");
|
|
||||||
|
|
||||||
WINTUN_SESSION_HANDLE session =
|
InitializeWintun();
|
||||||
WintunStartSession(adapter, 0x200000); // ring buffer size
|
|
||||||
if (!session)
|
mAdapter = WintunOpenAdapter(
|
||||||
|
L"ColumnLynx",
|
||||||
|
std::wstring(ifName.begin(), ifName.end()).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!mAdapter)
|
||||||
|
throw std::runtime_error("Wintun adapter not found");
|
||||||
|
|
||||||
|
mSession = WintunStartSession(mAdapter, 0x200000);
|
||||||
|
if (!mSession)
|
||||||
throw std::runtime_error("Failed to start Wintun session");
|
throw std::runtime_error("Failed to start Wintun session");
|
||||||
|
|
||||||
mHandle = WintunGetReadWaitEvent(session);
|
mHandle = WintunGetReadWaitEvent(mSession);
|
||||||
mFd = -1; // not used on Windows
|
mFd = -1;
|
||||||
mIfName = ifName;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
throw std::runtime_error("Unsupported platform");
|
throw std::runtime_error("Unsupported platform");
|
||||||
@@ -89,9 +133,8 @@ namespace ColumnLynx::Net {
|
|||||||
if (mFd >= 0)
|
if (mFd >= 0)
|
||||||
close(mFd);
|
close(mFd);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
// Wintun sessions need explicit stop
|
if (mSession)
|
||||||
// (assuming you stored the session handle as member)
|
WintunEndSession(mSession);
|
||||||
// WintunEndSession(mSession);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,9 +201,12 @@ namespace ColumnLynx::Net {
|
|||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
WINTUN_PACKET* packet = WintunReceivePacket(mSession, nullptr);
|
WINTUN_PACKET* packet = WintunReceivePacket(mSession, nullptr);
|
||||||
if (!packet) return {};
|
if (!packet)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::vector<uint8_t> buf(packet->Data,
|
||||||
|
packet->Data + packet->Length);
|
||||||
|
|
||||||
std::vector<uint8_t> buf(packet->Data, packet->Data + packet->Length);
|
|
||||||
WintunReleaseReceivePacket(mSession, packet);
|
WintunReleaseReceivePacket(mSession, packet);
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
@@ -206,7 +252,10 @@ namespace ColumnLynx::Net {
|
|||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
WINTUN_PACKET* tx = WintunAllocateSendPacket(mSession, (DWORD)packet.size());
|
WINTUN_PACKET* tx =
|
||||||
|
WintunAllocateSendPacket(mSession,
|
||||||
|
static_cast<DWORD>(packet.size()));
|
||||||
|
|
||||||
if (!tx)
|
if (!tx)
|
||||||
throw std::runtime_error("WintunAllocateSendPacket failed");
|
throw std::runtime_error("WintunAllocateSendPacket failed");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user