pull/686/head
Jeff Becker 5 years ago
parent 32d73199e6
commit 2403ab8f86
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -65,9 +65,11 @@ set(LIB_PLATFORM_SRC
ev/pipe.cpp ev/pipe.cpp
metrics/metrictank_publisher.cpp metrics/metrictank_publisher.cpp
metrics/publishers.cpp metrics/publishers.cpp
net/ip.cpp
net/net.cpp net/net.cpp
net/net_addr.cpp net/net_addr.cpp
net/net_inaddr.cpp net/net_inaddr.cpp
net/net_int.cpp
# for android shim # for android shim
${ANDROID_PLATFORM_SRC} ${ANDROID_PLATFORM_SRC}
# process isolation implementation # process isolation implementation
@ -194,8 +196,6 @@ set(LIB_SRC
messages/transfer_traffic.cpp messages/transfer_traffic.cpp
net/address_info.cpp net/address_info.cpp
net/exit_info.cpp net/exit_info.cpp
net/ip.cpp
net/net_int.cpp
nodedb.cpp nodedb.cpp
path/path.cpp path/path.cpp
path/path_types.cpp path/path_types.cpp

@ -5,6 +5,7 @@
#include <util/endian.hpp> #include <util/endian.hpp>
#include <util/logger.hpp> #include <util/logger.hpp>
#include <util/printer.hpp> #include <util/printer.hpp>
#include <net/ip.hpp>
#include <array> #include <array>
@ -165,7 +166,7 @@ namespace llarp
} }
void void
Message::AddINReply(llarp::huint32_t ip, bool isV6, RR_TTL_t ttl) Message::AddINReply(llarp::huint128_t ip, bool isV6, RR_TTL_t ttl)
{ {
if(questions.size()) if(questions.size())
{ {
@ -182,9 +183,10 @@ namespace llarp
} }
else else
{ {
rec.rr_type = qTypeA; const auto addr = net::IPPacket::TruncateV6(ip);
rec.rr_type = qTypeA;
rec.rData.resize(4); rec.rData.resize(4);
htobe32buf(rec.rData.data(), ip.h); htobe32buf(rec.rData.data(), addr.h);
} }
answers.emplace_back(std::move(rec)); answers.emplace_back(std::move(rec));
} }

@ -64,7 +64,7 @@ namespace llarp
AddCNAMEReply(std::string name, RR_TTL_t ttl = 1); AddCNAMEReply(std::string name, RR_TTL_t ttl = 1);
void void
AddINReply(llarp::huint32_t addr, bool isV6, RR_TTL_t ttl = 1); AddINReply(llarp::huint128_t addr, bool isV6, RR_TTL_t ttl = 1);
void void
AddAReply(std::string name, RR_TTL_t ttl = 1); AddAReply(std::string name, RR_TTL_t ttl = 1);

@ -154,9 +154,9 @@ llarp_ev_add_tun(struct llarp_ev_loop *loop, struct llarp_tun_io *tun)
dev->setup(); dev->setup();
return dev->add_ev(); // start up tun and add to event queue return dev->add_ev(); // start up tun and add to event queue
} }
#endif
llarp::LogWarn("Loop could not create tun"); llarp::LogWarn("Loop could not create tun");
return false; return false;
#endif
} }
bool bool

@ -613,6 +613,7 @@ namespace libuv
m_CloseFuncs.emplace_back(std::bind(&tun_glue ::Close, glue)); m_CloseFuncs.emplace_back(std::bind(&tun_glue ::Close, glue));
return true; return true;
} }
delete glue; delete glue;
return false; return false;
} }

