From db0920d921c6984d85fba97b8ccd9d51065684f4 Mon Sep 17 00:00:00 2001 From: Rick V Date: Thu, 30 Jan 2020 01:36:03 -0600 Subject: [PATCH] use backport fork for release installer only move all invariant assets to common repo remove ded code, libuv patches can be swapped in at build time for debug/release builds --- daemon/main.cpp | 1 + llarp/ev/ev_win32.cpp | 496 ---------------------------------- llarp/ev/ev_win32.hpp | 86 ------ llarp/handlers/exit.cpp | 17 +- ui-win32/Program.cs | 3 + win32-setup/Makefile | 43 +-- win32-setup/lokinet-win32.iss | 1 + 7 files changed, 35 insertions(+), 612 deletions(-) diff --git a/daemon/main.cpp b/daemon/main.cpp index 594ebb321..a97b42758 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -44,6 +44,7 @@ startWinsock() perror("Failed to start Windows Sockets"); return err; } + ::CreateMutex(nullptr, FALSE, "lokinet_win32_daemon"); return 0; } diff --git a/llarp/ev/ev_win32.cpp b/llarp/ev/ev_win32.cpp index 7d564a14b..ae4109ee8 100644 --- a/llarp/ev/ev_win32.cpp +++ b/llarp/ev/ev_win32.cpp @@ -235,501 +235,5 @@ exit_tun_loop() DeleteCriticalSection(&HandlerMtx); } } -/* -// now zero-copy -ssize_t -TCPWrite(llarp_tcp_conn* conn, const byte_t* ptr, size_t sz) -{ - llarp::ev_io* io = (llarp::ev_io*)conn->impl; - return uwrite(io->fd, (char*)ptr, sz); -} - -llarp_win32_loop::~llarp_win32_loop() -{ - exit_tun_loop(); -} - -namespace llarp -{ - int - tcp_conn::read(byte_t* buf, size_t sz) - { - if(_shouldClose) - return -1; - - ssize_t amount = uread(fd, (char*)buf, sz); - - if(amount > 0) - { - if(tcp.read) - tcp.read(&tcp, llarp_buffer_t(buf, amount)); - } - else - { - // error - _shouldClose = true; - 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; - return uwrite(fd, (char*)buf, sz); - } - - 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(); - } - // Winsock 2.x no longer returns WSAEINPROGRESS - else if(WSAGetLastError() == WSAEWOULDBLOCK) - { - // in progress - llarp::LogDebug("connect in progress"); - WSASetLastError(0); - return; - } - else if(_conn->error) - { - // wtf? - char ebuf[1024]; - int err = WSAGetLastError(); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, - ebuf, 1024, nullptr); - int l = strlen(ebuf); - ebuf[l - 2] = '\0'; // remove line break - llarp::LogError("error connecting: ", ebuf, " [", err, "]"); - _conn->error(_conn); - } - } - - int - tcp_serv::read(byte_t*, size_t) - { - int new_fd = ::accept(fd, nullptr, nullptr); - if(new_fd == -1) - { - char ebuf[1024]; - int err = WSAGetLastError(); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, - ebuf, 1024, nullptr); - int l = strlen(ebuf); - ebuf[l - 2] = '\0'; // remove line break - llarp::LogError("failed to accept on ", fd, ":", ebuf, " [", err, "]"); - return -1; - } - // build handler - llarp::tcp_conn* connimpl = new tcp_conn(loop, new_fd); - connimpl->tcp.write = &TCPWrite; - connimpl->tcp.loop = loop; - 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, (char*)b.base, sz, 0, addr, &slen); - if(ret < 0) - return -1; - if(static_cast< size_t >(ret) > sz) - return -1; - b.sz = ret; - if(udp->recvfrom) - udp->recvfrom(udp, addr, ManagedBuffer{b}); - else - { - m_RecvPackets.emplace_back( - PacketEvent{llarp::Addr(*addr), PacketBuffer(ret)}); - std::copy_n(buf, ret, m_RecvPackets.back().pkt.data()); - } - return 0; - } - - bool - udp_listener::RecvMany(llarp_pkt_list* pkts) - { - *pkts = std::move(m_RecvPackets); - m_RecvPackets = llarp_pkt_list(); - return pkts->size() > 0; - } - - static int - UDPSendTo(llarp_udp_io* udp, const sockaddr* to, const byte_t* ptr, size_t sz) - { - llarp::ev_io* io = (llarp::ev_io*)udp->impl; - return io->sendto(to, ptr, sz); - } - - 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, (char*)data, sz, 0, to, slen); - if(sent == -1) - { - char ebuf[1024]; - int err = WSAGetLastError(); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, - ebuf, 1024, nullptr); - llarp::LogWarn(ebuf); - } - return sent; - } - -}; // namespace llarp - -bool -llarp_win32_loop::tcp_connect(struct llarp_tcp_connecter* tcp, - const sockaddr* remoteaddr) -{ - // create socket - int fd = usocket(remoteaddr->sa_family, SOCK_STREAM, 0); - if(fd == -1) - return false; - llarp::tcp_conn* conn = new llarp::tcp_conn(this, fd, remoteaddr, tcp); - conn->tcp.write = &TCPWrite; - add_ev(conn, true); - conn->connect(); - return true; -} - -llarp::ev_io* -llarp_win32_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr) -{ - int fd = usocket(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); - } - // keep. inexplicably, windows now has unix domain sockets - // for now, use the ID numbers directly until this comes out of - // beta - else if(bindaddr->sa_family == AF_UNIX) - sz = sizeof(sockaddr_un); - - if(::bind(fd, bindaddr, sz) == -1) - { - uclose(fd); - return nullptr; - } - if(ulisten(fd, 5) == -1) - { - uclose(fd); - return nullptr; - } - return new llarp::tcp_serv(this, fd, tcp); -} - -bool -llarp_win32_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_win32_loop::running() const -{ - return (upollfd != nullptr); -} - -bool -llarp_win32_loop::init() -{ - if(!upollfd) - upollfd = upoll_create(1); - return upollfd != nullptr; -} - -// OK, the event loop, as it exists now, will _only_ -// work on sockets (and not very efficiently at that). -int -llarp_win32_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 && WSAGetLastError()) - { - 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_win32_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_win32_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 = usocket(addr->sa_family, SOCK_DGRAM, 0); - if(fd == -1) - { - perror("usocket()"); - return -1; - } - - if(addr->sa_family == AF_INET6) - { - // enable dual stack explicitly - int dual = 1; - if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&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_win32_loop::close_ev(llarp::ev_io* ev) -{ - return upoll_ctl(upollfd, UPOLL_CTL_DEL, ev->fd, nullptr) != -1; -} -// no tunnels here -llarp::ev_io* -llarp_win32_loop::create_tun(llarp_tun_io* tun) -{ - UNREFERENCED_PARAMETER(tun); - return nullptr; -} - -llarp::ev_io* -llarp_win32_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; - l->sendto = &llarp::UDPSendTo; - return listener; -} - -bool -llarp_win32_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_win32_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_win32_loop::stop() -{ - if(upollfd) - upoll_destroy(upollfd); - upollfd = nullptr; - llarp::LogDebug("destroy upoll"); -} - -void -llarp_win32_loop::tick_listeners() -{ - llarp_ev_loop::tick_listeners(); - for(auto& func : m_Tickers) - LogicCall(m_Logic, func); -} -*/ #endif diff --git a/llarp/ev/ev_win32.hpp b/llarp/ev/ev_win32.hpp index 381c023ea..2ce43f510 100644 --- a/llarp/ev/ev_win32.hpp +++ b/llarp/ev/ev_win32.hpp @@ -100,90 +100,4 @@ struct win32_tun_io } }; -// UDP event loop (no longer used, we libuv for now) -// PLEASE convert me to IOCPs so we don't have to use that -// EXTREMELY CURSED libuv event loop and its llarp_vpn_io_pipe -// -// For you see, on Windows, we have enough local user permissions to set -// up a VPN tunnel interface internally, and have lokinet consume this -// file descriptor directly. See win32_tun_io for this impl. llarp_vpn_io -// assumes that an external entity or process is required to inject packets -// into the VPN interface provided by the OS. -// -// Not only that, the win32 IOCP facility handles timing on its own, you can -// specify an interval to tick directly into the call to -// GetQueuedCompletionStatus(2) -/*struct llarp_win32_loop : public llarp_ev_loop -{ - upoll_t* upollfd; - std::shared_ptr< llarp::Logic > m_Logic; - std::vector< std::function< void(void) > > m_Tickers; - - llarp_win32_loop() : upollfd(nullptr) - { - } - - 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); - - ~llarp_win32_loop(); - - bool - running() const; - - bool - init(); - - int - tick(int ms); - - int - run(); - - int - udp_bind(const sockaddr* addr); - - bool - close_ev(llarp::ev_io* ev); - - // no tunnels here - 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(); - - bool - add_ticker(std::function< void(void) > func) override - { - m_Tickers.emplace_back(func); - return true; - } - - void - set_logic(std::shared_ptr< llarp::Logic > l) override - { - m_Logic = l; - } - - void - tick_listeners() override; -}; -*/ -#endif #endif diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index ddf53e720..a06db779e 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -36,18 +36,15 @@ namespace llarp : m_Router(r) , m_Resolver(std::make_shared< dns::Proxy >( r->netloop(), r->logic(), r->netloop(), r->logic(), this)) - , m_Name(name) -#ifdef _WIN32 - , m_Tun - { - {0}, 0, 0, {0}, nullptr, nullptr, nullptr, + , m_Name(name) +#ifdef _WIN32 + , m_Tun{{0}, 0, 0, {0}, nullptr, nullptr, nullptr, #else - , m_Tun{{0}, 0, {0}, nullptr, nullptr, nullptr, + , m_Tun{{0}, 0, {0}, nullptr, nullptr, nullptr, #endif - nullptr, nullptr, nullptr, nullptr, nullptr - } - , m_LocalResolverAddr("127.0.0.1", 53), - m_InetToNetwork(name + "_exit_rx", r->netloop(), r->netloop()) + nullptr, nullptr, nullptr, nullptr, nullptr} + , m_LocalResolverAddr("127.0.0.1", 53) + , m_InetToNetwork(name + "_exit_rx", r->netloop(), r->netloop()) { m_Tun.user = this; diff --git a/ui-win32/Program.cs b/ui-win32/Program.cs index 4f2a330aa..a04bab098 100644 --- a/ui-win32/Program.cs +++ b/ui-win32/Program.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Threading; using System.Windows.Forms; namespace network.loki.lokinet.win32.ui @@ -15,6 +16,7 @@ namespace network.loki.lokinet.win32.ui static void Main() { // Scrub any old lokinet process left behind + Mutex m = new Mutex(true, "lokinet_dotnet_ui"); Process[] old_pids = Process.GetProcessesByName("lokinet"); foreach (Process pid in old_pids) { @@ -33,6 +35,7 @@ namespace network.loki.lokinet.win32.ui } catch { } + m.ReleaseMutex(); } } } diff --git a/win32-setup/Makefile b/win32-setup/Makefile index 476f619ee..b50426512 100644 --- a/win32-setup/Makefile +++ b/win32-setup/Makefile @@ -1,4 +1,8 @@ # Makefile for windows install pkg and helper library +# debug/internal builds need not support xp +# release builds *should*, but this does NOT remain a hard +# requirement for cutting releases, it can be pulled at any +# time really CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ @@ -37,48 +41,47 @@ lokinet-bootstrap.exe: mbedtls curl dbghelp cp ../LICENSE .;unix2dos LICENSE LICENSE dbghelp: - wget https://snowlight.net/loki/win32-dist/dbghelp32.dll - wget https://snowlight.net/loki/win32-dist/dbghelp64.dll + wget http://installer.lokinet.org/win32/dbghelp32.dll + wget http://installer.lokinet.org/win32/dbghelp64.dll else regdbhelper.dll: - wget https://snowlight.net/loki/win32-dist/dbghelp32.dll - wget https://snowlight.net/loki/win32-dist/dbghelp64.dll - wget https://snowlight.net/loki/win32-dist/regdbhelper.dll + wget http://installer.lokinet.org/win32/regdbhelper.dll lokinet-bootstrap.exe: - wget https://snowlight.net/loki/win32-dist/lokinet-bootstrap.exe + wget http://installer.lokinet.org/win32/lokinet-bootstrap.exe wget -O rootcerts.pem https://curl.haxx.se/ca/cacert.pem cp ../LICENSE .;unix2dos LICENSE LICENSE dbghelp: - : + wget http://installer.lokinet.org/win32/dbghelp32.dll + wget http://installer.lokinet.org/win32/dbghelp64.dll endif # Common rules 7z.exe: - wget https://snowlight.net/loki/win32-dist/7z.exe + wget http://installer.lokinet.org/win32/7z.exe tcpv6: - wget https://snowlight.net/loki/win32-dist/inet6.7z + wget http://installer.lokinet.org/win32/inet6.7z tap-win32: - wget https://snowlight.net/loki/win32-dist/tap-windows-9.21.2.7z + wget http://installer.lokinet.org/win32/tap-windows-9.21.2.7z mv tap-windows-9.21.2.7z tuntapv9_n6.7z - wget https://snowlight.net/loki/win32-dist/tap-windows-9.9.2_3.7z + wget http://installer.lokinet.org/win32/tap-windows-9.9.2_3.7z mv tap-windows-9.9.2_3.7z tuntapv9.7z - -libuv: - git clone https://github.com/libuv/libuv.git - cd libuv; ./autogen.sh; ./configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 CC=$(CC) CXX=$(CXX) CFLAGS="$(CFLAGS)" --disable-shared --prefix=$(PWD) - make -C libuv -j4 install - make -C libuv -j4 distclean - cd libuv; ./configure --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 CC=$(CC64) CXX=$(CXX64) CFLAGS="$(CFLAGS)" --disable-shared - make -C libuv -j4 + +libuv: + git clone https://github.com/despair86/libuv.git + cd libuv; ./autogen.sh; ./configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 CC=$(CC) CXX=$(CXX) CFLAGS="$(CFLAGS)" --disable-shared --prefix=$(PWD) + make -C libuv -j4 install + make -C libuv -j4 distclean + cd libuv; ./configure --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 CC=$(CC64) CXX=$(CXX64) CFLAGS="$(CFLAGS)" --disable-shared + make -C libuv -j4 cp libuv/.libs/libuv.a $(PWD)/lib64 qt5-ui: - wget https://snowlight.net/loki/win32-dist/lokinet-qt5-ui.7z + wget http://installer.lokinet.org/win32/lokinet-qt5-ui.7z clean: -rm -rf curl-7* include lib mbedtls-2* *.exe *.dll *.pem *.7z diff --git a/win32-setup/lokinet-win32.iss b/win32-setup/lokinet-win32.iss index 0ce516505..f6818aaf1 100644 --- a/win32-setup/lokinet-win32.iss +++ b/win32-setup/lokinet-win32.iss @@ -54,6 +54,7 @@ InternalCompressLevel=ultra64 MinVersion=0,5.0 ArchitecturesInstallIn64BitMode=x64 VersionInfoCopyright=Copyright ©2018-2020 Loki Project +AppMutex=lokinet_win32_daemon,lokinet_qt5_ui,lokinet_dotnet_ui [Languages] Name: "english"; MessagesFile: "compiler:Default.isl"