1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

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.
This commit is contained in:
despair 2018-11-02 15:43:53 -05:00
parent 24770f3cdd
commit 04e620ebf2
10 changed files with 132 additions and 51 deletions

View file

@ -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")

View file

@ -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();

View file

@ -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

View file

@ -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--)
{

View file

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

View file

@ -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)
{

View file

@ -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

View file

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

View file

@ -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)

View file

@ -31,10 +31,12 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#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 <arpa/inet.h>
#include <netinet/in.h>