@ -8,7 +8,7 @@ namespace llarp
{ {
Endpoint::Endpoint(const llarp::PubKey& remoteIdent, Endpoint::Endpoint(const llarp::PubKey& remoteIdent,
const llarp::PathID_t& beginPath, bool rewriteIP, const llarp::PathID_t& beginPath, bool rewriteIP,
huint32_t ip, llarp::handlers::ExitEndpoint* parent) huint128_t ip, llarp::handlers::ExitEndpoint* parent)
: createdAt(parent->Now()) : createdAt(parent->Now())
, m_Parent(parent) , m_Parent(parent)
, m_remoteSignKey(remoteIdent) , m_remoteSignKey(remoteIdent)
@ -108,16 +108,16 @@ namespace llarp
if(m_UpstreamQueue.size() > MaxUpstreamQueueSize) if(m_UpstreamQueue.size() > MaxUpstreamQueueSize)
return false; return false;
llarp::net::IPv4Packet pkt; llarp::net::IPPacket pkt;
if(!pkt.Load(buf.underlying)) if(!pkt.Load(buf.underlying))
return false; return false;
huint32_t dst; huint32_t dst;
if(m_RewriteSource) if(m_RewriteSource)
dst = m_Parent->GetIfAddr(); dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr());
else else
dst = pkt.dst(); dst = pkt.dstv4();
pkt.UpdateIPv4PacketOnDst(m_IP, dst); pkt.UpdateV4Address(net::IPPacket::TruncateV6(m_IP), dst);
m_UpstreamQueue.emplace(pkt, counter); m_UpstreamQueue.emplace(pkt, counter);
m_TxRate += buf.underlying.sz; m_TxRate += buf.underlying.sz;
m_LastActive = m_Parent->Now(); m_LastActive = m_Parent->Now();
@ -127,16 +127,16 @@ namespace llarp
bool bool
Endpoint::QueueInboundTraffic(ManagedBuffer buf) Endpoint::QueueInboundTraffic(ManagedBuffer buf)
{ {
llarp::net::IPv4Packet pkt; llarp::net::IPPacket pkt;
if(!pkt.Load(buf.underlying)) if(!pkt.Load(buf.underlying))
return false; return false;
huint32_t src; huint128_t src;
if(m_RewriteSource) if(m_RewriteSource)
src = m_Parent->GetIfAddr(); src = m_Parent->GetIfAddr();
else else
src = pkt.src(); src = pkt.srcv6();
pkt.UpdateIPv4PacketOnDst(src, m_IP); pkt.UpdateV6Address(src, m_IP);
const llarp_buffer_t& pktbuf = pkt.Buffer(); // life time extension const llarp_buffer_t& pktbuf = pkt.Buffer(); // life time extension
const uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize; const uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize;
if(m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end()) if(m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())

@ -24,7 +24,7 @@ namespace llarp
static constexpr size_t MaxUpstreamQueueSize = 256; static constexpr size_t MaxUpstreamQueueSize = 256;
Endpoint(const llarp::PubKey& remoteIdent, Endpoint(const llarp::PubKey& remoteIdent,
const llarp::PathID_t& beginPath, bool rewriteIP, huint32_t ip, const llarp::PathID_t& beginPath, bool rewriteIP, huint128_t ip,
llarp::handlers::ExitEndpoint* parent); llarp::handlers::ExitEndpoint* parent);
~Endpoint(); ~Endpoint();
@ -97,7 +97,7 @@ namespace llarp
return m_RxRate; return m_RxRate;
} }
huint32_t huint128_t
LocalIP() const LocalIP() const
{ {
return m_IP; return m_IP;
@ -109,7 +109,7 @@ namespace llarp
llarp::handlers::ExitEndpoint* m_Parent; llarp::handlers::ExitEndpoint* m_Parent;
llarp::PubKey m_remoteSignKey; llarp::PubKey m_remoteSignKey;
llarp::PathID_t m_CurrentPath; llarp::PathID_t m_CurrentPath;
llarp::huint32_t m_IP; llarp::huint128_t m_IP;
uint64_t m_TxRate, m_RxRate; uint64_t m_TxRate, m_RxRate;
llarp_time_t m_LastActive; llarp_time_t m_LastActive;
bool m_RewriteSource; bool m_RewriteSource;
@ -121,12 +121,12 @@ namespace llarp
struct UpstreamBuffer struct UpstreamBuffer
{ {
UpstreamBuffer(const llarp::net::IPv4Packet& p, uint64_t c) UpstreamBuffer(const llarp::net::IPPacket& p, uint64_t c)
: pkt(p), counter(c) : pkt(p), counter(c)
{ {
} }
llarp::net::IPv4Packet pkt; llarp::net::IPPacket pkt;
uint64_t counter; uint64_t counter;
bool bool

@ -199,7 +199,7 @@ namespace llarp
{ {
if(m_WritePacket) if(m_WritePacket)
{ {
llarp::net::IPv4Packet pkt; llarp::net::IPPacket pkt;
if(!pkt.Load(buf)) if(!pkt.Load(buf))
return false; return false;
m_Downstream.emplace(counter, pkt); m_Downstream.emplace(counter, pkt);
@ -221,8 +221,7 @@ namespace llarp
} }
bool bool
BaseSession::QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, BaseSession::QueueUpstreamTraffic(llarp::net::IPPacket pkt, const size_t N)
const size_t N)
{ {
const llarp_buffer_t& buf = pkt.Buffer(); const llarp_buffer_t& buf = pkt.Buffer();
auto& queue = m_Upstream[buf.sz / N]; auto& queue = m_Upstream[buf.sz / N];

@ -74,7 +74,7 @@ namespace llarp
HandlePathBuilt(llarp::path::Path_ptr p) override; HandlePathBuilt(llarp::path::Path_ptr p) override;
bool bool
QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, const size_t packSize); QueueUpstreamTraffic(llarp::net::IPPacket pkt, const size_t packSize);
/// flush upstream to exit via paths /// flush upstream to exit via paths
bool bool
@ -139,7 +139,7 @@ namespace llarp
using TieredQueue_t = std::map< uint8_t, UpstreamTrafficQueue_t >; using TieredQueue_t = std::map< uint8_t, UpstreamTrafficQueue_t >;
TieredQueue_t m_Upstream; TieredQueue_t m_Upstream;
using DownstreamPkt = std::pair< uint64_t, llarp::net::IPv4Packet >; using DownstreamPkt = std::pair< uint64_t, llarp::net::IPPacket >;
struct DownstreamPktSorter struct DownstreamPktSorter
{ {

@ -68,7 +68,7 @@ namespace llarp
huint32_t ip; huint32_t ip;
if(!dns::DecodePTR(msg.questions[0].qname, ip)) if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false; return false;
return m_OurRange.Contains(ip); return m_OurRange.ContainsV4(ip);
} }
else if(msg.questions[0].qtype == dns::qTypeA else if(msg.questions[0].qtype == dns::qTypeA
|| msg.questions[0].qtype == dns::qTypeCNAME || msg.questions[0].qtype == dns::qTypeCNAME
@ -91,14 +91,15 @@ namespace llarp
huint32_t ip; huint32_t ip;
if(!dns::DecodePTR(msg.questions[0].qname, ip)) if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false; return false;
if(ip == m_IfAddr) huint128_t ipv6 = net::IPPacket::ExpandV4(ip);
if(ipv6 == m_IfAddr)
{ {
RouterID us = GetRouter()->pubkey(); RouterID us = GetRouter()->pubkey();
msg.AddAReply(us.ToString(), 300); msg.AddAReply(us.ToString(), 300);
} }
else else
{ {
auto itr = m_IPToKey.find(ip); auto itr = m_IPToKey.find(ipv6);
if(itr != m_IPToKey.end() if(itr != m_IPToKey.end()
&& m_SNodeKeys.find(itr->second) != m_SNodeKeys.end()) && m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
{ {
@ -155,7 +156,7 @@ namespace llarp
RouterID r; RouterID r;
if(r.FromString(msg.questions[0].Name())) if(r.FromString(msg.questions[0].Name()))
{ {
huint32_t ip; huint128_t ip;
PubKey pubKey(r); PubKey pubKey(r);
if(m_SNodeKeys.find(pubKey) == m_SNodeKeys.end()) if(m_SNodeKeys.find(pubKey) == m_SNodeKeys.end())
{ {
@ -212,11 +213,12 @@ namespace llarp
m_InetToNetwork.Process([&](Pkt_t &pkt) { m_InetToNetwork.Process([&](Pkt_t &pkt) {
PubKey pk; PubKey pk;
{ {
auto itr = m_IPToKey.find(pkt.dst()); auto itr = m_IPToKey.find(pkt.dstv6());
if(itr == m_IPToKey.end()) if(itr == m_IPToKey.end())
{ {
// drop // drop
LogWarn(Name(), " dropping packet, has no session at ", pkt.dst()); LogWarn(Name(), " dropping packet, has no session at ",
pkt.dstv4());
return; return;
} }
pk = itr->second; pk = itr->second;
@ -285,10 +287,10 @@ namespace llarp
{ {
// map our address // map our address
const PubKey us(m_Router->pubkey()); const PubKey us(m_Router->pubkey());
const huint32_t ip = GetIfAddr(); const huint128_t ip = GetIfAddr();
m_KeyToIP[us] = ip; m_KeyToIP[us] = ip;
m_IPToKey[ip] = us; m_IPToKey[ip] = us;
m_IPActivity[ip] = std::numeric_limits< llarp_time_t >::max(); m_IPActivity[ip] = std::numeric_limits< llarp_time_t >::max();
m_SNodeKeys.insert(us); m_SNodeKeys.insert(us);
if(m_ShouldInitTun) if(m_ShouldInitTun)
{ {
@ -311,7 +313,7 @@ namespace llarp
return m_Router; return m_Router;
} }
huint32_t huint128_t
ExitEndpoint::GetIfAddr() const ExitEndpoint::GetIfAddr() const
{ {
return m_IfAddr; return m_IfAddr;
@ -340,10 +342,10 @@ namespace llarp
return m_KeyToIP.find(pk) != m_KeyToIP.end(); return m_KeyToIP.find(pk) != m_KeyToIP.end();
} }
huint32_t huint128_t
ExitEndpoint::GetIPForIdent(const PubKey pk) ExitEndpoint::GetIPForIdent(const PubKey pk)
{ {
huint32_t found = {0}; huint128_t found = {0};
if(!HasLocalMappedAddrFor(pk)) if(!HasLocalMappedAddrFor(pk))
{ {
// allocate and map // allocate and map
@ -372,14 +374,14 @@ namespace llarp
return found; return found;
} }
huint32_t huint128_t
ExitEndpoint::AllocateNewAddress() ExitEndpoint::AllocateNewAddress()
{ {
if(m_NextAddr < m_HigestAddr) if(m_NextAddr < m_HigestAddr)
return ++m_NextAddr; return ++m_NextAddr;
// find oldest activity ip address // find oldest activity ip address
huint32_t found = {0}; huint128_t found = {0};
llarp_time_t min = std::numeric_limits< llarp_time_t >::max(); llarp_time_t min = std::numeric_limits< llarp_time_t >::max();
auto itr = m_IPActivity.begin(); auto itr = m_IPActivity.begin();
while(itr != m_IPActivity.end()) while(itr != m_IPActivity.end())
@ -409,7 +411,7 @@ namespace llarp
ExitEndpoint::KickIdentOffExit(const PubKey &pk) ExitEndpoint::KickIdentOffExit(const PubKey &pk)
{ {
LogInfo(Name(), " kicking ", pk, " off exit"); LogInfo(Name(), " kicking ", pk, " off exit");
huint32_t ip = m_KeyToIP[pk]; huint128_t ip = m_KeyToIP[pk];
m_KeyToIP.erase(pk); m_KeyToIP.erase(pk);
m_IPToKey.erase(ip); m_IPToKey.erase(ip);
auto range = m_ActiveExits.equal_range(pk); auto range = m_ActiveExits.equal_range(pk);
@ -419,7 +421,7 @@ namespace llarp
} }
void void
ExitEndpoint::MarkIPActive(huint32_t ip) ExitEndpoint::MarkIPActive(huint128_t ip)
{ {
m_IPActivity[ip] = GetRouter()->Now(); m_IPActivity[ip] = GetRouter()->Now();
} }
@ -432,13 +434,13 @@ namespace llarp
} }
bool bool
ExitEndpoint::QueueSNodePacket(const llarp_buffer_t &buf, huint32_t from) ExitEndpoint::QueueSNodePacket(const llarp_buffer_t &buf, huint128_t from)
{ {
net::IPv4Packet pkt; net::IPPacket pkt;
if(!pkt.Load(buf)) if(!pkt.Load(buf))
return false; return false;
// rewrite ip // rewrite ip
pkt.UpdateIPv4PacketOnDst(from, m_IfAddr); pkt.UpdateV6Address(from, m_IfAddr);
return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer()); return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer());
} }
@ -529,12 +531,19 @@ namespace llarp
strncpy(m_Tun.ifaddr, host_str.c_str(), sizeof(m_Tun.ifaddr) - 1); strncpy(m_Tun.ifaddr, host_str.c_str(), sizeof(m_Tun.ifaddr) - 1);
m_Tun.netmask = std::atoi(nmask_str.c_str()); m_Tun.netmask = std::atoi(nmask_str.c_str());
Addr ifaddr(host_str); huint32_t ip;
m_IfAddr = ifaddr.xtohl(); if(ip.FromString(host_str))
m_OurRange.netmask_bits = netmask_ipv4_bits(m_Tun.netmask); {
m_OurRange.addr = m_IfAddr; m_IfAddr = net::IPPacket::ExpandV4(ip);
m_NextAddr = m_IfAddr; m_OurRange.netmask_bits = netmask_ipv6_bits(m_Tun.netmask + 96);
m_HigestAddr = m_IfAddr | (~m_OurRange.netmask_bits); }
else if(m_IfAddr.FromString(host_str))
{
m_OurRange.netmask_bits = netmask_ipv6_bits(m_Tun.netmask);
}
m_OurRange.addr = m_IfAddr;
m_NextAddr = m_IfAddr;
m_HigestAddr = m_IfAddr | (~m_OurRange.netmask_bits);
LogInfo(Name(), " set ifaddr range to ", m_Tun.ifaddr, "/", LogInfo(Name(), " set ifaddr range to ", m_Tun.ifaddr, "/",
m_Tun.netmask, " lo=", m_IfAddr, " hi=", m_HigestAddr); m_Tun.netmask, " lo=", m_IfAddr, " hi=", m_HigestAddr);
} }
@ -564,7 +573,7 @@ namespace llarp
return true; return true;
} }
huint32_t huint128_t
ExitEndpoint::ObtainServiceNodeIP(const RouterID &other) ExitEndpoint::ObtainServiceNodeIP(const RouterID &other)
{ {
const PubKey pubKey(other); const PubKey pubKey(other);
@ -573,7 +582,7 @@ namespace llarp
if(pubKey == us) if(pubKey == us)
return m_IfAddr; return m_IfAddr;
huint32_t ip = GetIPForIdent(pubKey); huint128_t ip = GetIPForIdent(pubKey);
if(m_SNodeKeys.emplace(pubKey).second) if(m_SNodeKeys.emplace(pubKey).second)
{ {
auto session = std::make_shared< exit::SNodeSession >( auto session = std::make_shared< exit::SNodeSession >(
@ -593,7 +602,7 @@ namespace llarp
{ {
if(wantInternet && !m_PermitExit) if(wantInternet && !m_PermitExit)
return false; return false;
huint32_t ip = GetIPForIdent(pk); auto ip = GetIPForIdent(pk);
if(GetRouter()->pathContext().TransitHopPreviousIsRouter(path, if(GetRouter()->pathContext().TransitHopPreviousIsRouter(path,
pk.as_array())) pk.as_array()))
{ {

@ -99,29 +99,29 @@ namespace llarp
bool bool
HasLocalMappedAddrFor(const PubKey& pk) const; HasLocalMappedAddrFor(const PubKey& pk) const;
huint32_t huint128_t
GetIfAddr() const; GetIfAddr() const;
void void
Flush(); Flush();
private: private:
huint32_t huint128_t
GetIPForIdent(const PubKey pk); GetIPForIdent(const PubKey pk);
huint32_t huint128_t
AllocateNewAddress(); AllocateNewAddress();
/// obtain ip for service node session, creates a new session if one does /// obtain ip for service node session, creates a new session if one does
/// not existing already /// not existing already
huint32_t huint128_t
ObtainServiceNodeIP(const RouterID& router); ObtainServiceNodeIP(const RouterID& router);
bool bool
QueueSNodePacket(const llarp_buffer_t& buf, huint32_t from); QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
void void
MarkIPActive(huint32_t ip); MarkIPActive(huint128_t ip);
void void
KickIdentOffExit(const PubKey& pk); KickIdentOffExit(const PubKey& pk);
@ -139,7 +139,7 @@ namespace llarp
PubKey::Hash > PubKey::Hash >
m_ActiveExits; m_ActiveExits;
using KeyMap_t = std::unordered_map< PubKey, huint32_t, PubKey::Hash >; using KeyMap_t = std::unordered_map< PubKey, huint128_t, PubKey::Hash >;
KeyMap_t m_KeyToIP; KeyMap_t m_KeyToIP;
@ -153,14 +153,15 @@ namespace llarp
/// snode sessions we are talking to directly /// snode sessions we are talking to directly
SNodeSessions_t m_SNodeSessions; SNodeSessions_t m_SNodeSessions;
std::unordered_map< huint32_t, PubKey, huint32_t::Hash > m_IPToKey; std::unordered_map< huint128_t, PubKey, huint128_t::Hash > m_IPToKey;
huint32_t m_IfAddr; huint128_t m_IfAddr;
huint32_t m_HigestAddr; huint128_t m_HigestAddr;
huint32_t m_NextAddr;
huint128_t m_NextAddr;
IPRange m_OurRange; IPRange m_OurRange;
std::unordered_map< huint32_t, llarp_time_t, huint32_t::Hash > std::unordered_map< huint128_t, llarp_time_t, huint128_t::Hash >
m_IPActivity; m_IPActivity;
llarp_tun_io m_Tun; llarp_tun_io m_Tun;
@ -168,7 +169,7 @@ namespace llarp
Addr m_LocalResolverAddr; Addr m_LocalResolverAddr;
std::vector< Addr > m_UpstreamResolvers; std::vector< Addr > m_UpstreamResolvers;
using Pkt_t = net::IPv4Packet; using Pkt_t = net::IPPacket;
using PacketQueue_t = using PacketQueue_t =
util::CoDelQueue< Pkt_t, Pkt_t::GetTime, Pkt_t::PutTime, util::CoDelQueue< Pkt_t, Pkt_t::GetTime, Pkt_t::PutTime,
Pkt_t::CompareOrder, Pkt_t::GetNow, util::NullMutex, Pkt_t::CompareOrder, Pkt_t::GetNow, util::NullMutex,

@ -19,7 +19,7 @@ namespace llarp
bool bool
HandleWriteIPPacket(const llarp_buffer_t &, HandleWriteIPPacket(const llarp_buffer_t &,
std::function< huint32_t(void) >) override std::function< huint128_t(void) >) override
{ {
return true; return true;
} }
@ -30,7 +30,13 @@ namespace llarp
return shared_from_this(); return shared_from_this();
} }
huint32_t bool
SupportsV6() const override
{
return false;
}
huint128_t
ObtainIPForAddr(const AlignedBuffer< 32 > &, bool) override ObtainIPForAddr(const AlignedBuffer< 32 > &, bool) override
{ {
return {0}; return {0};

@ -200,13 +200,22 @@ namespace llarp
return false; return false;
} }
auto ip_str = v.substr(pos + 1); auto ip_str = v.substr(pos + 1);
in_addr ip; huint32_t ip;
if(inet_pton(AF_INET, ip_str.c_str(), &ip) != 1) huint128_t ipv6;
if(ip.FromString(ip_str))
{ {
llarp::LogError("cannot map to invalid ip ", ip_str); ipv6 = net::IPPacket::ExpandV4(ip);
}
else if(ipv6.FromString(ip_str))
{
}
else
{
llarp::LogError(Name(), "failed to map ", ip_str,
" failed to parse IP");
return false; return false;
} }
return MapAddress(addr, huint32_t{ntohl(ip.s_addr)}, false); return MapAddress(addr, ipv6, false);
} }
if(k == "ifname") if(k == "ifname")
{ {
@ -222,6 +231,7 @@ namespace llarp
if(k == "ifaddr") if(k == "ifaddr")
{ {
std::string addr; std::string addr;
m_UseV6 = addr.find(":") != std::string::npos;
auto pos = v.find("/"); auto pos = v.find("/");
if(pos != std::string::npos) if(pos != std::string::npos)
{ {
@ -245,8 +255,11 @@ namespace llarp
} }
else else
{ {
tunif.netmask = 32; if(m_UseV6)
addr = v; tunif.netmask = 128;
else
tunif.netmask = 32;
addr = v;
} }
llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ", llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ",
tunif.netmask); tunif.netmask);
@ -257,17 +270,16 @@ namespace llarp
} }
bool bool
TunEndpoint::HasLocalIP(const huint32_t &ip) const TunEndpoint::HasLocalIP(const huint128_t &ip) const
{ {
return m_IPToAddr.find(ip) != m_IPToAddr.end(); return m_IPToAddr.find(ip) != m_IPToAddr.end();
} }
bool bool
TunEndpoint::QueueOutboundTraffic(llarp::net::IPv4Packet &&pkt) TunEndpoint::QueueOutboundTraffic(llarp::net::IPPacket &&pkt)
{ {
return m_NetworkToUserPktQueue.EmplaceIf( return m_NetworkToUserPktQueue.EmplaceIf(
[](llarp::net::IPv4Packet &) -> bool { return true; }, [](llarp::net::IPPacket &) -> bool { return true; }, std::move(pkt));
std::move(pkt));
} }
void void
@ -354,7 +366,8 @@ namespace llarp
else if(msg.questions[0].qtype == dns::qTypeA else if(msg.questions[0].qtype == dns::qTypeA
|| msg.questions[0].qtype == dns::qTypeAAAA) || msg.questions[0].qtype == dns::qTypeAAAA)
{ {
const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA; const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA && SupportsV6();
const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
llarp::service::Address addr; llarp::service::Address addr;
// on MacOS this is a typeA query // on MacOS this is a typeA query
if(is_random_snode(msg)) if(is_random_snode(msg))
@ -371,7 +384,7 @@ namespace llarp
context->ForEachService( context->ForEachService(
[&](const std::string &, [&](const std::string &,
const std::shared_ptr< service::Endpoint > &service) -> bool { const std::shared_ptr< service::Endpoint > &service) -> bool {
huint32_t ip = service->GetIfAddr(); huint128_t ip = service->GetIfAddr();
if(ip.h) if(ip.h)
{ {
msg.AddINReply(ip, isV6); msg.AddINReply(ip, isV6);
@ -384,10 +397,14 @@ namespace llarp
} }
else if(addr.FromString(qname, ".loki")) else if(addr.FromString(qname, ".loki"))
{ {
if(HasAddress(addr)) if(isV4 && SupportsV6())
{ {
huint32_t ip = ObtainIPForAddr(addr, false); msg.AddNXReply();
msg.AddINReply(ip, isV6); }
else if(HasAddress(addr))
{
huint128_t ip = ObtainIPForAddr(addr, false);
msg.AddINReply(ip, isV6);
} }
else else
{ {
@ -397,7 +414,7 @@ namespace llarp
return EnsurePathToService( return EnsurePathToService(
addr, addr,
[=](const Address &, OutboundContext *ctx) { [=](const Address &, OutboundContext *ctx) {
SendDNSReply(addr, ctx, replyMsg, reply, false, isV6); SendDNSReply(addr, ctx, replyMsg, reply, false, isV6 || !isV4);
}, },
2000); 2000);
} }
@ -419,22 +436,24 @@ namespace llarp
else if(msg.questions[0].qtype == dns::qTypePTR) else if(msg.questions[0].qtype == dns::qTypePTR)
{ {
// reverse dns // reverse dns
huint32_t ip = {0}; huint128_t ipv6 = {0};
huint32_t ip = {0};
if(!dns::DecodePTR(msg.questions[0].qname, ip)) if(!dns::DecodePTR(msg.questions[0].qname, ip))
{ {
msg.AddNXReply(); msg.AddNXReply();
reply(msg); reply(msg);
return true; return true;
} }
ipv6 = net::IPPacket::ExpandV4(ip);
llarp::service::Address addr( llarp::service::Address addr(
ObtainAddrForIP< llarp::service::Address >(ip, true)); ObtainAddrForIP< llarp::service::Address >(ipv6, true));
if(!addr.IsZero()) if(!addr.IsZero())
{ {
msg.AddAReply(addr.ToString(".snode")); msg.AddAReply(addr.ToString(".snode"));
reply(msg); reply(msg);
return true; return true;
} }
addr = ObtainAddrForIP< llarp::service::Address >(ip, false); addr = ObtainAddrForIP< llarp::service::Address >(ipv6, false);
if(!addr.IsZero()) if(!addr.IsZero())
{ {
msg.AddAReply(addr.ToString(".loki")); msg.AddAReply(addr.ToString(".loki"));
@ -461,6 +480,12 @@ namespace llarp
m_Exit->ResetInternalState(); m_Exit->ResetInternalState();
} }
bool
TunEndpoint::SupportsV6() const
{
return m_UseV6;
}
// FIXME: pass in which question it should be addressing // FIXME: pass in which question it should be addressing
bool bool
TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const
@ -480,20 +505,19 @@ namespace llarp
huint32_t ip = {0}; huint32_t ip = {0};
if(!dns::DecodePTR(msg.questions[0].qname, ip)) if(!dns::DecodePTR(msg.questions[0].qname, ip))
return false; return false;
return m_OurRange.Contains(ip); return m_OurRange.ContainsV4(ip);
} }
} }
return false; return false;
} }
bool bool
TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip, TunEndpoint::MapAddress(const service::Address &addr, huint128_t ip,
bool SNode) bool SNode)
{ {
auto itr = m_IPToAddr.find(ip); auto itr = m_IPToAddr.find(ip);
if(itr != m_IPToAddr.end()) if(itr != m_IPToAddr.end())
{ {
// XXX is calling inet_ntoa safe in this context? it's MP-unsafe
llarp::LogWarn(ip, " already mapped to ", llarp::LogWarn(ip, " already mapped to ",
service::Address(itr->second.as_array()).ToString()); service::Address(itr->second.as_array()).ToString());
return false; return false;
@ -572,31 +596,44 @@ namespace llarp
*/ */
if(res->ai_family == AF_INET6) if(res->ai_family == AF_INET6)
{ {
llarp::LogError(Name(), m_UseV6 = true;
" failed to set up tun interface, we don't support "
"IPv6 format");
return false;
} }
freeaddrinfo(res);
struct in_addr addr; // network byte order freeaddrinfo(res);
if(inet_aton(tunif.ifaddr, &addr) == 0) if(m_UseV6)
{ {
llarp::LogError(Name(), " failed to set up tun interface, cant parse ", llarp::LogInfo(Name(), " using IPV6");
tunif.ifaddr); }
return false; else
{
struct in_addr addr; // network byte order
if(inet_aton(tunif.ifaddr, &addr) == 0)
{
llarp::LogError(Name(),
" failed to set up tun interface, cant parse ",
tunif.ifaddr);
return false;
}
}
huint32_t ip;
if(ip.FromString(tunif.ifaddr))
{
m_OurIP = net::IPPacket::ExpandV4(ip);
m_OurRange.netmask_bits = netmask_ipv6_bits(tunif.netmask + 96);
}
else if(m_OurIP.FromString(tunif.ifaddr))
{
m_OurRange.netmask_bits = netmask_ipv6_bits(tunif.netmask);
} }
llarp::Addr lAddr(tunif.ifaddr); m_NextIP = m_OurIP;
m_OurRange.addr = m_OurIP;
m_OurIP = lAddr.xtohl(); m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
m_NextIP = m_OurIP; llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ",
m_OurRange.netmask_bits = netmask_ipv4_bits(tunif.netmask); m_OurIP);
m_OurRange.addr = m_OurIP;
m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr);
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ", llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ",
m_OurRange); m_OurRange);
MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode()); MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode());
if(m_OnUp) if(m_OnUp)
{ {
@ -661,20 +698,30 @@ namespace llarp
void void
TunEndpoint::FlushSend() TunEndpoint::FlushSend()
{ {
m_UserToNetworkPktQueue.Process([&](net::IPv4Packet &pkt) { m_UserToNetworkPktQueue.Process([&](net::IPPacket &pkt) {
std::function< bool(const llarp_buffer_t &) > sendFunc; std::function< bool(const llarp_buffer_t &) > sendFunc;
auto itr = m_IPToAddr.find(pkt.dst());
huint128_t dst;
if(pkt.IsV4())
dst = net::IPPacket::ExpandV4(pkt.dstv4());
else
dst = pkt.dstv6();
auto itr = m_IPToAddr.find(dst);
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end())
{ {
if(m_Exit && !llarp::IsIPv4Bogon(pkt.dst())) if(m_Exit && pkt.IsV4() && !llarp::IsIPv4Bogon(pkt.dstv4()))
{ {
pkt.UpdateIPv4PacketOnDst({0}, pkt.dst()); pkt.UpdateV4Address({0}, pkt.dstv4());
m_Exit->QueueUpstreamTraffic(std::move(pkt), m_Exit->QueueUpstreamTraffic(std::move(pkt),
llarp::routing::ExitPadSize); llarp::routing::ExitPadSize);
} }
else else
llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst()); {
return true; llarp::LogWarn(Name(), " has no endpoint for ", dst);
llarp::DumpBuffer(pkt.ConstBuffer());
}
return;
} }
if(m_SNodes.at(itr->second)) if(m_SNodes.at(itr->second))
@ -684,25 +731,26 @@ namespace llarp
} }
else else
{ {
sendFunc = sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this,
std::bind(&TunEndpoint::SendToServiceOrQueue, this, service::Address(itr->second.as_array()),
service::Address(itr->second.as_array()), std::placeholders::_1, pkt.ServiceProtocol());
std::placeholders::_1, service::eProtocolTraffic);
} }
// prepare packet for insertion into network // prepare packet for insertion into network
// this includes clearing IP addresses, recalculating checksums, etc // this includes clearing IP addresses, recalculating checksums, etc
pkt.UpdateIPv4PacketOnSrc(); if(pkt.IsV4())
pkt.UpdateV4Address({0}, {0});
else
pkt.UpdateV6Address({0}, {0});
if(sendFunc && sendFunc(pkt.Buffer())) if(sendFunc && sendFunc(pkt.Buffer()))
return true; return;
llarp::LogWarn(Name(), " did not flush packets"); llarp::LogWarn(Name(), " did not flush packets");
return true;
}); });
} }
bool bool
TunEndpoint::HandleWriteIPPacket(const llarp_buffer_t &b, TunEndpoint::HandleWriteIPPacket(
std::function< huint32_t(void) > getFromIP) const llarp_buffer_t &b, std::function< huint128_t(void) > getFromIP)
{ {
// llarp::LogInfo("got packet from ", msg->sender.Addr()); // llarp::LogInfo("got packet from ", msg->sender.Addr());
auto themIP = getFromIP(); auto themIP = getFromIP();
@ -710,7 +758,7 @@ namespace llarp
auto usIP = m_OurIP; auto usIP = m_OurIP;
ManagedBuffer buf(b); ManagedBuffer buf(b);
return m_NetworkToUserPktQueue.EmplaceIf( return m_NetworkToUserPktQueue.EmplaceIf(
[buf, themIP, usIP](net::IPv4Packet &pkt) -> bool { [buf, themIP, usIP](net::IPPacket &pkt) -> bool {
// load // load
if(!pkt.Load(buf)) if(!pkt.Load(buf))
return false; return false;
@ -720,32 +768,39 @@ namespace llarp
// - packets with weird src/dst addresses // - packets with weird src/dst addresses
// (0.0.0.0/8 but not 0.0.0.0) // (0.0.0.0/8 but not 0.0.0.0)
// - packets with 0 src but non-0 dst and oposite // - packets with 0 src but non-0 dst and oposite
auto hdr = pkt.Header(); if(pkt.IsV4())
if(pkt.sz < sizeof(*hdr) || hdr->version != 4
|| (hdr->saddr != 0 && *(byte_t *)&(hdr->saddr) == 0)
|| (hdr->daddr != 0 && *(byte_t *)&(hdr->daddr) == 0)
|| ((hdr->saddr == 0) != (hdr->daddr == 0)))
{ {
return false; auto hdr = pkt.Header();
if(pkt.sz < sizeof(*hdr)
|| (hdr->saddr != 0 && *(byte_t *)&(hdr->saddr) == 0)
|| (hdr->daddr != 0 && *(byte_t *)&(hdr->daddr) == 0)
|| ((hdr->saddr == 0) != (hdr->daddr == 0)))
{
return false;
}
pkt.UpdateV4Address(net::IPPacket::TruncateV6(themIP), net::IPPacket::TruncateV6(usIP));
}
else if(pkt.IsV6())
{
if(pkt.srcv6() != huint128_t{0} || pkt.dstv6() != huint128_t{0})
return false;
pkt.UpdateV6Address(themIP, usIP);
} }
// update packet to use proper addresses, recalc checksums
pkt.UpdateIPv4PacketOnDst(themIP, usIP);
return true; return true;
}); });
} }
huint32_t huint128_t
TunEndpoint::GetIfAddr() const TunEndpoint::GetIfAddr() const
{ {
return m_OurIP; return m_OurIP;
} }
huint32_t huint128_t
TunEndpoint::ObtainIPForAddr(const AlignedBuffer< 32 > &addr, bool snode) TunEndpoint::ObtainIPForAddr(const AlignedBuffer< 32 > &addr, bool snode)
{ {
llarp_time_t now = Now(); llarp_time_t now = Now();
huint32_t nextIP = {0}; huint128_t nextIP = {0};
AlignedBuffer< 32 > ident(addr); AlignedBuffer< 32 > ident(addr);
{ {
// previously allocated address // previously allocated address
@ -779,7 +834,7 @@ namespace llarp
// we are full // we are full
// expire least active ip // expire least active ip
// TODO: prevent DoS // TODO: prevent DoS
std::pair< huint32_t, llarp_time_t > oldest = {huint32_t{0}, 0}; std::pair< huint128_t, llarp_time_t > oldest = {huint128_t{0}, 0};
// find oldest entry // find oldest entry
auto itr = m_IPActivity.begin(); auto itr = m_IPActivity.begin();
@ -808,19 +863,20 @@ namespace llarp
} }
bool bool
TunEndpoint::HasRemoteForIP(huint32_t ip) const TunEndpoint::HasRemoteForIP(huint128_t ip) const
{ {
return m_IPToAddr.find(ip) != m_IPToAddr.end(); return m_IPToAddr.find(ip) != m_IPToAddr.end();
} }
void void
TunEndpoint::MarkIPActive(huint32_t ip) TunEndpoint::MarkIPActive(huint128_t ip)
{ {
llarp::LogDebug(Name(), " address " , ip, " is active");
m_IPActivity[ip] = std::max(Now(), m_IPActivity[ip]); m_IPActivity[ip] = std::max(Now(), m_IPActivity[ip]);
} }
void void
TunEndpoint::MarkIPActiveForever(huint32_t ip) TunEndpoint::MarkIPActiveForever(huint128_t ip)
{ {
m_IPActivity[ip] = std::numeric_limits< uint64_t >::max(); m_IPActivity[ip] = std::numeric_limits< uint64_t >::max();
} }
@ -844,7 +900,7 @@ namespace llarp
self->m_Exit->FlushDownstream(); self->m_Exit->FlushDownstream();
} }
// flush network to user // flush network to user
self->m_NetworkToUserPktQueue.Process([tun](net::IPv4Packet &pkt) { self->m_NetworkToUserPktQueue.Process([tun](net::IPPacket &pkt) {
if(!llarp_ev_tun_async_write(tun, pkt.Buffer())) if(!llarp_ev_tun_async_write(tun, pkt.Buffer()))
llarp::LogWarn("packet dropped"); llarp::LogWarn("packet dropped");
}); });
@ -857,9 +913,7 @@ namespace llarp
TunEndpoint *self = static_cast< TunEndpoint * >(tun->user); TunEndpoint *self = static_cast< TunEndpoint * >(tun->user);
ManagedBuffer buf(b); ManagedBuffer buf(b);
if(!self->m_UserToNetworkPktQueue.EmplaceIf( if(!self->m_UserToNetworkPktQueue.EmplaceIf(
[buf](net::IPv4Packet &pkt) -> bool { [buf](net::IPPacket &pkt) -> bool { return pkt.Load(buf); }))
return pkt.Load(buf) && pkt.Header()->version == 4;
}))
{ {
#if defined(DEBUG) || !defined(RELEASE_MOTTO) #if defined(DEBUG) || !defined(RELEASE_MOTTO)
llarp::LogInfo("invalid pkt"); llarp::LogInfo("invalid pkt");

@ -46,6 +46,9 @@ namespace llarp
std::unordered_map< std::string, std::string > std::unordered_map< std::string, std::string >
NotifyParams() const override; NotifyParams() const override;
bool
SupportsV6() const override;
bool bool
ShouldHookDNSMessage(const dns::Message& msg) const override; ShouldHookDNSMessage(const dns::Message& msg) const override;
@ -58,7 +61,7 @@ namespace llarp
TickTun(llarp_time_t now); TickTun(llarp_time_t now);
bool bool
MapAddress(const service::Address& remote, huint32_t ip, bool SNode); MapAddress(const service::Address& remote, huint128_t ip, bool SNode);
bool bool
Start() override; Start() override;
@ -81,11 +84,11 @@ namespace llarp
/// handle inbound traffic /// handle inbound traffic
bool bool
HandleWriteIPPacket(const llarp_buffer_t& buf, HandleWriteIPPacket(const llarp_buffer_t& buf,
std::function< huint32_t(void) > getFromIP) override; std::function< huint128_t(void) > getFromIP) override;
/// queue outbound packet to the world /// queue outbound packet to the world
bool bool
QueueOutboundTraffic(llarp::net::IPv4Packet&& pkt); QueueOutboundTraffic(llarp::net::IPPacket&& pkt);
/// we have a resolvable ip address /// we have a resolvable ip address
bool bool
@ -95,11 +98,11 @@ namespace llarp
} }
/// get the local interface's address /// get the local interface's address
huint32_t huint128_t
GetIfAddr() const override; GetIfAddr() const override;
bool bool
HasLocalIP(const huint32_t& ip) const; HasLocalIP(const huint128_t& ip) const;
llarp_tun_io tunif; llarp_tun_io tunif;
std::unique_ptr< llarp_fd_promise > Promise; std::unique_ptr< llarp_fd_promise > Promise;
@ -124,7 +127,7 @@ namespace llarp
/// get a key for ip address /// get a key for ip address
template < typename Addr > template < typename Addr >
Addr Addr
ObtainAddrForIP(huint32_t ip, bool isSNode) ObtainAddrForIP(huint128_t ip, bool isSNode)
{ {
auto itr = m_IPToAddr.find(ip); auto itr = m_IPToAddr.find(ip);
if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode) if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode)
@ -145,7 +148,7 @@ namespace llarp
} }
/// get ip address for key unconditionally /// get ip address for key unconditionally
huint32_t huint128_t
ObtainIPForAddr(const AlignedBuffer< 32 >& addr, ObtainIPForAddr(const AlignedBuffer< 32 >& addr,
bool serviceNode) override; bool serviceNode) override;
@ -158,33 +161,33 @@ namespace llarp
protected: protected:
using PacketQueue_t = llarp::util::CoDelQueue< using PacketQueue_t = llarp::util::CoDelQueue<
net::IPv4Packet, net::IPv4Packet::GetTime, net::IPv4Packet::PutTime, net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime,
net::IPv4Packet::CompareOrder, net::IPv4Packet::GetNow >; net::IPPacket::CompareOrder, net::IPPacket::GetNow >;
/// queue for sending packets over the network from us /// queue for sending packets over the network from us
PacketQueue_t m_UserToNetworkPktQueue; PacketQueue_t m_UserToNetworkPktQueue;
/// queue for sending packets to user from network /// queue for sending packets to user from network
PacketQueue_t m_NetworkToUserPktQueue; PacketQueue_t m_NetworkToUserPktQueue;
/// return true if we have a remote loki address for this ip address /// return true if we have a remote loki address for this ip address
bool bool
HasRemoteForIP(huint32_t ipv4) const; HasRemoteForIP(huint128_t ipv4) const;
/// mark this address as active /// mark this address as active
void void
MarkIPActive(huint32_t ip); MarkIPActive(huint128_t ip);
/// mark this address as active forever /// mark this address as active forever
void void
MarkIPActiveForever(huint32_t ip); MarkIPActiveForever(huint128_t ip);
/// flush ip packets /// flush ip packets
virtual void virtual void
FlushSend(); FlushSend();
/// maps ip to key (host byte order) /// maps ip to key (host byte order)
std::unordered_map< huint32_t, AlignedBuffer< 32 >, huint32_t::Hash > std::unordered_map< huint128_t, AlignedBuffer< 32 >, huint128_t::Hash >
m_IPToAddr; m_IPToAddr;
/// maps key to ip (host byte order) /// maps key to ip (host byte order)
std::unordered_map< AlignedBuffer< 32 >, huint32_t, std::unordered_map< AlignedBuffer< 32 >, huint128_t,
AlignedBuffer< 32 >::Hash > AlignedBuffer< 32 >::Hash >
m_AddrToIP; m_AddrToIP;
@ -199,10 +202,29 @@ namespace llarp
{ {
ManagedBuffer copy{buf}; ManagedBuffer copy{buf};
return m_NetworkToUserPktQueue.EmplaceIf( return m_NetworkToUserPktQueue.EmplaceIf(
[&](llarp::net::IPv4Packet& pkt) -> bool { [&](llarp::net::IPPacket& pkt) -> bool {
if(!pkt.Load(copy.underlying)) if(!pkt.Load(copy.underlying))
return false; return false;
pkt.UpdateIPv4PacketOnDst(pkt.src(), m_OurIP); if(SupportsV6())
{
if(pkt.IsV4())
{
pkt.UpdateV6Address(net::IPPacket::ExpandV4(pkt.srcv4()),
m_OurIP);
}
else
{
pkt.UpdateV6Address(pkt.srcv6(), m_OurIP);
}
}
else
{
if(pkt.IsV4())
pkt.UpdateV4Address(pkt.srcv4(),
net::IPPacket::TruncateV6(m_OurIP));
else
return false;
}
return true; return true;
}); });
} }
@ -215,7 +237,7 @@ namespace llarp
{ {
if(ctx) if(ctx)
{ {
huint32_t ip = ObtainIPForAddr(addr, snode); huint128_t ip = ObtainIPForAddr(addr, snode);
query->AddINReply(ip, sendIPv6); query->AddINReply(ip, sendIPv6);
} }
else else
@ -233,14 +255,14 @@ namespace llarp
std::shared_ptr< dns::Proxy > m_Resolver; std::shared_ptr< dns::Proxy > m_Resolver;
/// maps ip address to timestamp last active /// maps ip address to timestamp last active
std::unordered_map< huint32_t, llarp_time_t, huint32_t::Hash > std::unordered_map< huint128_t, llarp_time_t, huint128_t::Hash >
m_IPActivity; m_IPActivity;
/// our ip address (host byte order) /// our ip address (host byte order)
huint32_t m_OurIP; huint128_t m_OurIP;
/// next ip address to allocate (host byte order) /// next ip address to allocate (host byte order)
huint32_t m_NextIP; huint128_t m_NextIP;
/// highest ip address to allocate (host byte order) /// highest ip address to allocate (host byte order)
huint32_t m_MaxIP; huint128_t m_MaxIP;
/// our ip range we are using /// our ip range we are using
llarp::IPRange m_OurRange; llarp::IPRange m_OurRange;
/// upstream dns resolver list /// upstream dns resolver list
@ -249,6 +271,8 @@ namespace llarp
llarp::Addr m_LocalResolverAddr; llarp::Addr m_LocalResolverAddr;
/// list of strict connect addresses for hooks /// list of strict connect addresses for hooks
std::vector< llarp::Addr > m_StrictConnectAddrs; std::vector< llarp::Addr > m_StrictConnectAddrs;
/// use v6?
bool m_UseV6;
}; };
} // namespace handlers } // namespace handlers
} // namespace llarp } // namespace llarp

@ -15,8 +15,61 @@ namespace llarp
{ {
namespace net namespace net
{ {
huint128_t
IPPacket::In6ToHUInt(in6_addr addr)
{
#if __BYTE_ORDER == __BIG_ENDIAN
return huint128_t{addr.s6_addr32[0]}
| (huint128_t{addr.s6_addr32[1]} << 32)
| (huint128_t{addr.s6_addr32[2]} << 64)
| (huint128_t{addr.s6_addr32[3]} << 96);
#else
return huint128_t{ntohl(addr.s6_addr32[3])}
| (huint128_t{ntohl(addr.s6_addr32[2])} << 32)
| (huint128_t{ntohl(addr.s6_addr32[1])} << 64)
| (huint128_t{ntohl(addr.s6_addr32[0])} << 96);
#endif
}
in6_addr
IPPacket::HUIntToIn6(huint128_t x)
{
in6_addr addr;
auto i = ntoh128(x.h);
memcpy(&addr, &i, 16);
return addr;
}
huint128_t
IPPacket::ExpandV4(huint32_t i)
{
huint128_t ff = {0xff};
huint128_t expanded{i.h};
return (ff << 40) | (ff << 32) | expanded;
}
huint32_t
IPPacket::TruncateV6(huint128_t i)
{
huint32_t ret = {0};
ret.h = (uint32_t)(i.h & (0x00000000ffffffffUL));
return ret;
}
huint128_t
IPPacket::srcv6() const
{
return In6ToHUInt(HeaderV6()->srcaddr);
}
huint128_t
IPPacket::dstv6() const
{
return In6ToHUInt(HeaderV6()->dstaddr);
}
bool bool
IPv4Packet::Load(const llarp_buffer_t &pkt) IPPacket::Load(const llarp_buffer_t &pkt)
{ {
if(pkt.sz > sizeof(buf)) if(pkt.sz > sizeof(buf))
return false; return false;
@ -26,17 +79,37 @@ namespace llarp
} }
llarp_buffer_t llarp_buffer_t
IPv4Packet::ConstBuffer() const IPPacket::ConstBuffer() const
{ {
return {buf, sz}; return {buf, sz};
} }
llarp_buffer_t llarp_buffer_t
IPv4Packet::Buffer() IPPacket::Buffer()
{ {
return {buf, sz}; return {buf, sz};
} }
huint32_t
IPPacket::srcv4() const
{
return huint32_t{ntohl(Header()->saddr)};
}
huint32_t
IPPacket::dstv4() const
{
return huint32_t{ntohl(Header()->daddr)};
}
void
IPPacket::UpdateV6Address(huint128_t src, huint128_t dst)
{
auto hdr = HeaderV6();
hdr->srcaddr = HUIntToIn6(src);
hdr->dstaddr = HUIntToIn6(dst);
}
#if 0 #if 0
static uint32_t static uint32_t
ipchksum_pseudoIPv4(nuint32_t src_ip, nuint32_t dst_ip, uint8_t proto, ipchksum_pseudoIPv4(nuint32_t src_ip, nuint32_t dst_ip, uint8_t proto,
@ -140,8 +213,9 @@ namespace llarp
} }
void void
IPv4Packet::UpdateIPv4PacketOnDst(huint32_t newSrcIP, huint32_t newDstIP) IPPacket::UpdateV4Address(huint32_t newSrcIP, huint32_t newDstIP)
{ {
llarp::LogDebug("set src=", newSrcIP, " dst=", newDstIP);
auto hdr = Header(); auto hdr = Header();
auto oSrcIP = nuint32_t{hdr->saddr}; auto oSrcIP = nuint32_t{hdr->saddr};
@ -227,9 +301,9 @@ namespace llarp
// if(check->n == 0x0000) // if(check->n == 0x0000)
// check->n = 0xFFff; // check->n = 0xFFff;
} }
/*
void void
IPv4Packet::UpdateIPv4PacketOnSrc() IPacket::UpdateIPv4PacketOnSrc()
{ {
auto hdr = Header(); auto hdr = Header();
@ -269,5 +343,6 @@ namespace llarp
hdr->saddr = 0; hdr->saddr = 0;
hdr->daddr = 0; hdr->daddr = 0;
} }
*/
} // namespace net } // namespace net
} // namespace llarp } // namespace llarp

@ -74,7 +74,17 @@ typedef struct ip_hdr
#endif #endif
struct ipv6_header
{
unsigned char version : 4;
unsigned char pad_small : 4;
uint8_t pad [7];
in6_addr srcaddr;
in6_addr dstaddr;
};
#include <memory> #include <memory>
#include <service/protocol.hpp>
struct llarp_ev_loop; struct llarp_ev_loop;
@ -82,28 +92,21 @@ namespace llarp
{ {
namespace net namespace net
{ {
/// a network layer packet /// an Packet
struct NetPacket struct IPPacket
{ {
virtual ~NetPacket(){}; static huint128_t
In6ToHUInt(in6_addr addr);
virtual byte_t static in6_addr
Version() const = 0; HUIntToIn6(huint128_t x);
virtual byte_t static huint128_t
IPProto() const = 0; ExpandV4(huint32_t x);
virtual llarp_buffer_t static huint32_t
Buffer() = 0; TruncateV6(huint128_t x);
virtual llarp_buffer_t
ConstBuffer() const = 0;
};
/// an IPv4 Packet
/// TODO: make it implement NetPacket
struct IPv4Packet
{
static constexpr size_t MaxSize = 1500; static constexpr size_t MaxSize = 1500;
llarp_time_t timestamp; llarp_time_t timestamp;
size_t sz; size_t sz;
@ -121,7 +124,7 @@ namespace llarp
struct GetTime struct GetTime
{ {
llarp_time_t llarp_time_t
operator()(const IPv4Packet& pkt) const operator()(const IPPacket& pkt) const
{ {
return pkt.timestamp; return pkt.timestamp;
} }
@ -134,7 +137,7 @@ namespace llarp
{ {
} }
void void
operator()(IPv4Packet& pkt) const operator()(IPPacket& pkt) const
{ {
pkt.timestamp = llarp_ev_loop_time_now_ms(loop); pkt.timestamp = llarp_ev_loop_time_now_ms(loop);
} }
@ -156,7 +159,7 @@ namespace llarp
struct CompareSize struct CompareSize
{ {
bool bool
operator()(const IPv4Packet& left, const IPv4Packet& right) operator()(const IPPacket& left, const IPPacket& right)
{ {
return left.sz < right.sz; return left.sz < right.sz;
} }
@ -165,7 +168,7 @@ namespace llarp
struct CompareOrder struct CompareOrder
{ {
bool bool
operator()(const IPv4Packet& left, const IPv4Packet& right) operator()(const IPPacket& left, const IPPacket& right)
{ {
return left.timestamp < right.timestamp; return left.timestamp < right.timestamp;
} }
@ -183,37 +186,70 @@ namespace llarp
return (ip_header*)&buf[0]; return (ip_header*)&buf[0];
} }
inline huint32_t inline ipv6_header*
src() HeaderV6()
{
return (ipv6_header*)&buf[0];
}
inline const ipv6_header*
HeaderV6() const
{ {
return huint32_t{ntohl(Header()->saddr)}; return (ipv6_header*)&buf[0];
} }
inline huint32_t inline int
dst() Version() const
{ {
return huint32_t{ntohl(Header()->daddr)}; return Header()->version;
} }
inline void inline bool
src(huint32_t ip) IsV4() const
{ {
Header()->saddr = htonl(ip.h); return Version() == 4;
} }
inline void inline bool
dst(huint32_t ip) IsV6() const
{ {
Header()->daddr = htonl(ip.h); return Version() == 6;
} }
// update ip packet (after packet gets out of network) inline service::ProtocolType
ServiceProtocol() const
{
if(IsV4())
return service::eProtocolTrafficV4;
else if(IsV6())
return service::eProtocolTrafficV6;
else
return service::eProtocolControl;
}
huint128_t
srcv6() const;
huint128_t
dstv6() const;
huint32_t
srcv4() const;
huint32_t
dstv4() const;
huint128_t
src4to6() const;
huint128_t
dst4to6() const;
void void
UpdateIPv4PacketOnDst(huint32_t newSrcIP, huint32_t newDstIP); UpdateV4Address(huint32_t src, huint32_t dst);
// update ip packet (before packet gets inserted into network)
void void
UpdateIPv4PacketOnSrc(); UpdateV6Address(huint128_t src, huint128_t dst);
}; };
} // namespace net } // namespace net

@ -13,6 +13,7 @@
#endif #endif
#include <net/net_addr.hpp> #include <net/net_addr.hpp>
#include <net/ip.hpp>
#include <util/logger.hpp> #include <util/logger.hpp>
#include <util/str.hpp> #include <util/str.hpp>
@ -1010,6 +1011,37 @@ namespace llarp
return IsBogon(host); return IsBogon(host);
} }
bool
IPRange::ContainsV4(const huint32_t& ip) const
{
return Contains(net::IPPacket::ExpandV4(ip));
}
std::string
IPRange::ToString() const
{
char buf[INET6_ADDRSTRLEN + 1] = {0};
std::string str;
in6_addr inaddr;
size_t numset = 0;
absl::uint128 bits = netmask_bits.h;
while(bits)
{
if(bits & 1)
numset++;
bits >>= 1;
}
str += inet_ntop(AF_INET6, &inaddr, buf, sizeof(buf));
return str + "/" + std::to_string(numset);
}
IPRange
iprange_ipv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask)
{
return IPRange{net::IPPacket::ExpandV4(ipaddr_ipv4_bits(a, b, c, d)),
netmask_ipv6_bits(mask + 96)};
}
bool bool
IsIPv4Bogon(const huint32_t& addr) IsIPv4Bogon(const huint32_t& addr)
{ {
@ -1024,7 +1056,7 @@ namespace llarp
iprange_ipv4(224, 0, 0, 0, 4), iprange_ipv4(240, 0, 0, 0, 4)}; iprange_ipv4(224, 0, 0, 0, 4), iprange_ipv4(240, 0, 0, 0, 4)};
for(const auto& bogon : bogonRanges) for(const auto& bogon : bogonRanges)
{ {
if(bogon.Contains(addr)) if(bogon.ContainsV4(addr))
{ {
#if defined(TESTNET) #if defined(TESTNET)
return false; return false;

@ -1,6 +1,7 @@
#ifndef LLARP_NET_HPP #ifndef LLARP_NET_HPP
#define LLARP_NET_HPP #define LLARP_NET_HPP
#include <absl/numeric/int128.h>
#include <net/address_info.hpp> #include <net/address_info.hpp>
#include <net/net_int.hpp> #include <net/net_int.hpp>
#include <net/net.h> #include <net/net.h>
@ -59,16 +60,19 @@ namespace llarp
{ {
struct IPRange struct IPRange
{ {
huint32_t addr; huint128_t addr;
huint32_t netmask_bits; huint128_t netmask_bits;
/// return true if ip is contained in this ip range /// return true if ip is contained in this ip range
bool bool
Contains(const huint32_t& ip) const Contains(const huint128_t& ip) const
{ {
return (addr & netmask_bits) == (ip & netmask_bits); return (addr & netmask_bits) == (ip & netmask_bits);
} }
bool
ContainsV4(const huint32_t& ip) const;
friend std::ostream& friend std::ostream&
operator<<(std::ostream& out, const IPRange& a) operator<<(std::ostream& out, const IPRange& a)
{ {
@ -76,13 +80,27 @@ namespace llarp
} }
std::string std::string
ToString() const ToString() const;
{
return addr.ToString() + "/"
+ std::to_string(llarp::bits::count_bits(netmask_bits.h));
}
}; };
huint128_t
ExpandV4(huint32_t x);
/// get a netmask with the higest numset bits set
constexpr huint128_t
__netmask_ipv6_bits(uint32_t numset)
{
return (128 - numset)
? (huint128_t{1} << numset) | __netmask_ipv6_bits(numset + 1)
: huint128_t{0};
}
constexpr huint128_t
netmask_ipv6_bits(uint32_t numset)
{
return __netmask_ipv6_bits(128 - numset);
}
/// get a netmask with the higest numset bits set /// get a netmask with the higest numset bits set
constexpr uint32_t constexpr uint32_t
__netmask_ipv4_bits(uint32_t numset) __netmask_ipv4_bits(uint32_t numset)
@ -90,7 +108,7 @@ namespace llarp
return (32 - numset) ? (1 << numset) | __netmask_ipv4_bits(numset + 1) : 0; return (32 - numset) ? (1 << numset) | __netmask_ipv4_bits(numset + 1) : 0;
} }
/// get an ipv4 netmask given some /N range /// get a netmask given some /N range
constexpr huint32_t constexpr huint32_t
netmask_ipv4_bits(uint32_t num) netmask_ipv4_bits(uint32_t num)
{ {
@ -107,11 +125,8 @@ namespace llarp
#endif #endif
} }
constexpr IPRange IPRange
iprange_ipv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask) iprange_ipv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask);
{
return IPRange{ipaddr_ipv4_bits(a, b, c, d), netmask_ipv4_bits(mask)};
}
bool bool
IsIPv4Bogon(const huint32_t& addr); IsIPv4Bogon(const huint32_t& addr);

@ -1,5 +1,5 @@
#include <net/net_int.hpp> #include <net/net_int.hpp>
#include <net/ip.hpp>
#include <string> #include <string>
namespace llarp namespace llarp
@ -15,6 +15,15 @@ namespace llarp
c[10] = 0xff; c[10] = 0xff;
} }
template <>
void
huint128_t::ToV6(V6Container& c)
{
c.resize(16);
const in6_addr addr = net::IPPacket::HUIntToIn6(*this);
std::copy_n(addr.s6_addr, 16, c.begin());
}
template <> template <>
std::string std::string
huint32_t::ToString() const huint32_t::ToString() const
@ -25,6 +34,40 @@ namespace llarp
return ""; return "";
return tmp; return tmp;
} }
template <>
std::string
huint128_t::ToString() const
{
absl::uint128 addr = ntoh128(h);
char tmp[INET6_ADDRSTRLEN] = {0};
if(!inet_ntop(AF_INET6, (void*)&addr, tmp, sizeof(tmp)))
return "";
return tmp;
}
template <>
bool
huint32_t::FromString(const std::string& str)
{
uint32_t n;
if(!inet_pton(AF_INET, str.c_str(), &n))
return false;
h = ntohl(n);
return true;
}
template <>
bool
huint128_t::FromString(const std::string& str)
{
absl::uint128 i;
if(!inet_pton(AF_INET6, str.c_str(), &i))
return false;
h = ntoh128(i);
return true;
}
template <> template <>
std::string std::string
nuint32_t::ToString() const nuint32_t::ToString() const

@ -19,6 +19,9 @@
#include <util/endian.hpp> #include <util/endian.hpp>
#include <vector> #include <vector>
#include <absl/numeric/int128.h>
#include <absl/hash/hash.h>
namespace llarp namespace llarp
{ {
template < typename UInt_t > template < typename UInt_t >
@ -28,25 +31,33 @@ namespace llarp
constexpr huint_t operator&(huint_t x) const constexpr huint_t operator&(huint_t x) const
{ {
return huint_t{UInt_t(h & x.h)}; return huint_t{UInt_t{h & x.h}};
} }
constexpr huint_t constexpr huint_t
operator|(huint_t x) const operator|(huint_t x) const
{ {
return huint_t{UInt_t(h | x.h)}; return huint_t{UInt_t{h | x.h}};
} }
constexpr huint_t constexpr huint_t
operator^(huint_t x) const operator^(huint_t x) const
{ {
return huint_t{UInt_t(h ^ x.h)}; return huint_t{UInt_t{h ^ x.h}};
} }
constexpr huint_t constexpr huint_t
operator~() const operator~() const
{ {
return huint_t{UInt_t(~h)}; return huint_t{UInt_t{~h}};
}
constexpr huint_t
operator<<(int n) const
{
UInt_t v{h};
v <<= n;
return huint_t{v};
} }
inline huint_t inline huint_t
@ -69,20 +80,26 @@ namespace llarp
return h < x.h; return h < x.h;
} }
constexpr bool
operator!=(huint_t x) const
{
return h != x.h;
}
constexpr bool constexpr bool
operator==(huint_t x) const operator==(huint_t x) const
{ {
return h == x.h; return h == x.h;
} }
struct Hash using Hash = absl::Hash< huint_t< UInt_t > >;
template < typename H >
friend H
AbslHashValue(H h, const huint_t< UInt_t >& i)
{ {
inline size_t return H::combine(std::move(h), i.h);
operator()(huint_t x) const }
{
return std::hash< UInt_t >{}(x.h);
}
};
using V6Container = std::vector< uint8_t >; using V6Container = std::vector< uint8_t >;
void void
@ -91,6 +108,9 @@ namespace llarp
std::string std::string
ToString() const; ToString() const;
bool
FromString(const std::string&);
friend std::ostream& friend std::ostream&
operator<<(std::ostream& out, const huint_t& i) operator<<(std::ostream& out, const huint_t& i)
{ {
@ -98,8 +118,9 @@ namespace llarp
} }
}; };
using huint32_t = huint_t< uint32_t >; using huint32_t = huint_t< uint32_t >;
using huint16_t = huint_t< uint16_t >; using huint16_t = huint_t< uint16_t >;
using huint128_t = huint_t< absl::uint128 >;
template < typename UInt_t > template < typename UInt_t >
struct nuint_t struct nuint_t
@ -177,8 +198,9 @@ namespace llarp
} }
}; };
using nuint32_t = nuint_t< uint32_t >; using nuint32_t = nuint_t< uint32_t >;
using nuint16_t = nuint_t< uint16_t >; using nuint16_t = nuint_t< uint16_t >;
using nuint128_t = nuint_t< absl::uint128 >;
static inline nuint32_t static inline nuint32_t
xhtonl(huint32_t x) xhtonl(huint32_t x)

@ -14,7 +14,8 @@ namespace llarp
const Identity& localident, const Identity& localident,
const PQPubKey& introsetPubKey, const PQPubKey& introsetPubKey,
const Introduction& remote, const Introduction& remote,
IDataHandler* h, const ConvoTag& t) IDataHandler* h, const ConvoTag& t,
ProtocolType proto)
: logic(l) : logic(l)
, remote(r) , remote(r)
, m_LocalIdentity(localident) , m_LocalIdentity(localident)
@ -23,6 +24,7 @@ namespace llarp
, handler(h) , handler(h)
, tag(t) , tag(t)
{ {
msg.proto = proto;
} }
void void
@ -69,8 +71,6 @@ namespace llarp
self->msg.sender = self->m_LocalIdentity.pub; self->msg.sender = self->m_LocalIdentity.pub;
// set version // set version
self->msg.version = LLARP_PROTO_VERSION; self->msg.version = LLARP_PROTO_VERSION;
// set protocol
self->msg.proto = eProtocolTraffic;
// encrypt and sign // encrypt and sign
if(self->frame.EncryptAndSign(self->msg, K, self->m_LocalIdentity)) if(self->frame.EncryptAndSign(self->msg, K, self->m_LocalIdentity))
self->logic->queue_job({self, &Result}); self->logic->queue_job({self, &Result});

@ -30,7 +30,7 @@ namespace llarp
const Identity& localident, const Identity& localident,
const PQPubKey& introsetPubKey, const PQPubKey& introsetPubKey,
const Introduction& remote, IDataHandler* h, const Introduction& remote, IDataHandler* h,
const ConvoTag& t); const ConvoTag& t, ProtocolType proto);
static void static void
Result(void* user); Result(void* user);

@ -154,7 +154,7 @@ namespace llarp
bool bool
Context::FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode, Context::FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode,
huint32_t &ip) huint128_t &ip)
{ {
auto itr = m_Endpoints.begin(); auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end()) while(itr != m_Endpoints.end())

@ -33,7 +33,7 @@ namespace llarp
bool bool
FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode, FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode,
huint32_t &); huint128_t &);
/// function visitor returns false to prematurely break iteration /// function visitor returns false to prematurely break iteration
void void

@ -856,7 +856,7 @@ namespace llarp
bool bool
Endpoint::ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg) Endpoint::ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg)
{ {
if(msg->proto == eProtocolTraffic) if(msg->proto == eProtocolTrafficV4 || msg->proto == eProtocolTrafficV6)
{ {
util::Lock l(&m_InboundTrafficQueueMutex); util::Lock l(&m_InboundTrafficQueueMutex);
m_InboundTrafficQueue.emplace(msg); m_InboundTrafficQueue.emplace(msg);
@ -1009,7 +1009,7 @@ namespace llarp
auto session = std::make_shared< exit::SNodeSession >( auto session = std::make_shared< exit::SNodeSession >(
snode, snode,
std::bind(&Endpoint::HandleWriteIPPacket, this, _1, std::bind(&Endpoint::HandleWriteIPPacket, this, _1,
[themIP]() -> huint32_t { return themIP; }), [themIP]() -> huint128_t { return themIP; }),
m_Router, m_NumPaths, numHops, false, ShouldBundleRC()); m_Router, m_NumPaths, numHops, false, ShouldBundleRC());
m_SNodeSessions.emplace(snode, session); m_SNodeSessions.emplace(snode, session);
} }
@ -1033,7 +1033,7 @@ namespace llarp
Endpoint::SendToSNodeOrQueue(const RouterID& addr, Endpoint::SendToSNodeOrQueue(const RouterID& addr,
const llarp_buffer_t& buf) const llarp_buffer_t& buf)
{ {
auto pkt = std::make_shared< net::IPv4Packet >(); auto pkt = std::make_shared< net::IPPacket >();
if(!pkt->Load(buf)) if(!pkt->Load(buf))
return false; return false;
EnsurePathToSNode(addr, [pkt](RouterID, exit::BaseSession_ptr s) { EnsurePathToSNode(addr, [pkt](RouterID, exit::BaseSession_ptr s) {
@ -1055,7 +1055,7 @@ namespace llarp
{ {
const auto& msg = m_InboundTrafficQueue.top(); const auto& msg = m_InboundTrafficQueue.top();
llarp_buffer_t buf(msg->payload); llarp_buffer_t buf(msg->payload);
HandleWriteIPPacket(buf, [&]() -> huint32_t { HandleWriteIPPacket(buf, [&]() -> huint128_t {
return ObtainIPForAddr(msg->sender.Addr(), false); return ObtainIPForAddr(msg->sender.Addr(), false);
}); });
m_InboundTrafficQueue.pop(); m_InboundTrafficQueue.pop();

@ -81,10 +81,10 @@ namespace llarp
} }
/// get our ifaddr if it is set /// get our ifaddr if it is set
virtual huint32_t virtual huint128_t
GetIfAddr() const GetIfAddr() const
{ {
return huint32_t{0}; return huint128_t{0};
} }
virtual void virtual void
@ -151,7 +151,7 @@ namespace llarp
HandleHiddenServiceFrame(path::Path_ptr p, HandleHiddenServiceFrame(path::Path_ptr p,
const service::ProtocolFrame& msg); const service::ProtocolFrame& msg);
virtual huint32_t virtual huint128_t
ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode) = 0; ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode) = 0;
virtual bool virtual bool
@ -173,7 +173,7 @@ namespace llarp
virtual bool virtual bool
HandleWriteIPPacket(const llarp_buffer_t& pkt, HandleWriteIPPacket(const llarp_buffer_t& pkt,
std::function< huint32_t(void) > getFromIP) = 0; std::function< huint128_t(void) > getFromIP) = 0;
bool bool
ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg); ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg);
@ -313,6 +313,9 @@ namespace llarp
/// parent context that owns this endpoint /// parent context that owns this endpoint
Context* const context; Context* const context;
virtual bool
SupportsV6() const = 0;
void void
RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false); RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false);

@ -160,13 +160,12 @@ namespace llarp
currentConvoTag.Randomize(); currentConvoTag.Randomize();
AsyncKeyExchange* ex = new AsyncKeyExchange( AsyncKeyExchange* ex = new AsyncKeyExchange(
m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(), m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(),
currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag); currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag, t);
ex->hook = ex->hook =
std::bind(&OutboundContext::Send, this, std::placeholders::_1, path); std::bind(&OutboundContext::Send, this, std::placeholders::_1, path);
ex->msg.PutBuffer(payload); ex->msg.PutBuffer(payload);
ex->msg.proto = t;
ex->msg.introReply = path->intro; ex->msg.introReply = path->intro;
ex->frame.F = ex->msg.introReply.pathID; ex->frame.F = ex->msg.introReply.pathID;
llarp_threadpool_queue_job(m_Endpoint->CryptoWorker(), llarp_threadpool_queue_job(m_Endpoint->CryptoWorker(),

@ -33,8 +33,9 @@ namespace llarp
using ProtocolType = uint64_t; using ProtocolType = uint64_t;
constexpr ProtocolType eProtocolControl = 0UL; constexpr ProtocolType eProtocolControl = 0UL;
constexpr ProtocolType eProtocolTraffic = 1UL; constexpr ProtocolType eProtocolTrafficV4 = 1UL;
constexpr ProtocolType eProtocolTrafficV6 = 2UL;
/// inner message /// inner message
struct ProtocolMessage struct ProtocolMessage
@ -42,7 +43,7 @@ namespace llarp
ProtocolMessage(const ConvoTag& tag); ProtocolMessage(const ConvoTag& tag);
ProtocolMessage(); ProtocolMessage();
~ProtocolMessage(); ~ProtocolMessage();
ProtocolType proto = eProtocolTraffic; ProtocolType proto = eProtocolTrafficV4;
llarp_time_t queued = 0; llarp_time_t queued = 0;
std::vector< byte_t > payload; std::vector< byte_t > payload;
Introduction introReply; Introduction introReply;

@ -6,6 +6,7 @@
#include <numeric> #include <numeric>
#include <type_traits> #include <type_traits>
#include <limits> #include <limits>
#include <absl/numeric/int128.h>
namespace llarp namespace llarp
{ {

@ -5,6 +5,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#include <absl/numeric/int128.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/endian.h> #include <sys/endian.h>
@ -189,4 +190,19 @@ htole64buf(void *buf, uint64_t big64)
htobuf64(buf, htole64(big64)); htobuf64(buf, htole64(big64));
} }
inline absl::uint128
ntoh128(absl::uint128 i)
{
#if __BYTE_ORDER == __BIG_ENDIAN
return i;
#else
uint64_t *ptr = (uint64_t *)&i;
absl::uint128 ret;
uint64_t *retptr = (uint64_t *)&ret;
htobe64buf(retptr, ptr[1]);
htobe64buf(retptr + 1, ptr[0]);
return ret;
#endif
}
#endif #endif

@ -2,27 +2,63 @@
#include <net/net.hpp> #include <net/net.hpp>
#include <net/net_inaddr.hpp> #include <net/net_inaddr.hpp>
#include <net/net_int.hpp>
#include <net/ip.hpp>
struct TestNet : public ::testing::Test struct TestNet : public ::testing::Test
{ {
}; };
TEST_F(TestNet, TestIn6AddrFromString)
{
llarp::huint128_t ip;
ASSERT_TRUE(ip.FromString("fc00::1"));
}
TEST_F(TestNet, TestIn6AddrFromStringFail)
{
llarp::huint128_t ip;
ASSERT_FALSE(ip.FromString("10.1.1.1"));
}
TEST_F(TestNet, TestIn6AddrToHUIntLoopback)
{
llarp::huint128_t loopback = {0};
ASSERT_TRUE(loopback.FromString("::1"));
in6_addr addr = IN6ADDR_LOOPBACK_INIT;
auto huint = llarp::net::IPPacket::In6ToHUInt(addr);
ASSERT_EQ(huint, loopback);
}
TEST_F(TestNet, TestIn6AddrToHUInt)
{
llarp::huint128_t huint_parsed = {0};
ASSERT_TRUE(huint_parsed.FromString("fd00::1"));
in6_addr addr = { { { 0xfd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
auto huint = llarp::net::IPPacket::In6ToHUInt(addr);
ASSERT_EQ(huint, huint_parsed);
huint_parsed.h ++;
ASSERT_NE(huint, huint_parsed);
}
TEST_F(TestNet, TestRangeContains8) TEST_F(TestNet, TestRangeContains8)
{ {
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 1, 8) ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 1, 8)
.Contains(llarp::ipaddr_ipv4_bits(10, 40, 11, 6))); .ContainsV4(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
} }
TEST_F(TestNet, TestRangeContains24) TEST_F(TestNet, TestRangeContains24)
{ {
ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24) ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253))); .ContainsV4(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
} }
TEST_F(TestNet, TestRangeContainsFail) TEST_F(TestNet, TestRangeContainsFail)
{ {
ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24) ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253))); .ContainsV4(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
} }
TEST_F(TestNet, TestIPv4Netmask) TEST_F(TestNet, TestIPv4Netmask)

@ -188,14 +188,50 @@ tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s4, uint32_t bits)
return 0; return 0;
} }
struct in6_ifreq {
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
unsigned int ifr6_ifindex;
};
int int
tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s6, uint32_t bits) tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s6, uint32_t bits)
{ {
(void)dev; struct ifreq ifr;
(void)s6; struct sockaddr_in6 sai;
(void)bits; int sockfd;
tuntap_log(TUNTAP_LOG_NOTICE, "IPv6 is not implemented on your system"); struct in6_ifreq ifr6;
return -1;
sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
if (sockfd == -1) {
return -1;
}
/* get interface name */
strncpy(ifr.ifr_name, dev->if_name, IFNAMSIZ);
memset(&sai, 0, sizeof(struct sockaddr));
sai.sin6_family = AF_INET6;
sai.sin6_port = 0;
memcpy((char *) &ifr6.ifr6_addr, (char *) s6,
sizeof(struct in6_addr));
if (ioctl(sockfd, SIOGIFINDEX, &ifr) < 0) {
perror("SIOGIFINDEX");
close(sockfd);
return -1;
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = bits;
if (ioctl(sockfd, SIOCSIFADDR, &ifr6) < 0) {
perror("SIOCSIFADDR");
close(sockfd);
return -1;
}
close(sockfd);
return 0;
} }
int int

@ -161,7 +161,7 @@ extern "C"
llarp::LogError("invalid ipv6 address: ", addr); llarp::LogError("invalid ipv6 address: ", addr);
return -1; return -1;
} }
return tuntap_sys_set_ipv6(dev, &baddr6, mask); return tuntap_sys_set_ipv6(dev, &baddr6, netmask);
} }
else if(errval == -1) else if(errval == -1)
{ {

Loading…
Cancel
Save