mirror of https://github.com/oxen-io/lokinet
ipv6
This commit is contained in:
parent
32d73199e6
commit
2403ab8f86
|
@ -65,9 +65,11 @@ set(LIB_PLATFORM_SRC
|
|||
ev/pipe.cpp
|
||||
metrics/metrictank_publisher.cpp
|
||||
metrics/publishers.cpp
|
||||
net/ip.cpp
|
||||
net/net.cpp
|
||||
net/net_addr.cpp
|
||||
net/net_inaddr.cpp
|
||||
net/net_int.cpp
|
||||
# for android shim
|
||||
${ANDROID_PLATFORM_SRC}
|
||||
# process isolation implementation
|
||||
|
@ -194,8 +196,6 @@ set(LIB_SRC
|
|||
messages/transfer_traffic.cpp
|
||||
net/address_info.cpp
|
||||
net/exit_info.cpp
|
||||
net/ip.cpp
|
||||
net/net_int.cpp
|
||||
nodedb.cpp
|
||||
path/path.cpp
|
||||
path/path_types.cpp
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <util/endian.hpp>
|
||||
#include <util/logger.hpp>
|
||||
#include <util/printer.hpp>
|
||||
#include <net/ip.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
|
@ -165,7 +166,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
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())
|
||||
{
|
||||
|
@ -182,9 +183,10 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
rec.rr_type = qTypeA;
|
||||
const auto addr = net::IPPacket::TruncateV6(ip);
|
||||
rec.rr_type = qTypeA;
|
||||
rec.rData.resize(4);
|
||||
htobe32buf(rec.rData.data(), ip.h);
|
||||
htobe32buf(rec.rData.data(), addr.h);
|
||||
}
|
||||
answers.emplace_back(std::move(rec));
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace llarp
|
|||
AddCNAMEReply(std::string name, RR_TTL_t ttl = 1);
|
||||
|
||||
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
|
||||
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();
|
||||
return dev->add_ev(); // start up tun and add to event queue
|
||||
}
|
||||
#endif
|
||||
llarp::LogWarn("Loop could not create tun");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -613,6 +613,7 @@ namespace libuv
|
|||
m_CloseFuncs.emplace_back(std::bind(&tun_glue ::Close, glue));
|
||||
return true;
|
||||
}
|
||||
|
||||
delete glue;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace llarp
|
|||
{
|
||||
Endpoint::Endpoint(const llarp::PubKey& remoteIdent,
|
||||
const llarp::PathID_t& beginPath, bool rewriteIP,
|
||||
huint32_t ip, llarp::handlers::ExitEndpoint* parent)
|
||||
huint128_t ip, llarp::handlers::ExitEndpoint* parent)
|
||||
: createdAt(parent->Now())
|
||||
, m_Parent(parent)
|
||||
, m_remoteSignKey(remoteIdent)
|
||||
|
@ -108,16 +108,16 @@ namespace llarp
|
|||
if(m_UpstreamQueue.size() > MaxUpstreamQueueSize)
|
||||
return false;
|
||||
|
||||
llarp::net::IPv4Packet pkt;
|
||||
llarp::net::IPPacket pkt;
|
||||
if(!pkt.Load(buf.underlying))
|
||||
return false;
|
||||
|
||||
huint32_t dst;
|
||||
if(m_RewriteSource)
|
||||
dst = m_Parent->GetIfAddr();
|
||||
dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr());
|
||||
else
|
||||
dst = pkt.dst();
|
||||
pkt.UpdateIPv4PacketOnDst(m_IP, dst);
|
||||
dst = pkt.dstv4();
|
||||
pkt.UpdateV4Address(net::IPPacket::TruncateV6(m_IP), dst);
|
||||
m_UpstreamQueue.emplace(pkt, counter);
|
||||
m_TxRate += buf.underlying.sz;
|
||||
m_LastActive = m_Parent->Now();
|
||||
|
@ -127,16 +127,16 @@ namespace llarp
|
|||
bool
|
||||
Endpoint::QueueInboundTraffic(ManagedBuffer buf)
|
||||
{
|
||||
llarp::net::IPv4Packet pkt;
|
||||
llarp::net::IPPacket pkt;
|
||||
if(!pkt.Load(buf.underlying))
|
||||
return false;
|
||||
|
||||
huint32_t src;
|
||||
huint128_t src;
|
||||
if(m_RewriteSource)
|
||||
src = m_Parent->GetIfAddr();
|
||||
else
|
||||
src = pkt.src();
|
||||
pkt.UpdateIPv4PacketOnDst(src, m_IP);
|
||||
src = pkt.srcv6();
|
||||
pkt.UpdateV6Address(src, m_IP);
|
||||
const llarp_buffer_t& pktbuf = pkt.Buffer(); // life time extension
|
||||
const uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize;
|
||||
if(m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace llarp
|
|||
static constexpr size_t MaxUpstreamQueueSize = 256;
|
||||
|
||||
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);
|
||||
|
||||
~Endpoint();
|
||||
|
@ -97,7 +97,7 @@ namespace llarp
|
|||
return m_RxRate;
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
LocalIP() const
|
||||
{
|
||||
return m_IP;
|
||||
|
@ -109,7 +109,7 @@ namespace llarp
|
|||
llarp::handlers::ExitEndpoint* m_Parent;
|
||||
llarp::PubKey m_remoteSignKey;
|
||||
llarp::PathID_t m_CurrentPath;
|
||||
llarp::huint32_t m_IP;
|
||||
llarp::huint128_t m_IP;
|
||||
uint64_t m_TxRate, m_RxRate;
|
||||
llarp_time_t m_LastActive;
|
||||
bool m_RewriteSource;
|
||||
|
@ -121,12 +121,12 @@ namespace llarp
|
|||
|
||||
struct UpstreamBuffer
|
||||
{
|
||||
UpstreamBuffer(const llarp::net::IPv4Packet& p, uint64_t c)
|
||||
UpstreamBuffer(const llarp::net::IPPacket& p, uint64_t c)
|
||||
: pkt(p), counter(c)
|
||||
{
|
||||
}
|
||||
|
||||
llarp::net::IPv4Packet pkt;
|
||||
llarp::net::IPPacket pkt;
|
||||
uint64_t counter;
|
||||
|
||||
bool
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace llarp
|
|||
{
|
||||
if(m_WritePacket)
|
||||
{
|
||||
llarp::net::IPv4Packet pkt;
|
||||
llarp::net::IPPacket pkt;
|
||||
if(!pkt.Load(buf))
|
||||
return false;
|
||||
m_Downstream.emplace(counter, pkt);
|
||||
|
@ -221,8 +221,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
BaseSession::QueueUpstreamTraffic(llarp::net::IPv4Packet pkt,
|
||||
const size_t N)
|
||||
BaseSession::QueueUpstreamTraffic(llarp::net::IPPacket pkt, const size_t N)
|
||||
{
|
||||
const llarp_buffer_t& buf = pkt.Buffer();
|
||||
auto& queue = m_Upstream[buf.sz / N];
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace llarp
|
|||
HandlePathBuilt(llarp::path::Path_ptr p) override;
|
||||
|
||||
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
|
||||
bool
|
||||
|
@ -139,7 +139,7 @@ namespace llarp
|
|||
using TieredQueue_t = std::map< uint8_t, UpstreamTrafficQueue_t >;
|
||||
TieredQueue_t m_Upstream;
|
||||
|
||||
using DownstreamPkt = std::pair< uint64_t, llarp::net::IPv4Packet >;
|
||||
using DownstreamPkt = std::pair< uint64_t, llarp::net::IPPacket >;
|
||||
|
||||
struct DownstreamPktSorter
|
||||
{
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace llarp
|
|||
huint32_t ip;
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
return false;
|
||||
return m_OurRange.Contains(ip);
|
||||
return m_OurRange.ContainsV4(ip);
|
||||
}
|
||||
else if(msg.questions[0].qtype == dns::qTypeA
|
||||
|| msg.questions[0].qtype == dns::qTypeCNAME
|
||||
|
@ -91,14 +91,15 @@ namespace llarp
|
|||
huint32_t ip;
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
return false;
|
||||
if(ip == m_IfAddr)
|
||||
huint128_t ipv6 = net::IPPacket::ExpandV4(ip);
|
||||
if(ipv6 == m_IfAddr)
|
||||
{
|
||||
RouterID us = GetRouter()->pubkey();
|
||||
msg.AddAReply(us.ToString(), 300);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto itr = m_IPToKey.find(ip);
|
||||
auto itr = m_IPToKey.find(ipv6);
|
||||
if(itr != m_IPToKey.end()
|
||||
&& m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
|
||||
{
|
||||
|
@ -155,7 +156,7 @@ namespace llarp
|
|||
RouterID r;
|
||||
if(r.FromString(msg.questions[0].Name()))
|
||||
{
|
||||
huint32_t ip;
|
||||
huint128_t ip;
|
||||
PubKey pubKey(r);
|
||||
if(m_SNodeKeys.find(pubKey) == m_SNodeKeys.end())
|
||||
{
|
||||
|
@ -212,11 +213,12 @@ namespace llarp
|
|||
m_InetToNetwork.Process([&](Pkt_t &pkt) {
|
||||
PubKey pk;
|
||||
{
|
||||
auto itr = m_IPToKey.find(pkt.dst());
|
||||
auto itr = m_IPToKey.find(pkt.dstv6());
|
||||
if(itr == m_IPToKey.end())
|
||||
{
|
||||
// drop
|
||||
LogWarn(Name(), " dropping packet, has no session at ", pkt.dst());
|
||||
LogWarn(Name(), " dropping packet, has no session at ",
|
||||
pkt.dstv4());
|
||||
return;
|
||||
}
|
||||
pk = itr->second;
|
||||
|
@ -285,10 +287,10 @@ namespace llarp
|
|||
{
|
||||
// map our address
|
||||
const PubKey us(m_Router->pubkey());
|
||||
const huint32_t ip = GetIfAddr();
|
||||
m_KeyToIP[us] = ip;
|
||||
m_IPToKey[ip] = us;
|
||||
m_IPActivity[ip] = std::numeric_limits< llarp_time_t >::max();
|
||||
const huint128_t ip = GetIfAddr();
|
||||
m_KeyToIP[us] = ip;
|
||||
m_IPToKey[ip] = us;
|
||||
m_IPActivity[ip] = std::numeric_limits< llarp_time_t >::max();
|
||||
m_SNodeKeys.insert(us);
|
||||
if(m_ShouldInitTun)
|
||||
{
|
||||
|
@ -311,7 +313,7 @@ namespace llarp
|
|||
return m_Router;
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
ExitEndpoint::GetIfAddr() const
|
||||
{
|
||||
return m_IfAddr;
|
||||
|
@ -340,10 +342,10 @@ namespace llarp
|
|||
return m_KeyToIP.find(pk) != m_KeyToIP.end();
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
ExitEndpoint::GetIPForIdent(const PubKey pk)
|
||||
{
|
||||
huint32_t found = {0};
|
||||
huint128_t found = {0};
|
||||
if(!HasLocalMappedAddrFor(pk))
|
||||
{
|
||||
// allocate and map
|
||||
|
@ -372,14 +374,14 @@ namespace llarp
|
|||
return found;
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
ExitEndpoint::AllocateNewAddress()
|
||||
{
|
||||
if(m_NextAddr < m_HigestAddr)
|
||||
return ++m_NextAddr;
|
||||
|
||||
// find oldest activity ip address
|
||||
huint32_t found = {0};
|
||||
huint128_t found = {0};
|
||||
llarp_time_t min = std::numeric_limits< llarp_time_t >::max();
|
||||
auto itr = m_IPActivity.begin();
|
||||
while(itr != m_IPActivity.end())
|
||||
|
@ -409,7 +411,7 @@ namespace llarp
|
|||
ExitEndpoint::KickIdentOffExit(const PubKey &pk)
|
||||
{
|
||||
LogInfo(Name(), " kicking ", pk, " off exit");
|
||||
huint32_t ip = m_KeyToIP[pk];
|
||||
huint128_t ip = m_KeyToIP[pk];
|
||||
m_KeyToIP.erase(pk);
|
||||
m_IPToKey.erase(ip);
|
||||
auto range = m_ActiveExits.equal_range(pk);
|
||||
|
@ -419,7 +421,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
ExitEndpoint::MarkIPActive(huint32_t ip)
|
||||
ExitEndpoint::MarkIPActive(huint128_t ip)
|
||||
{
|
||||
m_IPActivity[ip] = GetRouter()->Now();
|
||||
}
|
||||
|
@ -432,13 +434,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
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))
|
||||
return false;
|
||||
// rewrite ip
|
||||
pkt.UpdateIPv4PacketOnDst(from, m_IfAddr);
|
||||
pkt.UpdateV6Address(from, m_IfAddr);
|
||||
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);
|
||||
m_Tun.netmask = std::atoi(nmask_str.c_str());
|
||||
|
||||
Addr ifaddr(host_str);
|
||||
m_IfAddr = ifaddr.xtohl();
|
||||
m_OurRange.netmask_bits = netmask_ipv4_bits(m_Tun.netmask);
|
||||
m_OurRange.addr = m_IfAddr;
|
||||
m_NextAddr = m_IfAddr;
|
||||
m_HigestAddr = m_IfAddr | (~m_OurRange.netmask_bits);
|
||||
huint32_t ip;
|
||||
if(ip.FromString(host_str))
|
||||
{
|
||||
m_IfAddr = net::IPPacket::ExpandV4(ip);
|
||||
m_OurRange.netmask_bits = netmask_ipv6_bits(m_Tun.netmask + 96);
|
||||
}
|
||||
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, "/",
|
||||
m_Tun.netmask, " lo=", m_IfAddr, " hi=", m_HigestAddr);
|
||||
}
|
||||
|
@ -564,7 +573,7 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
ExitEndpoint::ObtainServiceNodeIP(const RouterID &other)
|
||||
{
|
||||
const PubKey pubKey(other);
|
||||
|
@ -573,7 +582,7 @@ namespace llarp
|
|||
if(pubKey == us)
|
||||
return m_IfAddr;
|
||||
|
||||
huint32_t ip = GetIPForIdent(pubKey);
|
||||
huint128_t ip = GetIPForIdent(pubKey);
|
||||
if(m_SNodeKeys.emplace(pubKey).second)
|
||||
{
|
||||
auto session = std::make_shared< exit::SNodeSession >(
|
||||
|
@ -593,7 +602,7 @@ namespace llarp
|
|||
{
|
||||
if(wantInternet && !m_PermitExit)
|
||||
return false;
|
||||
huint32_t ip = GetIPForIdent(pk);
|
||||
auto ip = GetIPForIdent(pk);
|
||||
if(GetRouter()->pathContext().TransitHopPreviousIsRouter(path,
|
||||
pk.as_array()))
|
||||
{
|
||||
|
|
|
@ -99,29 +99,29 @@ namespace llarp
|
|||
bool
|
||||
HasLocalMappedAddrFor(const PubKey& pk) const;
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
GetIfAddr() const;
|
||||
|
||||
void
|
||||
Flush();
|
||||
|
||||
private:
|
||||
huint32_t
|
||||
huint128_t
|
||||
GetIPForIdent(const PubKey pk);
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
AllocateNewAddress();
|
||||
|
||||
/// obtain ip for service node session, creates a new session if one does
|
||||
/// not existing already
|
||||
huint32_t
|
||||
huint128_t
|
||||
ObtainServiceNodeIP(const RouterID& router);
|
||||
|
||||
bool
|
||||
QueueSNodePacket(const llarp_buffer_t& buf, huint32_t from);
|
||||
QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
|
||||
|
||||
void
|
||||
MarkIPActive(huint32_t ip);
|
||||
MarkIPActive(huint128_t ip);
|
||||
|
||||
void
|
||||
KickIdentOffExit(const PubKey& pk);
|
||||
|
@ -139,7 +139,7 @@ namespace llarp
|
|||
PubKey::Hash >
|
||||
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;
|
||||
|
||||
|
@ -153,14 +153,15 @@ namespace llarp
|
|||
/// snode sessions we are talking to directly
|
||||
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;
|
||||
huint32_t m_HigestAddr;
|
||||
huint32_t m_NextAddr;
|
||||
huint128_t m_IfAddr;
|
||||
huint128_t m_HigestAddr;
|
||||
|
||||
huint128_t m_NextAddr;
|
||||
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;
|
||||
|
||||
llarp_tun_io m_Tun;
|
||||
|
@ -168,7 +169,7 @@ namespace llarp
|
|||
Addr m_LocalResolverAddr;
|
||||
std::vector< Addr > m_UpstreamResolvers;
|
||||
|
||||
using Pkt_t = net::IPv4Packet;
|
||||
using Pkt_t = net::IPPacket;
|
||||
using PacketQueue_t =
|
||||
util::CoDelQueue< Pkt_t, Pkt_t::GetTime, Pkt_t::PutTime,
|
||||
Pkt_t::CompareOrder, Pkt_t::GetNow, util::NullMutex,
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
HandleWriteIPPacket(const llarp_buffer_t &,
|
||||
std::function< huint32_t(void) >) override
|
||||
std::function< huint128_t(void) >) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -30,7 +30,13 @@ namespace llarp
|
|||
return shared_from_this();
|
||||
}
|
||||
|
||||
huint32_t
|
||||
bool
|
||||
SupportsV6() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
huint128_t
|
||||
ObtainIPForAddr(const AlignedBuffer< 32 > &, bool) override
|
||||
{
|
||||
return {0};
|
||||
|
|
|
@ -200,13 +200,22 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
auto ip_str = v.substr(pos + 1);
|
||||
in_addr ip;
|
||||
if(inet_pton(AF_INET, ip_str.c_str(), &ip) != 1)
|
||||
huint32_t ip;
|
||||
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 MapAddress(addr, huint32_t{ntohl(ip.s_addr)}, false);
|
||||
return MapAddress(addr, ipv6, false);
|
||||
}
|
||||
if(k == "ifname")
|
||||
{
|
||||
|
@ -222,6 +231,7 @@ namespace llarp
|
|||
if(k == "ifaddr")
|
||||
{
|
||||
std::string addr;
|
||||
m_UseV6 = addr.find(":") != std::string::npos;
|
||||
auto pos = v.find("/");
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
|
@ -245,8 +255,11 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
tunif.netmask = 32;
|
||||
addr = v;
|
||||
if(m_UseV6)
|
||||
tunif.netmask = 128;
|
||||
else
|
||||
tunif.netmask = 32;
|
||||
addr = v;
|
||||
}
|
||||
llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ",
|
||||
tunif.netmask);
|
||||
|
@ -257,17 +270,16 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::HasLocalIP(const huint32_t &ip) const
|
||||
TunEndpoint::HasLocalIP(const huint128_t &ip) const
|
||||
{
|
||||
return m_IPToAddr.find(ip) != m_IPToAddr.end();
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::QueueOutboundTraffic(llarp::net::IPv4Packet &&pkt)
|
||||
TunEndpoint::QueueOutboundTraffic(llarp::net::IPPacket &&pkt)
|
||||
{
|
||||
return m_NetworkToUserPktQueue.EmplaceIf(
|
||||
[](llarp::net::IPv4Packet &) -> bool { return true; },
|
||||
std::move(pkt));
|
||||
[](llarp::net::IPPacket &) -> bool { return true; }, std::move(pkt));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -354,7 +366,8 @@ namespace llarp
|
|||
else if(msg.questions[0].qtype == dns::qTypeA
|
||||
|| 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;
|
||||
// on MacOS this is a typeA query
|
||||
if(is_random_snode(msg))
|
||||
|
@ -371,7 +384,7 @@ namespace llarp
|
|||
context->ForEachService(
|
||||
[&](const std::string &,
|
||||
const std::shared_ptr< service::Endpoint > &service) -> bool {
|
||||
huint32_t ip = service->GetIfAddr();
|
||||
huint128_t ip = service->GetIfAddr();
|
||||
if(ip.h)
|
||||
{
|
||||
msg.AddINReply(ip, isV6);
|
||||
|
@ -384,10 +397,14 @@ namespace llarp
|
|||
}
|
||||
else if(addr.FromString(qname, ".loki"))
|
||||
{
|
||||
if(HasAddress(addr))
|
||||
if(isV4 && SupportsV6())
|
||||
{
|
||||
huint32_t ip = ObtainIPForAddr(addr, false);
|
||||
msg.AddINReply(ip, isV6);
|
||||
msg.AddNXReply();
|
||||
}
|
||||
else if(HasAddress(addr))
|
||||
{
|
||||
huint128_t ip = ObtainIPForAddr(addr, false);
|
||||
msg.AddINReply(ip, isV6);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -397,7 +414,7 @@ namespace llarp
|
|||
return EnsurePathToService(
|
||||
addr,
|
||||
[=](const Address &, OutboundContext *ctx) {
|
||||
SendDNSReply(addr, ctx, replyMsg, reply, false, isV6);
|
||||
SendDNSReply(addr, ctx, replyMsg, reply, false, isV6 || !isV4);
|
||||
},
|
||||
2000);
|
||||
}
|
||||
|
@ -419,22 +436,24 @@ namespace llarp
|
|||
else if(msg.questions[0].qtype == dns::qTypePTR)
|
||||
{
|
||||
// reverse dns
|
||||
huint32_t ip = {0};
|
||||
huint128_t ipv6 = {0};
|
||||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
{
|
||||
msg.AddNXReply();
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
ipv6 = net::IPPacket::ExpandV4(ip);
|
||||
llarp::service::Address addr(
|
||||
ObtainAddrForIP< llarp::service::Address >(ip, true));
|
||||
ObtainAddrForIP< llarp::service::Address >(ipv6, true));
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
msg.AddAReply(addr.ToString(".snode"));
|
||||
reply(msg);
|
||||
return true;
|
||||
}
|
||||
addr = ObtainAddrForIP< llarp::service::Address >(ip, false);
|
||||
addr = ObtainAddrForIP< llarp::service::Address >(ipv6, false);
|
||||
if(!addr.IsZero())
|
||||
{
|
||||
msg.AddAReply(addr.ToString(".loki"));
|
||||
|
@ -461,6 +480,12 @@ namespace llarp
|
|||
m_Exit->ResetInternalState();
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::SupportsV6() const
|
||||
{
|
||||
return m_UseV6;
|
||||
}
|
||||
|
||||
// FIXME: pass in which question it should be addressing
|
||||
bool
|
||||
TunEndpoint::ShouldHookDNSMessage(const dns::Message &msg) const
|
||||
|
@ -480,20 +505,19 @@ namespace llarp
|
|||
huint32_t ip = {0};
|
||||
if(!dns::DecodePTR(msg.questions[0].qname, ip))
|
||||
return false;
|
||||
return m_OurRange.Contains(ip);
|
||||
return m_OurRange.ContainsV4(ip);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::MapAddress(const service::Address &addr, huint32_t ip,
|
||||
TunEndpoint::MapAddress(const service::Address &addr, huint128_t ip,
|
||||
bool SNode)
|
||||
{
|
||||
auto itr = m_IPToAddr.find(ip);
|
||||
if(itr != m_IPToAddr.end())
|
||||
{
|
||||
// XXX is calling inet_ntoa safe in this context? it's MP-unsafe
|
||||
llarp::LogWarn(ip, " already mapped to ",
|
||||
service::Address(itr->second.as_array()).ToString());
|
||||
return false;
|
||||
|
@ -572,31 +596,44 @@ namespace llarp
|
|||
*/
|
||||
if(res->ai_family == AF_INET6)
|
||||
{
|
||||
llarp::LogError(Name(),
|
||||
" failed to set up tun interface, we don't support "
|
||||
"IPv6 format");
|
||||
return false;
|
||||
m_UseV6 = true;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
struct in_addr addr; // network byte order
|
||||
if(inet_aton(tunif.ifaddr, &addr) == 0)
|
||||
if(m_UseV6)
|
||||
{
|
||||
llarp::LogError(Name(), " failed to set up tun interface, cant parse ",
|
||||
tunif.ifaddr);
|
||||
return false;
|
||||
llarp::LogInfo(Name(), " using IPV6");
|
||||
}
|
||||
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_OurIP = lAddr.xtohl();
|
||||
m_NextIP = m_OurIP;
|
||||
m_OurRange.netmask_bits = netmask_ipv4_bits(tunif.netmask);
|
||||
m_OurRange.addr = m_OurIP;
|
||||
m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
|
||||
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ", lAddr);
|
||||
m_NextIP = m_OurIP;
|
||||
m_OurRange.addr = m_OurIP;
|
||||
m_MaxIP = m_OurIP | (~m_OurRange.netmask_bits);
|
||||
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ",
|
||||
m_OurIP);
|
||||
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ",
|
||||
m_OurRange);
|
||||
|
||||
MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode());
|
||||
if(m_OnUp)
|
||||
{
|
||||
|
@ -661,20 +698,30 @@ namespace llarp
|
|||
void
|
||||
TunEndpoint::FlushSend()
|
||||
{
|
||||
m_UserToNetworkPktQueue.Process([&](net::IPv4Packet &pkt) {
|
||||
m_UserToNetworkPktQueue.Process([&](net::IPPacket &pkt) {
|
||||
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(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),
|
||||
llarp::routing::ExitPadSize);
|
||||
}
|
||||
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))
|
||||
|
@ -684,25 +731,26 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
sendFunc =
|
||||
std::bind(&TunEndpoint::SendToServiceOrQueue, this,
|
||||
service::Address(itr->second.as_array()),
|
||||
std::placeholders::_1, service::eProtocolTraffic);
|
||||
sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this,
|
||||
service::Address(itr->second.as_array()),
|
||||
std::placeholders::_1, pkt.ServiceProtocol());
|
||||
}
|
||||
// prepare packet for insertion into network
|
||||
// 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()))
|
||||
return true;
|
||||
return;
|
||||
llarp::LogWarn(Name(), " did not flush packets");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::HandleWriteIPPacket(const llarp_buffer_t &b,
|
||||
std::function< huint32_t(void) > getFromIP)
|
||||
TunEndpoint::HandleWriteIPPacket(
|
||||
const llarp_buffer_t &b, std::function< huint128_t(void) > getFromIP)
|
||||
{
|
||||
// llarp::LogInfo("got packet from ", msg->sender.Addr());
|
||||
auto themIP = getFromIP();
|
||||
|
@ -710,7 +758,7 @@ namespace llarp
|
|||
auto usIP = m_OurIP;
|
||||
ManagedBuffer buf(b);
|
||||
return m_NetworkToUserPktQueue.EmplaceIf(
|
||||
[buf, themIP, usIP](net::IPv4Packet &pkt) -> bool {
|
||||
[buf, themIP, usIP](net::IPPacket &pkt) -> bool {
|
||||
// load
|
||||
if(!pkt.Load(buf))
|
||||
return false;
|
||||
|
@ -720,32 +768,39 @@ namespace llarp
|
|||
// - packets with weird src/dst addresses
|
||||
// (0.0.0.0/8 but not 0.0.0.0)
|
||||
// - packets with 0 src but non-0 dst and oposite
|
||||
auto hdr = pkt.Header();
|
||||
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)))
|
||||
if(pkt.IsV4())
|
||||
{
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
TunEndpoint::GetIfAddr() const
|
||||
{
|
||||
return m_OurIP;
|
||||
}
|
||||
|
||||
huint32_t
|
||||
huint128_t
|
||||
TunEndpoint::ObtainIPForAddr(const AlignedBuffer< 32 > &addr, bool snode)
|
||||
{
|
||||
llarp_time_t now = Now();
|
||||
huint32_t nextIP = {0};
|
||||
llarp_time_t now = Now();
|
||||
huint128_t nextIP = {0};
|
||||
AlignedBuffer< 32 > ident(addr);
|
||||
{
|
||||
// previously allocated address
|
||||
|
@ -779,7 +834,7 @@ namespace llarp
|
|||
// we are full
|
||||
// expire least active ip
|
||||
// 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
|
||||
auto itr = m_IPActivity.begin();
|
||||
|
@ -808,19 +863,20 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
TunEndpoint::HasRemoteForIP(huint32_t ip) const
|
||||
TunEndpoint::HasRemoteForIP(huint128_t ip) const
|
||||
{
|
||||
return m_IPToAddr.find(ip) != m_IPToAddr.end();
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
void
|
||||
TunEndpoint::MarkIPActiveForever(huint32_t ip)
|
||||
TunEndpoint::MarkIPActiveForever(huint128_t ip)
|
||||
{
|
||||
m_IPActivity[ip] = std::numeric_limits< uint64_t >::max();
|
||||
}
|
||||
|
@ -844,7 +900,7 @@ namespace llarp
|
|||
self->m_Exit->FlushDownstream();
|
||||
}
|
||||
// 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()))
|
||||
llarp::LogWarn("packet dropped");
|
||||
});
|
||||
|
@ -857,9 +913,7 @@ namespace llarp
|
|||
TunEndpoint *self = static_cast< TunEndpoint * >(tun->user);
|
||||
ManagedBuffer buf(b);
|
||||
if(!self->m_UserToNetworkPktQueue.EmplaceIf(
|
||||
[buf](net::IPv4Packet &pkt) -> bool {
|
||||
return pkt.Load(buf) && pkt.Header()->version == 4;
|
||||
}))
|
||||
[buf](net::IPPacket &pkt) -> bool { return pkt.Load(buf); }))
|
||||
{
|
||||
#if defined(DEBUG) || !defined(RELEASE_MOTTO)
|
||||
llarp::LogInfo("invalid pkt");
|
||||
|
|
|
@ -46,6 +46,9 @@ namespace llarp
|
|||
std::unordered_map< std::string, std::string >
|
||||
NotifyParams() const override;
|
||||
|
||||
bool
|
||||
SupportsV6() const override;
|
||||
|
||||
bool
|
||||
ShouldHookDNSMessage(const dns::Message& msg) const override;
|
||||
|
||||
|
@ -58,7 +61,7 @@ namespace llarp
|
|||
TickTun(llarp_time_t now);
|
||||
|
||||
bool
|
||||
MapAddress(const service::Address& remote, huint32_t ip, bool SNode);
|
||||
MapAddress(const service::Address& remote, huint128_t ip, bool SNode);
|
||||
|
||||
bool
|
||||
Start() override;
|
||||
|
@ -81,11 +84,11 @@ namespace llarp
|
|||
/// handle inbound traffic
|
||||
bool
|
||||
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
|
||||
bool
|
||||
QueueOutboundTraffic(llarp::net::IPv4Packet&& pkt);
|
||||
QueueOutboundTraffic(llarp::net::IPPacket&& pkt);
|
||||
|
||||
/// we have a resolvable ip address
|
||||
bool
|
||||
|
@ -95,11 +98,11 @@ namespace llarp
|
|||
}
|
||||
|
||||
/// get the local interface's address
|
||||
huint32_t
|
||||
huint128_t
|
||||
GetIfAddr() const override;
|
||||
|
||||
bool
|
||||
HasLocalIP(const huint32_t& ip) const;
|
||||
HasLocalIP(const huint128_t& ip) const;
|
||||
|
||||
llarp_tun_io tunif;
|
||||
std::unique_ptr< llarp_fd_promise > Promise;
|
||||
|
@ -124,7 +127,7 @@ namespace llarp
|
|||
/// get a key for ip address
|
||||
template < typename Addr >
|
||||
Addr
|
||||
ObtainAddrForIP(huint32_t ip, bool isSNode)
|
||||
ObtainAddrForIP(huint128_t ip, bool isSNode)
|
||||
{
|
||||
auto itr = m_IPToAddr.find(ip);
|
||||
if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode)
|
||||
|
@ -145,7 +148,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
/// get ip address for key unconditionally
|
||||
huint32_t
|
||||
huint128_t
|
||||
ObtainIPForAddr(const AlignedBuffer< 32 >& addr,
|
||||
bool serviceNode) override;
|
||||
|
||||
|
@ -158,33 +161,33 @@ namespace llarp
|
|||
|
||||
protected:
|
||||
using PacketQueue_t = llarp::util::CoDelQueue<
|
||||
net::IPv4Packet, net::IPv4Packet::GetTime, net::IPv4Packet::PutTime,
|
||||
net::IPv4Packet::CompareOrder, net::IPv4Packet::GetNow >;
|
||||
net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime,
|
||||
net::IPPacket::CompareOrder, net::IPPacket::GetNow >;
|
||||
/// queue for sending packets over the network from us
|
||||
PacketQueue_t m_UserToNetworkPktQueue;
|
||||
/// queue for sending packets to user from network
|
||||
PacketQueue_t m_NetworkToUserPktQueue;
|
||||
/// return true if we have a remote loki address for this ip address
|
||||
bool
|
||||
HasRemoteForIP(huint32_t ipv4) const;
|
||||
HasRemoteForIP(huint128_t ipv4) const;
|
||||
|
||||
/// mark this address as active
|
||||
void
|
||||
MarkIPActive(huint32_t ip);
|
||||
MarkIPActive(huint128_t ip);
|
||||
|
||||
/// mark this address as active forever
|
||||
void
|
||||
MarkIPActiveForever(huint32_t ip);
|
||||
MarkIPActiveForever(huint128_t ip);
|
||||
|
||||
/// flush ip packets
|
||||
virtual void
|
||||
FlushSend();
|
||||
|
||||
/// 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;
|
||||
/// maps key to ip (host byte order)
|
||||
std::unordered_map< AlignedBuffer< 32 >, huint32_t,
|
||||
std::unordered_map< AlignedBuffer< 32 >, huint128_t,
|
||||
AlignedBuffer< 32 >::Hash >
|
||||
m_AddrToIP;
|
||||
|
||||
|
@ -199,10 +202,29 @@ namespace llarp
|
|||
{
|
||||
ManagedBuffer copy{buf};
|
||||
return m_NetworkToUserPktQueue.EmplaceIf(
|
||||
[&](llarp::net::IPv4Packet& pkt) -> bool {
|
||||
[&](llarp::net::IPPacket& pkt) -> bool {
|
||||
if(!pkt.Load(copy.underlying))
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
@ -215,7 +237,7 @@ namespace llarp
|
|||
{
|
||||
if(ctx)
|
||||
{
|
||||
huint32_t ip = ObtainIPForAddr(addr, snode);
|
||||
huint128_t ip = ObtainIPForAddr(addr, snode);
|
||||
query->AddINReply(ip, sendIPv6);
|
||||
}
|
||||
else
|
||||
|
@ -233,14 +255,14 @@ namespace llarp
|
|||
std::shared_ptr< dns::Proxy > m_Resolver;
|
||||
|
||||
/// 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;
|
||||
/// our ip address (host byte order)
|
||||
huint32_t m_OurIP;
|
||||
huint128_t m_OurIP;
|
||||
/// next ip address to allocate (host byte order)
|
||||
huint32_t m_NextIP;
|
||||
huint128_t m_NextIP;
|
||||
/// highest ip address to allocate (host byte order)
|
||||
huint32_t m_MaxIP;
|
||||
huint128_t m_MaxIP;
|
||||
/// our ip range we are using
|
||||
llarp::IPRange m_OurRange;
|
||||
/// upstream dns resolver list
|
||||
|
@ -249,6 +271,8 @@ namespace llarp
|
|||
llarp::Addr m_LocalResolverAddr;
|
||||
/// list of strict connect addresses for hooks
|
||||
std::vector< llarp::Addr > m_StrictConnectAddrs;
|
||||
/// use v6?
|
||||
bool m_UseV6;
|
||||
};
|
||||
} // namespace handlers
|
||||
} // namespace llarp
|
||||
|
|
|
@ -15,8 +15,61 @@ namespace llarp
|
|||
{
|
||||
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
|
||||
IPv4Packet::Load(const llarp_buffer_t &pkt)
|
||||
IPPacket::Load(const llarp_buffer_t &pkt)
|
||||
{
|
||||
if(pkt.sz > sizeof(buf))
|
||||
return false;
|
||||
|
@ -26,17 +79,37 @@ namespace llarp
|
|||
}
|
||||
|
||||
llarp_buffer_t
|
||||
IPv4Packet::ConstBuffer() const
|
||||
IPPacket::ConstBuffer() const
|
||||
{
|
||||
return {buf, sz};
|
||||
}
|
||||
|
||||
llarp_buffer_t
|
||||
IPv4Packet::Buffer()
|
||||
IPPacket::Buffer()
|
||||
{
|
||||
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
|
||||
static uint32_t
|
||||
ipchksum_pseudoIPv4(nuint32_t src_ip, nuint32_t dst_ip, uint8_t proto,
|
||||
|
@ -140,8 +213,9 @@ namespace llarp
|
|||
}
|
||||
|
||||
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 oSrcIP = nuint32_t{hdr->saddr};
|
||||
|
@ -227,9 +301,9 @@ namespace llarp
|
|||
// if(check->n == 0x0000)
|
||||
// check->n = 0xFFff;
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
IPv4Packet::UpdateIPv4PacketOnSrc()
|
||||
IPacket::UpdateIPv4PacketOnSrc()
|
||||
{
|
||||
auto hdr = Header();
|
||||
|
||||
|
@ -269,5 +343,6 @@ namespace llarp
|
|||
hdr->saddr = 0;
|
||||
hdr->daddr = 0;
|
||||
}
|
||||
*/
|
||||
} // namespace net
|
||||
} // namespace llarp
|
||||
|
|
110
llarp/net/ip.hpp
110
llarp/net/ip.hpp
|
@ -74,7 +74,17 @@ typedef struct ip_hdr
|
|||
|
||||
#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 <service/protocol.hpp>
|
||||
|
||||
struct llarp_ev_loop;
|
||||
|
||||
|
@ -82,28 +92,21 @@ namespace llarp
|
|||
{
|
||||
namespace net
|
||||
{
|
||||
/// a network layer packet
|
||||
struct NetPacket
|
||||
/// an Packet
|
||||
struct IPPacket
|
||||
{
|
||||
virtual ~NetPacket(){};
|
||||
static huint128_t
|
||||
In6ToHUInt(in6_addr addr);
|
||||
|
||||
virtual byte_t
|
||||
Version() const = 0;
|
||||
static in6_addr
|
||||
HUIntToIn6(huint128_t x);
|
||||
|
||||
virtual byte_t
|
||||
IPProto() const = 0;
|
||||
static huint128_t
|
||||
ExpandV4(huint32_t x);
|
||||
|
||||
virtual llarp_buffer_t
|
||||
Buffer() = 0;
|
||||
static huint32_t
|
||||
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;
|
||||
llarp_time_t timestamp;
|
||||
size_t sz;
|
||||
|
@ -121,7 +124,7 @@ namespace llarp
|
|||
struct GetTime
|
||||
{
|
||||
llarp_time_t
|
||||
operator()(const IPv4Packet& pkt) const
|
||||
operator()(const IPPacket& pkt) const
|
||||
{
|
||||
return pkt.timestamp;
|
||||
}
|
||||
|
@ -134,7 +137,7 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
void
|
||||
operator()(IPv4Packet& pkt) const
|
||||
operator()(IPPacket& pkt) const
|
||||
{
|
||||
pkt.timestamp = llarp_ev_loop_time_now_ms(loop);
|
||||
}
|
||||
|
@ -156,7 +159,7 @@ namespace llarp
|
|||
struct CompareSize
|
||||
{
|
||||
bool
|
||||
operator()(const IPv4Packet& left, const IPv4Packet& right)
|
||||
operator()(const IPPacket& left, const IPPacket& right)
|
||||
{
|
||||
return left.sz < right.sz;
|
||||
}
|
||||
|
@ -165,7 +168,7 @@ namespace llarp
|
|||
struct CompareOrder
|
||||
{
|
||||
bool
|
||||
operator()(const IPv4Packet& left, const IPv4Packet& right)
|
||||
operator()(const IPPacket& left, const IPPacket& right)
|
||||
{
|
||||
return left.timestamp < right.timestamp;
|
||||
}
|
||||
|
@ -183,37 +186,70 @@ namespace llarp
|
|||
return (ip_header*)&buf[0];
|
||||
}
|
||||
|
||||
inline huint32_t
|
||||
src()
|
||||
inline ipv6_header*
|
||||
HeaderV6()
|
||||
{
|
||||
return huint32_t{ntohl(Header()->saddr)};
|
||||
return (ipv6_header*)&buf[0];
|
||||
}
|
||||
|
||||
inline huint32_t
|
||||
dst()
|
||||
inline const ipv6_header*
|
||||
HeaderV6() const
|
||||
{
|
||||
return huint32_t{ntohl(Header()->daddr)};
|
||||
return (ipv6_header*)&buf[0];
|
||||
}
|
||||
|
||||
inline void
|
||||
src(huint32_t ip)
|
||||
inline int
|
||||
Version() const
|
||||
{
|
||||
Header()->saddr = htonl(ip.h);
|
||||
return Header()->version;
|
||||
}
|
||||
|
||||
inline void
|
||||
dst(huint32_t ip)
|
||||
inline bool
|
||||
IsV4() const
|
||||
{
|
||||
Header()->daddr = htonl(ip.h);
|
||||
return Version() == 4;
|
||||
}
|
||||
|
||||
// update ip packet (after packet gets out of network)
|
||||
inline bool
|
||||
IsV6() const
|
||||
{
|
||||
return Version() == 6;
|
||||
}
|
||||
|
||||
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
|
||||
UpdateIPv4PacketOnDst(huint32_t newSrcIP, huint32_t newDstIP);
|
||||
UpdateV4Address(huint32_t src, huint32_t dst);
|
||||
|
||||
// update ip packet (before packet gets inserted into network)
|
||||
void
|
||||
UpdateIPv4PacketOnSrc();
|
||||
UpdateV6Address(huint128_t src, huint128_t dst);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#endif
|
||||
|
||||
#include <net/net_addr.hpp>
|
||||
#include <net/ip.hpp>
|
||||
#include <util/logger.hpp>
|
||||
#include <util/str.hpp>
|
||||
|
||||
|
@ -1010,6 +1011,37 @@ namespace llarp
|
|||
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
|
||||
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)};
|
||||
for(const auto& bogon : bogonRanges)
|
||||
{
|
||||
if(bogon.Contains(addr))
|
||||
if(bogon.ContainsV4(addr))
|
||||
{
|
||||
#if defined(TESTNET)
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef LLARP_NET_HPP
|
||||
#define LLARP_NET_HPP
|
||||
|
||||
#include <absl/numeric/int128.h>
|
||||
#include <net/address_info.hpp>
|
||||
#include <net/net_int.hpp>
|
||||
#include <net/net.h>
|
||||
|
@ -59,16 +60,19 @@ namespace llarp
|
|||
{
|
||||
struct IPRange
|
||||
{
|
||||
huint32_t addr;
|
||||
huint32_t netmask_bits;
|
||||
huint128_t addr;
|
||||
huint128_t netmask_bits;
|
||||
|
||||
/// return true if ip is contained in this ip range
|
||||
bool
|
||||
Contains(const huint32_t& ip) const
|
||||
Contains(const huint128_t& ip) const
|
||||
{
|
||||
return (addr & netmask_bits) == (ip & netmask_bits);
|
||||
}
|
||||
|
||||
bool
|
||||
ContainsV4(const huint32_t& ip) const;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const IPRange& a)
|
||||
{
|
||||
|
@ -76,13 +80,27 @@ namespace llarp
|
|||
}
|
||||
|
||||
std::string
|
||||
ToString() const
|
||||
{
|
||||
return addr.ToString() + "/"
|
||||
+ std::to_string(llarp::bits::count_bits(netmask_bits.h));
|
||||
}
|
||||
ToString() const;
|
||||
};
|
||||
|
||||
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
|
||||
constexpr uint32_t
|
||||
__netmask_ipv4_bits(uint32_t numset)
|
||||
|
@ -90,7 +108,7 @@ namespace llarp
|
|||
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
|
||||
netmask_ipv4_bits(uint32_t num)
|
||||
{
|
||||
|
@ -107,11 +125,8 @@ namespace llarp
|
|||
#endif
|
||||
}
|
||||
|
||||
constexpr IPRange
|
||||
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)};
|
||||
}
|
||||
IPRange
|
||||
iprange_ipv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask);
|
||||
|
||||
bool
|
||||
IsIPv4Bogon(const huint32_t& addr);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <net/net_int.hpp>
|
||||
|
||||
#include <net/ip.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace llarp
|
||||
|
@ -15,6 +15,15 @@ namespace llarp
|
|||
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 <>
|
||||
std::string
|
||||
huint32_t::ToString() const
|
||||
|
@ -25,6 +34,40 @@ namespace llarp
|
|||
return "";
|
||||
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 <>
|
||||
std::string
|
||||
nuint32_t::ToString() const
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include <util/endian.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include <absl/numeric/int128.h>
|
||||
#include <absl/hash/hash.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
template < typename UInt_t >
|
||||
|
@ -28,25 +31,33 @@ namespace llarp
|
|||
|
||||
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
|
||||
operator|(huint_t x) const
|
||||
{
|
||||
return huint_t{UInt_t(h | x.h)};
|
||||
return huint_t{UInt_t{h | x.h}};
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -69,20 +80,26 @@ namespace llarp
|
|||
return h < x.h;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator!=(huint_t x) const
|
||||
{
|
||||
return h != x.h;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator==(huint_t x) const
|
||||
{
|
||||
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
|
||||
operator()(huint_t x) const
|
||||
{
|
||||
return std::hash< UInt_t >{}(x.h);
|
||||
}
|
||||
};
|
||||
return H::combine(std::move(h), i.h);
|
||||
}
|
||||
|
||||
using V6Container = std::vector< uint8_t >;
|
||||
void
|
||||
|
@ -91,6 +108,9 @@ namespace llarp
|
|||
std::string
|
||||
ToString() const;
|
||||
|
||||
bool
|
||||
FromString(const std::string&);
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const huint_t& i)
|
||||
{
|
||||
|
@ -98,8 +118,9 @@ namespace llarp
|
|||
}
|
||||
};
|
||||
|
||||
using huint32_t = huint_t< uint32_t >;
|
||||
using huint16_t = huint_t< uint16_t >;
|
||||
using huint32_t = huint_t< uint32_t >;
|
||||
using huint16_t = huint_t< uint16_t >;
|
||||
using huint128_t = huint_t< absl::uint128 >;
|
||||
|
||||
template < typename UInt_t >
|
||||
struct nuint_t
|
||||
|
@ -177,8 +198,9 @@ namespace llarp
|
|||
}
|
||||
};
|
||||
|
||||
using nuint32_t = nuint_t< uint32_t >;
|
||||
using nuint16_t = nuint_t< uint16_t >;
|
||||
using nuint32_t = nuint_t< uint32_t >;
|
||||
using nuint16_t = nuint_t< uint16_t >;
|
||||
using nuint128_t = nuint_t< absl::uint128 >;
|
||||
|
||||
static inline nuint32_t
|
||||
xhtonl(huint32_t x)
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace llarp
|
|||
const Identity& localident,
|
||||
const PQPubKey& introsetPubKey,
|
||||
const Introduction& remote,
|
||||
IDataHandler* h, const ConvoTag& t)
|
||||
IDataHandler* h, const ConvoTag& t,
|
||||
ProtocolType proto)
|
||||
: logic(l)
|
||||
, remote(r)
|
||||
, m_LocalIdentity(localident)
|
||||
|
@ -23,6 +24,7 @@ namespace llarp
|
|||
, handler(h)
|
||||
, tag(t)
|
||||
{
|
||||
msg.proto = proto;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -69,8 +71,6 @@ namespace llarp
|
|||
self->msg.sender = self->m_LocalIdentity.pub;
|
||||
// set version
|
||||
self->msg.version = LLARP_PROTO_VERSION;
|
||||
// set protocol
|
||||
self->msg.proto = eProtocolTraffic;
|
||||
// encrypt and sign
|
||||
if(self->frame.EncryptAndSign(self->msg, K, self->m_LocalIdentity))
|
||||
self->logic->queue_job({self, &Result});
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace llarp
|
|||
const Identity& localident,
|
||||
const PQPubKey& introsetPubKey,
|
||||
const Introduction& remote, IDataHandler* h,
|
||||
const ConvoTag& t);
|
||||
const ConvoTag& t, ProtocolType proto);
|
||||
|
||||
static void
|
||||
Result(void* user);
|
||||
|
|
|
@ -154,7 +154,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
Context::FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode,
|
||||
huint32_t &ip)
|
||||
huint128_t &ip)
|
||||
{
|
||||
auto itr = m_Endpoints.begin();
|
||||
while(itr != m_Endpoints.end())
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
FindBestAddressFor(const AlignedBuffer< 32 > &addr, bool isSNode,
|
||||
huint32_t &);
|
||||
huint128_t &);
|
||||
|
||||
/// function visitor returns false to prematurely break iteration
|
||||
void
|
||||
|
|
|
@ -856,7 +856,7 @@ namespace llarp
|
|||
bool
|
||||
Endpoint::ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg)
|
||||
{
|
||||
if(msg->proto == eProtocolTraffic)
|
||||
if(msg->proto == eProtocolTrafficV4 || msg->proto == eProtocolTrafficV6)
|
||||
{
|
||||
util::Lock l(&m_InboundTrafficQueueMutex);
|
||||
m_InboundTrafficQueue.emplace(msg);
|
||||
|
@ -1009,7 +1009,7 @@ namespace llarp
|
|||
auto session = std::make_shared< exit::SNodeSession >(
|
||||
snode,
|
||||
std::bind(&Endpoint::HandleWriteIPPacket, this, _1,
|
||||
[themIP]() -> huint32_t { return themIP; }),
|
||||
[themIP]() -> huint128_t { return themIP; }),
|
||||
m_Router, m_NumPaths, numHops, false, ShouldBundleRC());
|
||||
m_SNodeSessions.emplace(snode, session);
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ namespace llarp
|
|||
Endpoint::SendToSNodeOrQueue(const RouterID& addr,
|
||||
const llarp_buffer_t& buf)
|
||||
{
|
||||
auto pkt = std::make_shared< net::IPv4Packet >();
|
||||
auto pkt = std::make_shared< net::IPPacket >();
|
||||
if(!pkt->Load(buf))
|
||||
return false;
|
||||
EnsurePathToSNode(addr, [pkt](RouterID, exit::BaseSession_ptr s) {
|
||||
|
@ -1055,7 +1055,7 @@ namespace llarp
|
|||
{
|
||||
const auto& msg = m_InboundTrafficQueue.top();
|
||||
llarp_buffer_t buf(msg->payload);
|
||||
HandleWriteIPPacket(buf, [&]() -> huint32_t {
|
||||
HandleWriteIPPacket(buf, [&]() -> huint128_t {
|
||||
return ObtainIPForAddr(msg->sender.Addr(), false);
|
||||
});
|
||||
m_InboundTrafficQueue.pop();
|
||||
|
|
|
@ -81,10 +81,10 @@ namespace llarp
|
|||
}
|
||||
|
||||
/// get our ifaddr if it is set
|
||||
virtual huint32_t
|
||||
virtual huint128_t
|
||||
GetIfAddr() const
|
||||
{
|
||||
return huint32_t{0};
|
||||
return huint128_t{0};
|
||||
}
|
||||
|
||||
virtual void
|
||||
|
@ -151,7 +151,7 @@ namespace llarp
|
|||
HandleHiddenServiceFrame(path::Path_ptr p,
|
||||
const service::ProtocolFrame& msg);
|
||||
|
||||
virtual huint32_t
|
||||
virtual huint128_t
|
||||
ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode) = 0;
|
||||
|
||||
virtual bool
|
||||
|
@ -173,7 +173,7 @@ namespace llarp
|
|||
|
||||
virtual bool
|
||||
HandleWriteIPPacket(const llarp_buffer_t& pkt,
|
||||
std::function< huint32_t(void) > getFromIP) = 0;
|
||||
std::function< huint128_t(void) > getFromIP) = 0;
|
||||
|
||||
bool
|
||||
ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg);
|
||||
|
@ -313,6 +313,9 @@ namespace llarp
|
|||
/// parent context that owns this endpoint
|
||||
Context* const context;
|
||||
|
||||
virtual bool
|
||||
SupportsV6() const = 0;
|
||||
|
||||
void
|
||||
RegenAndPublishIntroSet(llarp_time_t now, bool forceRebuild = false);
|
||||
|
||||
|
|
|
@ -160,13 +160,12 @@ namespace llarp
|
|||
currentConvoTag.Randomize();
|
||||
AsyncKeyExchange* ex = new AsyncKeyExchange(
|
||||
m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(),
|
||||
currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag);
|
||||
currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag, t);
|
||||
|
||||
ex->hook =
|
||||
std::bind(&OutboundContext::Send, this, std::placeholders::_1, path);
|
||||
|
||||
ex->msg.PutBuffer(payload);
|
||||
ex->msg.proto = t;
|
||||
ex->msg.introReply = path->intro;
|
||||
ex->frame.F = ex->msg.introReply.pathID;
|
||||
llarp_threadpool_queue_job(m_Endpoint->CryptoWorker(),
|
||||
|
|
|
@ -33,8 +33,9 @@ namespace llarp
|
|||
|
||||
using ProtocolType = uint64_t;
|
||||
|
||||
constexpr ProtocolType eProtocolControl = 0UL;
|
||||
constexpr ProtocolType eProtocolTraffic = 1UL;
|
||||
constexpr ProtocolType eProtocolControl = 0UL;
|
||||
constexpr ProtocolType eProtocolTrafficV4 = 1UL;
|
||||
constexpr ProtocolType eProtocolTrafficV6 = 2UL;
|
||||
|
||||
/// inner message
|
||||
struct ProtocolMessage
|
||||
|
@ -42,7 +43,7 @@ namespace llarp
|
|||
ProtocolMessage(const ConvoTag& tag);
|
||||
ProtocolMessage();
|
||||
~ProtocolMessage();
|
||||
ProtocolType proto = eProtocolTraffic;
|
||||
ProtocolType proto = eProtocolTrafficV4;
|
||||
llarp_time_t queued = 0;
|
||||
std::vector< byte_t > payload;
|
||||
Introduction introReply;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <numeric>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <absl/numeric/int128.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <absl/numeric/int128.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/endian.h>
|
||||
|
@ -189,4 +190,19 @@ htole64buf(void *buf, uint64_t 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
|
||||
|
|
|
@ -2,27 +2,63 @@
|
|||
|
||||
#include <net/net.hpp>
|
||||
#include <net/net_inaddr.hpp>
|
||||
#include <net/net_int.hpp>
|
||||
#include <net/ip.hpp>
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -188,14 +188,50 @@ tuntap_sys_set_ipv4(struct device *dev, t_tun_in_addr *s4, uint32_t bits)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct in6_ifreq {
|
||||
struct in6_addr ifr6_addr;
|
||||
__u32 ifr6_prefixlen;
|
||||
unsigned int ifr6_ifindex;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
tuntap_sys_set_ipv6(struct device *dev, t_tun_in6_addr *s6, uint32_t bits)
|
||||
{
|
||||
(void)dev;
|
||||
(void)s6;
|
||||
(void)bits;
|
||||
tuntap_log(TUNTAP_LOG_NOTICE, "IPv6 is not implemented on your system");
|
||||
return -1;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in6 sai;
|
||||
int sockfd;
|
||||
struct in6_ifreq ifr6;
|
||||
|
||||
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
|
||||
|
|
|
@ -161,7 +161,7 @@ extern "C"
|
|||
llarp::LogError("invalid ipv6 address: ", addr);
|
||||
return -1;
|
||||
}
|
||||
return tuntap_sys_set_ipv6(dev, &baddr6, mask);
|
||||
return tuntap_sys_set_ipv6(dev, &baddr6, netmask);
|
||||
}
|
||||
else if(errval == -1)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue