Merge pull request #283 from despair86/dev

more windows fixes
pull/287/head
Jeff 5 years ago committed by GitHub
commit 1369c3b23c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,7 @@ option(USE_LIBABYSS "enable libabyss" )
option(USE_AVX2 "enable avx2 code" )
option(USE_NETNS "enable networking namespace support. Linux only" )
option(AMD_RYZEN_HACK "hack for AMD Ryzen FPU bug (support FMA3 and FMA4 in FPU, but does not show in CPUID)" )
option(STATIC_LINK "emit fully linked binaries" )
option(STATIC_LINK_RUNTIME "link statically against compiler runtime, standard library and pthreads")
option(NON_PC_TARGET "non-pc target build: iphone, andriod, embedded non-i386 SBC, etc" )
option(SHADOW "use shadow testing framework. linux only" )
option(ASAN "use address sanitiser, if your system has it" )
@ -32,20 +32,27 @@ if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND SHADOW)
message( FATAL_ERROR "shadow-framework is Linux only" )
endif(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND SHADOW)
if (STATIC_LINK AND SHADOW)
# might be redundant. Waiting on new 2U blade to spin up new
# lunix box -rick
if (STATIC_LINK_RUNTIME AND SHADOW)
message(FATAL_ERROR "the shadow-framework build cannot be linked statically!")
endif(STATIC_LINK AND SHADOW)
endif(STATIC_LINK_RUNTIME AND SHADOW)
if (WIN32 AND NOT STATIC_LINK)
message("Shared object builds are not yet supported for Windows, linking statically")
set(STATIC_LINK ON)
endif(WIN32 AND NOT STATIC_LINK)
if (WIN32 AND NOT STATIC_LINK_RUNTIME)
message("must ship compiler runtime libraries with this build: libwinpthread-1.dll, libgcc_s_dw2-1.dll, and libstdc++-6.dll")
message("for release builds, turn on STATIC_LINK_RUNTIME in cmake options")
#set(STATIC_LINK_RUNTIME ON)
endif(WIN32 AND NOT STATIC_LINK_RUNTIME)
add_compile_options(-fPIC)
# still need the headers unconditionally
set(ABSEIL_DIR vendor/abseil-cpp)
add_subdirectory(${ABSEIL_DIR})
include_directories(${ABSEIL_DIR})
if (NOT WIN32)
add_compile_options(-fPIC)
add_subdirectory(${ABSEIL_DIR})
endif(NOT WIN32)
# turns off those annoying warnings for
# target-specific crypto code paths not
# applicable to the host's FPU -rick
@ -86,6 +93,10 @@ endif(WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
if(WIN32)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-bad-function-cast>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-cast-function-type>)
# unlike unix where you get a *single* compiler ID string in .comment
# GNU ld sees fit to merge *all* the .ident sections in object files
# to .r[o]data section one after the other!
add_compile_options(-fno-ident)
set(FS_LIB stdc++fs)
endif(WIN32)
@ -104,27 +115,24 @@ else()
endif(DEBIAN)
# only needed if using AVX2
# TODO: generate a config-time test for this
# in cmake
if(AMD_RYZEN_HACK AND USE_AVX2)
set(CRYPTO_FLAGS -march=native -mfpmath=sse -mavx -mavx2 -mfma)
endif(AMD_RYZEN_HACK AND USE_AVX2)
if(WITH_SHARED)
set(CRYPTO_FLAGS ${CRYPTO_FLAGS} -fPIC)
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if(STATIC_LINK)
if(STATIC_LINK_RUNTIME)
add_compile_options(-static)
if(USING_CLANG)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static -Wl,--whole-archive -Wl,--no-whole-archive")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" )
endif(USING_CLANG)
endif(STATIC_LINK)
endif(STATIC_LINK_RUNTIME)
if(USE_NETNS)
add_definitions(-DNETNS=1)
@ -346,6 +354,7 @@ set(LIB_PLATFORM_SRC
${ISOLATE_PROC_SRC}
# tun
${LIBTUNTAP_SRC}
${EV_SRC}
# c++17 compat code
${CXX_COMPAT_SRC}
# win32 inline code
@ -502,7 +511,6 @@ set(DNSLIB_SRC
set(LIB_SRC
${DNSLIB_SRC}
${EV_SRC}
${UTP_SRC}
llarp/config.cpp
llarp/context.cpp
@ -698,11 +706,11 @@ if(USE_LIBABYSS)
${ABYSS}/src/json.cpp)
add_library(${ABYSS_LIB} STATIC ${ABYSS_SRC})
set(ALL_SRC ${ALL_SRC} ${ABYSS_SRC} ${ABYSS}/main.cpp)
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
if (NOT WIN32)
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
target_link_libraries(${ABYSS_EXE} ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB} Threads::Threads)
else()
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp llarp/win32/abyss.rc)
target_link_libraries(${ABYSS_EXE} ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi Threads::Threads)
endif(NOT WIN32)
@ -727,8 +735,8 @@ else()
add_executable(${TEST_EXE} ${TEST_SRC})
add_executable(${EXE} ${EXE_SRC})
else()
add_executable(${TEST_EXE} ${TEST_SRC} llarp/constants/version.rc)
add_executable(${EXE} ${EXE_SRC} llarp/constants/version.rc)
add_executable(${TEST_EXE} ${TEST_SRC} llarp/win32/test.rc)
add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc)
endif(NOT WIN32)
target_include_directories(${TEST_EXE} PRIVATE test)
@ -747,7 +755,14 @@ else()
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
add_library(${UTIL_LIB} STATIC ${LIB_UTIL_SRC})
# cut back on fluff
if (NOT WIN32)
target_link_libraries(${UTIL_LIB} absl::optional)
else()
target_link_libraries(${UTIL_LIB})
endif(NOT WIN32)
add_library(${PLATFORM_LIB} STATIC ${LIB_PLATFORM_SRC})
if(USE_LIBABYSS)
@ -780,7 +795,11 @@ else()
if(WITH_SHARED)
add_library(${SHARED_LIB} SHARED ${LIB_SRC})
target_link_libraries(${SHARED_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS} ${UTIL_LIB} ${PLATFORM_LIB} Threads::Threads)
install(TARGETS ${SHARED_LIB} LIBRARY DESTINATION lib)
if (WIN32)
target_link_libraries(${SHARED_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS} ${UTIL_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi Threads::Threads)
else (NOT WIN32)
target_link_libraries(${SHARED_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS} ${UTIL_LIB} ${PLATFORM_LIB} Threads::Threads)
install(TARGETS ${SHARED_LIB} LIBRARY DESTINATION lib)
endif(WIN32)
endif(WITH_SHARED)
endif(SHADOW)

@ -70,11 +70,11 @@ BUILD_ROOT = $(REPO)/build
SCAN_BUILD ?= scan-build
CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'")
CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'")
ANALYZE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'")
ANALYZE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'")
COVERAGE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DWITH_COVERAGE=yes '$(REPO)'")
COVERAGE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DWITH_COVERAGE=yes '$(REPO)'")
TARGETS = $(REPO)/lokinet
SIGS = $(TARGETS:=.sig)
@ -102,7 +102,7 @@ debug-configure:
release-configure: clean
mkdir -p '$(BUILD_ROOT)'
$(CONFIG_CMD) -DSTATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
$(CONFIG_CMD) -DSTATIC_LINK_RUNTIME=ON -DCMAKE_BUILD_TYPE=Release -DRELEASE_MOTTO="$(shell cat motto.txt)" -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)'
debug: debug-configure
$(MAKE) -C $(BUILD_ROOT)

