diff --git a/LICENSE b/LICENSE index 17889aaec..e0dd48d4c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ 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 warranty. In no event will the authors be held liable for any damages diff --git a/include/tuntap.h b/include/tuntap.h index 2f0447309..28da2e51b 100644 --- a/include/tuntap.h +++ b/include/tuntap.h @@ -143,6 +143,9 @@ extern "C" char if_name[IF_NAMESIZE]; #if defined(FreeBSD) int mode; +#endif +#if defined(Windows) + OVERLAPPED ovl; #endif }; diff --git a/llarp/ev.hpp b/llarp/ev.hpp index 3fb4e3153..d91fe37e2 100644 --- a/llarp/ev.hpp +++ b/llarp/ev.hpp @@ -57,7 +57,8 @@ namespace llarp #ifndef _WIN32 return write(fd, data, sz) != -1; #else - return WriteFile(std::get< HANDLE >(fd), data, sz, nullptr, nullptr); + DWORD w; + return WriteFile(std::get< HANDLE >(fd), data, sz, &w, nullptr); #endif } diff --git a/llarp/ev_win32.hpp b/llarp/ev_win32.hpp index c9651736f..689f791c6 100644 --- a/llarp/ev_win32.hpp +++ b/llarp/ev_win32.hpp @@ -17,14 +17,17 @@ namespace llarp // we receive queued data in the OVERLAPPED data field, // much like the pipefds in the UNIX kqueue and loonix // epoll handles - // 0 is the read port, 1 is the write port - WSAOVERLAPPED portfds[2] = {0}; + WSAOVERLAPPED* portfd; 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() { + delete portfd; } int @@ -43,8 +46,10 @@ namespace llarp unsigned long flags = 0; WSABUF wbuf = {sz, static_cast< char* >(buf)}; // WSARecvFrom - int ret = ::WSARecvFrom(std::get< SOCKET >(fd), &wbuf, 1, nullptr, &flags, - addr, &slen, &portfds[0], nullptr); + llarp::LogInfo("read ", sz, " bytes into socket"); + int ret = + ::WSARecvFrom(std::get< SOCKET >(fd), &wbuf, 1, nullptr, &flags, addr, + &slen, portfd, nullptr); // 997 is the error code for queued ops int s_errno = ::WSAGetLastError(); if(ret && s_errno != 997) @@ -74,8 +79,9 @@ namespace llarp return -1; } // WSASendTo + llarp::LogInfo("write ", sz, " bytes into socket"); 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(); if(sent && s_errno != 997) { @@ -90,6 +96,7 @@ namespace llarp { llarp_tun_io* t; device* tunif; + OVERLAPPED* tun_async; tun(llarp_tun_io* tio) : ev_io(INVALID_HANDLE_VALUE) , t(tio) @@ -115,6 +122,12 @@ namespace llarp ev_io::flush_write(); } + bool + do_write(void* data, size_t sz) + { + return WriteFile(std::get< HANDLE >(fd), data, sz, nullptr, tun_async); + } + int read(void* buf, size_t sz) { @@ -147,7 +160,8 @@ namespace llarp return false; } - fd = tunif->tun_fd; + fd = tunif->tun_fd; + tun_async = &tunif->ovl; if(std::get< HANDLE >(fd) == INVALID_HANDLE_VALUE) return false; @@ -199,22 +213,19 @@ struct llarp_win32_loop : public llarp_ev_loop // as an arch-specific pointer value ULONG_PTR ev_id = 0; WSAOVERLAPPED* qdata = nullptr; - int result = 0; - int idx = 0; - - do + BOOL result = + ::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms); + int idx = 0; + 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 = - reinterpret_cast< llarp::udp_listener* >(ev_id); - if(ev && !ev->fd.valueless_by_exception()) - { - ev->getData(readbuf, sizeof(readbuf), iolen); - } + llarp::LogInfo("size: ", iolen, "\tev_id: ", ev_id, "\tqdata: ", qdata); + ev->getData(readbuf, sizeof(readbuf), iolen); } ++idx; - } while(::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms)); + } if(!idx) return -1; @@ -252,6 +263,8 @@ struct llarp_win32_loop : public llarp_ev_loop reinterpret_cast< llarp::udp_listener* >(ev_id); if(ev && !ev->fd.valueless_by_exception()) { + llarp::LogInfo("size: ", iolen, "\tev_id: ", ev_id, + "\tqdata: ", qdata); ev->getData(readbuf, sizeof(readbuf), iolen); } } @@ -307,7 +320,7 @@ struct llarp_win32_loop : public llarp_ev_loop } } llarp::Addr a(*addr); - llarp::LogDebug("bind to ", a); + llarp::LogInfo("bind to ", a); if(bind(fd, addr, slen) == -1) { perror("bind()"); diff --git a/vendor/libtuntap-master/tuntap-windows.c b/vendor/libtuntap-master/tuntap-windows.c index ebf9addca..e58eccdab 100644 --- a/vendor/libtuntap-master/tuntap-windows.c +++ b/vendor/libtuntap-master/tuntap-windows.c @@ -394,7 +394,7 @@ tuntap_read(struct device *dev, void *buf, size_t size) { 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(); @@ -410,7 +410,7 @@ tuntap_write(struct device *dev, void *buf, size_t size) { 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(); diff --git a/vendor/libtuntap-master/tuntap.cpp b/vendor/libtuntap-master/tuntap.cpp index e821714a1..630107b23 100644 --- a/vendor/libtuntap-master/tuntap.cpp +++ b/vendor/libtuntap-master/tuntap.cpp @@ -68,6 +68,9 @@ extern "C" dev->tun_fd = TUNFD_INVALID_VALUE; dev->ctrl_sock = -1; dev->flags = 0; + #if defined(Windows) + memset(&dev->ovl, 0, sizeof(OVERLAPPED)); + #endif __tuntap_log = &tuntap_log_default; return dev;