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.
pull/45/head
despair 6 years ago
parent 24770f3cdd
commit 04e620ebf2

@ -185,8 +185,7 @@ if(UNIX)
endif() endif()
elseif(WIN32) elseif(WIN32)
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c) set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c)
add_definitions(-DWIN32_LEAN_AND_MEAN) add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x500 -D_WIN32_WINNT=0x500)
add_definitions(-DWIN32)
else() else()
message(FATAL_ERROR "What operating system _are_ you building on/for?") message(FATAL_ERROR "What operating system _are_ you building on/for?")
endif(UNIX) endif(UNIX)
@ -525,7 +524,13 @@ if(USE_LIBABYSS)
add_library(${ABYSS_LIB} STATIC ${ABYSS_SRC}) add_library(${ABYSS_LIB} STATIC ${ABYSS_SRC})
set(ALL_SRC ${ALL_SRC} ${ABYSS_SRC} ${ABYSS}/main.cpp) set(ALL_SRC ${ALL_SRC} ${ABYSS_SRC} ${ABYSS}/main.cpp)
add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp) add_executable(${ABYSS_EXE} ${ABYSS}/main.cpp)
if (NOT WIN32)
target_link_libraries(${ABYSS_EXE} ${PLATFORM_LIB}) 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) set(TEST_SRC ${TEST_SRC} test/jsonrpc_unittest.cpp)
# for freebsd # for freebsd
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")