@ -1,4 +1,4 @@
Copyright (c)2018 Rick V. All rights reserved.
Copyright (c)2018-2019 Rick V. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

@ -17,11 +17,16 @@ LIBS ?=
WINNT_INCLUDE ?=
WINNT_LIBS ?=
ifdef LTO
LTO_FLAG = -flto
LTO_LDFLAG = -flto -march=nocona -mfpmath=sse -Ofast
endif
.PHONY: download prepare all default
# windows target only
.c.o:
$(CC) $(WINNT_INCLUDE) -Iinclude -Ofast -march=nocona -mfpmath=sse $< -c
$(CC) $(WINNT_INCLUDE) -Iinclude $(LTO_FLAG) -Ofast -march=nocona -mfpmath=sse $< -c
zpipe: zpipe.c miniz.c
$(NATIVE_CC) $(INCLUDE) -Iinclude $(LIBS) $^ -s -static -o $@
@ -38,24 +43,24 @@ prepare: zpipe base64enc download
./base64enc < data.enc > out.bin
sed -ie "s/.\{76\}/&\n/g" out.bin
sed -i 's/.*/\"&\"/g' out.bin
sed -i '51,2258d' bootstrap.c
sed -i '61,2268d' bootstrap.c
echo ';' >> out.bin
sed -i '50r out.bin' bootstrap.c
sed -i '60r out.bin' bootstrap.c
prepare-testnet: zpipe base64enc download
./zpipe < cacert.pem > data.enc
./base64enc < data.enc > out.bin
sed -ie "s/.\{76\}/&\n/g" out.bin
sed -i 's/.*/\"&\"/g' out.bin
sed -i '49,2135d' testnet.c
sed -i '58,2144d' testnet.c
echo ';' >> out.bin
sed -i '48r out.bin' testnet.c
sed -i '57r out.bin' testnet.c
lokinet-bootstrap: bootstrap.o miniz.o
$(CC) $(WINNT_LIBS) -static -s $^ -o $@.exe -lmbedx509 -lmbedtls -lmbedcrypto -lws2_32
$(CC) $(WINNT_LIBS) -s -static $^ -o $@.exe $(LTO_LDFLAG) -lmbedx509 -lmbedtls -lmbedcrypto -lws2_32
lokinet-bootstrap-testnet: testnet.o miniz.o
$(CC) $(WINNT_LIBS) -static -s $^ -o $@.exe -lmbedx509 -lmbedtls -lmbedcrypto -lws2_32
$(CC) $(WINNT_LIBS) -s -static $^ -o $@.exe $(LTO_LDFLAG) -lmbedx509 -lmbedtls -lmbedcrypto -lws2_32
clean:
-@rm lokinet*.exe
-@rm base64enc

@ -1,5 +1,5 @@
/*
* Copyright (c)2018 Rick V. All rights reserved.
* Copyright (c)2018-2019 Rick V. All rights reserved.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@ -18,6 +18,16 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
/* this is a tiny build-time utility that base64 encodes up to 512K
* of text/binary data from stdin. (On UNIX, we'd use GNU's [g]base64(1)
* to encode the stream. Can't guarantee that a windows user will have cygwin
* installed, so we bootstrap these at build-time instead.)
*
* here, it is used to encode the compressed zlib-stream of the
* Netscape root certificate trust store on behalf of the lokinet
* for NT bootstrap stubs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

@ -1,5 +1,5 @@
/*
* Copyright (c)2018 Rick V. All rights reserved.
* Copyright (c)2018-2019 Rick V. All rights reserved.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@ -54,7 +54,7 @@ mbedtls_x509_crt cacert;
unsigned char* ca_certs;
/* imageboard ref just because */
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.13.0;U;Windows NT ";
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.16.0;U;Windows NT ";
/* netscape ca bundle */
static const unsigned char ca_cert_store_encoded[] =

@ -1,5 +1,5 @@
/*
* Copyright (c)2018 Rick V. All rights reserved.
* Copyright (c)2018-2019 Rick V. All rights reserved.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@ -53,7 +53,7 @@ mbedtls_x509_crt cacert;
unsigned char* ca_certs;
static const char* request = "GET /i2procks.signed HTTP/1.0\r\n";
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.13.0;U;Windows NT ";
static char userAgent[] = "NetRunner_Micro/0.1 PolarSSL/2.16.0;U;Windows NT ";
static const unsigned char ca_cert_store_encoded[] =
"eAG8/Uey69izPYz1MYqKUENSUN+fBAhDKEINeEMCJLzpKOAIbwgPzEJD0AA0AXUVmpc2z7m+bpnf"
"e+/Tjbp1zgVBAtjcO3PlWrkz/w//B+j/8H/4g56auEr+aJ9/MNQfetuOfzBJP+bPPArGZABnvE/6"

@ -181,8 +181,13 @@ int main(int argc, char **argv)
SET_BINARY_MODE(stdout);
/* do compression if no arguments */
/* Warning: Not compatible with plain libz, dial it back down to
* 9 if this is required, uber-level is 10
* since we have everything crammed in miniz, we don't depend on
* libz at all.
*/
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
ret = def(stdin, stdout, MZ_UBER_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;

@ -6,7 +6,10 @@
#include <getopt.h>
#include <signal.h>
#if !defined(_WIN32) && !defined(__OpenBSD__)
#include <wordexp.h>
#endif
#include <string>
#include <iostream>
@ -62,6 +65,9 @@ handle_signal_win32(DWORD fdwCtrlType)
std::string
resolvePath(std::string conffname)
{
// implemented in netbsd, removed downstream for security reasons
// even though it is defined by POSIX.1-2001+
#if !defined(_WIN32) && !defined(__OpenBSD__)
wordexp_t exp_result;
wordexp(conffname.c_str(), &exp_result, 0);
char *resolvedPath = realpath(exp_result.we_wordv[0], NULL);
@ -71,6 +77,11 @@ resolvePath(std::string conffname)
return "";
}
return resolvedPath;
#else
// TODO(despair): dig through LLVM local patch set
// one of these exists deep in the bowels of LLVMSupport
return conffname; // eww, easier said than done outside of cygwin
#endif
}
int
@ -110,11 +121,6 @@ main(int argc, char *argv[])
genconfigOnly = true;
break;
case 'r':
#ifdef _WIN32
llarp::LogWarn(
"please don't try this at home, the relay feature is untested on "
"windows server --R.");
#endif
asRouter = true;
break;
case 'f':
@ -227,7 +233,7 @@ main(int argc, char *argv[])
}
// this is important, can downgrade from Info though
llarp::LogInfo("Running from: ", cpp17::filesystem::current_path());
llarp::LogInfo("Running from: ", fs::current_path().string());
llarp::LogInfo("Using config file: ", conffname);
ctx = llarp_main_init(conffname.c_str(), multiThreaded);
int code = 1;

