From 04e620ebf2c0fc609f7b5e9b46477919cc2940e8 Mon Sep 17 00:00:00 2001 From: despair Date: Fri, 2 Nov 2018 15:43:53 -0500 Subject: [PATCH] add iocp tcp connect msys2 grabs its reactos sdk headers straight out of git most cross-compilers use the versioned releases (v6 as of last week) huh. for once setting the windows version macros doesn't break anything. --- CMakeLists.txt | 9 ++- crypto/csrng/randombytes_salsa20_random.c | 2 +- include/llarp/net.h | 5 +- libabyss/src/client.cpp | 8 +-- libabyss/src/server.cpp | 2 +- libutp/libutp_inet_ntop.cpp | 3 +- llarp/ev.hpp | 69 ++++++++++++++------ llarp/ev_kqueue.hpp | 5 -- llarp/ev_win32.hpp | 78 ++++++++++++++++++----- vendor/libtuntap-master/tuntap.cpp | 2 + 10 files changed, 132 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b11270635..92870df47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,8 +185,7 @@ if(UNIX) endif() elseif(WIN32) set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c) - add_definitions(-DWIN32_LEAN_AND_MEAN) - add_definitions(-DWIN32) + add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x500 -D_WIN32_WINNT=0x500) else() message(FATAL_ERROR "What operating system _are_ you building on/for?") endif(UNIX) @@ -525,7 +524,13 @@ if(USE_LIBABYSS) 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) target_link_libraries(${ABYSS_EXE} ${PLATFORM_LIB}) +else() + target_link_libraries(${ABYSS_EXE} ${PLATFORM_LIB} ws2_32 iphlpapi) +endif(NOT WIN32) + set(TEST_SRC ${TEST_SRC} test/jsonrpc_unittest.cpp) # for freebsd if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") diff --git a/crypto/csrng/randombytes_salsa20_random.c b/crypto/csrng/randombytes_salsa20_random.c index 81b69cc68..772c23c0a 100644 --- a/crypto/csrng/randombytes_salsa20_random.c +++ b/crypto/csrng/randombytes_salsa20_random.c @@ -400,7 +400,7 @@ randombytes_salsa20_random_stir(void) if (hCAPINg) { /* call BCryptGenRandom(2) */ - getrandom = GetProcAddress(hCAPINg, "BCryptGenRandom"); + getrandom = (CNGAPI_DRBG)GetProcAddress(hCAPINg, "BCryptGenRandom"); if(!BCRYPT_SUCCESS(getrandom(NULL, m0, sizeof m0,BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { sodium_misuse(); diff --git a/include/llarp/net.h b/include/llarp/net.h index 8d03ae500..55b349cad 100644 --- a/include/llarp/net.h +++ b/include/llarp/net.h @@ -9,16 +9,15 @@ extern "C" { #endif +#if _WIN32_WINNT < 0x600 const char* inet_ntop(int af, const void* src, char* dst, size_t size); int inet_pton(int af, const char* src, void* dst); +#endif #ifdef __cplusplus } #endif -#ifndef ssize_t -#define ssize_t long -#endif typedef unsigned short in_port_t; typedef unsigned int in_addr_t; #else diff --git a/libabyss/src/client.cpp b/libabyss/src/client.cpp index 5d4aab1aa..9b11b8647 100644 --- a/libabyss/src/client.cpp +++ b/libabyss/src/client.cpp @@ -144,13 +144,13 @@ namespace abyss { if(state == eInitial) return true; - if(sz == 0) + if(!sz) return true; bool done = false; while(state < eReadResponseBody) { const char* end = strstr(buf, "\r\n"); - if(end == nullptr) + if(!end) return false; string_view line(buf, end - buf); switch(state) @@ -214,7 +214,7 @@ namespace abyss char buf[512] = {0}; int sz = snprintf(buf, sizeof(buf), "POST /rpc HTTP/1.0\r\nContent-Type: " - "application/json\r\nContent-Length: %lu\r\nAccept: " + "application/json\r\nContent-Length: %zu\r\nAccept: " "application/json\r\n", body.size()); if(sz <= 0) @@ -294,7 +294,7 @@ namespace abyss ++itr; } // open at most 10 connections - size_t numCalls = std::min(m_PendingCalls.size(), 10UL); + size_t numCalls = std::min(m_PendingCalls.size(), (size_t)10UL); llarp::LogDebug("tick connect to rpc ", numCalls, " times"); while(numCalls--) { diff --git a/libabyss/src/server.cpp b/libabyss/src/server.cpp index 71e782e12..45c733d00 100644 --- a/libabyss/src/server.cpp +++ b/libabyss/src/server.cpp @@ -217,7 +217,7 @@ namespace abyss return false; } - if(sz == 0) + if(!sz) return true; bool done = false; diff --git a/libutp/libutp_inet_ntop.cpp b/libutp/libutp_inet_ntop.cpp index 369837977..f0b892a55 100644 --- a/libutp/libutp_inet_ntop.cpp +++ b/libutp/libutp_inet_ntop.cpp @@ -30,13 +30,14 @@ // we already have our own definition of these // -despair +#ifndef inet_ntop namespace { extern "C" { const char* inet_ntop(int af, const void *src, char *dst, size_t size); int inet_pton(int af, const char *src, void *dst); } } - +#endif //###################################################################### const char *libutp::inet_ntop(int af, const void *src, char *dest, size_t length) { diff --git a/llarp/ev.hpp b/llarp/ev.hpp index f09fd0054..e2664e017 100644 --- a/llarp/ev.hpp +++ b/llarp/ev.hpp @@ -171,11 +171,17 @@ namespace llarp return false; } + virtual void + flush_write() + { + flush_write_buffers(0); + } + /// called in event loop when fd is ready for writing /// requeues anything not written /// this assumes fd is set to non blocking virtual void - flush_write() + flush_write_buffers(size_t amount) { if(m_LossyWriteQueue) m_LossyWriteQueue->Process([&](WriteBuffer& buffer) { @@ -185,34 +191,58 @@ namespace llarp }); else if(m_BlockingWriteQueue) { - // write buffers - while(m_BlockingWriteQueue->size()) + if(amount) { - auto& itr = m_BlockingWriteQueue->front(); - ssize_t result = do_write(itr.buf, itr.bufsz); - if(result == -1) - return; - ssize_t dlt = itr.bufsz - result; - if(dlt > 0) + while(amount && m_BlockingWriteQueue->size()) { - // queue remaining to front of queue - WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt); + auto& itr = m_BlockingWriteQueue->front(); + ssize_t result = do_write(itr.buf, std::min(amount, itr.bufsz)); + if(result == -1) + return; + ssize_t dlt = itr.bufsz - result; + if(dlt > 0) + { + // queue remaining to front of queue + WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt); + m_BlockingWriteQueue->pop_front(); + m_BlockingWriteQueue->push_front(buff); + // TODO: errno? + return; + } m_BlockingWriteQueue->pop_front(); - m_BlockingWriteQueue->push_front(buff); - // TODO: errno? - return; + amount -= result; } - m_BlockingWriteQueue->pop_front(); - if(errno == EAGAIN || errno == EWOULDBLOCK) + } + else + { + // write buffers + while(m_BlockingWriteQueue->size()) { - errno = 0; - return; + auto& itr = m_BlockingWriteQueue->front(); + ssize_t result = do_write(itr.buf, itr.bufsz); + if(result == -1) + return; + ssize_t dlt = itr.bufsz - result; + if(dlt > 0) + { + // queue remaining to front of queue + WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt); + m_BlockingWriteQueue->pop_front(); + m_BlockingWriteQueue->push_front(buff); + // TODO: errno? + return; + } + m_BlockingWriteQueue->pop_front(); + if(errno == EAGAIN || errno == EWOULDBLOCK) + { + errno = 0; + return; + } } } } /// reset errno errno = 0; - SetLastError(0); } std::unique_ptr< LossyWriteQueue_t > m_LossyWriteQueue; @@ -439,6 +469,7 @@ namespace llarp // finally create aliases by platform #ifdef _WIN32 using ev_io = win32_ev_io; +#define sizeof(sockaddr_un) 115 #else using ev_io = posix_ev_io; #endif diff --git a/llarp/ev_kqueue.hpp b/llarp/ev_kqueue.hpp index a5a776329..b70055984 100644 --- a/llarp/ev_kqueue.hpp +++ b/llarp/ev_kqueue.hpp @@ -12,11 +12,6 @@ #include #endif -// MacOS needs this -#ifndef SOCK_NONBLOCK -#define SOCK_NONBLOCK O_NONBLOCK -#endif - // original upstream #include #include diff --git a/llarp/ev_win32.hpp b/llarp/ev_win32.hpp index 0026690c2..a1e5af24c 100644 --- a/llarp/ev_win32.hpp +++ b/llarp/ev_win32.hpp @@ -8,14 +8,13 @@ #include "ev.hpp" #include "logger.hpp" +// TODO: convert all socket errno calls to WSAGetLastError(3), +// don't think winsock sets regular errno to this day namespace llarp { int tcp_conn::read(void* buf, size_t sz) { - if(_shouldClose) - return -1; - WSABUF r_buf = {sz, (char*)buf}; DWORD amount = 0; @@ -24,8 +23,8 @@ namespace llarp TRUE); if(amount > 0) { - if(tcp->read) - tcp->read(tcp, buf, amount); + if(tcp.read) + tcp.read(&tcp, buf, amount); } else { @@ -51,6 +50,43 @@ namespace llarp return sent; } + void + tcp_conn::flush_write() + { + connected(); + ev_io::flush_write(); + } + + 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(std::get< SOCKET >(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); + } + } + int tcp_serv::read(void*, size_t) { @@ -61,24 +97,16 @@ namespace llarp strerror(errno)); return -1; } - llarp_tcp_conn* conn = new llarp_tcp_conn; - // zero out callbacks - conn->tick = nullptr; - conn->closed = nullptr; - conn->read = nullptr; // build handler - llarp::tcp_conn* connimpl = new tcp_conn(new_fd, conn); - conn->impl = connimpl; - conn->loop = loop; + llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd); if(loop->add_ev(connimpl, true)) { // call callback if(tcp->accepted) - tcp->accepted(tcp, conn); + tcp->accepted(tcp, &connimpl->tcp); return 0; } // cleanup error - delete conn; delete connimpl; return -1; } @@ -254,6 +282,26 @@ struct llarp_win32_loop : public llarp_ev_loop { } + bool + tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr) + { + // create socket + DWORD on = 1; + SOCKET fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0); + if(fd == INVALID_SOCKET) + return false; + // set non blocking + if(ioctlsocket(fd, FIONBIO, &on) == SOCKET_ERROR) + { + ::closesocket(fd); + return false; + } + llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp); + add_ev(conn, true); + conn->connect(); + return true; + } + ~llarp_win32_loop() { if(iocpfd != INVALID_HANDLE_VALUE) diff --git a/vendor/libtuntap-master/tuntap.cpp b/vendor/libtuntap-master/tuntap.cpp index 5baf601cf..b3e36092e 100644 --- a/vendor/libtuntap-master/tuntap.cpp +++ b/vendor/libtuntap-master/tuntap.cpp @@ -31,10 +31,12 @@ #include #include #include +#if _WIN32_WINNT < 0x0600 extern "C" int inet_pton(int af, const char *src, void *dst); extern "C" const char * inet_ntop(int af, const void *src, char *dst, size_t size); +#endif #else #include #include