diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 05e4122dc..a2141d957 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -106,6 +106,7 @@ add_library(liblokinet bootstrap.cpp context.cpp + endpoint_base.cpp crypto/crypto_libsodium.cpp crypto/crypto.cpp crypto/encrypted_frame.cpp diff --git a/llarp/endpoint_base.hpp b/llarp/endpoint_base.hpp index 9aaa3f438..b16581637 100644 --- a/llarp/endpoint_base.hpp +++ b/llarp/endpoint_base.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "oxenmq/variant.h" diff --git a/llarp/exit/endpoint.cpp b/llarp/exit/endpoint.cpp index 7fb73ab25..9a442090a 100644 --- a/llarp/exit/endpoint.cpp +++ b/llarp/exit/endpoint.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -108,10 +109,18 @@ namespace llarp } bool - Endpoint::QueueOutboundTraffic(ManagedBuffer buf, uint64_t counter, service::ProtocolType t) + Endpoint::QueueOutboundTraffic( + PathID_t path, ManagedBuffer buf, uint64_t counter, service::ProtocolType t) { + const service::ConvoTag tag{path.as_array()}; if (t == service::ProtocolType::QUIC) + { + auto quic = m_Parent->GetQUICTunnel(); + if (not quic) + return false; + quic->receive_packet(tag, buf.underlying); return false; + } // queue overflow if (m_UpstreamQueue.size() > MaxUpstreamQueueSize) return false; diff --git a/llarp/exit/endpoint.hpp b/llarp/exit/endpoint.hpp index f5e517f83..1eb3bd8be 100644 --- a/llarp/exit/endpoint.hpp +++ b/llarp/exit/endpoint.hpp @@ -66,7 +66,8 @@ namespace llarp /// queue outbound traffic /// does ip rewrite here bool - QueueOutboundTraffic(ManagedBuffer pkt, uint64_t counter, service::ProtocolType t); + QueueOutboundTraffic( + PathID_t txid, ManagedBuffer pkt, uint64_t counter, service::ProtocolType t); /// update local path id and cascade information to parent /// return true if success diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index b4f27d4c9..165c7e8d4 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -19,14 +19,14 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, - quic::TunnelManager* quictun) + EndpointBase* parent) : llarp::path::Builder{r, numpaths, hoplen} , m_ExitRouter{routerId} , m_WritePacket{std::move(writepkt)} , m_Counter{0} , m_LastUse{r->Now()} , m_BundleRC{false} - , m_QUIC{quictun} + , m_Parent{parent} { CryptoManager::instance()->identity_keygen(m_ExitIdentity); } @@ -188,12 +188,14 @@ namespace llarp uint64_t counter, service::ProtocolType t) { + const service::ConvoTag tag{path->TXID().as_array()}; + if (t == service::ProtocolType::QUIC) { - if (buf.sz < 4 or not m_QUIC) + auto quic = m_Parent->GetQUICTunnel(); + if (not quic) return false; - service::ConvoTag tag{path->TXID().as_array()}; - m_QUIC->receive_packet(tag, buf); + quic->receive_packet(tag, buf); return true; } @@ -336,8 +338,8 @@ namespace llarp size_t numpaths, size_t hoplen, bool useRouterSNodeKey, - quic::TunnelManager* quictun) - : BaseSession{snodeRouter, writepkt, r, numpaths, hoplen, quictun} + EndpointBase* parent) + : BaseSession{snodeRouter, writepkt, r, numpaths, hoplen, parent} { if (useRouterSNodeKey) { diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index ee01db5e2..6511ed6ce 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -12,6 +12,8 @@ namespace llarp { + class EndpointBase; + namespace quic { class TunnelManager; @@ -39,7 +41,7 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, - quic::TunnelManager* quictun); + EndpointBase* parent); ~BaseSession() override; @@ -169,7 +171,7 @@ namespace llarp std::vector m_PendingCallbacks; const bool m_BundleRC; - quic::TunnelManager* const m_QUIC; + EndpointBase* const m_Parent; void CallPendingCallbacks(bool success); @@ -183,8 +185,8 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, - quic::TunnelManager* quictun) - : BaseSession{snodeRouter, writepkt, r, numpaths, hoplen, quictun} + EndpointBase* parent) + : BaseSession{snodeRouter, writepkt, r, numpaths, hoplen, parent} {} ~ExitSession() override = default; @@ -214,7 +216,7 @@ namespace llarp size_t numpaths, size_t hoplen, bool useRouterSNodeKey, - quic::TunnelManager* quictun); + EndpointBase* parent); ~SNodeSession() override = default; diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 0c50253af..d7e291100 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -717,7 +717,7 @@ namespace llarp 2, 1, true, - GetQUICTunnel()); + this); // this is a new service node make an outbound session to them m_SNodeSessions.emplace(other, session); } diff --git a/llarp/handlers/null.hpp b/llarp/handlers/null.hpp index 9a5094299..34dbafb35 100644 --- a/llarp/handlers/null.hpp +++ b/llarp/handlers/null.hpp @@ -26,7 +26,11 @@ namespace llarp service::ProtocolType t, uint64_t) override { - if (t != service::ProtocolType::QUIC and t != service::ProtocolType::Control) + + if (t == service::ProtocolType::Control) + return true; + + if (t != service::ProtocolType::QUIC) return false; auto* quic = GetQUICTunnel(); @@ -40,7 +44,6 @@ namespace llarp LogWarn("invalid incoming quic packet, dropping"); return false; } - LogInfo("tag active T=", tag); MarkConvoTagActive(tag); quic->receive_packet(tag, buf); m_router->loop()->wakeup(); diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 5a217e70c..f8811bdff 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -33,8 +33,6 @@ namespace llarp { namespace handlers { - constexpr size_t udp_header_size = 8; - // Intercepts DNS IP packets going to an IP on the tun interface; this is currently used on // Android where binding to a DNS port (i.e. via llarp::dns::Proxy) isn't possible because of OS // restrictions, but a tun interface *is* available. @@ -50,38 +48,15 @@ namespace llarp SendServerMessageBufferTo( const SockAddr& to, const SockAddr& from, llarp_buffer_t buf) override { - net::IPPacket pkt; - - if (buf.sz + 28 > sizeof(pkt.buf)) + const auto pkt = net::IPPacket::UDP( + from.getIPv4(), + ToNet(huint16_t{from.getPort()}), + to.getIPv4(), + ToNet(huint16_t{to.getPort()}), + buf); + + if (pkt.sz == 0) return; - - auto* hdr = pkt.Header(); - pkt.buf[1] = 0; - hdr->version = 4; - hdr->ihl = 5; - hdr->tot_len = htons(buf.sz + 28); - hdr->protocol = 0x11; // udp - hdr->ttl = 64; - hdr->frag_off = htons(0b0100000000000000); - - hdr->saddr = from.getIPv4().n; - hdr->daddr = to.getIPv4().n; - - // make udp packet - uint8_t* ptr = pkt.buf + 20; - htobe16buf(ptr, from.getPort()); - ptr += 2; - htobe16buf(ptr, to.getPort()); - ptr += 2; - htobe16buf(ptr, buf.sz + udp_header_size); - ptr += 2; - htobe16buf(ptr, uint16_t{0}); // checksum - ptr += 2; - std::copy_n(buf.base, buf.sz, ptr); - - hdr->check = 0; - hdr->check = net::ipchksum(pkt.buf, 20); - pkt.sz = 28 + buf.sz; m_Endpoint->HandleWriteIPPacket( pkt.ConstBuffer(), net::ExpandV4(from.asIPv4()), net::ExpandV4(to.asIPv4()), 0); } diff --git a/llarp/net/ip_packet.cpp b/llarp/net/ip_packet.cpp index c983de750..353024b74 100644 --- a/llarp/net/ip_packet.cpp +++ b/llarp/net/ip_packet.cpp @@ -530,5 +530,51 @@ namespace llarp } return std::nullopt; } + + IPPacket + IPPacket::UDP( + nuint32_t srcaddr, + nuint16_t srcport, + nuint32_t dstaddr, + nuint16_t dstport, + const llarp_buffer_t& buf) + { + net::IPPacket pkt; + + if (buf.sz + 28 > sizeof(pkt.buf)) + { + pkt.sz = 0; + return pkt; + } + auto* hdr = pkt.Header(); + pkt.buf[1] = 0; + hdr->version = 4; + hdr->ihl = 5; + hdr->tot_len = htons(buf.sz + 28); + hdr->protocol = 0x11; // udp + hdr->ttl = 64; + hdr->frag_off = htons(0b0100000000000000); + + hdr->saddr = srcaddr.n; + hdr->daddr = dstaddr.n; + + // make udp packet + uint8_t* ptr = pkt.buf + 20; + std::memcpy(ptr, &srcport.n, 2); + ptr += 2; + std::memcpy(ptr, &dstport.n, 2); + ptr += 2; + htobe16buf(ptr, static_cast(buf.sz + 8)); + ptr += 2; + htobe16buf(ptr, uint16_t{0}); // checksum + ptr += 2; + std::copy_n(buf.base, buf.sz, ptr); + + hdr->check = 0; + hdr->check = net::ipchksum(pkt.buf, 20); + pkt.sz = 28 + buf.sz; + return pkt; + } + } // namespace net } // namespace llarp diff --git a/llarp/net/ip_packet.hpp b/llarp/net/ip_packet.hpp index 6375bbb3a..bf58e974a 100644 --- a/llarp/net/ip_packet.hpp +++ b/llarp/net/ip_packet.hpp @@ -120,6 +120,13 @@ namespace llarp size_t sz; byte_t buf[MaxSize]; + static IPPacket + UDP(nuint32_t srcaddr, + nuint16_t srcport, + nuint32_t dstaddr, + nuint16_t dstport, + const llarp_buffer_t& data); + ManagedBuffer Buffer(); diff --git a/llarp/net/net_int.cpp b/llarp/net/net_int.cpp index caecb7ab4..973d6ed4e 100644 --- a/llarp/net/net_int.cpp +++ b/llarp/net/net_int.cpp @@ -82,6 +82,19 @@ namespace llarp return tmp; } + template <> + bool + huint16_t::FromString(const std::string& str) + { + if (auto val = std::atoi(str.c_str()); val >= 0) + { + h = val; + return true; + } + else + return false; + } + template <> bool huint32_t::FromString(const std::string& str) diff --git a/llarp/net/net_int.hpp b/llarp/net/net_int.hpp index 61d5ff589..616e912d8 100644 --- a/llarp/net/net_int.hpp +++ b/llarp/net/net_int.hpp @@ -127,7 +127,7 @@ namespace llarp template struct nuint_t { - UInt_t n; + UInt_t n = 0; constexpr nuint_t operator&(nuint_t x) const @@ -185,6 +185,16 @@ namespace llarp std::string ToString() const; + bool + FromString(const std::string& data) + { + huint_t x; + if (not x.FromString(data)) + return false; + *this = ToNet(x); + return true; + } + friend std::ostream& operator<<(std::ostream& out, const nuint_t& i) { diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index dab5878dd..489275f98 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -416,7 +416,10 @@ namespace llarp continue; uint64_t counter = bufbe64toh(pkt.data()); sent &= endpoint->QueueOutboundTraffic( - ManagedBuffer(llarp_buffer_t(pkt.data() + 8, pkt.size() - 8)), counter, msg.protocol); + info.txID, + ManagedBuffer(llarp_buffer_t(pkt.data() + 8, pkt.size() - 8)), + counter, + msg.protocol); } return sent; } diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 6ce6dc99c..cc0a3104e 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1220,7 +1220,19 @@ namespace llarp MarkAddressOutbound(remote); auto& sessions = m_state->m_RemoteSessions; - + { + auto range = sessions.equal_range(remote); + auto itr = range.first; + while (itr != range.second) + { + if (itr->second->ReadyToSend()) + { + hook(remote, itr->second.get()); + return true; + } + ++itr; + } + } // add response hook to list for address. m_state->m_PendingServiceLookups.emplace(remote, hook); @@ -1318,7 +1330,7 @@ namespace llarp numDesiredPaths, numHops, false, - GetQUICTunnel()); + this); m_state->m_SNodeSessions.emplace(snode, std::make_pair(session, tag)); } @@ -1346,7 +1358,9 @@ namespace llarp return false; LogWarn("sent to tag T=", tag); if (auto maybe = GetEndpointWithConvoTag(tag)) + { return SendToOrQueue(*maybe, pkt, t); + } return false; } diff --git a/llarp/util/aligned.hpp b/llarp/util/aligned.hpp index 7e20360e8..d588d154a 100644 --- a/llarp/util/aligned.hpp +++ b/llarp/util/aligned.hpp @@ -193,7 +193,13 @@ namespace llarp bool IsZero() const { - return sodium_is_zero(data(), size()); + const uint64_t* ptr = reinterpret_cast(data()); + for (size_t idx = 0; idx < SIZE / sizeof(uint64_t); idx++) + { + if (ptr[idx]) + return false; + } + return true; } void