@ -95,7 +95,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite,
}
// write fname ini
std::ofstream f(fname);
std::ofstream f(fname, std::ios::out | std::ios::binary);
if(!f.is_open())
{
llarp::LogError("failed to open ", fname, " for writing");
@ -239,7 +239,8 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath)
// start client.ini
// write fname ini
{
std::ofstream clientini_f(snappExample_fpath);
std::ofstream clientini_f(snappExample_fpath,
std::ios::binary | std::ios::out);
if(f.is_open())
{
clientini_f << "# this is an example configuration for a snapp";

@ -28,6 +28,7 @@ llarp_ev_loop_alloc(struct llarp_ev_loop **ev)
#elif defined(_WIN32) || defined(_WIN64) || defined(__NT__)
*ev = new llarp_win32_loop;
#else
// TODO: fall back to a generic select-based event loop
#error no event loop subclass
#endif
(*ev)->init();

@ -1 +1,533 @@
#include <ev/ev_epoll.hpp>
#ifdef ANDROID
/** TODO: correct this value */
#define SOCK_NONBLOCK (0)
#endif
namespace llarp
{
inline int
tcp_conn::read(byte_t* buf, size_t sz)
{
if(_shouldClose)
return -1;
ssize_t amount = ::read(fd, buf, sz);
if(amount > 0)
{
if(tcp.read)
tcp.read(&tcp, llarp_buffer_t(buf, amount));
}
else
{
// error
_shouldClose = true;
return -1;
}
return 0;
}
inline void
tcp_conn::flush_write()
{
connected();
ev_io::flush_write();
}
inline ssize_t
tcp_conn::do_write(void* buf, size_t sz)
{
if(_shouldClose)
return -1;
// pretty much every UNIX system still extant, _including_ solaris
// (on both sides of the fork) can ignore SIGPIPE....except
// the other vendored systems... -rick
return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe
}
inline void
tcp_conn::connect()
{
socklen_t slen = sizeof(sockaddr_in);
if(_addr.ss_family == AF_UNIX)
slen = sizeof(sockaddr_un);
else if(_addr.ss_family == AF_INET6)
slen = sizeof(sockaddr_in6);
int result = ::connect(fd, (const sockaddr*)&_addr, slen);
if(result == 0)
{
llarp::LogDebug("connected immedidately");
connected();
}
else if(errno == EINPROGRESS)
{
// in progress
llarp::LogDebug("connect in progress");
errno = 0;
return;
}
else if(_conn->error)
{
// wtf?
llarp::LogError("error connecting ", strerror(errno));
_conn->error(_conn);
}
}
inline int
tcp_serv::read(byte_t*, size_t)
{
int new_fd = ::accept(fd, nullptr, nullptr);
if(new_fd == -1)
{
llarp::LogError("failed to accept on ", fd, ":", strerror(errno));
return -1;
}
// build handler
llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd);
if(loop->add_ev(connimpl, true))
{
// call callback
if(tcp->accepted)
tcp->accepted(tcp, &connimpl->tcp);
return 0;
}
// cleanup error
delete connimpl;
return -1;
}
bool
udp_listener::tick()
{
if(udp->tick)
udp->tick(udp);
return true;
}
int
udp_listener::read(byte_t* buf, size_t sz)
{
llarp_buffer_t b;
b.base = buf;
b.cur = b.base;
sockaddr_in6 src;
socklen_t slen = sizeof(sockaddr_in6);
sockaddr* addr = (sockaddr*)&src;
ssize_t ret = ::recvfrom(fd, b.base, sz, 0, addr, &slen);
if(ret < 0)
return -1;
if(static_cast< size_t >(ret) > sz)
return -1;
b.sz = ret;
udp->recvfrom(udp, addr, ManagedBuffer{b});
return 0;
}
int
udp_listener::sendto(const sockaddr* to, const void* data, size_t sz)
{
socklen_t slen;
switch(to->sa_family)
{
case AF_INET:
slen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
slen = sizeof(struct sockaddr_in6);
break;
default:
return -1;
}
ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen);
if(sent == -1)
{
llarp::LogWarn(strerror(errno));
}
return sent;
}
int
tun::sendto(__attribute__((unused)) const sockaddr* to,
__attribute__((unused)) const void* data,
__attribute__((unused)) size_t sz)
{
return -1;
}
bool
tun::tick()
{
if(t->tick)
t->tick(t);
flush_write();
return true;
}
void
tun::flush_write()
{
if(t->before_write)
t->before_write(t);
ev_io::flush_write();
}
int
tun::read(byte_t* buf, size_t sz)
{
ssize_t ret = tuntap_read(tunif, buf, sz);
if(ret > 0 && t->recvpkt)
{
// does not have pktinfo
t->recvpkt(t, llarp_buffer_t(buf, ret));
}
return ret;
}
int
tun::wait_for_fd_promise(struct device* dev)
{
llarp::tun* t = static_cast< llarp::tun* >(dev->user);
if(t->t->get_fd_promise)
{
struct llarp_fd_promise* promise = t->t->get_fd_promise(t->t);
if(promise)
return llarp_fd_promise_wait_for_value(promise);
}
return -1;
}
bool
tun::setup()
{
// for android
if(t->get_fd_promise)
{
tunif->obtain_fd = &wait_for_fd_promise;
tunif->user = this;
}
llarp::LogDebug("set ifname to ", t->ifname);
strncpy(tunif->if_name, t->ifname, sizeof(tunif->if_name));
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
{
llarp::LogWarn("failed to start interface");
return false;
}
if(t->get_fd_promise == nullptr)
{
if(tuntap_up(tunif) == -1)
{
llarp::LogWarn("failed to put interface up: ", strerror(errno));
return false;
}
if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1)
{
llarp::LogWarn("failed to set ip");
return false;
}
}
fd = tunif->tun_fd;
if(fd == -1)
return false;
// set non blocking
int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
return false;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1;
}
}; // namespace llarp
bool
llarp_epoll_loop::tcp_connect(struct llarp_tcp_connecter* tcp,
const sockaddr* remoteaddr)
{
// create socket
int fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0);
if(fd == -1)
return false;
// set non blocking
int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
{
::close(fd);
return false;
}
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
{
::close(fd);
return false;
}
llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp);
add_ev(conn, true);
conn->connect();
return true;
}
llarp::ev_io*
llarp_epoll_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
{
int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0);
if(fd == -1)
return nullptr;
socklen_t sz = sizeof(sockaddr_in);
if(bindaddr->sa_family == AF_INET6)
{
sz = sizeof(sockaddr_in6);
}
else if(bindaddr->sa_family == AF_UNIX)
{
sz = sizeof(sockaddr_un);
}
if(::bind(fd, bindaddr, sz) == -1)
{
::close(fd);
return nullptr;
}
if(::listen(fd, 5) == -1)
{
::close(fd);
return nullptr;
}
return new llarp::tcp_serv(this, fd, tcp);
}
bool
llarp_epoll_loop::udp_listen(llarp_udp_io* l, const sockaddr* src)
{
auto ev = create_udp(l, src);
if(ev)
l->fd = ev->fd;
return ev && add_ev(ev, false);
}
bool
llarp_epoll_loop::running() const
{
return epollfd != -1;
}
bool
llarp_epoll_loop::init()
{
if(epollfd == -1)
epollfd = epoll_create(1);
return false;
}
int
llarp_epoll_loop::tick(int ms)
{
epoll_event events[1024];
int result;
result = epoll_wait(epollfd, events, 1024, ms);
if(result > 0)
{
int idx = 0;
while(idx < result)
{
llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr);
if(ev)
{
llarp::LogDebug(idx, " of ", result,
" events=", std::to_string(events[idx].events));
if(events[idx].events & EPOLLERR)
{
ev->error();
}
else
{
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
}
}
++idx;
}
}
if(result != -1)
tick_listeners();
return result;
}
int
llarp_epoll_loop::run()
{
epoll_event events[1024];
int result;
do
{
result = epoll_wait(epollfd, events, 1024, EV_TICK_INTERVAL);
if(result > 0)
{
int idx = 0;
while(idx < result)
{
llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr);
if(ev)
{
if(events[idx].events & EPOLLERR)
{
ev->error();
}
else
{
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
}
}
++idx;
}
}
if(result != -1)
tick_listeners();
} while(epollfd != -1);
return result;
}
int
llarp_epoll_loop::udp_bind(const sockaddr* addr)
{
socklen_t slen;
switch(addr->sa_family)
{
case AF_INET:
slen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
slen = sizeof(struct sockaddr_in6);
break;
default:
return -1;
}
int fd = socket(addr->sa_family, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket()");
return -1;
}
if(addr->sa_family == AF_INET6)
{
// enable dual stack explicitly
int dual = 1;
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &dual, sizeof(dual)) == -1)
{
// failed
perror("setsockopt()");
close(fd);
return -1;
}
}
llarp::Addr a(*addr);
llarp::LogDebug("bind to ", a);
if(bind(fd, addr, slen) == -1)
{
perror("bind()");
close(fd);
return -1;
}
return fd;
}
bool
llarp_epoll_loop::close_ev(llarp::ev_io* ev)
{
return epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->fd, nullptr) != -1;
}
llarp::ev_io*
llarp_epoll_loop::create_tun(llarp_tun_io* tun)
{
llarp::tun* t = new llarp::tun(tun, this);
if(tun->get_fd_promise)
{
}
else if(t->setup())
{
return t;
}
delete t;
return nullptr;
}
llarp::ev_io*
llarp_epoll_loop::create_udp(llarp_udp_io* l, const sockaddr* src)
{
int fd = udp_bind(src);
if(fd == -1)
return nullptr;
llarp::ev_io* listener = new llarp::udp_listener(fd, l);
l->impl = listener;
return listener;
}
bool
llarp_epoll_loop::add_ev(llarp::ev_io* e, bool write)
{
epoll_event ev;
ev.data.ptr = e;
ev.events = EPOLLIN | EPOLLERR;
if(write)
ev.events |= EPOLLOUT;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, e->fd, &ev) == -1)
{
delete e;
return false;
}
handlers.emplace_back(e);
return true;
}
bool
llarp_epoll_loop::udp_close(llarp_udp_io* l)
{
bool ret = false;
llarp::udp_listener* listener = static_cast< llarp::udp_listener* >(l->impl);
if(listener)
{
close_ev(listener);
// remove handler
auto itr = handlers.begin();
while(itr != handlers.end())
{
if(itr->get() == listener)
itr = handlers.erase(itr);
else
++itr;
}
l->impl = nullptr;
ret = true;
}
return ret;
}
void
llarp_epoll_loop::stop()
{
// close all handlers before closing the epoll fd
auto itr = handlers.begin();
while(itr != handlers.end())
{
close_ev(itr->get());
itr = handlers.erase(itr);
}
if(epollfd != -1)
close(epollfd);
epollfd = -1;
}

