diff --git a/llarp/iwp/linklayer.cpp b/llarp/iwp/linklayer.cpp index 13ec7c222..3ad98cbc7 100644 --- a/llarp/iwp/linklayer.cpp +++ b/llarp/iwp/linklayer.cpp @@ -90,7 +90,7 @@ namespace llarp::iwp } void - LinkLayer::UnmapAddr(const IpAddress& addr) + LinkLayer::UnmapAddr(const SockAddr& addr) { m_AuthedAddrs.erase(addr); } @@ -104,9 +104,8 @@ namespace llarp::iwp void LinkLayer::AddWakeup(std::weak_ptr session) { - if (m_PlaintextRecv.full()) - HandleWakeupPlaintext(); - m_PlaintextRecv.tryPushBack(session); + if (auto ptr = session.lock()) + m_PlaintextRecv[ptr->GetRemoteEndpoint()] = session; } void @@ -118,13 +117,13 @@ namespace llarp::iwp void LinkLayer::HandleWakeupPlaintext() { - while (not m_PlaintextRecv.empty()) + for (const auto& [addr, session] : m_PlaintextRecv) { - auto session = m_PlaintextRecv.popFront(); auto ptr = session.lock(); if (ptr) ptr->HandlePlaintext(); } + m_PlaintextRecv.clear(); PumpDone(); } diff --git a/llarp/iwp/linklayer.hpp b/llarp/iwp/linklayer.hpp index cc9e90c3a..a713a34b9 100644 --- a/llarp/iwp/linklayer.hpp +++ b/llarp/iwp/linklayer.hpp @@ -51,7 +51,7 @@ namespace llarp::iwp MapAddr(const RouterID& pk, ILinkSession* s) override; void - UnmapAddr(const IpAddress& addr); + UnmapAddr(const SockAddr& addr); void WakeupPlaintext(); @@ -64,8 +64,8 @@ namespace llarp::iwp HandleWakeupPlaintext(); EventLoopWakeup* const m_Wakeup; - llarp::thread::Queue> m_PlaintextRecv; - std::unordered_map m_AuthedAddrs; + std::unordered_map, SockAddr::Hash> m_PlaintextRecv; + std::unordered_map m_AuthedAddrs; const bool permitInbound; }; diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 7fd6874b4..99f56d166 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -33,7 +33,7 @@ namespace llarp , m_Inbound{false} , m_Parent(p) , m_CreatedAt{p->Now()} - , m_RemoteAddr(ai.toIpAddress()) + , m_RemoteAddr{ai} , m_ChosenAI(ai) , m_RemoteRC(rc) , m_PlaintextRecv{PlaintextQueueSize} @@ -43,12 +43,12 @@ namespace llarp CryptoManager::instance()->shorthash(m_SessionKey, llarp_buffer_t(rc.pubkey)); } - Session::Session(LinkLayer* p, const IpAddress& from) + Session::Session(LinkLayer* p, const SockAddr& from) : m_State{State::Initial} , m_Inbound{true} , m_Parent(p) , m_CreatedAt{p->Now()} - , m_RemoteAddr(from) + , m_RemoteAddr{from} , m_PlaintextRecv{PlaintextQueueSize} { token.Randomize(); @@ -62,7 +62,7 @@ namespace llarp { LogDebug("send ", sz, " to ", m_RemoteAddr); const llarp_buffer_t pkt(buf, sz); - m_Parent->SendTo_LL(m_RemoteAddr.createSockAddr(), pkt); + m_Parent->SendTo_LL(m_RemoteAddr, pkt); m_LastTX = time_now_ms(); m_TXRate += sz; } diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index e6b71f2e0..acccd56a3 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -44,7 +44,7 @@ namespace llarp /// outbound session Session(LinkLayer* parent, const RouterContact& rc, const AddressInfo& ai); /// inbound session - Session(LinkLayer* parent, const IpAddress& from); + Session(LinkLayer* parent, const SockAddr& from); ~Session() = default; @@ -85,7 +85,7 @@ namespace llarp return m_RemoteRC.pubkey; } - IpAddress + const SockAddr& GetRemoteEndpoint() const override { return m_RemoteAddr; @@ -153,7 +153,7 @@ namespace llarp /// parent link layer LinkLayer* const m_Parent; const llarp_time_t m_CreatedAt; - const IpAddress m_RemoteAddr; + const SockAddr m_RemoteAddr; AddressInfo m_ChosenAI; /// remote rc diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 39756add1..0c03840e7 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -152,7 +152,7 @@ namespace llarp { try { - m_ourAddr = IpAddress(ifname); + m_ourAddr = SockAddr{ifname + ":0"}; } catch (const std::exception& e) { @@ -162,7 +162,7 @@ namespace llarp } } m_ourAddr.setPort(port); - return llarp_ev_add_udp(m_Loop, &m_udp, m_ourAddr.createSockAddr()) != -1; + return llarp_ev_add_udp(m_Loop, &m_udp, m_ourAddr) != -1; } void @@ -233,7 +233,7 @@ namespace llarp { Lock_t l_authed(m_AuthedLinksMutex); Lock_t l_pending(m_PendingMutex); - IpAddress addr = s->GetRemoteEndpoint(); + const auto addr = s->GetRemoteEndpoint(); auto itr = m_Pending.find(addr); if (itr != m_Pending.end()) { @@ -307,7 +307,7 @@ namespace llarp llarp::AddressInfo to; if (!PickAddress(rc, to)) return false; - const IpAddress address = to.toIpAddress(); + const SockAddr address{to}; { Lock_t l(m_PendingMutex); if (m_Pending.count(address) >= MaxSessionsPerKey) @@ -471,7 +471,7 @@ namespace llarp bool ILinkLayer::GetOurAddressInfo(llarp::AddressInfo& addr) const { - addr.fromIpAddress(m_ourAddr); + addr.fromSockAddr(m_ourAddr); addr.dialect = Name(); addr.pubkey = TransportPubKey(); addr.rank = Rank(); @@ -495,7 +495,7 @@ namespace llarp { static constexpr size_t MaxSessionsPerEndpoint = 5; Lock_t lock(m_PendingMutex); - IpAddress address = s->GetRemoteEndpoint(); + const auto address = s->GetRemoteEndpoint(); if (m_Pending.count(address) >= MaxSessionsPerEndpoint) return false; m_Pending.emplace(address, s); diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index 19503df01..a428df0fa 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -258,20 +258,20 @@ namespace llarp std::shared_ptr m_Logic = nullptr; llarp_ev_loop_ptr m_Loop; - IpAddress m_ourAddr; + SockAddr m_ourAddr; llarp_udp_io m_udp; SecretKey m_SecretKey; using AuthedLinks = std::unordered_multimap, RouterID::Hash>; using Pending = - std::unordered_multimap, IpAddress::Hash>; + std::unordered_multimap, SockAddr::Hash>; mutable DECLARE_LOCK(Mutex_t, m_AuthedLinksMutex, ACQUIRED_BEFORE(m_PendingMutex)); AuthedLinks m_AuthedLinks GUARDED_BY(m_AuthedLinksMutex); mutable DECLARE_LOCK(Mutex_t, m_PendingMutex, ACQUIRED_AFTER(m_AuthedLinksMutex)); Pending m_Pending GUARDED_BY(m_PendingMutex); - std::unordered_map m_RecentlyClosed; + std::unordered_map m_RecentlyClosed; }; using LinkLayer_ptr = std::shared_ptr; diff --git a/llarp/link/session.hpp b/llarp/link/session.hpp index 73cf6cff5..8a744c07e 100644 --- a/llarp/link/session.hpp +++ b/llarp/link/session.hpp @@ -95,7 +95,7 @@ namespace llarp IsInbound() const = 0; /// get remote address - virtual IpAddress + virtual const SockAddr& GetRemoteEndpoint() const = 0; // get remote rc diff --git a/llarp/net/address_info.cpp b/llarp/net/address_info.cpp index 1c2ff66c9..399aec920 100644 --- a/llarp/net/address_info.cpp +++ b/llarp/net/address_info.cpp @@ -158,13 +158,11 @@ namespace llarp } void - AddressInfo::fromIpAddress(const IpAddress& address) + AddressInfo::fromSockAddr(const SockAddr& addr) { - SockAddr addr = address.createSockAddr(); const sockaddr_in6* addr6 = addr; memcpy(ip.s6_addr, addr6->sin6_addr.s6_addr, sizeof(ip.s6_addr)); - - port = address.getPort().value_or(0); + port = addr.getPort(); } std::ostream& diff --git a/llarp/net/address_info.hpp b/llarp/net/address_info.hpp index 39489075d..5c9c9ac09 100644 --- a/llarp/net/address_info.hpp +++ b/llarp/net/address_info.hpp @@ -44,9 +44,9 @@ namespace llarp IpAddress toIpAddress() const; - /// Updates our ip and port to reflact that of the given IpAddress + /// Updates our ip and port to reflact that of the given SockAddr void - fromIpAddress(const IpAddress& address); + fromSockAddr(const SockAddr& address); std::ostream& print(std::ostream& stream, int level, int spaces) const; diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index 648f923b3..ceb3d3b14 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -545,7 +545,7 @@ namespace llarp return std::nullopt; } - std::optional + std::optional GetInterfaceAddr(const std::string& ifname, int af) { sockaddr_storage s; @@ -553,8 +553,7 @@ namespace llarp sptr->sa_family = af; if (!llarp_getifaddr(ifname.c_str(), af, sptr)) return std::nullopt; - llarp::SockAddr saddr = SockAddr{*sptr}; - return llarp::IpAddress(saddr); + return SockAddr{*sptr}; } std::optional @@ -570,7 +569,7 @@ namespace llarp } bool - AllInterfaces(int af, IpAddress& result) + AllInterfaces(int af, SockAddr& result) { if (af == AF_INET) { @@ -578,25 +577,18 @@ namespace llarp addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); - SockAddr saddr = SockAddr(addr); - result = IpAddress(saddr); + result = SockAddr{addr}; return true; } if (af == AF_INET6) { - throw std::runtime_error("Fix me: IPv6 not supported yet"); - /* sockaddr_in6 addr6; addr6.sin6_family = AF_INET6; addr6.sin6_port = htons(0); addr6.sin6_addr = IN6ADDR_ANY_INIT; - result = IpAddress(SockAddr(addr6)); + result = SockAddr{addr6}; return true; - */ } - - // TODO: implement sockaddr_ll - return false; } diff --git a/llarp/net/net.hpp b/llarp/net/net.hpp index 5aa8ce25c..c65243a1e 100644 --- a/llarp/net/net.hpp +++ b/llarp/net/net.hpp @@ -59,7 +59,7 @@ namespace llarp IsBogonRange(const in6_addr& host, const in6_addr& mask); bool - AllInterfaces(int af, IpAddress& addr); + AllInterfaces(int af, SockAddr& addr); /// get first network interface with public address bool @@ -74,7 +74,7 @@ namespace llarp FindFreeTun(); /// get network interface address for network interface with ifname - std::optional + std::optional GetInterfaceAddr(const std::string& ifname, int af = AF_INET); /// get an interface's ip6 address diff --git a/llarp/net/net_int.cpp b/llarp/net/net_int.cpp index d8c378a05..5642201ba 100644 --- a/llarp/net/net_int.cpp +++ b/llarp/net/net_int.cpp @@ -4,6 +4,13 @@ namespace llarp { + template <> + huint32_t + ToHost(nuint32_t n) + { + return xntohl(n); + } + template <> nuint32_t ToNet(huint32_t h) diff --git a/llarp/net/route.cpp b/llarp/net/route.cpp index 682e0e94c..c66de1b93 100644 --- a/llarp/net/route.cpp +++ b/llarp/net/route.cpp @@ -375,7 +375,8 @@ namespace llarp::net throw std::runtime_error("we dont have our own net interface?"); int nl_cmd = RTM_NEWROUTE; int nl_flags = NLM_F_CREATE | NLM_F_EXCL; - read_addr(maybe->toHost().c_str(), &gw_addr); + const auto host = maybe->asIPv4().ToString(); + read_addr(host.c_str(), &gw_addr); read_addr("0.0.0.0", &to_addr, 1); do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eLowerDefault, if_idx); read_addr("128.0.0.0", &to_addr, 1); @@ -441,7 +442,8 @@ namespace llarp::net throw std::runtime_error("we dont have our own net interface?"); int nl_cmd = RTM_DELROUTE; int nl_flags = 0; - read_addr(maybe->toHost().c_str(), &gw_addr); + const auto host = maybe->asIPv4().ToString(); + read_addr(host.c_str(), &gw_addr); read_addr("0.0.0.0", &to_addr, 1); do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eLowerDefault, if_idx); read_addr("128.0.0.0", &to_addr, 1); diff --git a/llarp/net/sock_addr.cpp b/llarp/net/sock_addr.cpp index a4598a02e..495cea5b1 100644 --- a/llarp/net/sock_addr.cpp +++ b/llarp/net/sock_addr.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -10,6 +11,11 @@ namespace llarp { + bool + operator==(const in6_addr& lh, const in6_addr& rh) + { + return memcmp(&lh, &rh, sizeof(in6_addr)) == 0; + } /// shared utility functions /// @@ -51,13 +57,17 @@ namespace llarp setIPv4(a, b, c, d); setPort(port); } - SockAddr::SockAddr(std::string_view addr) { init(); fromString(addr); } + SockAddr::SockAddr(const AddressInfo& info) : SockAddr{info.ip} + { + setPort(info.port); + } + SockAddr::SockAddr(const SockAddr& other) { *this = other; @@ -174,18 +184,8 @@ namespace llarp bool SockAddr::operator==(const SockAddr& other) const { - if (m_addr.sin6_family != other.m_addr.sin6_family) - return false; - - if (getPort() != other.getPort()) - return false; - - return ( - 0 - == memcmp( - m_addr.sin6_addr.s6_addr, - other.m_addr.sin6_addr.s6_addr, - sizeof(m_addr.sin6_addr.s6_addr))); + return m_addr.sin6_addr == other.m_addr.sin6_addr + and m_addr.sin6_port == other.m_addr.sin6_port; } huint128_t @@ -194,6 +194,13 @@ namespace llarp return net::In6ToHUInt(m_addr.sin6_addr); } + huint32_t + SockAddr::asIPv4() const + { + const nuint32_t n{m_addr4.sin_addr.s_addr}; + return ToHost(n); + } + void SockAddr::fromString(std::string_view str) { diff --git a/llarp/net/sock_addr.hpp b/llarp/net/sock_addr.hpp index bf0b42aa6..5784f3ab1 100644 --- a/llarp/net/sock_addr.hpp +++ b/llarp/net/sock_addr.hpp @@ -20,6 +20,8 @@ inet_pton(int af, const char* src, void* dst); namespace llarp { + struct AddressInfo; + /// A simple SockAddr wrapper which provides a sockaddr_in (IPv4). Memory management is handled /// in constructor and destructor (if needed) and copying is disabled. struct SockAddr @@ -29,6 +31,8 @@ namespace llarp SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port); SockAddr(std::string_view addr); + SockAddr(const AddressInfo&); + SockAddr(const SockAddr&); SockAddr& operator=(const SockAddr&); @@ -75,15 +79,31 @@ namespace llarp void setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d); + /// port is in host order void setPort(uint16_t port); + /// port is in host order uint16_t getPort() const; huint128_t asIPv6() const; + huint32_t + asIPv4() const; + + struct Hash + { + size_t + operator()(const SockAddr& addr) const noexcept + { + const std::hash port{}; + const std::hash ip{}; + return (port(addr.getPort()) << 3) ^ ip(addr.asIPv6()); + } + }; + private: bool m_empty = true; sockaddr_in6 m_addr; diff --git a/llarp/router/route_poker.cpp b/llarp/router/route_poker.cpp index d537a8f8b..6dcf14b98 100644 --- a/llarp/router/route_poker.cpp +++ b/llarp/router/route_poker.cpp @@ -174,7 +174,8 @@ namespace llarp { // explicit route pokes for first hops m_Router->ForEachPeer( - [&](auto session, auto) mutable { AddRoute(session->GetRemoteEndpoint().toIP()); }, false); + [&](auto session, auto) mutable { AddRoute(session->GetRemoteEndpoint().asIPv4()); }, + false); // add default route const auto ep = m_Router->hiddenServiceContext().GetDefault(); net::AddDefaultRouteViaInterface(ep->GetIfName()); @@ -185,7 +186,8 @@ namespace llarp { // unpoke routes for first hops m_Router->ForEachPeer( - [&](auto session, auto) mutable { DelRoute(session->GetRemoteEndpoint().toIP()); }, false); + [&](auto session, auto) mutable { DelRoute(session->GetRemoteEndpoint().asIPv4()); }, + false); // remove default route const auto ep = m_Router->hiddenServiceContext().GetDefault(); net::DelDefaultRouteViaInterface(ep->GetIfName()); diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 53b9fb222..ddaacaec7 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -472,7 +472,7 @@ namespace llarp transport_keyfile = m_keyManager->m_transportKeyPath; ident_keyfile = m_keyManager->m_idKeyPath; - _ourAddress = conf.router.m_publicAddress; + _ourAddress = conf.router.m_publicAddress.createSockAddr(); RouterContact::BlockBogons = conf.router.m_blockBogons; @@ -1032,9 +1032,9 @@ namespace llarp if (link->GetOurAddressInfo(ai)) { // override ip and port - if (not _ourAddress.isEmpty()) + if (_ourAddress) { - ai.fromIpAddress(_ourAddress); + ai.fromSockAddr(*_ourAddress); } if (RouterContact::BlockBogons && IsBogon(ai.ip)) return; diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 1750fc566..5fe527c57 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -178,7 +178,7 @@ namespace llarp void QueueDiskIO(std::function func) override; - IpAddress _ourAddress; + std::optional _ourAddress; llarp_ev_loop_ptr _netloop; std::shared_ptr _logic;