From d1cbd58a3f5b0786134fc55fdd8884bf783e052f Mon Sep 17 00:00:00 2001 From: despair Date: Thu, 13 Dec 2018 13:27:01 -0600 Subject: [PATCH] back to square one need to be able to queue up a TUN read/write at each tick then finish dealing with it in the main event loop which is damn near impossible to do along with unix-style asio that waits for data to appear/disappear before signalling --- llarp/ev.hpp | 25 +--- llarp/ev_win32.hpp | 39 +++++- llarp/win32_upoll.c | 157 +---------------------- llarp/win32_upoll.h | 25 ---- vendor/libtuntap-master/tuntap-windows.c | 2 +- 5 files changed, 40 insertions(+), 208 deletions(-) diff --git a/llarp/ev.hpp b/llarp/ev.hpp index d495c4bc7..d75e36ee3 100644 --- a/llarp/ev.hpp +++ b/llarp/ev.hpp @@ -163,9 +163,9 @@ namespace llarp virtual int sendto(const sockaddr* dst, const void* data, size_t sz) { - (void)(dst); - (void)(data); - (void)(sz); + UNREFERENCED_PARAMETER(dst); + UNREFERENCED_PARAMETER(data); + UNREFERENCED_PARAMETER(sz); return -1; }; @@ -180,23 +180,6 @@ namespace llarp virtual ssize_t do_write(void* data, size_t sz) { - if(this->is_tun) - { - DWORD x; - bool r; - asio_evt_pkt* pkt = new asio_evt_pkt; - pkt->sz = sz; - pkt->write = true; - int e = 0; - r = WriteFile(fd.tun, data, sz, &x, &pkt->pkt); - if(r) // we returned immediately - return x; - e = GetLastError(); - if(e == ERROR_IO_PENDING) - return sz; - else - return -1; - } return uwrite(fd.socket, (char*)data, sz); } @@ -537,6 +520,8 @@ namespace llarp #ifdef _WIN32 using ev_io = win32_ev_io; + // From the preview SDK, should take a look at that + // periodically in case its definition changes #define UNIX_PATH_MAX 108 typedef struct sockaddr_un diff --git a/llarp/ev_win32.hpp b/llarp/ev_win32.hpp index 8cdfc82a9..bdfc0464b 100644 --- a/llarp/ev_win32.hpp +++ b/llarp/ev_win32.hpp @@ -154,13 +154,31 @@ namespace llarp return true; } + virtual ssize_t + do_write(void* buf, size_t sz) + { + DWORD x; + bool r; + asio_evt_pkt* pkt = new asio_evt_pkt; + memset(pkt, 0, sizeof(asio_evt_pkt)); + pkt->sz = sz; + pkt->write = true; + int e = 0; + r = WriteFile(fd.tun, buf, sz, &x, &pkt->pkt); + if(r) // we returned immediately + return x; + e = GetLastError(); + if(e == ERROR_IO_PENDING) + return sz; + else + return -1; + } + int read(byte_t* buf, size_t sz) { ssize_t ret = tuntap_read(tunif, buf, sz); if(ret > 0 && t->recvpkt) - // should have pktinfo - // I have no idea... t->recvpkt(t, llarp::InitBuffer(buf, ret)); return ret; } @@ -356,6 +374,7 @@ struct llarp_win32_loop : public llarp_ev_loop return upollfd && (tun_event_queue != INVALID_HANDLE_VALUE); } + // Service paths first, then virtual interface int tick(int ms) { @@ -393,7 +412,7 @@ struct llarp_win32_loop : public llarp_ev_loop DWORD size = 0; OVERLAPPED* ovl = nullptr; ULONG_PTR listener = 0; - asio_evt_pkt* pkt; + asio_evt_pkt* pkt = nullptr; while( GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, ms)) { @@ -403,14 +422,17 @@ struct llarp_win32_loop : public llarp_ev_loop llarp::LogWarn("incomplete async io operation: got ", size, " bytes, expected ", pkt->sz, " bytes");*/ if(!pkt->write) + { ev->read(readbuf, size); + printf("read tun\n"); + } else { ev->flush_write_buffers(pkt->sz); printf("write tun\n"); } ++result; - delete pkt; + delete pkt; // don't leak } if(result != -1) @@ -547,8 +569,9 @@ struct llarp_win32_loop : public llarp_ev_loop if(e->is_tun) { asio_evt_pkt* pkt = new asio_evt_pkt; - pkt->write = false; - pkt->sz = sizeof(readbuf); + memset(pkt, 0, sizeof(asio_evt_pkt)); + pkt->write = false; + pkt->sz = sizeof(readbuf); CreateIoCompletionPort(e->fd.tun, tun_event_queue, (ULONG_PTR)e, 1024); // queue an initial read ReadFile(e->fd.tun, readbuf, sizeof(readbuf), nullptr, &pkt->pkt); @@ -610,7 +633,9 @@ struct llarp_win32_loop : public llarp_ev_loop extern "C" asio_evt_pkt* getTunEventPkt() { - return new asio_evt_pkt; + asio_evt_pkt* newpkt = new asio_evt_pkt; + memset(newpkt, 0, sizeof(asio_evt_pkt)); + return newpkt; } #endif diff --git a/llarp/win32_upoll.c b/llarp/win32_upoll.c index f25764eea..7dd3a3e98 100644 --- a/llarp/win32_upoll.c +++ b/llarp/win32_upoll.c @@ -3,6 +3,7 @@ #pragma GCC diagnostic ignored "-Wvla" /* emulated epoll, because the native async event system does not do * particularly well with notification + * update: now win32-exclusive */ #include "win32_upoll.h" @@ -172,75 +173,6 @@ upoll_ctl(upoll_t* upq, int op, intptr_t fd, upoll_event_t* event) return 0; } -#if defined(HAVE_POLL) -int -upoll_wait_poll(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) -{ - /* FD_SETSIZE should be smaller than OPEN_MAX, but OPEN_MAX isn't portable */ - if(nev > FD_SETSIZE) - nev = FD_SETSIZE; - - unote_t* nvec[nev]; - int r, i, nfds = 0; - uint32_t hint; - struct pollfd pfds[nev]; - - unote_t* n = NULL; - ulist_t* s = ulist_mark(&upq->alive); - ulist_t* q = ulist_next(&upq->alive); - - while(q != s && nfds < nev) - { - n = ulist_data(q, unote_t, queue); - q = ulist_next(q); - - ulist_remove(&n->queue); - ulist_insert(&upq->alive, &n->queue); - - nvec[nfds] = n; - pfds[nfds].events = 0; - pfds[nfds].fd = n->fd; - if(n->event.events & UPOLLIN) - { - pfds[nfds].events |= POLLIN; - } - if(n->event.events & UPOLLOUT) - { - pfds[nfds].events |= POLLOUT; - } - nfds++; - } - - r = poll(pfds, nfds, timeout); - if(r < 0) - return -errno; - - int e = 0; - for(i = 0; i < nfds && e < nev; i++) - { - hint = 0; - if(pfds[i].revents) - { - n = nvec[i]; - if(pfds[i].revents & POLLIN) - hint |= UPOLLIN; - if(pfds[i].revents & POLLOUT) - hint |= UPOLLOUT; - if(pfds[i].revents & (POLLERR | POLLNVAL | POLLHUP)) - hint |= (UPOLLERR | UPOLLIN); - - if(hint & UPOLLERR) - hint &= ~UPOLLOUT; - - evs[e].data = n->event.data; - evs[e].events = hint; - ++e; - } - } - - return e; -} -#else int upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) { @@ -302,21 +234,13 @@ upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) nfds++; } -#if defined(__WINDOWS__) int rc = select(0, &pollin, &pollout, &pollerr, tvp); if(rc == SOCKET_ERROR) { assert(WSAGetLastError() == WSAENOTSOCK); return -WSAGetLastError(); } -#else - int rc = select(maxfd + 1, &pollin, &pollout, &pollerr, tvp); - if(rc == -1) - { - assert(errno == EINTR || errno == EBADF); - return -errno; - } -#endif + e = 0; for(i = 0; i < nfds && e < nev; i++) { @@ -345,17 +269,12 @@ upoll_wait_select(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) } return e; } -#endif int upoll_wait(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) { int r = 0; -#if defined(HAVE_POLL) - r = upoll_wait_poll(upq, evs, nev, timeout); -#else r = upoll_wait_select(upq, evs, nev, timeout); -#endif return r; } @@ -364,20 +283,12 @@ usocket(int domain, int type, int proto) { intptr_t fd = (intptr_t)socket(domain, type, proto); -#if defined(__WINDOWS__) if(fd < 0) return -WSAGetLastError(); unsigned long flags = 1; int rc = ioctlsocket((SOCKET)fd, FIONBIO, &flags); if(rc < 0) return -WSAGetLastError(); -#else - if(fd < 0) - return -errno; - int rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); - if(rc < 0) - return -errno; -#endif return fd; } @@ -391,12 +302,8 @@ ubind(intptr_t fd, const char* host, const char* serv) int optval = 0; unsigned int optlen = sizeof(optval); -#if defined(__WINDOWS__) int rc = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, (char*)&optval, (int*)&optlen); -#else - int rc = getsockopt(fd, SOL_SOCKET, SO_TYPE, &optval, &optlen); -#endif hint.ai_family = AF_INET; hint.ai_socktype = optval; @@ -406,25 +313,15 @@ ubind(intptr_t fd, const char* host, const char* serv) optval = 1; if(!rc) { -#if defined(__WINDOWS__) rc = setsockopt((SOCKET)fd, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval)); -#else - rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); -#endif if(!rc) rc = bind(fd, info->ai_addr, info->ai_addrlen); } freeaddrinfo(info); if(rc) - { -#if defined(__WINDOWS__) return WSAGetLastError(); -#else - return errno; -#endif - } return 0; } @@ -439,11 +336,7 @@ uconnect(intptr_t fd, const char* host, const char* serv) int optval = 0; unsigned int optlen; -#if defined(__WINDOWS__) int rc = getsockopt(fd, SOL_SOCKET, SO_TYPE, (char*)&optval, (int*)&optlen); -#else - int rc = getsockopt(fd, SOL_SOCKET, SO_TYPE, &optval, &optlen); -#endif hint.ai_family = AF_INET; hint.ai_socktype = optval; @@ -451,25 +344,14 @@ uconnect(intptr_t fd, const char* host, const char* serv) rc = getaddrinfo(host, serv, &hint, &info); if(!rc) - { -#if defined(__WINDOWS__) rc = connect((SOCKET)fd, info->ai_addr, info->ai_addrlen); -#else - rc = connect(fd, info->ai_addr, info->ai_addrlen); -#endif - } freeaddrinfo(info); if(rc) { -#if defined(__WINDOWS__) if(WSAGetLastError() != WSAEWOULDBLOCK) return WSAGetLastError(); -#else - if(errno != EINPROGRESS) - return errno; -#endif } return 0; } @@ -488,15 +370,9 @@ uaccept(intptr_t sock) addr.sa_family = AF_INET; socklen_t addr_len; -#if defined(__WINDOWS__) intptr_t fd = (intptr_t)accept((SOCKET)sock, &addr, &addr_len); if(fd == -1) return WSAGetLastError(); -#else - intptr_t fd = accept(sock, &addr, &addr_len); - if(fd < 0) - return errno; -#endif return fd; } @@ -504,11 +380,7 @@ uaccept(intptr_t sock) int uclose(intptr_t sock) { -#if defined(__WINDOWS__) return closesocket((SOCKET)sock); -#else - return close(sock); -#endif } int @@ -573,7 +445,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * add argument make_overlapped */ -#if defined(__WINDOWS__) int usocketpair(intptr_t socks[2], int async) { @@ -646,28 +517,4 @@ usocketpair(intptr_t socks[2], int async) socks[0] = socks[1] = -1; return SOCKET_ERROR; } -#else -int -usocketpair(intptr_t socks[2], int dummy) -{ - int sovec[2]; - if(socks == 0) - { - errno = EINVAL; - return -1; - } - dummy = socketpair(AF_LOCAL, SOCK_STREAM, 0, sovec); - if(dummy) - { - socks[0] = socks[1] = -1; - } - else - { - socks[0] = sovec[0]; - socks[1] = sovec[1]; - } - return dummy; -} -#endif - #endif \ No newline at end of file diff --git a/llarp/win32_upoll.h b/llarp/win32_upoll.h index 6f6949e3a..2eb6fec17 100644 --- a/llarp/win32_upoll.h +++ b/llarp/win32_upoll.h @@ -28,38 +28,13 @@ #include #include -#if defined(__WINDOWS__) #include #include #include #include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#if defined(__linux__) -#undef HAVE_EPOLL -#define HAVE_EPOLL 1 -#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -#undef HAVE_POLL -#define HAVE_POLL 1 -#else #undef HAVE_SELECT #define HAVE_SELECT 1 -#endif - -#if defined(HAVE_EPOLL) -#include -#elif defined(HAVE_POLL) -#include -#endif typedef struct unote unote_t; typedef struct ulist ulist_t; diff --git a/vendor/libtuntap-master/tuntap-windows.c b/vendor/libtuntap-master/tuntap-windows.c index 4248b4a2e..991ab06c0 100644 --- a/vendor/libtuntap-master/tuntap-windows.c +++ b/vendor/libtuntap-master/tuntap-windows.c @@ -444,7 +444,7 @@ tuntap_read(struct device *dev, void *buf, size_t size) if(e && e != 997) { tuntap_log(TUNTAP_LOG_ERR, - (const char *)formated_error(L"%1%0", _doserrno)); + (const char *)formated_error(L"%1%0", e)); return -1; } }