@ -25,98 +25,6 @@
namespace llarp
{
inline int
tcp_conn::read(byte_t* buf, size_t sz)
{
if(_shouldClose)
return -1;
ssize_t amount = ::read(fd, buf, sz);
if(amount > 0)
{
if(tcp.read)
tcp.read(&tcp, llarp_buffer_t(buf, amount));
}
else
{
// error
_shouldClose = true;
return -1;
}
return 0;
}
inline void
tcp_conn::flush_write()
{
connected();
ev_io::flush_write();
}
inline ssize_t
tcp_conn::do_write(void* buf, size_t sz)
{
if(_shouldClose)
return -1;
// pretty much every UNIX system still extant, _including_ solaris
// (on both sides of the fork) can ignore SIGPIPE....except
// the other vendored systems... -rick
return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe
}
inline void
tcp_conn::connect()
{
socklen_t slen = sizeof(sockaddr_in);
if(_addr.ss_family == AF_UNIX)
slen = sizeof(sockaddr_un);
else if(_addr.ss_family == AF_INET6)
slen = sizeof(sockaddr_in6);
int result = ::connect(fd, (const sockaddr*)&_addr, slen);
if(result == 0)
{
llarp::LogDebug("connected immedidately");
connected();
}
else if(errno == EINPROGRESS)
{
// in progress
llarp::LogDebug("connect in progress");
errno = 0;
return;
}
else if(_conn->error)
{
// wtf?
llarp::LogError("error connecting ", strerror(errno));
_conn->error(_conn);
}
}
inline int
tcp_serv::read(byte_t*, size_t)
{
int new_fd = ::accept(fd, nullptr, nullptr);
if(new_fd == -1)
{
llarp::LogError("failed to accept on ", fd, ":", strerror(errno));
return -1;
}
// build handler
llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd);
if(loop->add_ev(connimpl, true))
{
// call callback
if(tcp->accepted)
tcp->accepted(tcp, &connimpl->tcp);
return 0;
}
// cleanup error
delete connimpl;
return -1;
}
struct udp_listener : public ev_io
{
llarp_udp_io* udp;
@ -128,54 +36,13 @@ namespace llarp
}
bool
tick()
{
if(udp->tick)
udp->tick(udp);
return true;
}
tick();
int
read(byte_t* buf, size_t sz)
{
llarp_buffer_t b;
b.base = buf;
b.cur = b.base;
sockaddr_in6 src;
socklen_t slen = sizeof(sockaddr_in6);
sockaddr* addr = (sockaddr*)&src;
ssize_t ret = ::recvfrom(fd, b.base, sz, 0, addr, &slen);
if(ret < 0)
return -1;
if(static_cast< size_t >(ret) > sz)
return -1;
b.sz = ret;
udp->recvfrom(udp, addr, ManagedBuffer{b});
return 0;
}
read(byte_t* buf, size_t sz);
int
sendto(const sockaddr* to, const void* data, size_t sz)
{
socklen_t slen;
switch(to->sa_family)
{
case AF_INET:
slen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
slen = sizeof(struct sockaddr_in6);
break;
default:
return -1;
}
ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen);
if(sent == -1)
{
llarp::LogWarn(strerror(errno));
}
return sent;
}
sendto(const sockaddr* to, const void* data, size_t sz);
};
struct tun : public ev_io
@ -192,93 +59,22 @@ namespace llarp
};
int
sendto(__attribute__((unused)) const sockaddr* to,
__attribute__((unused)) const void* data,
__attribute__((unused)) size_t sz)
{
return -1;
}
sendto(const sockaddr* to, const void* data, size_t sz);
bool
tick()
{
if(t->tick)
t->tick(t);
flush_write();
return true;
}
tick();
void
flush_write()
{
if(t->before_write)
t->before_write(t);
ev_io::flush_write();
}
flush_write();
int
read(byte_t* buf, size_t sz)
{
ssize_t ret = tuntap_read(tunif, buf, sz);
if(ret > 0 && t->recvpkt)
{
// does not have pktinfo
t->recvpkt(t, llarp_buffer_t(buf, ret));
}
return ret;
}
read(byte_t* buf, size_t sz);
static int
wait_for_fd_promise(struct device* dev)
{
llarp::tun* t = static_cast< llarp::tun* >(dev->user);
if(t->t->get_fd_promise)
{
struct llarp_fd_promise* promise = t->t->get_fd_promise(t->t);
if(promise)
return llarp_fd_promise_wait_for_value(promise);
}
return -1;
}
wait_for_fd_promise(struct device* dev);
bool
setup()
{
// for android
if(t->get_fd_promise)
{
tunif->obtain_fd = &wait_for_fd_promise;
tunif->user = this;
}
llarp::LogDebug("set ifname to ", t->ifname);
strncpy(tunif->if_name, t->ifname, sizeof(tunif->if_name));
if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1)
{
llarp::LogWarn("failed to start interface");
return false;
}
if(t->get_fd_promise == nullptr)
{
if(tuntap_up(tunif) == -1)
{
llarp::LogWarn("failed to put interface up: ", strerror(errno));
return false;
}
if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1)
{
llarp::LogWarn("failed to set ip");
return false;
}
}
fd = tunif->tun_fd;
if(fd == -1)
return false;
// set non blocking
int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
return false;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1;
}
setup();
~tun()
{
@ -291,307 +87,58 @@ namespace llarp
struct llarp_epoll_loop : public llarp_ev_loop
{
int epollfd;
llarp_epoll_loop() : epollfd(-1)
{
}
bool
tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr)
~llarp_epoll_loop()
{
// create socket
int fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0);
if(fd == -1)
return false;
// set non blocking
int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1)
{
::close(fd);
return false;
}
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
{
::close(fd);
return false;
}
llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp);
add_ev(conn, true);
conn->connect();
return true;
if(epollfd != -1)
close(epollfd);
}
bool
tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr);
llarp::ev_io*
bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
{
int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0);
if(fd == -1)
return nullptr;
socklen_t sz = sizeof(sockaddr_in);
if(bindaddr->sa_family == AF_INET6)
{
sz = sizeof(sockaddr_in6);
}
else if(bindaddr->sa_family == AF_UNIX)
{
sz = sizeof(sockaddr_un);
}
if(::bind(fd, bindaddr, sz) == -1)
{
::close(fd);
return nullptr;
}
if(::listen(fd, 5) == -1)
{
::close(fd);
return nullptr;
}
return new llarp::tcp_serv(this, fd, tcp);
}
bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr);
virtual bool
udp_listen(llarp_udp_io* l, const sockaddr* src)
{
auto ev = create_udp(l, src);
if(ev)
l->fd = ev->fd;
return ev && add_ev(ev, false);
}
~llarp_epoll_loop()
{
if(epollfd != -1)
close(epollfd);
}
udp_listen(llarp_udp_io* l, const sockaddr* src);
bool
running() const
{
return epollfd != -1;
}
running() const;
bool
init()
{
if(epollfd == -1)
epollfd = epoll_create(1);
return false;
}
init();
int
tick(int ms)
{
epoll_event events[1024];
int result;
result = epoll_wait(epollfd, events, 1024, ms);
if(result > 0)
{
int idx = 0;
while(idx < result)
{
llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr);
if(ev)
{
llarp::LogDebug(idx, " of ", result,
" events=", std::to_string(events[idx].events));
if(events[idx].events & EPOLLERR)
{
ev->error();
}
else
{
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
}
}
++idx;
}
}
if(result != -1)
tick_listeners();
return result;
}
tick(int ms);
int
run()
{
epoll_event events[1024];
int result;
do
{
result = epoll_wait(epollfd, events, 1024, EV_TICK_INTERVAL);
if(result > 0)
{
int idx = 0;
while(idx < result)
{
llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr);
if(ev)
{
if(events[idx].events & EPOLLERR)
{
ev->error();
}
else
{
if(events[idx].events & EPOLLIN)
{
ev->read(readbuf, sizeof(readbuf));
}
if(events[idx].events & EPOLLOUT)
{
ev->flush_write();
}
}
}
++idx;
}
}
if(result != -1)
tick_listeners();
} while(epollfd != -1);
return result;
}
run();
int
udp_bind(const sockaddr* addr)
{
socklen_t slen;
switch(addr->sa_family)
{
case AF_INET:
slen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
slen = sizeof(struct sockaddr_in6);
break;
default:
return -1;
}
int fd = socket(addr->sa_family, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket()");
return -1;
}
if(addr->sa_family == AF_INET6)
{
// enable dual stack explicitly
int dual = 1;
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &dual, sizeof(dual)) == -1)
{
// failed
perror("setsockopt()");
close(fd);
return -1;
}
}
llarp::Addr a(*addr);
llarp::LogDebug("bind to ", a);
if(bind(fd, addr, slen) == -1)
{
perror("bind()");
close(fd);
return -1;
}
return fd;
}
udp_bind(const sockaddr* addr);
bool
close_ev(llarp::ev_io* ev)
{
return epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->fd, nullptr) != -1;
}
close_ev(llarp::ev_io* ev);
llarp::ev_io*
create_tun(llarp_tun_io* tun)
{
llarp::tun* t = new llarp::tun(tun, this);
if(tun->get_fd_promise)
{
}
else if(t->setup())
{
return t;
}
delete t;
return nullptr;
}
create_tun(llarp_tun_io* tun);
llarp::ev_io*
create_udp(llarp_udp_io* l, const sockaddr* src)
{
int fd = udp_bind(src);
if(fd == -1)
return nullptr;
llarp::ev_io* listener = new llarp::udp_listener(fd, l);
l->impl = listener;
return listener;
}
create_udp(llarp_udp_io* l, const sockaddr* src);
bool
add_ev(llarp::ev_io* e, bool write)
{
epoll_event ev;
ev.data.ptr = e;
ev.events = EPOLLIN | EPOLLERR;
if(write)
ev.events |= EPOLLOUT;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, e->fd, &ev) == -1)
{
delete e;
return false;
}
handlers.emplace_back(e);
return true;
}
add_ev(llarp::ev_io* e, bool write);
bool
udp_close(llarp_udp_io* l)
{
bool ret = false;
llarp::udp_listener* listener =
static_cast< llarp::udp_listener* >(l->impl);
if(listener)
{
close_ev(listener);
// remove handler
auto itr = handlers.begin();
while(itr != handlers.end())
{
if(itr->get() == listener)
itr = handlers.erase(itr);
else
++itr;
}
l->impl = nullptr;
ret = true;
}
return ret;
}
udp_close(llarp_udp_io* l);
void
stop()
{
// close all handlers before closing the epoll fd
auto itr = handlers.begin();
while(itr != handlers.end())
{
close_ev(itr->get());
itr = handlers.erase(itr);
}
if(epollfd != -1)
close(epollfd);
epollfd = -1;
}
stop();
};
#endif

