1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00
lokinet/llarp/net/address_info.cpp
Jason Rhinelander f168b7cf72
llarp_buffer_t: rename badly named operator==
It didn't do equality, it did "does the remaining space start with the
argument" (and so the replacement in the previous commit was broken).

This renames it to avoid the confusion and restores to what it was doing
on dev.
2022-09-19 20:25:51 -03:00

194 lines
4.3 KiB
C++

#include "address_info.hpp"
#include <stdexcept>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "net.hpp"
#include <llarp/util/bencode.h>
#include <llarp/util/mem.h>
#include <cstring>
namespace llarp
{
bool
operator==(const AddressInfo& lhs, const AddressInfo& rhs)
{
// we don't care about rank
return lhs.pubkey == rhs.pubkey && lhs.port == rhs.port && lhs.dialect == rhs.dialect
&& lhs.ip == rhs.ip;
}
bool
operator<(const AddressInfo& lhs, const AddressInfo& rhs)
{
return lhs.rank < rhs.rank || lhs.ip < rhs.ip || lhs.port < rhs.port;
}
std::variant<nuint32_t, nuint128_t>
AddressInfo::IP() const
{
return SockAddr{ip}.getIP();
}
bool
AddressInfo::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf)
{
uint64_t i;
char tmp[128] = {0};
llarp_buffer_t strbuf;
// rank
if (key.startswith("c"))
{
if (!bencode_read_integer(buf, &i))
return false;
if (i > 65536 || i <= 0)
return false;
rank = i;
return true;
}
// dialect
if (key.startswith("d"))
{
if (!bencode_read_string(buf, &strbuf))
return false;
if (strbuf.sz > sizeof(tmp))
return false;
memcpy(tmp, strbuf.base, strbuf.sz);
tmp[strbuf.sz] = 0;
dialect = std::string(tmp);
return true;
}
// encryption public key
if (key.startswith("e"))
{
return pubkey.BDecode(buf);
}
// ip address
if (key.startswith("i"))
{
if (!bencode_read_string(buf, &strbuf))
return false;
if (strbuf.sz >= sizeof(tmp))
return false;
memcpy(tmp, strbuf.base, strbuf.sz);
tmp[strbuf.sz] = 0;
return inet_pton(AF_INET6, tmp, &ip.s6_addr[0]) == 1;
}
// port
if (key.startswith("p"))
{
if (!bencode_read_integer(buf, &i))
return false;
if (i > 65536 || i <= 0)
return false;
port = i;
return true;
}
// version
if (key.startswith("v"))
{
if (!bencode_read_integer(buf, &i))
return false;
return i == llarp::constants::proto_version;
}
// bad key
return false;
}
bool
AddressInfo::BEncode(llarp_buffer_t* buff) const
{
char ipbuff[128] = {0};
const char* ipstr;
if (!bencode_start_dict(buff))
return false;
/* rank */
if (!bencode_write_bytestring(buff, "c", 1))
return false;
if (!bencode_write_uint64(buff, rank))
return false;
/* dialect */
if (!bencode_write_bytestring(buff, "d", 1))
return false;
if (!bencode_write_bytestring(buff, dialect.c_str(), dialect.size()))
return false;
/* encryption key */
if (!bencode_write_bytestring(buff, "e", 1))
return false;
if (!bencode_write_bytestring(buff, pubkey.data(), PUBKEYSIZE))
return false;
/** ip */
ipstr = inet_ntop(AF_INET6, (void*)&ip, ipbuff, sizeof(ipbuff));
if (!ipstr)
return false;
if (!bencode_write_bytestring(buff, "i", 1))
return false;
if (!bencode_write_bytestring(buff, ipstr, strnlen(ipstr, sizeof(ipbuff))))
return false;
/** port */
if (!bencode_write_bytestring(buff, "p", 1))
return false;
if (!bencode_write_uint64(buff, port))
return false;
/** version */
if (!bencode_write_uint64_entry(buff, "v", 1, llarp::constants::proto_version))
return false;
/** end */
return bencode_end(buff);
}
IpAddress
AddressInfo::toIpAddress() const
{
SockAddr addr(ip);
addr.setPort(port);
return IpAddress(addr);
}
void
AddressInfo::fromSockAddr(const SockAddr& addr)
{
const auto* addr6 = static_cast<const sockaddr_in6*>(addr);
memcpy(ip.s6_addr, addr6->sin6_addr.s6_addr, sizeof(ip.s6_addr));
port = addr.getPort();
}
std::string
AddressInfo::ToString() const
{
char tmp[INET6_ADDRSTRLEN] = {0};
inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp));
return fmt::format("[{}]:{}", tmp, port);
}
void
to_json(nlohmann::json& j, const AddressInfo& a)
{
char tmp[128] = {0};
inet_ntop(AF_INET6, (void*)&a.ip, tmp, sizeof(tmp));
j = nlohmann::json{
{"rank", a.rank},
{"dialect", a.dialect},
{"pubkey", a.pubkey.ToString()},
{"in6_addr", tmp},
{"port", a.port}};
}
} // namespace llarp