diff --git a/CMakeLists.txt b/CMakeLists.txt index b7b9ef3c1..4b0cfcc16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,9 +212,6 @@ endif(JEMALLOC) # FS_LIB should resolve to nothing on all other platforms # it is only required on win32 -rick set(LIBS ${MALLOC_LIB} ${FS_LIB}) -if(NOT WIN32) - set(LIBS ${LIBS} uv) -endif() if(ANDROID) list(APPEND LIBS log) diff --git a/cmake/solaris.cmake b/cmake/solaris.cmake index a3915e3b3..afc788065 100644 --- a/cmake/solaris.cmake +++ b/cmake/solaris.cmake @@ -1,23 +1,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - # check if we have the (saner) emulation of epoll here - # it's basically linux epoll but with a sane method of - # dealing with closed file handles that still exist in the - # epoll set - # - # Note that the zombie of Oracle Solaris 2.11.x will NOT have - # this, the header check is the only method we have to distinguish - # them. -rick the svr4 guy + # we switched to libuv set(SOLARIS ON) - option(USE_POLL "Revert to using poll(2) event loop (useful if targeting Oracle Solaris)" OFF) set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lsocket -lnsl") add_definitions(-D_POSIX_PTHREAD_SEMANTICS) - INCLUDE(CheckIncludeFiles) - CHECK_INCLUDE_FILES(sys/epoll.h SOLARIS_HAVE_EPOLL) - if (SOLARIS_HAVE_EPOLL AND NOT USE_POLL) - message(STATUS "Using fast emulation of Linux epoll(5) on Solaris.") - add_definitions(-DSOLARIS_HAVE_EPOLL) - else() - set(SOLARIS_HAVE_EPOLL OFF) - message(STATUS "Falling back to poll(2)-based event loop.") - endif() endif() diff --git a/cmake/unix.cmake b/cmake/unix.cmake index 5b833ec48..ad8dc1472 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -3,34 +3,23 @@ add_definitions(-DPOSIX) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c ABSOLUTE) - get_filename_component(EV_SRC "llarp/ev/ev_epoll.cpp" ABSOLUTE) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c ABSOLUTE) - get_filename_component(EV_SRC "llarp/ev/ev_epoll.cpp" ABSOLUTE) elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-openbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) - get_filename_component(EV_SRC "llarp/ev/ev_kqueue.cpp" ABSOLUTE) elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-netbsd.c ${TT_ROOT}/tuntap-unix-bsd.c) - get_filename_component(EV_SRC "llarp/ev/ev_kqueue.cpp" ABSOLUTE) elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c) - get_filename_component(EV_SRC "llarp/ev/ev_kqueue.cpp" ABSOLUTE) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c) - get_filename_component(EV_SRC "llarp/ev/ev_kqueue.cpp" ABSOLUTE) elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-sunos.c) - if (SOLARIS_HAVE_EPOLL) - get_filename_component(EV_SRC "llarp/ev/ev_epoll.cpp" ABSOLUTE) - else() - get_filename_component(EV_SRC "llarp/ev/ev_sun.cpp" ABSOLUTE) - endif() else() message(FATAL_ERROR "Your operating system is not supported yet") endif() -set(EXE_LIBS ${STATIC_LIB} cppbackport libutp) +set(EXE_LIBS ${STATIC_LIB} cppbackport libutp uv) if(RELEASE_MOTTO) add_definitions(-DLLARP_RELEASE_MOTTO="${RELEASE_MOTTO}") diff --git a/llarp/ev/ev_epoll.cpp b/llarp/ev/ev_epoll.cpp deleted file mode 100644 index 0877f4ee6..000000000 --- a/llarp/ev/ev_epoll.cpp +++ /dev/null @@ -1,578 +0,0 @@ -#include - -namespace llarp -{ - int - tcp_conn::read(byte_t* buf, size_t sz) - { - if(_shouldClose) - return -1; - - ssize_t amount = ::read(fd, buf, sz); - - if(amount > 0) - { - if(tcp.read) - tcp.read(&tcp, llarp_buffer_t(buf, amount)); - } - else if(amount < 0) - { - // error - _shouldClose = true; - errno = 0; - return -1; - } - return 0; - } - - void - tcp_conn::flush_write() - { - connected(); - ev_io::flush_write(); - } - - ssize_t - tcp_conn::do_write(void* buf, size_t sz) - { - if(_shouldClose) - return -1; - // pretty much every UNIX system still extant, _including_ solaris - // (on both sides of the fork) can ignore SIGPIPE....except - // the other vendored systems... -rick - return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe - } - - 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(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); - errno = 0; - } - } - - int - tcp_serv::read(byte_t*, size_t) - { - int new_fd = ::accept(fd, nullptr, nullptr); - if(new_fd == -1) - { - llarp::LogError("failed to accept on ", fd, ":", strerror(errno)); - return -1; - } - // build handler - llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd); - if(loop->add_ev(connimpl, true)) - { - // call callback - if(tcp->accepted) - tcp->accepted(tcp, &connimpl->tcp); - return 0; - } - // cleanup error - delete connimpl; - return -1; - } - - bool - udp_listener::tick() - { - if(udp->tick) - udp->tick(udp); - return true; - } - - int - udp_listener::read(byte_t* buf, size_t sz) - { - llarp_buffer_t b; - b.base = buf; - b.cur = b.base; - sockaddr_in6 src; - socklen_t slen = sizeof(sockaddr_in6); - sockaddr* addr = (sockaddr*)&src; - ssize_t ret = ::recvfrom(fd, b.base, sz, 0, addr, &slen); - if(ret < 0) - { - errno = 0; - return -1; - } - if(static_cast< size_t >(ret) > sz) - return -1; - b.sz = ret; - udp->recvfrom(udp, addr, ManagedBuffer{b}); - return ret; - } - - int - udp_listener::sendto(const sockaddr* to, const void* data, size_t sz) - { - socklen_t slen; - switch(to->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; - default: - return -1; - } - ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen); - if(sent == -1) - { - llarp::LogWarn(strerror(errno)); - } - return sent; - } - - int - tun::sendto(__attribute__((unused)) const sockaddr* to, - __attribute__((unused)) const void* data, - __attribute__((unused)) size_t sz) - { - return -1; - } - - bool - tun::tick() - { - if(t->tick) - t->tick(t); - flush_write(); - return true; - } - - void - tun::flush_write() - { - if(t->before_write) - t->before_write(t); - ev_io::flush_write(); - } - - int - tun::read(byte_t* buf, size_t sz) - { - ssize_t ret = tuntap_read(tunif, buf, sz); - if(ret > 0 && t->recvpkt) - { - // does not have pktinfo - t->recvpkt(t, llarp_buffer_t(buf, ret)); - } - return ret; - } - - ssize_t - tun::do_write(void* buf, size_t sz) - { - if(writefd != -1) // case of android - return ::write(writefd, buf, sz); - return ev_io::do_write(buf, sz); - } - - int - tun::wait_for_fd_promise(struct device* dev) - { - llarp::tun* t = static_cast< llarp::tun* >(dev->user); - if(t->t->get_fd_promise) - { - struct llarp_fd_promise* promise = t->t->get_fd_promise(t->t); - if(promise) - { - // get promise - auto p = promise->Get(); - // set write fd - t->writefd = p.second; - // return read fd - return p.first; - } - } - return -1; - } - - bool - tun::setup() - { - // for android / ios - if(t->get_fd_promise) - { - tunif->obtain_fd = &wait_for_fd_promise; - tunif->user = this; - } - llarp::LogDebug("set ifname to ", t->ifname); - strncpy(tunif->if_name, t->ifname, sizeof(tunif->if_name)); - if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1) - { - llarp::LogWarn("failed to start interface"); - return false; - } - if(t->get_fd_promise == nullptr) - { - if(tuntap_up(tunif) == -1) - { - llarp::LogWarn("failed to put interface up: ", strerror(errno)); - return false; - } - if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1) - { - llarp::LogWarn("failed to set ip"); - return false; - } - } - fd = tunif->tun_fd; - if(fd == -1) - return false; - // set non blocking - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - return false; - return fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1; - } - -}; // namespace llarp - -bool -llarp_epoll_loop::tcp_connect(struct llarp_tcp_connecter* tcp, - const sockaddr* remoteaddr) -{ - // create socket - int fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return false; - // set non blocking - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - { - ::close(fd); - return false; - } - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - ::close(fd); - return false; - } - llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp); - add_ev(conn, true); - conn->connect(); - return true; -} - -llarp::ev_io* -llarp_epoll_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr) -{ - int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return nullptr; - socklen_t sz = sizeof(sockaddr_in); - if(bindaddr->sa_family == AF_INET6) - { - sz = sizeof(sockaddr_in6); - } - else if(bindaddr->sa_family == AF_UNIX) - { - sz = sizeof(sockaddr_un); - } - if(::bind(fd, bindaddr, sz) == -1) - { - ::close(fd); - return nullptr; - } - if(::listen(fd, 5) == -1) - { - ::close(fd); - return nullptr; - } - return new llarp::tcp_serv(this, fd, tcp); -} - -static int -llarp_ev_epoll_sendto(struct llarp_udp_io* udp, const struct sockaddr* to, - const byte_t* pkt, size_t sz) -{ - const llarp::Addr toaddr(*to); - return ::sendto(udp->fd, pkt, sz, 0, toaddr, toaddr.SockLen()); -} - -bool -llarp_epoll_loop::udp_listen(llarp_udp_io* l, const sockaddr* src) -{ - auto ev = create_udp(l, src); - if(ev) - { - l->fd = ev->fd; - l->sendto = &llarp_ev_epoll_sendto; - } - return ev && add_ev(ev, false); -} - -bool -llarp_epoll_loop::running() const -{ - return epollfd != -1; -} - -bool -llarp_epoll_loop::init() -{ - if(epollfd == -1) - epollfd = epoll_create(1); - return false; -} - -int -llarp_epoll_loop::tick(int ms) -{ - epoll_event events[1024]; - int result; - result = epoll_wait(epollfd, events, 1024, ms); - bool didRead = false; - bool didWrite = false; - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr); - if(ev) - { - llarp::LogDebug(idx, " of ", result, " on ", ev->fd, - " events=", std::to_string(events[idx].events)); - if(events[idx].events & EPOLLERR && errno) - { - IO([&]() -> ssize_t { - llarp::LogDebug("epoll error"); - ev->error(); - return 0; - }); - } - else - { - // write THEN READ don't revert me - if(events[idx].events & EPOLLOUT) - { - didWrite = true; - IO([&]() -> ssize_t { - llarp::LogDebug("epoll out"); - ev->flush_write(); - return 0; - }); - } - if(events[idx].events & EPOLLIN) - { - didRead = true; - IO([&]() -> ssize_t { - llarp::LogDebug("epoll in"); - return ev->read(readbuf, sizeof(readbuf)); - }); - } - } - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - /// if we didn't get an io events we sleep to avoid 100% cpu use - if(didWrite && !didRead) - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - return result; -} - -int -llarp_epoll_loop::run() -{ - epoll_event events[1024]; - int result; - do - { - result = epoll_wait(epollfd, events, 1024, EV_TICK_INTERVAL); - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr); - if(ev) - { - if(events[idx].events & EPOLLERR) - { - ev->error(); - } - else - { - if(events[idx].events & EPOLLIN) - { - ev->read(readbuf, sizeof(readbuf)); - } - if(events[idx].events & EPOLLOUT) - { - ev->flush_write(); - } - } - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - } while(epollfd != -1); - return result; -} - -int -llarp_epoll_loop::udp_bind(const sockaddr* addr) -{ - socklen_t slen; - switch(addr->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; - default: - return -1; - } - int fd = socket(addr->sa_family, SOCK_DGRAM, 0); - if(fd == -1) - { - perror("socket()"); - return -1; - } - - if(addr->sa_family == AF_INET6) - { - // enable dual stack explicitly - int dual = 1; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &dual, sizeof(dual)) == -1) - { - // failed - perror("setsockopt()"); - close(fd); - return -1; - } - } - llarp::Addr a(*addr); - llarp::LogDebug("bind to ", a); - if(bind(fd, addr, slen) == -1) - { - perror("bind()"); - close(fd); - return -1; - } - - return fd; -} - -bool -llarp_epoll_loop::close_ev(llarp::ev_io* ev) -{ - return epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->fd, nullptr) != -1; -} - -llarp::ev_io* -llarp_epoll_loop::create_tun(llarp_tun_io* tun) -{ - llarp::tun* t = new llarp::tun(tun, shared_from_this()); - if(tun->get_fd_promise) - { - } - else if(t->setup()) - { - return t; - } - delete t; - return nullptr; -} - -llarp::ev_io* -llarp_epoll_loop::create_udp(llarp_udp_io* l, const sockaddr* src) -{ - int fd = udp_bind(src); - if(fd == -1) - return nullptr; - llarp::ev_io* listener = new llarp::udp_listener(fd, l); - l->impl = listener; - return listener; -} - -bool -llarp_epoll_loop::add_ev(llarp::ev_io* e, bool write) -{ - epoll_event ev; - ev.data.ptr = e; - ev.events = EPOLLIN | EPOLLERR; - if(write) - ev.events |= EPOLLOUT; - if(epoll_ctl(epollfd, EPOLL_CTL_ADD, e->fd, &ev) == -1) - { - delete e; - return false; - } - handlers.emplace_back(e); - return true; -} - -bool -llarp_epoll_loop::udp_close(llarp_udp_io* l) -{ - bool ret = false; - llarp::udp_listener* listener = static_cast< llarp::udp_listener* >(l->impl); - if(listener) - { - close_ev(listener); - // remove handler - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - if(itr->get() == listener) - itr = handlers.erase(itr); - else - ++itr; - } - l->impl = nullptr; - ret = true; - } - return ret; -} - -void -llarp_epoll_loop::stop() -{ - // close all handlers before closing the epoll fd - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - close_ev(itr->get()); - itr = handlers.erase(itr); - } - - if(epollfd != -1) - close(epollfd); - epollfd = -1; -} diff --git a/llarp/ev/ev_epoll.hpp b/llarp/ev/ev_epoll.hpp deleted file mode 100644 index 2fbb97ec9..000000000 --- a/llarp/ev/ev_epoll.hpp +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef EV_EPOLL_HPP -#define EV_EPOLL_HPP - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace llarp -{ - struct udp_listener : public ev_io - { - llarp_udp_io* udp; - - udp_listener(int fd, llarp_udp_io* u) : ev_io(fd), udp(u){}; - - ~udp_listener() - { - } - - bool - tick() override; - - int - read(byte_t* buf, size_t sz) override; - - int - sendto(const sockaddr* to, const void* data, size_t sz) override; - }; - - struct tun : public ev_io - { - llarp_tun_io* t; - int writefd; - device* tunif; - tun(llarp_tun_io* tio, llarp_ev_loop_ptr l) - : ev_io(-1, new LossyWriteQueue_t("tun_write_queue", l, l)) - , t(tio) - , writefd(-1) - , tunif(tuntap_init()) - - { - - }; - - int - sendto(const sockaddr* to, const void* data, size_t sz) override; - - bool - tick() override; - - void - flush_write() override; - - ssize_t - do_write(void* buf, size_t sz) override; - - int - read(byte_t* buf, size_t sz) override; - - static int - wait_for_fd_promise(struct device* dev); - - bool - setup(); - - ~tun() - { - if(tunif) - tuntap_destroy(tunif); - } - }; -}; // namespace llarp - -struct llarp_epoll_loop - : public llarp_ev_loop, - public std::enable_shared_from_this< llarp_epoll_loop > -{ - int epollfd; - - llarp_epoll_loop() : epollfd(-1) - { - } - - ~llarp_epoll_loop() - { - } - - bool - tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr); - - llarp::ev_io* - bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr); - - virtual bool - udp_listen(llarp_udp_io* l, const sockaddr* src); - - bool - running() const; - - bool - init(); - - int - tick(int ms); - - int - run(); - - int - udp_bind(const sockaddr* addr); - - bool - close_ev(llarp::ev_io* ev); - - llarp::ev_io* - create_tun(llarp_tun_io* tun); - - llarp::ev_io* - create_udp(llarp_udp_io* l, const sockaddr* src); - - bool - add_ev(llarp::ev_io* e, bool write); - - bool - udp_close(llarp_udp_io* l); - - void - stop(); -}; - -#endif diff --git a/llarp/ev/ev_kqueue.cpp b/llarp/ev/ev_kqueue.cpp deleted file mode 100644 index eb626fce5..000000000 --- a/llarp/ev/ev_kqueue.cpp +++ /dev/null @@ -1,599 +0,0 @@ -#include - -namespace llarp -{ - inline int - tcp_conn::read(byte_t* buf, size_t sz) - { - if(sz == 0) - { - if(tcp.read) - tcp.read(&tcp, {nullptr, nullptr, 0}); - return 0; - } - if(_shouldClose) - return -1; - - ssize_t amount = ::read(fd, buf, sz); - - if(amount >= 0) - { - if(tcp.read) - tcp.read(&tcp, llarp_buffer_t(buf, amount)); - } - else - { - if(errno == EAGAIN || errno == EWOULDBLOCK) - return amount; - _shouldClose = true; - return -1; - } - return amount; - } - - inline void - tcp_conn::flush_write() - { - connected(); - ev_io::flush_write(); - } - - inline ssize_t - tcp_conn::do_write(void* buf, size_t sz) - { - if(_shouldClose) - return -1; - -#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) - // macintosh uses a weird sockopt - return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe -#else - return ::send(fd, buf, sz, 0); -#endif - } - - inline 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(fd, (const sockaddr*)&_addr, slen); - if(result == 0) - { - llarp::LogDebug("Connected"); - connected(); - } - else if(errno == EINPROGRESS) - { - llarp::LogDebug("connect in progress"); - errno = 0; - return; - } - else if(_conn) - { - _conn->error(_conn); - } - } - - inline int - tcp_serv::read(byte_t*, size_t) - { - int new_fd = ::accept(fd, nullptr, nullptr); - if(new_fd == -1) - { - llarp::LogError("failed to accept on ", fd, ": ", strerror(errno)); - return -1; - } - // get flags - int flags = fcntl(new_fd, F_GETFL, 0); - if(flags == -1) - { - ::close(new_fd); - return -1; - } - // set flags - if(fcntl(new_fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - llarp::LogError("Failed to set non block on ", fd, ": ", strerror(errno)); - ::close(new_fd); - return -1; - } - // build handler - llarp::tcp_conn* connimpl = new llarp::tcp_conn(loop, new_fd); - if(loop->add_ev(connimpl, true)) - { - // call callback - if(tcp->accepted) - tcp->accepted(tcp, &connimpl->tcp); - return 0; - } - // cleanup error - delete connimpl; - return -1; - } - - bool - udp_listener::tick() - { - if(udp->tick) - udp->tick(udp); - return true; - } - - int - udp_listener::read(byte_t* buf, size_t sz) - { - sockaddr_in6 src; - socklen_t slen = sizeof(sockaddr_in6); - sockaddr* addr = (sockaddr*)&src; - ssize_t ret = ::recvfrom(fd, buf, sz, 0, addr, &slen); - if(ret < 0) - { - llarp::LogWarn("recvfrom failed"); - return -1; - } - if(static_cast< size_t >(ret) > sz) - { - llarp::LogWarn("ret > sz"); - return -1; - } - if(!addr) - { - llarp::LogWarn("no source addr"); - } - // Addr is the source - udp->recvfrom(udp, addr, ManagedBuffer{llarp_buffer_t(buf, ret)}); - return 0; - } - - int - udp_listener::sendto(const sockaddr* to, const void* data, size_t sz) - { - socklen_t slen; - switch(to->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; - default: - return -1; - } - if(!fd) - { - printf("kqueue sendto fd empty\n"); - return -1; - } - ssize_t sent = ::sendto(fd, data, sz, 0, to, slen); - if(sent == -1 || errno) - { - llarp::LogError("failed to send udp: ", strerror(errno)); - errno = 0; - } - return sent; - } - - int - tun::sendto(__attribute__((unused)) const sockaddr* to, - __attribute__((unused)) const void* data, - __attribute__((unused)) size_t sz) - { - return -1; - } - -#ifdef __APPLE__ - ssize_t - tun::do_write(void* buf, size_t sz) - { - iovec vecs[2]; - // TODO: IPV6 - uint32_t val = htonl(AF_INET); - vecs[0].iov_base = &val; - vecs[0].iov_len = sizeof(val); - vecs[1].iov_base = buf; - vecs[1].iov_len = sz; - return writev(fd, vecs, 2); - } -#endif - - void - tun::before_flush_write() - { - if(t->before_write) - { - t->before_write(t); - } - } - - bool - tun::tick() - { - if(t->tick) - t->tick(t); - flush_write(); - return true; - } - - int - tun::read(byte_t* buf, size_t) - { -// all BSDs have packet info except freebsd -#ifdef __FreeBSD__ - const ssize_t offset = 0; -#else - const ssize_t offset = 4; -#endif - - ssize_t ret = ::read(fd, buf, 1500); - if(ret > offset && t->recvpkt) - { - buf += offset; - ret -= offset; - llarp_buffer_t pkt(buf, ret); - t->recvpkt(t, pkt); - } - return ret; - } - - bool - tun::setup() - { - llarp::LogDebug("set up tunif"); - if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, TUNTAP_ID_ANY) == -1) - return false; - - if(tuntap_up(tunif) == -1) - return false; - if(tuntap_set_ifname(tunif, t->ifname) == -1) - return false; - llarp::LogInfo("set ", tunif->if_name, " to use address ", t->ifaddr); - - if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1) - return false; - fd = tunif->tun_fd; - return fd != -1; - } - -} // namespace llarp - -llarp::ev_io* -llarp_kqueue_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr) -{ - int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return nullptr; - socklen_t sz = sizeof(sockaddr_in); - if(bindaddr->sa_family == AF_INET6) - { - sz = sizeof(sockaddr_in6); - } - else if(bindaddr->sa_family == AF_UNIX) - { - sz = sizeof(sockaddr_un); - } - if(::bind(fd, bindaddr, sz) == -1) - { - ::close(fd); - return nullptr; - } - if(::listen(fd, 5) == -1) - { - ::close(fd); - return nullptr; - } - // set non blocking - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - { - ::close(fd); - return nullptr; - } - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - ::close(fd); - return nullptr; - } - llarp::ev_io* serv = new llarp::tcp_serv(this, fd, tcp); - tcp->impl = serv; - return serv; -} - -llarp::ev_io* -llarp_kqueue_loop::create_tun(llarp_tun_io* tun) -{ - llarp::tun* t = new llarp::tun(tun, shared_from_this()); - if(t->setup()) - return t; - delete t; - return nullptr; -} - -bool -llarp_kqueue_loop::init() -{ - if(kqueuefd == -1) - { - kqueuefd = kqueue(); - } - return kqueuefd != -1; -} - -bool -llarp_kqueue_loop::running() const -{ - return kqueuefd != -1; -} - -bool -llarp_kqueue_loop::tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) -{ - int fd = ::socket(addr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return false; - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - { - ::close(fd); - return false; - } - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - ::close(fd); - return false; - } - - llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, addr, tcp); - add_ev(conn, true); - conn->connect(); - return true; -} - -int -llarp_kqueue_loop::tick(int ms) -{ - std::array< struct kevent, 1024 > events; - int result; - timespec t; - t.tv_sec = 0; - t.tv_nsec = ms * 1000000UL; - result = kevent(kqueuefd, nullptr, 0, events.data(), events.size(), &t); - // result: 0 is a timeout - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].udata); - if(ev) - { - // it'll crash if we flip these - if(events[idx].filter & EVFILT_WRITE) - { - IO([&]() -> ssize_t { - ev->flush_write_buffers(events[idx].data); - return 0; - }); - } - if(events[idx].filter & EVFILT_READ) - { - IO([&]() -> ssize_t { - return ev->read( - readbuf, std::min(sizeof(readbuf), size_t(events[idx].data))); - }); - } - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - return result; -} - -int -llarp_kqueue_loop::run() -{ - timespec t; - t.tv_sec = 0; - t.tv_nsec = 1000000UL * EV_TICK_INTERVAL; - struct kevent events[1024]; - int result; - do - { - result = kevent(kqueuefd, nullptr, 0, events, 1024, &t); - // result: 0 is a timeout - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].udata); - if(ev) - { - if(events[idx].filter & EVFILT_READ) - ev->read(readbuf, - std::min(sizeof(readbuf), size_t(events[idx].data))); - if(events[idx].filter & EVFILT_WRITE) - ev->flush_write_buffers(events[idx].data); - } - else - { - llarp::LogWarn("kqueue event ", idx, " udata wasnt an ev_io"); - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - } while(result != -1); - return result; -} - -int -llarp_kqueue_loop::udp_bind(const sockaddr* addr) -{ - socklen_t slen; - llarp::LogDebug("kqueue bind affam", addr->sa_family); - switch(addr->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; -#ifdef AF_LINK -#endif -#ifdef AF_PACKET - case AF_PACKET: - slen = sizeof(struct sockaddr_ll); - break; -#endif - default: - llarp::LogError("unsupported address family"); - return -1; - } - int fd = socket(addr->sa_family, SOCK_DGRAM, 0); - if(fd == -1) - { - perror("socket()"); - return -1; - } - - if(addr->sa_family == AF_INET6) - { - // enable dual stack explicitly - int dual = 1; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &dual, sizeof(dual)) == -1) - { - // failed - perror("setsockopt()"); - close(fd); - return -1; - } - } - llarp::Addr a(*addr); - llarp::LogDebug("bind to ", a); - // FreeBSD handbook said to do this - if(addr->sa_family == AF_INET && INADDR_ANY) - a._addr4.sin_addr.s_addr = htonl(INADDR_ANY); - - if(bind(fd, addr, slen) == -1) - { - perror("bind()"); - close(fd); - return -1; - } - return fd; -} - -static int -llarp_ev_kqueue_sendto(struct llarp_udp_io* udp, const struct sockaddr* to, - const byte_t* pkt, size_t sz) -{ - const llarp::Addr toaddr(*to); - return ::sendto(udp->fd, pkt, sz, 0, toaddr, toaddr.SockLen()); -} - -bool -llarp_kqueue_loop::udp_listen(llarp_udp_io* l, const sockaddr* src) -{ - auto ev = create_udp(l, src); - if(ev) - { - l->fd = ev->fd; - l->sendto = &llarp_ev_kqueue_sendto; - } - return ev && add_ev(ev, false); -} - -bool -llarp_kqueue_loop::close_ev(llarp::ev_io* ev) -{ - EV_SET(&ev->change, ev->fd, ev->flags, EV_DELETE, 0, 0, nullptr); - return kevent(kqueuefd, &ev->change, 1, nullptr, 0, nullptr) != -1; -} - -llarp::ev_io* -llarp_kqueue_loop::create_udp(llarp_udp_io* l, const sockaddr* src) -{ - int fd = udp_bind(src); - if(fd == -1) - return nullptr; - llarp::udp_listener* listener = new llarp::udp_listener(fd, l); - l->impl = listener; - return listener; -} - -bool -llarp_kqueue_loop::add_ev(llarp::ev_io* ev, bool w) -{ - ev->flags = EVFILT_READ; - EV_SET(&ev->change, ev->fd, EVFILT_READ, EV_ADD, 0, 0, ev); - if(kevent(kqueuefd, &ev->change, 1, nullptr, 0, nullptr) == -1) - { - llarp::LogError("Failed to add event: ", strerror(errno)); - delete ev; - return false; - } - if(w) - { - ev->flags |= EVFILT_WRITE; - EV_SET(&ev->change, ev->fd, EVFILT_WRITE, EV_ADD, 0, 0, ev); - if(kevent(kqueuefd, &ev->change, 1, nullptr, 0, nullptr) == -1) - { - llarp::LogError("Failed to add event: ", strerror(errno)); - delete ev; - return false; - } - } - handlers.emplace_back(ev); - return true; -} - -bool -llarp_kqueue_loop::udp_close(llarp_udp_io* l) -{ - bool ret = false; - auto listener = static_cast< llarp::udp_listener* >(l->impl); - if(listener) - { - // printf("Calling close_ev for [%x] fd[%d]\n", listener, listener->fd); - ret = close_ev(listener); - // remove handler - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - if(itr->get() == listener) - { - itr = handlers.erase(itr); - ret = true; - } - else - ++itr; - } - l->impl = nullptr; - } - return ret; -} - -void -llarp_kqueue_loop::stop() -{ - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - close_ev(itr->get()); - itr = handlers.erase(itr); - } - - if(kqueuefd != -1) - ::close(kqueuefd); - - kqueuefd = -1; -} diff --git a/llarp/ev/ev_kqueue.hpp b/llarp/ev/ev_kqueue.hpp deleted file mode 100644 index 9d8d043a2..000000000 --- a/llarp/ev/ev_kqueue.hpp +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef EV_KQUEUE_HPP -#define EV_KQUEUE_HPP - -#include -#include -#include -#include -#include - -#include - -// why did we need a macro here, kqueue(7) _only_ exists -// on BSD and Macintosh -#include -#include -#include -#include - -namespace llarp -{ - struct udp_listener : public ev_io - { - llarp_udp_io* udp; - - udp_listener(int fd, llarp_udp_io* u) : ev_io(fd), udp(u) - { - } - - ~udp_listener() - { - } - - bool - tick(); - - virtual int - read(byte_t* buf, size_t sz); - - virtual int - sendto(const sockaddr* to, const void* data, size_t sz); - }; - - struct tun : public ev_io - { - llarp_tun_io* t; - device* tunif; - tun(llarp_tun_io* tio, llarp_ev_loop_ptr l) - : ev_io(-1, new LossyWriteQueue_t("kqueue_tun_write", l, l)) - , t(tio) - , tunif(tuntap_init()) - { - } - - int - sendto(__attribute__((unused)) const sockaddr* to, - __attribute__((unused)) const void* data, - __attribute__((unused)) size_t sz) override; - -#ifdef __APPLE__ - ssize_t - do_write(void* buf, size_t sz) override; -#endif - - void - before_flush_write() override; - - bool - tick() override; - int - read(byte_t* buf, size_t) override; - - bool - setup(); - - ~tun() - { - if(tunif) - tuntap_destroy(tunif); - } - }; - -} // namespace llarp - -struct llarp_kqueue_loop final - : public llarp_ev_loop, - public std::enable_shared_from_this< llarp_kqueue_loop > -{ - int kqueuefd; - - llarp_kqueue_loop() : kqueuefd(-1) - { - } - - virtual ~llarp_kqueue_loop() - { - } - - bool - init() override; - - int - run() override; - - bool - running() const override; - - bool - tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) override; - - int - tick(int ms) override; - - int - udp_bind(const sockaddr* addr); - - bool - udp_listen(llarp_udp_io* l, const sockaddr* src) override; - - bool - close_ev(llarp::ev_io* ev) override; - - llarp::ev_io* - create_tun(llarp_tun_io* tun) override; - - llarp::ev_io* - bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr) override; - - llarp::ev_io* - create_udp(llarp_udp_io* l, const sockaddr* src); - - bool - add_ev(llarp::ev_io* ev, bool w) override; - - bool - udp_close(llarp_udp_io* l) override; - - void - stop() override; -}; - -#endif diff --git a/llarp/ev/ev_sun.cpp b/llarp/ev/ev_sun.cpp deleted file mode 100644 index 8cd2f4b67..000000000 --- a/llarp/ev/ev_sun.cpp +++ /dev/null @@ -1,526 +0,0 @@ -#include - -namespace llarp -{ - int - tcp_conn::read(byte_t* buf, size_t sz) - { - if(_shouldClose) - return -1; - - ssize_t amount = ::read(fd, buf, sz); - - if(amount > 0) - { - if(tcp.read) - tcp.read(&tcp, llarp_buffer_t(buf, amount)); - } - else if(amount < 0) - { - // error - _shouldClose = true; - errno = 0; - return -1; - } - return 0; - } - - void - tcp_conn::flush_write() - { - connected(); - ev_io::flush_write(); - } - - ssize_t - tcp_conn::do_write(void* buf, size_t sz) - { - if(_shouldClose) - return -1; - // pretty much every UNIX system still extant, _including_ solaris - // (on both sides of the fork) can ignore SIGPIPE....except - // the other vendored systems... -rick - return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe - } - - 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(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); - errno = 0; - } - } - - int - tcp_serv::read(byte_t*, size_t) - { - int new_fd = ::accept(fd, nullptr, nullptr); - if(new_fd == -1) - { - llarp::LogError("failed to accept on ", fd, ":", strerror(errno)); - return -1; - } - // build handler - llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd); - if(loop->add_ev(connimpl, true)) - { - // call callback - if(tcp->accepted) - tcp->accepted(tcp, &connimpl->tcp); - return 0; - } - // cleanup error - delete connimpl; - return -1; - } - - bool - udp_listener::tick() - { - if(udp->tick) - udp->tick(udp); - return true; - } - - int - udp_listener::read(byte_t* buf, size_t sz) - { - llarp_buffer_t b; - b.base = buf; - b.cur = b.base; - sockaddr_in6 src; - socklen_t slen = sizeof(sockaddr_in6); - sockaddr* addr = (sockaddr*)&src; - ssize_t ret = ::recvfrom(fd, b.base, sz, 0, addr, &slen); - if(ret < 0) - { - errno = 0; - return -1; - } - if(static_cast< size_t >(ret) > sz) - return -1; - b.sz = ret; - udp->recvfrom(udp, addr, ManagedBuffer{b}); - return ret; - } - - int - udp_listener::sendto(const sockaddr* to, const void* data, size_t sz) - { - socklen_t slen; - switch(to->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; - default: - return -1; - } - ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen); - if(sent == -1) - { - llarp::LogWarn(strerror(errno)); - } - return sent; - } - - int - tun::sendto(__attribute__((unused)) const sockaddr* to, - __attribute__((unused)) const void* data, - __attribute__((unused)) size_t sz) - { - return -1; - } - - bool - tun::tick() - { - if(t->tick) - t->tick(t); - flush_write(); - return true; - } - - void - tun::flush_write() - { - if(t->before_write) - t->before_write(t); - ev_io::flush_write(); - } - - int - tun::read(byte_t* buf, size_t sz) - { - ssize_t ret = tuntap_read(tunif, buf, sz); - if(ret > 0 && t->recvpkt) - { - // does not have pktinfo - t->recvpkt(t, llarp_buffer_t(buf, ret)); - } - return ret; - } - - bool - tun::setup() - { - llarp::LogDebug("set ifname to ", t->ifname); - strncpy(tunif->if_name, t->ifname, sizeof(tunif->if_name)); - if(tuntap_start(tunif, TUNTAP_MODE_TUNNEL, 0) == -1) - { - llarp::LogWarn("failed to start interface"); - return false; - } - if(tuntap_up(tunif) == -1) - { - llarp::LogWarn("failed to put interface up: ", strerror(errno)); - return false; - } - if(tuntap_set_ip(tunif, t->ifaddr, t->ifaddr, t->netmask) == -1) - { - llarp::LogWarn("failed to set ip"); - return false; - } - fd = tunif->tun_fd; - if(fd == -1) - return false; - // set non blocking - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - return false; - return fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1; - } - -}; // namespace llarp - -bool -llarp_poll_loop::tcp_connect(struct llarp_tcp_connecter* tcp, - const sockaddr* remoteaddr) -{ - // create socket - int fd = ::socket(remoteaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return false; - // set non blocking - int flags = fcntl(fd, F_GETFL, 0); - if(flags == -1) - { - ::close(fd); - return false; - } - if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - { - ::close(fd); - return false; - } - llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp); - add_ev(conn, true); - conn->connect(); - return true; -} - -llarp::ev_io* -llarp_poll_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr) -{ - int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return nullptr; - socklen_t sz = sizeof(sockaddr_in); - if(bindaddr->sa_family == AF_INET6) - { - sz = sizeof(sockaddr_in6); - } - else if(bindaddr->sa_family == AF_UNIX) - { - sz = sizeof(sockaddr_un); - } - if(::bind(fd, bindaddr, sz) == -1) - { - ::close(fd); - return nullptr; - } - if(::listen(fd, 5) == -1) - { - ::close(fd); - return nullptr; - } - return new llarp::tcp_serv(this, fd, tcp); -} - -bool -llarp_poll_loop::udp_listen(llarp_udp_io* l, const sockaddr* src) -{ - auto ev = create_udp(l, src); - if(ev) - l->fd = ev->fd; - return ev && add_ev(ev, false); -} - -bool -llarp_poll_loop::running() const -{ - return upollfd != nullptr; -} - -bool -llarp_poll_loop::init() -{ - if(!upollfd) - upollfd = upoll_create(1); // why do we return false? (see ev_epoll.cpp) - return false; -} - -int -llarp_poll_loop::tick(int ms) -{ - upoll_event_t events[1024]; - int result; - result = upoll_wait(upollfd, events, 1024, ms); - bool didIO = false; - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr); - if(ev) - { - llarp::LogDebug(idx, " of ", result, " on ", ev->fd, - " events=", std::to_string(events[idx].events)); - if(events[idx].events & UPOLLERR && errno) - { - IO([&]() -> ssize_t { - llarp::LogDebug("upoll error"); - ev->error(); - return 0; - }); - } - else - { - // write THEN READ don't revert me - if(events[idx].events & UPOLLOUT) - { - IO([&]() -> ssize_t { - llarp::LogDebug("upoll out"); - ev->flush_write(); - return 0; - }); - } - if(events[idx].events & UPOLLIN) - { - ssize_t amount = IO([&]() -> ssize_t { - llarp::LogDebug("upoll in"); - return ev->read(readbuf, sizeof(readbuf)); - }); - if(amount > 0) - didIO = true; - } - } - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - /// if we didn't get an io events we sleep to avoid 100% cpu use - if(!didIO) - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - return result; -} - -int -llarp_poll_loop::run() -{ - upoll_event_t events[1024]; - int result; - do - { - result = upoll_wait(upollfd, events, 1024, EV_TICK_INTERVAL); - if(result > 0) - { - int idx = 0; - while(idx < result) - { - llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].data.ptr); - if(ev) - { - if(events[idx].events & UPOLLERR) - { - ev->error(); - } - else - { - if(events[idx].events & UPOLLIN) - { - ev->read(readbuf, sizeof(readbuf)); - } - if(events[idx].events & UPOLLOUT) - { - ev->flush_write(); - } - } - } - ++idx; - } - } - if(result != -1) - tick_listeners(); - } while(upollfd); - return result; -} - -int -llarp_poll_loop::udp_bind(const sockaddr* addr) -{ - socklen_t slen; - switch(addr->sa_family) - { - case AF_INET: - slen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - slen = sizeof(struct sockaddr_in6); - break; - default: - return -1; - } - int fd = socket(addr->sa_family, SOCK_DGRAM, 0); - if(fd == -1) - { - perror("socket()"); - return -1; - } - - if(addr->sa_family == AF_INET6) - { - // enable dual stack explicitly - int dual = 1; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &dual, sizeof(dual)) == -1) - { - // failed - perror("setsockopt()"); - close(fd); - return -1; - } - } - llarp::Addr a(*addr); - llarp::LogDebug("bind to ", a); - if(bind(fd, addr, slen) == -1) - { - perror("bind()"); - close(fd); - return -1; - } - - return fd; -} - -bool -llarp_poll_loop::close_ev(llarp::ev_io* ev) -{ - return upoll_ctl(upollfd, UPOLL_CTL_DEL, ev->fd, nullptr) != -1; -} - -llarp::ev_io* -llarp_poll_loop::create_tun(llarp_tun_io* tun) -{ - llarp::tun* t = new llarp::tun(tun, shared_from_this()); - if(t->setup()) - { - return t; - } - delete t; - return nullptr; -} - -llarp::ev_io* -llarp_poll_loop::create_udp(llarp_udp_io* l, const sockaddr* src) -{ - int fd = udp_bind(src); - if(fd == -1) - return nullptr; - llarp::ev_io* listener = new llarp::udp_listener(fd, l); - l->impl = listener; - return listener; -} - -bool -llarp_poll_loop::add_ev(llarp::ev_io* e, bool write) -{ - upoll_event_t ev; - ev.data.ptr = e; - ev.events = UPOLLIN | UPOLLERR; - if(write) - ev.events |= UPOLLOUT; - if(upoll_ctl(upollfd, UPOLL_CTL_ADD, e->fd, &ev) == -1) - { - delete e; - return false; - } - handlers.emplace_back(e); - return true; -} - -bool -llarp_poll_loop::udp_close(llarp_udp_io* l) -{ - bool ret = false; - llarp::udp_listener* listener = static_cast< llarp::udp_listener* >(l->impl); - if(listener) - { - close_ev(listener); - // remove handler - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - if(itr->get() == listener) - itr = handlers.erase(itr); - else - ++itr; - } - l->impl = nullptr; - ret = true; - } - return ret; -} - -void -llarp_poll_loop::stop() -{ - // close all handlers before closing the upoll fd - auto itr = handlers.begin(); - while(itr != handlers.end()) - { - close_ev(itr->get()); - itr = handlers.erase(itr); - } - - if(upollfd) - upoll_destroy(upollfd); - upollfd = nullptr; -} diff --git a/llarp/ev/ev_sun.hpp b/llarp/ev/ev_sun.hpp deleted file mode 100644 index fc0e15b08..000000000 --- a/llarp/ev/ev_sun.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef EV_POLL_HPP -#define EV_POLL_HPP - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "upoll_sun.h" -#include -#include -#include - -namespace llarp -{ - struct udp_listener : public ev_io - { - llarp_udp_io* udp; - - udp_listener(int fd, llarp_udp_io* u) : ev_io(fd), udp(u){}; - - ~udp_listener() - { - } - - bool - tick(); - - int - read(byte_t* buf, size_t sz); - - int - sendto(const sockaddr* to, const void* data, size_t sz); - }; - - struct tun : public ev_io - { - llarp_tun_io* t; - int writefd; - device* tunif; - tun(llarp_tun_io* tio, llarp_ev_loop_ptr l) - : ev_io(-1, new LossyWriteQueue_t("tun_write_queue", l, l)) - , t(tio) - , writefd(-1) - , tunif(tuntap_init()) - - { - - }; - - int - sendto(const sockaddr* to, const void* data, size_t sz); - - bool - tick(); - - void - flush_write(); - - int - read(byte_t* buf, size_t sz); - - bool - setup(); - - ~tun() - { - if(tunif) - tuntap_destroy(tunif); - } - }; -}; // namespace llarp - -struct llarp_poll_loop : public llarp_ev_loop, - public std::enable_shared_from_this< llarp_poll_loop > -{ - upoll_t* upollfd; - - llarp_poll_loop() : upollfd(nullptr) - { - } - - ~llarp_poll_loop() - { - } - - bool - tcp_connect(struct llarp_tcp_connecter* tcp, const sockaddr* remoteaddr); - - llarp::ev_io* - bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr); - - virtual bool - udp_listen(llarp_udp_io* l, const sockaddr* src); - - bool - running() const; - - bool - init(); - - int - tick(int ms); - - int - run(); - - int - udp_bind(const sockaddr* addr); - - bool - close_ev(llarp::ev_io* ev); - - llarp::ev_io* - create_tun(llarp_tun_io* tun); - - llarp::ev_io* - create_udp(llarp_udp_io* l, const sockaddr* src); - - bool - add_ev(llarp::ev_io* e, bool write); - - bool - udp_close(llarp_udp_io* l); - - void - stop(); -}; - -#endif diff --git a/llarp/ev/upoll_sun.c b/llarp/ev/upoll_sun.c deleted file mode 100644 index 6b5ee8349..000000000 --- a/llarp/ev/upoll_sun.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "upoll_sun.h" - -#define uhash_slot(K, S) (((K) ^ (K >> 8)) & (S - 1)) - -static uhash_t* -uhash_create(uint32_t size) -{ - int i; - size--; - size |= size >> 1; - size |= size >> 2; - size |= size >> 4; - size |= size >> 8; - size |= size >> 16; - size++; - - uhash_t* hash = (uhash_t*)calloc(1, sizeof(uhash_t) + size * sizeof(ulist_t)); - hash->count = 0; - hash->size = size; - hash->items = (ulist_t*)(((char*)hash) + sizeof(uhash_t)); - - for(i = 0; i < size; i++) - { - ulist_init(&hash->items[i]); - } - - return hash; -} - -static void* -uhash_lookup(uhash_t* hash, intptr_t key) -{ - uint32_t slot = uhash_slot(key, hash->size); - ulist_t* q; - ulist_scan(q, &hash->items[slot]) - { - uitem_t* i = ulist_data(q, uitem_t, list); - if(i->key == key) - return i->val; - } - return NULL; -} -static void -uhash_insert(uhash_t* hash, intptr_t key, void* val) -{ - uint32_t slot = uhash_slot(key, hash->size); - - uitem_t* item = (uitem_t*)calloc(1, sizeof(uitem_t)); - ulist_init(&item->list); - item->key = key; - item->val = val; - - ulist_append(&hash->items[slot], &item->list); -} -static int -uhash_delete(uhash_t* hash, intptr_t key) -{ - uint32_t slot = uhash_slot(key, hash->size); - ulist_t* q; - ulist_scan(q, &hash->items[slot]) - { - uitem_t* i = ulist_data(q, uitem_t, list); - if(i->key == key) - { - ulist_remove(q); - free(q); - return 1; - } - } - return 0; -} -static int -uhash_destroy(uhash_t* hash) -{ - int i; - for(i = 0; i < hash->size; i++) - { - while(!ulist_empty(&hash->items[i])) - { - ulist_t* q = ulist_next(&hash->items[i]); - uitem_t* n = ulist_data(q, uitem_t, list); - ulist_remove(q); - free(n); - } - } - return 0; -} - -upoll_t* -upoll_create(uint32_t size) -{ - assert(size > 0); - upoll_t* upq = (upoll_t*)calloc(1, sizeof(upoll_t)); - - ulist_init(&upq->alive); - - upq->table = uhash_create(size); - return upq; -} - -void -upoll_destroy(upoll_t* upq) -{ - assert(upq != NULL); - uhash_destroy(upq->table); - ulist_t* q; - unote_t* n; - while(!ulist_empty(&upq->alive)) - { - q = ulist_next(&upq->alive); - n = ulist_data(n, unote_t, queue); - ulist_remove(q); - free(n); - } - free(upq); -} - -int -upoll_ctl(upoll_t* upq, int op, intptr_t fd, upoll_event_t* event) -{ - if(fd < 0) - return -EBADF; - - unote_t* note = NULL; - switch(op) - { - case UPOLL_CTL_ADD: - { - note = (unote_t*)uhash_lookup(upq->table, fd); - if(!note) - { - note = (unote_t*)calloc(1, sizeof(unote_t)); - note->upoll = upq; - ulist_init(¬e->queue); - note->event = *event; - note->fd = fd; - ulist_append(&upq->alive, ¬e->queue); - uhash_insert(upq->table, fd, (void*)note); - } - break; - } - case UPOLL_CTL_DEL: - { - note = (unote_t*)uhash_lookup(upq->table, fd); - if(!note) - return -ENOENT; - event = ¬e->event; - ulist_remove(¬e->queue); - uhash_delete(upq->table, fd); - free(note); - break; - } - case UPOLL_CTL_MOD: - { - note = (unote_t*)uhash_lookup(upq->table, fd); - if(!note) - return -ENOENT; - note->event = *event; - break; - } - default: - { - return -EINVAL; - } - } - return 0; -} - -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; -} - -int -upoll_wait(upoll_t* upq, upoll_event_t* evs, int nev, int timeout) -{ - int r = 0; - r = upoll_wait_poll(upq, evs, nev, timeout); - return r; -} \ No newline at end of file diff --git a/llarp/ev/upoll_sun.h b/llarp/ev/upoll_sun.h deleted file mode 100644 index 7e3ef562a..000000000 --- a/llarp/ev/upoll_sun.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef _UPOLL_H_ -#define _UPOLL_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include -#include - -#define UPOLL_CTL_ADD 1 -#define UPOLL_CTL_DEL 2 -#define UPOLL_CTL_MOD 3 - -#define UPOLLIN 0x01 -#define UPOLLOUT 0x02 -#define UPOLLERR 0x04 -#define UPOLLET 0x08 - - typedef struct upoll upoll_t; - - typedef union upoll_data { - void* ptr; - intptr_t fd; - uint32_t u32; - uint64_t u64; - } upoll_data_t; - - typedef struct upoll_event - { - uint32_t events; - upoll_data_t data; - } upoll_event_t; - - upoll_t* - upoll_create(uint32_t size); - int - upoll_ctl(upoll_t* upq, int op, intptr_t fd, upoll_event_t* event); - int - upoll_wait(upoll_t* upq, upoll_event_t* events, int maxevents, int timeout); - void - upoll_destroy(upoll_t* upq); - -#if(defined(__64BIT__) || defined(__x86_64__)) -#define __IS_64BIT__ -#else -#define __IS_32BIT__ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - typedef struct unote unote_t; - typedef struct ulist ulist_t; - typedef struct uitem uitem_t; - typedef struct uhash uhash_t; - - struct ulist - { - ulist_t* next; - ulist_t* prev; - }; - - struct uitem - { - ulist_t list; - intptr_t key; - void* val; - }; - - struct uhash - { - uint16_t count; - uint16_t size; - ulist_t* items; - }; - - struct upoll - { - int fd; /* backend fd (epoll, kqueue) */ - ulist_t alive; /* all notes this queue knows about */ - uhash_t* table; - }; - - struct unote - { - upoll_event_t event; - intptr_t fd; - ulist_t queue; /* handle for the queue's notes */ - upoll_t* upoll; - }; - -#define container_of(ptr, type, member) \ - ((type*)((char*)(ptr)-offsetof(type, member))) - -#define ulist_init(q) \ - (q)->prev = q; \ - (q)->next = q - -#define ulist_head(h) (h)->next -#define ulist_next(q) (q)->next - -#define ulist_tail(h) (h)->prev -#define ulist_prev(q) (q)->prev - -#define ulist_empty(h) (h == (h)->prev) - -#define ulist_append(h, x) \ - (x)->prev = (h)->prev; \ - (x)->prev->next = x; \ - (x)->next = h; \ - (h)->prev = x - -#define ulist_insert(h, x) \ - (x)->next = (h)->next; \ - (x)->next->prev = x; \ - (x)->prev = h; \ - (h)->next = x - -#define ulist_remove(x) \ - (x)->next->prev = (x)->prev; \ - (x)->prev->next = (x)->next; \ - (x)->prev = x; \ - (x)->next = x - -#define ulist_mark(h) (h) - -#define ulist_scan(q, h) \ - for((q) = ulist_head(h); (q) != ulist_mark(h); (q) = ulist_next(q)) - -#define ulist_data(q, type, link) container_of(q, type, link) - -#ifdef __cplusplus -} -#endif - -#endif /* _UPOLL_H_ */