@ -1,10 +1,11 @@
#include <ev/ev_win32.hpp>
// a single event queue for the TUN interface
HANDLE tun_event_queue = INVALID_HANDLE_VALUE;
static HANDLE tun_event_queue = INVALID_HANDLE_VALUE;
// we hand the kernel our thread handles to process completion events
HANDLE* kThreadPool;
static HANDLE* kThreadPool;
static int poolSize;
// list of TUN listeners (useful for exits or other nodes with multiple TUNs)
std::list< win32_tun_io* > tun_listeners;
@ -19,6 +20,7 @@ begin_tun_loop(int nThreads)
CreateThread(nullptr, 0, &tun_ev_loop, nullptr, 0, nullptr);
}
llarp::LogInfo("created ", nThreads, " threads for TUN event queue");
poolSize = nThreads;
}
// this one is called from the TUN handler
@ -162,7 +164,7 @@ tun_ev_loop(void* unused)
continue;
}
if(ev->t->recvpkt)
ev->t->recvpkt(ev->t, llarp::InitBuffer(pkt->buf, size));
ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size));
ev->read(ev->readbuf, sizeof(ev->readbuf));
}
else
@ -175,35 +177,40 @@ tun_ev_loop(void* unused)
ev->flush_write();
delete pkt; // don't leak
}
llarp::LogInfo("exit TUN event loop thread from system managed thread pool");
llarp::LogDebug("exit TUN event loop thread from system managed thread pool");
return 0;
}
void
exit_tun_loop()
{
// if we get all-ones in the queue, thread exits, and we clean up
PostQueuedCompletionStatus(tun_event_queue, 0, ~0, nullptr);
// kill the kernel's thread pool
int i = (&kThreadPool)[1] - kThreadPool; // get the size of our thread pool
llarp::LogInfo("closing ", i, " threads");
WaitForMultipleObjects(i, kThreadPool, TRUE, INFINITE);
for(int j = 0; j < i; ++j)
CloseHandle(kThreadPool[j]);
delete[] kThreadPool;
// the IOCP refcount is decreased each time an associated fd
// is closed
// the fds are closed in their destructors
// once we get to zero, we can safely close the event port
auto itr = tun_listeners.begin();
while(itr != tun_listeners.end())
if(kThreadPool)
{
delete(*itr);
itr = tun_listeners.erase(itr);
// kill the kernel's thread pool
// int i = (&kThreadPool)[1] - kThreadPool; // get the size of our thread
// pool
llarp::LogInfo("closing ", poolSize, " threads");
// if we get all-ones in the queue, thread exits, and we clean up
for(int j = 0; j < poolSize; ++j)
PostQueuedCompletionStatus(tun_event_queue, 0, ~0, nullptr);
WaitForMultipleObjects(poolSize, kThreadPool, TRUE, INFINITE);
for(int j = 0; j < poolSize; ++j)
CloseHandle(kThreadPool[j]);
delete[] kThreadPool;
kThreadPool = nullptr;
// the IOCP refcount is decreased each time an associated fd
// is closed
// the fds are closed in their destructors
// once we get to zero, we can safely close the event port
auto itr = tun_listeners.begin();
while(itr != tun_listeners.end())
{
delete(*itr);
itr = tun_listeners.erase(itr);
}
CloseHandle(tun_event_queue);
}
CloseHandle(tun_event_queue);
}
namespace llarp
@ -219,7 +226,7 @@ namespace llarp
if(amount > 0)
{
if(tcp.read)
tcp.read(&tcp, llarp::InitBuffer(buf, amount));
tcp.read(&tcp, llarp_buffer_t(buf, amount));
}
else
{
@ -259,7 +266,8 @@ namespace llarp
llarp::LogDebug("connected immedidately");
connected();
}
else if(WSAGetLastError() == WSAEINPROGRESS)
// Winsock 2.x no longer returns WSAEINPROGRESS
else if(WSAGetLastError() == WSAEWOULDBLOCK)
{
// in progress
llarp::LogDebug("connect in progress");
@ -273,7 +281,9 @@ namespace llarp
int err = WSAGetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL,
ebuf, 1024, nullptr);
llarp::LogError("error connecting: ", ebuf);
int l = strlen(ebuf);
ebuf[l - 2] = '\0'; // remove line break
llarp::LogError("error connecting: ", ebuf, " [", err, "]");
_conn->error(_conn);
}
}
@ -288,7 +298,9 @@ namespace llarp
int err = WSAGetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL,
ebuf, 1024, nullptr);
llarp::LogError("failed to accept on ", fd, ":", ebuf);
int l = strlen(ebuf);
ebuf[l - 2] = '\0'; // remove line break
llarp::LogError("failed to accept on ", fd, ":", ebuf, " [", err, "]");
return -1;
}
// build handler
@ -328,7 +340,7 @@ namespace llarp
if(static_cast< size_t >(ret) > sz)
return -1;
b.sz = ret;
udp->recvfrom(udp, addr, b);
udp->recvfrom(udp, addr, ManagedBuffer{b});
return 0;
}
@ -625,5 +637,8 @@ llarp_win32_loop::udp_close(llarp_udp_io* l)
void
llarp_win32_loop::stop()
{
// do nothing
if(upollfd)
upoll_destroy(upollfd);
upollfd = nullptr;
llarp::LogDebug("destroy upoll");
}