@ -400,7 +400,7 @@ randombytes_salsa20_random_stir(void)
if (hCAPINg) if (hCAPINg)
{ {
/* call BCryptGenRandom(2) */ /* 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))) if(!BCRYPT_SUCCESS(getrandom(NULL, m0, sizeof m0,BCRYPT_USE_SYSTEM_PREFERRED_RNG)))
{ {
sodium_misuse(); sodium_misuse();

@ -9,16 +9,15 @@
extern "C" extern "C"
{ {
#endif #endif
#if _WIN32_WINNT < 0x600
const char* const char*
inet_ntop(int af, const void* src, char* dst, size_t size); inet_ntop(int af, const void* src, char* dst, size_t size);
int int
inet_pton(int af, const char* src, void* dst); inet_pton(int af, const char* src, void* dst);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#ifndef ssize_t
#define ssize_t long
#endif
typedef unsigned short in_port_t; typedef unsigned short in_port_t;
typedef unsigned int in_addr_t; typedef unsigned int in_addr_t;
#else #else

@ -144,13 +144,13 @@ namespace abyss
{ {
if(state == eInitial) if(state == eInitial)
return true; return true;
if(sz == 0) if(!sz)
return true; return true;
bool done = false; bool done = false;
while(state < eReadResponseBody) while(state < eReadResponseBody)
{ {
const char* end = strstr(buf, "\r\n"); const char* end = strstr(buf, "\r\n");
if(end == nullptr) if(!end)
return false; return false;
string_view line(buf, end - buf); string_view line(buf, end - buf);
switch(state) switch(state)
@ -214,7 +214,7 @@ namespace abyss
char buf[512] = {0}; char buf[512] = {0};
int sz = snprintf(buf, sizeof(buf), int sz = snprintf(buf, sizeof(buf),
"POST /rpc HTTP/1.0\r\nContent-Type: " "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", "application/json\r\n",
body.size()); body.size());
if(sz <= 0) if(sz <= 0)
@ -294,7 +294,7 @@ namespace abyss
++itr; ++itr;
} }
// open at most 10 connections // 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"); llarp::LogDebug("tick connect to rpc ", numCalls, " times");
while(numCalls--) while(numCalls--)
{ {

@ -217,7 +217,7 @@ namespace abyss
return false; return false;
} }
if(sz == 0) if(!sz)
return true; return true;
bool done = false; bool done = false;

@ -30,13 +30,14 @@
// we already have our own definition of these // we already have our own definition of these
// -despair // -despair
#ifndef inet_ntop
namespace { namespace {
extern "C" { extern "C" {
const char* inet_ntop(int af, const void *src, char *dst, size_t size); const char* inet_ntop(int af, const void *src, char *dst, size_t size);
int inet_pton(int af, const char *src, void *dst); 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) const char *libutp::inet_ntop(int af, const void *src, char *dest, size_t length)
{ {

@ -171,11 +171,17 @@ namespace llarp
return false; return false;
} }
virtual void
flush_write()
{
flush_write_buffers(0);
}
/// called in event loop when fd is ready for writing /// called in event loop when fd is ready for writing
/// requeues anything not written /// requeues anything not written
/// this assumes fd is set to non blocking /// this assumes fd is set to non blocking
virtual void virtual void
flush_write() flush_write_buffers(size_t amount)
{ {
if(m_LossyWriteQueue) if(m_LossyWriteQueue)
m_LossyWriteQueue->Process([&](WriteBuffer& buffer) { m_LossyWriteQueue->Process([&](WriteBuffer& buffer) {
@ -185,34 +191,58 @@ namespace llarp
}); });
else if(m_BlockingWriteQueue) else if(m_BlockingWriteQueue)
{ {
// write buffers if(amount)
while(m_BlockingWriteQueue->size())
{ {
auto& itr = m_BlockingWriteQueue->front(); while(amount && m_BlockingWriteQueue->size())
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 auto& itr = m_BlockingWriteQueue->front();
WriteBuffer buff(itr.buf + dlt, itr.bufsz - dlt); 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->pop_front();
m_BlockingWriteQueue->push_front(buff); amount -= result;
// TODO: errno?
return;
} }
m_BlockingWriteQueue->pop_front(); }
if(errno == EAGAIN || errno == EWOULDBLOCK) else
{
// write buffers
while(m_BlockingWriteQueue->size())
{ {
errno = 0; auto& itr = m_BlockingWriteQueue->front();
return; 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 /// reset errno
errno = 0; errno = 0;
SetLastError(0);
} }
std::unique_ptr< LossyWriteQueue_t > m_LossyWriteQueue; std::unique_ptr< LossyWriteQueue_t > m_LossyWriteQueue;
@ -439,6 +469,7 @@ namespace llarp
// finally create aliases by platform // finally create aliases by platform
#ifdef _WIN32 #ifdef _WIN32
using ev_io = win32_ev_io; using ev_io = win32_ev_io;
#define sizeof(sockaddr_un) 115
#else #else
using ev_io = posix_ev_io; using ev_io = posix_ev_io;
#endif #endif

@ -12,11 +12,6 @@
#include <fcntl.h> #include <fcntl.h>
#endif #endif
// MacOS needs this
#ifndef SOCK_NONBLOCK
#define SOCK_NONBLOCK O_NONBLOCK
#endif
// original upstream // original upstream
#include <unistd.h> #include <unistd.h>
#include <cstdio> #include <cstdio>

@ -8,14 +8,13 @@
#include "ev.hpp" #include "ev.hpp"
#include "logger.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 namespace llarp
{ {
int int
tcp_conn::read(void* buf, size_t sz) tcp_conn::read(void* buf, size_t sz)
{ {
if(_shouldClose)
return -1;
WSABUF r_buf = {sz, (char*)buf}; WSABUF r_buf = {sz, (char*)buf};
DWORD amount = 0; DWORD amount = 0;
@ -24,8 +23,8 @@ namespace llarp
TRUE); TRUE);
if(amount > 0) if(amount > 0)
{ {
if(tcp->read) if(tcp.read)
tcp->read(tcp, buf, amount); tcp.read(&tcp, buf, amount);
} }
else else
{ {
@ -51,6 +50,43 @@ namespace llarp
return sent; 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 int
tcp_serv::read(void*, size_t) tcp_serv::read(void*, size_t)
{ {
@ -61,24 +97,16 @@ namespace llarp
strerror(errno)); strerror(errno));
return -1; return -1;
} }
llarp_tcp_conn* conn = new llarp_tcp_conn;
// zero out callbacks
conn->tick = nullptr;
conn->closed = nullptr;
conn->read = nullptr;
// build handler // build handler
llarp::tcp_conn* connimpl = new tcp_conn(new_fd, conn); llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd);
conn->impl = connimpl;
conn->loop = loop;
if(loop->add_ev(connimpl, true)) if(loop->add_ev(connimpl, true))
{ {
// call callback // call callback
if(tcp->accepted) if(tcp->accepted)
tcp->accepted(tcp, conn); tcp->accepted(tcp, &connimpl->tcp);
return 0; return 0;
} }
// cleanup error // cleanup error
delete conn;
delete connimpl; delete connimpl;
return -1; 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() ~llarp_win32_loop()
{ {
if(iocpfd != INVALID_HANDLE_VALUE) if(iocpfd != INVALID_HANDLE_VALUE)

@ -31,10 +31,12 @@
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <wspiapi.h> #include <wspiapi.h>
#if _WIN32_WINNT < 0x0600
extern "C" int extern "C" int
inet_pton(int af, const char *src, void *dst); inet_pton(int af, const char *src, void *dst);
extern "C" const char * extern "C" const char *
inet_ntop(int af, const void *src, char *dst, size_t size); inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#else #else
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>

Loading…
Cancel
Save