1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

various fixups and cleanups

* wire up last of the quic stuff
* clean up udp packet generation code
* pass EndpointBase not quic tunnel for quic stuff
* add {n,h}uint16_t::FromString
* add nuint_t::FromString
* make AlignedBuffer::IsZero non constant time call for speed
This commit is contained in:
Jeff Becker 2021-03-29 12:31:55 -04:00
parent 211a051444
commit 708e408c30
No known key found for this signature in database
GPG key ID: F357B3B42F6F9B05
16 changed files with 147 additions and 54 deletions

View file

@ -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

View file

@ -9,6 +9,7 @@
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <optional>
#include "oxenmq/variant.h"

View file

@ -3,6 +3,7 @@
#include <llarp/handlers/exit.hpp>
#include <llarp/path/path_context.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/quic/tunnel.hpp>
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;

View file

@ -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

View file

@ -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)
{

View file

@ -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<SessionReadyFunc> 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;

View file

@ -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);
}

View file

@ -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();

View file

@ -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;
const auto pkt = net::IPPacket::UDP(
from.getIPv4(),
ToNet(huint16_t{from.getPort()}),
to.getIPv4(),
ToNet(huint16_t{to.getPort()}),
buf);
if (buf.sz + 28 > sizeof(pkt.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);
}

View file

@ -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<uint16_t>(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

View file

@ -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();

View file

@ -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)

View file

@ -127,7 +127,7 @@ namespace llarp
template <typename UInt_t>
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<UInt_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)
{

View file

@ -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;
}

View file

@ -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;
}

View file

@ -193,7 +193,13 @@ namespace llarp
bool
IsZero() const
{
return sodium_is_zero(data(), size());
const uint64_t* ptr = reinterpret_cast<const uint64_t*>(data());
for (size_t idx = 0; idx < SIZE / sizeof(uint64_t); idx++)
{
if (ptr[idx])
return false;
}
return true;
}
void