@ -115,8 +115,6 @@ struct llarp_win32_loop : public llarp_ev_loop
~llarp_win32_loop()
{
if(upollfd)
upoll_destroy(upollfd);
}
bool

@ -9,7 +9,7 @@ namespace llarp
ConfigParser::LoadFile(const char* fname)
{
{
std::ifstream f(fname);
std::ifstream f(fname, std::ios::in | std::ios::binary);
if(!f.is_open())
return false;
f.seekg(0, std::ios::end);

@ -0,0 +1,124 @@
// WARNING: for the love of all that is good and holy
// please DO NOT convert this file to UTF-8, much less
// UTF-16 - the UNIX cross-rc does not understand UTF-16,
// and UTF-8 chews up the copyright symbols.
// -rick
//
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include <winresrc.h>
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#define STRINGIZER(version) #version
#ifdef LLARP_RELEASE_MOTTO
#define VERSION_STRING(version, codename, revision) \
STRINGIZER(version) "-release [" STRINGIZER(codename) "] (rev-" STRINGIZER(revision) ")"
#else
#define VERSION_STRING(version, revision) \
STRINGIZER(version) STRINGIZER(revision)
#endif
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 1033,1
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,0
PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "libabyss JSON-RPC daemon demo"
VALUE "CompanyName", "Loki Foundation"
VALUE "FileDescription", "LokiNET for Microsoft® Windows® NT™"
#ifdef LLARP_RELEASE_MOTTO
VALUE "FileVersion", VERSION_STRING(0.4.0, RELEASE_MOTTO, GIT_REV)
#else
VALUE "FileVersion", VERSION_STRING(0.4.0-dev-, GIT_REV)
#endif
VALUE "InternalName", "llarpd"
VALUE "LegalCopyright", "Copyright ©2018-2019 Jeff Becker, Rick V for the Loki Foundation. All rights reserved. This software is provided under the terms of the zlib-libpng licence; see the file LICENSE for details."
VALUE "OriginalFilename", "abyss-main.exe"
VALUE "ProductName", "LokiNET for Windows"
#ifdef LLARP_RELEASE_MOTTO
VALUE "ProductVersion", VERSION_STRING(0.4.0, RELEASE_MOTTO, GIT_REV)
#else
VALUE "ProductVersion", VERSION_STRING(0.4.0-dev-, GIT_REV)
#endif
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// RT_MANIFEST
//
1 RT_MANIFEST "app.xml"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

@ -0,0 +1,124 @@
// WARNING: for the love of all that is good and holy
// please DO NOT convert this file to UTF-8, much less
// UTF-16 - the UNIX cross-rc does not understand UTF-16,
// and UTF-8 chews up the copyright symbols.
// -rick
//
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include <winresrc.h>
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#define STRINGIZER(version) #version
#ifdef LLARP_RELEASE_MOTTO
#define VERSION_STRING(version, codename, revision) \
STRINGIZER(version) "-release [" STRINGIZER(codename) "] (rev-" STRINGIZER(revision) ")"
#else
#define VERSION_STRING(version, revision) \
STRINGIZER(version) STRINGIZER(revision)
#endif
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 1033,1
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,0
PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "LokiNET test suite"
VALUE "CompanyName", "Loki Foundation"
VALUE "FileDescription", "LokiNET for Microsoft® Windows® NT™"
#ifdef LLARP_RELEASE_MOTTO
VALUE "FileVersion", VERSION_STRING(0.4.0, RELEASE_MOTTO, GIT_REV)
#else
VALUE "FileVersion", VERSION_STRING(0.4.0-dev-, GIT_REV)
#endif
VALUE "InternalName", "llarpd"
VALUE "LegalCopyright", "Copyright ©2018-2019 Jeff Becker, Rick V for the Loki Foundation. All rights reserved. This software is provided under the terms of the zlib-libpng licence; see the file LICENSE for details."
VALUE "OriginalFilename", "llarpd.exe"
VALUE "ProductName", "LokiNET for Windows"
#ifdef LLARP_RELEASE_MOTTO
VALUE "ProductVersion", VERSION_STRING(0.4.0, RELEASE_MOTTO, GIT_REV)
#else
VALUE "ProductVersion", VERSION_STRING(0.4.0-dev-, GIT_REV)
#endif
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// RT_MANIFEST
//
1 RT_MANIFEST "app.xml"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

@ -83,7 +83,7 @@ BEGIN
VALUE "FileVersion", VERSION_STRING(0.4.0-dev-, GIT_REV)
#endif
VALUE "InternalName", "llarpd"
VALUE "LegalCopyright", "Copyright ©2018 Jeff Becker, Rick V for the Loki Foundation. All rights reserved. This software is provided under the terms of the zlib-libpng licence; see the file LICENSE for details."
VALUE "LegalCopyright", "Copyright ©2018-2019 Jeff Becker, Rick V for the Loki Foundation. All rights reserved. This software is provided under the terms of the zlib-libpng licence; see the file LICENSE for details."
VALUE "OriginalFilename", "llarpd.exe"
VALUE "ProductName", "LokiNET for Windows"
#ifdef LLARP_RELEASE_MOTTO

@ -71,6 +71,7 @@ uhash_delete(uhash_t* hash, intptr_t key)
{
ulist_remove(q);
free(q);
q = NULL;
return 1;
}
}
@ -88,6 +89,7 @@ uhash_destroy(uhash_t* hash)
uitem_t* n = ulist_data(q, uitem_t, list);
ulist_remove(q);
free(n);
n = NULL;
}
}
return 0;
@ -118,8 +120,10 @@ upoll_destroy(upoll_t* upq)
n = ulist_data(n, unote_t, queue);
ulist_remove(q);
free(n);
n = NULL;
}
free(upq);
upq = NULL;
}
int
@ -155,6 +159,7 @@ upoll_ctl(upoll_t* upq, int op, intptr_t fd, upoll_event_t* event)
ulist_remove(&note->queue);
uhash_delete(upq->table, fd);
free(note);
note = NULL;
break;
}
case UPOLL_CTL_MOD:

