try fixing win32 event loop

pull/20/head
despair86 6 years ago
parent 6ba60093d2
commit 94c5f46d33

@ -1,5 +1,5 @@
Copyright (c) 2018 Jeff Becker Copyright (c) 2018 Jeff Becker
Win32 port and portions copyright ©2018 Rick V. Windows NT port and portions copyright ©2018 Rick V.
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

@ -143,6 +143,9 @@ extern "C"
char if_name[IF_NAMESIZE]; char if_name[IF_NAMESIZE];
#if defined(FreeBSD) #if defined(FreeBSD)
int mode; int mode;
#endif
#if defined(Windows)
OVERLAPPED ovl;
#endif #endif
}; };

@ -57,7 +57,8 @@ namespace llarp
#ifndef _WIN32 #ifndef _WIN32
return write(fd, data, sz) != -1; return write(fd, data, sz) != -1;
#else #else
return WriteFile(std::get< HANDLE >(fd), data, sz, nullptr, nullptr); DWORD w;
return WriteFile(std::get< HANDLE >(fd), data, sz, &w, nullptr);
#endif #endif
} }

@ -17,14 +17,17 @@ namespace llarp
// we receive queued data in the OVERLAPPED data field, // we receive queued data in the OVERLAPPED data field,
// much like the pipefds in the UNIX kqueue and loonix // much like the pipefds in the UNIX kqueue and loonix
// epoll handles // epoll handles
// 0 is the read port, 1 is the write port WSAOVERLAPPED* portfd;
WSAOVERLAPPED portfds[2] = {0};
size_t iosz; size_t iosz;
udp_listener(SOCKET fd, llarp_udp_io* u) : ev_io(fd), udp(u){}; udp_listener(SOCKET fd, llarp_udp_io* u) : ev_io(fd), udp(u)
{
portfd = new WSAOVERLAPPED;
};
~udp_listener() ~udp_listener()
{ {
delete portfd;
} }
int int
@ -43,8 +46,10 @@ namespace llarp
unsigned long flags = 0; unsigned long flags = 0;
WSABUF wbuf = {sz, static_cast< char* >(buf)}; WSABUF wbuf = {sz, static_cast< char* >(buf)};
// WSARecvFrom // WSARecvFrom
int ret = ::WSARecvFrom(std::get< SOCKET >(fd), &wbuf, 1, nullptr, &flags, llarp::LogInfo("read ", sz, " bytes into socket");
addr, &slen, &portfds[0], nullptr); int ret =
::WSARecvFrom(std::get< SOCKET >(fd), &wbuf, 1, nullptr, &flags, addr,
&slen, portfd, nullptr);
// 997 is the error code for queued ops // 997 is the error code for queued ops
int s_errno = ::WSAGetLastError(); int s_errno = ::WSAGetLastError();
if(ret && s_errno != 997) if(ret && s_errno != 997)
@ -74,8 +79,9 @@ namespace llarp
return -1; return -1;
} }
// WSASendTo // WSASendTo
llarp::LogInfo("write ", sz, " bytes into socket");
ssize_t sent = ::WSASendTo(std::get< SOCKET >(fd), &wbuf, 1, nullptr, 0, ssize_t sent = ::WSASendTo(std::get< SOCKET >(fd), &wbuf, 1, nullptr, 0,
to, slen, &portfds[1], nullptr); to, slen, portfd, nullptr);
int s_errno = ::WSAGetLastError(); int s_errno = ::WSAGetLastError();
if(sent && s_errno != 997) if(sent && s_errno != 997)
{ {
@ -90,6 +96,7 @@ namespace llarp
{ {
llarp_tun_io* t; llarp_tun_io* t;
device* tunif; device* tunif;
OVERLAPPED* tun_async;
tun(llarp_tun_io* tio) tun(llarp_tun_io* tio)
: ev_io(INVALID_HANDLE_VALUE) : ev_io(INVALID_HANDLE_VALUE)
, t(tio) , t(tio)
@ -115,6 +122,12 @@ namespace llarp
ev_io::flush_write(); ev_io::flush_write();
} }
bool
do_write(void* data, size_t sz)
{
return WriteFile(std::get< HANDLE >(fd), data, sz, nullptr, tun_async);
}
int int
read(void* buf, size_t sz) read(void* buf, size_t sz)
{ {
@ -147,7 +160,8 @@ namespace llarp
return false; return false;
} }
fd = tunif->tun_fd; fd = tunif->tun_fd;
tun_async = &tunif->ovl;
if(std::get< HANDLE >(fd) == INVALID_HANDLE_VALUE) if(std::get< HANDLE >(fd) == INVALID_HANDLE_VALUE)
return false; return false;
@ -199,22 +213,19 @@ struct llarp_win32_loop : public llarp_ev_loop
// as an arch-specific pointer value // as an arch-specific pointer value
ULONG_PTR ev_id = 0; ULONG_PTR ev_id = 0;
WSAOVERLAPPED* qdata = nullptr; WSAOVERLAPPED* qdata = nullptr;
int result = 0; BOOL result =
int idx = 0; ::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms);
int idx = 0;
do if(result)
{ {
if(ev_id && qdata && iolen) llarp::udp_listener* ev = reinterpret_cast< llarp::udp_listener* >(ev_id);
if(ev && !ev->fd.valueless_by_exception())
{ {
llarp::udp_listener* ev = llarp::LogInfo("size: ", iolen, "\tev_id: ", ev_id, "\tqdata: ", qdata);
reinterpret_cast< llarp::udp_listener* >(ev_id); ev->getData(readbuf, sizeof(readbuf), iolen);
if(ev && !ev->fd.valueless_by_exception())
{
ev->getData(readbuf, sizeof(readbuf), iolen);
}
} }
++idx; ++idx;
} while(::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms)); }
if(!idx) if(!idx)
return -1; return -1;
@ -252,6 +263,8 @@ struct llarp_win32_loop : public llarp_ev_loop
reinterpret_cast< llarp::udp_listener* >(ev_id); reinterpret_cast< llarp::udp_listener* >(ev_id);
if(ev && !ev->fd.valueless_by_exception()) if(ev && !ev->fd.valueless_by_exception())
{ {
llarp::LogInfo("size: ", iolen, "\tev_id: ", ev_id,
"\tqdata: ", qdata);
ev->getData(readbuf, sizeof(readbuf), iolen); ev->getData(readbuf, sizeof(readbuf), iolen);
} }
} }
@ -307,7 +320,7 @@ struct llarp_win32_loop : public llarp_ev_loop
} }
} }
llarp::Addr a(*addr); llarp::Addr a(*addr);
llarp::LogDebug("bind to ", a); llarp::LogInfo("bind to ", a);
if(bind(fd, addr, slen) == -1) if(bind(fd, addr, slen) == -1)
{ {
perror("bind()"); perror("bind()");

@ -394,7 +394,7 @@ tuntap_read(struct device *dev, void *buf, size_t size)
{ {
DWORD len; DWORD len;
if(ReadFile(dev->tun_fd, buf, (DWORD)size, &len, NULL) == 0) if(ReadFile(dev->tun_fd, buf, (DWORD)size, &len, &dev->ovl) == 0)
{ {
int errcode = GetLastError(); int errcode = GetLastError();
@ -410,7 +410,7 @@ tuntap_write(struct device *dev, void *buf, size_t size)
{ {
DWORD len; DWORD len;
if(WriteFile(dev->tun_fd, buf, (DWORD)size, &len, NULL) == 0) if(WriteFile(dev->tun_fd, buf, (DWORD)size, &len, &dev->ovl) == 0)
{ {
int errcode = GetLastError(); int errcode = GetLastError();

@ -68,6 +68,9 @@ extern "C"
dev->tun_fd = TUNFD_INVALID_VALUE; dev->tun_fd = TUNFD_INVALID_VALUE;
dev->ctrl_sock = -1; dev->ctrl_sock = -1;
dev->flags = 0; dev->flags = 0;
#if defined(Windows)
memset(&dev->ovl, 0, sizeof(OVERLAPPED));
#endif
__tuntap_log = &tuntap_log_default; __tuntap_log = &tuntap_log_default;
return dev; return dev;

Loading…
Cancel
Save