From 1885b1cae9fff47941bd1939fd323bc9aac15e9a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 12 Mar 2021 12:41:48 -0500 Subject: [PATCH] more --- external/ngtcp2 | 2 +- llarp/CMakeLists.txt | 6 ++- llarp/config/config.cpp | 12 ++++++ llarp/config/config.hpp | 2 + llarp/quic/address.cpp | 1 - llarp/service/convotag.cpp | 6 +-- llarp/service/endpoint.cpp | 75 ++++++++++++++++++++++++++++++++++++++ llarp/service/endpoint.hpp | 4 ++ 8 files changed, 101 insertions(+), 7 deletions(-) diff --git a/external/ngtcp2 b/external/ngtcp2 index 51e95c8d8..241882dcd 160000 --- a/external/ngtcp2 +++ b/external/ngtcp2 @@ -1 +1 @@ -Subproject commit 51e95c8d8972abd69515d9790e8fbb774262d9ea +Subproject commit 241882dcda534ed6657f10626b7886583c052dd3 diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 161795de6..213b223a6 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -34,7 +34,7 @@ target_link_libraries(lokinet-util PUBLIC nlohmann_json::nlohmann_json filesystem date::date - oxenmq + oxenmq::oxenmq ) if(ANDROID) @@ -98,6 +98,7 @@ add_library(lokinet-quic quic/tunnel_client.cpp quic/tunnel_server.cpp ) + target_link_libraries(lokinet-quic PRIVATE lokinet-platform ngtcp2) add_library(liblokinet @@ -197,6 +198,7 @@ add_library(liblokinet service/address.cpp service/async_key_exchange.cpp service/auth.cpp + service/convotag.cpp service/context.cpp service/endpoint_state.cpp service/endpoint_util.cpp @@ -237,7 +239,7 @@ if(WITH_HIVE) ) endif() -target_link_libraries(liblokinet PUBLIC cxxopts lokinet-platform lokinet-util lokinet-cryptography lokinet-quic sqlite_orm) +target_link_libraries(liblokinet PUBLIC cxxopts lokinet-platform lokinet-util lokinet-cryptography lokinet-quic sqlite_orm ngtcp2) target_link_libraries(liblokinet PRIVATE libunbound) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 8f40f2fc6..23795acdb 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -1,6 +1,8 @@ +#include #include #include "config.hpp" +#include "config/definition.hpp" #include "ini.hpp" #include #include @@ -621,6 +623,16 @@ namespace llarp m_SRVRecords.push_back(std::move(newSRV)); }); + conf.defineOption( + "network", + "expose", + ClientOnly, + MultiValue, + Comment{ + "expose a local port via quic for liblokinet", + }, + [this](uint16_t port) { m_quicServerPorts.insert(port); }); + // Deprecated options: conf.defineOption("network", "enabled", Deprecated); } diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 9d4072c7c..4a0ba8169 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -121,6 +121,8 @@ namespace llarp std::optional m_baseV6Address; + std::unordered_set m_quicServerPorts; + // TODO: // on-up // on-down diff --git a/llarp/quic/address.cpp b/llarp/quic/address.cpp index 4b985e04a..0e62b029c 100644 --- a/llarp/quic/address.cpp +++ b/llarp/quic/address.cpp @@ -1,5 +1,4 @@ #include "address.hpp" -#include #include #include diff --git a/llarp/service/convotag.cpp b/llarp/service/convotag.cpp index 1da3cecc1..f51f69f9a 100644 --- a/llarp/service/convotag.cpp +++ b/llarp/service/convotag.cpp @@ -14,17 +14,17 @@ namespace llarp::service sockaddr_in6 ConvoTag::ToV6() const { - const auto* ptr = reinterpret_cast(m_data.data()); + const auto* ptr = reinterpret_cast(data()); sockaddr_in6 saddr{}; saddr.sin6_family = AF_INET6; - saddr.sin6_addr = net::HUIntToIn6(huint128_t{ptr[0], ptr[1]}); + saddr.sin6_addr = net::HUIntToIn6(huint128_t{uint128_t{ptr[0], ptr[1]}}); return saddr; } void ConvoTag::FromV6(sockaddr_in6 saddr) { - std::copy_n(saddr.sin6_addr.s6_addr, m_data.size(), m_data.data()); + std::copy_n(saddr.sin6_addr.s6_addr, size(), data()); } } // namespace llarp::service diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 66f3fc677..10b899db4 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -19,17 +19,25 @@ #include "endpoint_state.hpp" #include "endpoint_util.hpp" #include "hidden_service_address_lookup.hpp" +#include "net/ip.hpp" #include "outbound_context.hpp" #include "protocol.hpp" +#include "service/info.hpp" #include #include #include #include #include #include +#include #include +#include +#include +#include +#include + namespace llarp { namespace service @@ -72,6 +80,63 @@ namespace llarp m_StartupLNSMappings[name] = std::make_pair(range, auth); }); + auto loop = uv::Loop::MaybeGetLoop(Router()->loop()); + auto callback = [this, loop, ports = conf.m_quicServerPorts]( + quic::Server& serv, quic::Stream& stream, uint16_t port) { + if (ports.count(port) == 0) + { + return false; + } + + stream.close_callback = [](quic::Stream& st, + [[maybe_unused]] std::optional errcode) { + auto tcp = st.data(); + if (tcp) + tcp->close(); + }; + + auto localIP = net::TruncateV6(GetIfAddr()); + + std::string localhost = localIP.ToString(); + + auto tcp = loop->resource(); + auto error_handler = tcp->once( + [&stream, localhost, port](const uvw::ErrorEvent&, uvw::TCPHandle&) { + LogWarn("Failed to connect to ", localhost, ":", port, ", shutting down quic stream"); + stream.close(quic::tunnel::ERROR_CONNECT); + }); + tcp->once( + [streamw = stream.weak_from_this(), error_handler = std::move(error_handler)]( + const uvw::ConnectEvent&, uvw::TCPHandle& tcp) { + auto peer = tcp.peer(); + auto stream = streamw.lock(); + if (!stream) + { + LogWarn( + "Connected to ", + peer.ip, + ":", + peer.port, + " but quic stream has gone away; resetting local connection"); + tcp.closeReset(); + return; + } + LogDebug("Connected to ", peer.ip, ":", peer.port, " for quic ", stream->id()); + tcp.erase(error_handler); + quic::tunnel::install_stream_forwarding(tcp, *stream); + assert(stream->used() == 0); + + stream->append_buffer(new std::byte[1]{quic::tunnel::CONNECT_INIT}, 1); + tcp.read(); + }); + + tcp->connect(localhost, port); + + return true; + }; + + m_QuicServer = std::make_shared(this, loop, callback); + return m_state->Configure(conf); } @@ -1317,6 +1382,16 @@ namespace llarp return true; } + bool + Endpoint::SendTo(ConvoTag tag, const llarp_buffer_t& pkt, ProtocolType t) + { + // TODO: support snode + ServiceInfo ident{}; + if (not GetSenderFor(tag, ident)) + return false; + return SendToServiceOrQueue(ident.Addr(), pkt, t); + } + bool Endpoint::SendToSNodeOrQueue(const RouterID& addr, const llarp_buffer_t& buf) { diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 1d99eda29..956318561 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -11,11 +11,13 @@ #include "identity.hpp" #include "pendingbuffer.hpp" #include "protocol.hpp" +#include "quic/server.hpp" #include "sendcontext.hpp" #include "session.hpp" #include "lookup.hpp" #include #include +#include #include "endpoint_types.hpp" #include "auth.hpp" @@ -463,6 +465,8 @@ namespace llarp ConvoMap& Sessions(); // clang-format on thread::Queue m_RecvQueue; + + std::shared_ptr m_QuicServer; }; using Endpoint_ptr = std::shared_ptr;