@ -29,12 +29,10 @@
#include <sys/stat.h>
// this is probably big enough to get
// the lesser of 96 sockets or whatever
// the lesser of 4096 sockets or whatever
// the system allows
// this used to be 4096, but i think
// that took ages to process
#ifndef FD_SETSIZE
#define FD_SETSIZE 96
#define FD_SETSIZE 4096
#endif
#include <io.h>

@ -251,13 +251,66 @@ TEST_F(TestCryptoTypesSecret, secret_key_from_file_happy_bencode)
// - file not writeable
// - happy path
// Win32: check for root/admin/elevation privileges
#ifdef _WIN32
BOOL IsRunAsAdmin()
{
BOOL fIsRunAsAdmin = FALSE;
DWORD dwError = ERROR_SUCCESS;
PSID pAdministratorsGroup = NULL;
// Allocate and initialize a SID of the administrators group.
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdministratorsGroup))
{
dwError = GetLastError();
goto Cleanup;
}
// Determine whether the SID of administrators group is enabled in
// the primary access token of the process.
if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
{
dwError = GetLastError();
goto Cleanup;
}
Cleanup:
// Centralized cleanup for all allocated resources.
if (pAdministratorsGroup)
{
FreeSid(pAdministratorsGroup);
pAdministratorsGroup = NULL;
}
// Throw the error if something failed in the function.
if (ERROR_SUCCESS != dwError)
{
throw dwError;
}
return fIsRunAsAdmin;
}
#endif
TEST_F(TestCryptoTypesSecret, secret_key_to_missing_file)
{
// Verify writing to an unwritable file fails.
// Assume we're not running as root, so can't write to /
// Assume we're not running as root, so can't write to [C:]/
// if we are root just skip this test
#ifndef _WIN32
if(getuid() == 0)
return;
#else
if(IsRunAsAdmin())
return;
#endif
filename = "/" + filename;
p = filename;
ASSERT_FALSE(fs::exists(fs::status(p)));

@ -16,7 +16,11 @@ option(gtest_build_tests "Build all of gtest's own tests." OFF)
option(gtest_build_samples "Build gtest's sample programs." OFF)
if (WIN32)
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." ON)
else (NOT WIN32)
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
endif(WIN32)
option(
gtest_hide_internal_symbols

@ -31,7 +31,11 @@ TEST_F(TestINIParser, TestParseOneSection)
ASSERT_EQ(itr, sect.end());
itr = sect.find("key");
ASSERT_NE(itr, sect.end());
#if __cplusplus >= 201703L
ASSERT_STREQ(llarp::string_view_string(itr->second).c_str(), "val");
#else
ASSERT_STREQ(itr->second.c_str(), "val");
#endif
}
TEST_F(TestINIParser, TestParseSectionDuplicateKeys)
@ -49,4 +53,4 @@ TEST_F(TestINIParser, TestParseSectionDuplicateKeys)
TEST_F(TestINIParser, TestParseInvalid)
{
ASSERT_FALSE(parser.LoadString("srged5ghe5\nf34wtge5\nw34tgfs4ygsd5yg=4;\n#g4syhgd5\n"));
}
}

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lokivpn", "lokivpn.csproj", "{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CDEE73C-29C5-4781-BD74-1EEAC6F75A14}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {43867E52-9394-4EFC-A8FA-4382447D4B24}
EndGlobalSection
EndGlobal

@ -365,18 +365,6 @@
#error "absl endian detection needs to be set up for your compiler"
#endif
// MacOS 10.13 doesn't let you use <any>, <optional>, or <variant> even though
// the headers exist and are publicly noted to work. See
// https://github.com/abseil/abseil-cpp/issues/207 and
// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \
defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400
#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 1
#else
#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 0
#endif
// ABSL_HAVE_STD_ANY
//
// Checks whether C++17 std::any is available by checking whether <any> exists.
@ -386,7 +374,7 @@
#ifdef __has_include
#if __has_include(<any>) && __cplusplus >= 201703L && \
ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES
!(__APPLE__ && __MACH__)
#define ABSL_HAVE_STD_ANY 1
#endif
#endif
@ -400,7 +388,7 @@
#ifdef __has_include
#if __has_include(<optional>) && __cplusplus >= 201703L && \
ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES
!(__APPLE__ && __MACH__)
#define ABSL_HAVE_STD_OPTIONAL 1
#endif
#endif
@ -414,7 +402,7 @@
#ifdef __has_include
#if __has_include(<variant>) && __cplusplus >= 201703L && \
ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES
!(__APPLE__ && __MACH__)
#define ABSL_HAVE_STD_VARIANT 1
#endif
#endif

Loading…
Cancel
Save