lokinet/llarp/net/address_info.cpp

209 lines
4.5 KiB
C++
Raw Normal View History

#include "address_info.hpp"
2020-05-08 19:23:21 +02:00
#include <stdexcept>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include "net.hpp"
#include <llarp/util/bencode.h>
#include <llarp/util/mem.h>
#include <llarp/util/printer.hpp>
2019-07-31 01:42:13 +02:00
#include <cstring>
2018-08-31 14:46:54 +02:00
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)
{
2018-12-12 01:26:37 +01:00
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();
}
2018-08-31 14:46:54 +02:00
bool
AddressInfo::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf)
{
2018-08-31 14:46:54 +02:00
uint64_t i;
char tmp[128] = {0};
llarp_buffer_t strbuf;
// rank
if (key == "c")
2018-08-31 14:46:54 +02:00
{
if (!bencode_read_integer(buf, &i))
2018-08-31 14:46:54 +02:00
return false;
if (i > 65536 || i <= 0)
2018-08-31 14:46:54 +02:00
return false;
rank = i;
return true;
}
// dialect
if (key == "d")
2018-08-31 14:46:54 +02:00
{
if (!bencode_read_string(buf, &strbuf))
2018-08-31 14:46:54 +02:00
return false;
if (strbuf.sz > sizeof(tmp))
2018-08-31 14:46:54 +02:00
return false;
memcpy(tmp, strbuf.base, strbuf.sz);
tmp[strbuf.sz] = 0;
dialect = std::string(tmp);
2018-08-31 14:46:54 +02:00
return true;
}
// encryption public key
if (key == "e")
2018-08-31 14:46:54 +02:00
{
return pubkey.BDecode(buf);
2018-08-31 14:46:54 +02:00
}
// ip address
if (key == "i")
2018-08-31 14:46:54 +02:00
{
if (!bencode_read_string(buf, &strbuf))
2018-08-31 14:46:54 +02:00
return false;
if (strbuf.sz >= sizeof(tmp))
2018-08-31 14:46:54 +02:00
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 == "p")
2018-08-31 14:46:54 +02:00
{
if (!bencode_read_integer(buf, &i))
2018-08-31 14:46:54 +02:00
return false;
if (i > 65536 || i <= 0)
2018-08-31 14:46:54 +02:00
return false;
port = i;
return true;
}
// version
if (key == "v")
2018-08-31 14:46:54 +02:00
{
if (!bencode_read_integer(buf, &i))
2018-08-31 14:46:54 +02:00
return false;
2022-05-26 17:59:44 +02:00
return i == llarp::constants::proto_version;
2018-08-31 14:46:54 +02:00
}
// bad key
return false;
}
2018-08-31 14:46:54 +02:00
bool
AddressInfo::BEncode(llarp_buffer_t* buff) const
{
2018-08-31 14:46:54 +02:00
char ipbuff[128] = {0};
const char* ipstr;
if (!bencode_start_dict(buff))
return false;
2018-08-31 14:46:54 +02:00
/* rank */
if (!bencode_write_bytestring(buff, "c", 1))
return false;
if (!bencode_write_uint64(buff, rank))
return false;
2018-08-31 14:46:54 +02:00
/* dialect */
if (!bencode_write_bytestring(buff, "d", 1))
return false;
if (!bencode_write_bytestring(buff, dialect.c_str(), dialect.size()))
return false;
2018-08-31 14:46:54 +02:00
/* encryption key */
if (!bencode_write_bytestring(buff, "e", 1))
return false;
if (!bencode_write_bytestring(buff, pubkey.data(), PUBKEYSIZE))
2018-08-31 14:46:54 +02:00
return false;
/** ip */
ipstr = inet_ntop(AF_INET6, (void*)&ip, ipbuff, sizeof(ipbuff));
if (!ipstr)
2018-08-31 14:46:54 +02:00
return false;
if (!bencode_write_bytestring(buff, "i", 1))
2018-08-31 14:46:54 +02:00
return false;
if (!bencode_write_bytestring(buff, ipstr, strnlen(ipstr, sizeof(ipbuff))))
2018-08-31 14:46:54 +02:00
return false;
/** port */
if (!bencode_write_bytestring(buff, "p", 1))
2018-08-31 14:46:54 +02:00
return false;
if (!bencode_write_uint64(buff, port))
return false;
2018-08-31 14:46:54 +02:00
/** version */
2022-05-26 17:59:44 +02:00
if (!bencode_write_uint64_entry(buff, "v", 1, llarp::constants::proto_version))
2018-08-31 14:46:54 +02:00
return false;
/** end */
return bencode_end(buff);
}
2019-02-25 00:46:37 +01:00
2020-05-08 19:23:21 +02:00
IpAddress
AddressInfo::toIpAddress() const
{
2020-05-11 18:14:07 +02:00
SockAddr addr(ip);
addr.setPort(port);
return IpAddress(addr);
2020-05-08 19:23:21 +02:00
}
void
AddressInfo::fromSockAddr(const SockAddr& addr)
2020-05-08 19:23:21 +02:00
{
const auto* addr6 = static_cast<const sockaddr_in6*>(addr);
2020-05-11 18:14:07 +02:00
memcpy(ip.s6_addr, addr6->sin6_addr.s6_addr, sizeof(ip.s6_addr));
port = addr.getPort();
2020-05-08 19:23:21 +02:00
}
std::ostream&
AddressInfo::print(std::ostream& stream, int level, int spaces) const
2019-02-25 00:46:37 +01:00
{
char tmp[128] = {0};
inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp));
2019-02-25 00:46:37 +01:00
Printer printer(stream, level, spaces);
printer.printAttribute("ip", tmp);
printer.printAttribute("port", port);
return stream;
}
2019-08-20 00:25:40 +02:00
std::string
AddressInfo::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
2019-08-20 00:25:40 +02:00
void
to_json(nlohmann::json& j, const AddressInfo& a)
2019-08-20 00:25:40 +02:00
{
char tmp[128] = {0};
inet_ntop(AF_INET6, (void*)&a.ip, tmp, sizeof(tmp));
2019-08-20 00:25:40 +02:00
2021-03-05 18:31:52 +01:00
j = nlohmann::json{
{"rank", a.rank},
{"dialect", a.dialect},
{"pubkey", a.pubkey.ToString()},
{"in6_addr", tmp},
{"port", a.port}};
2019-08-20 00:25:40 +02:00
}
2018-08-31 14:46:54 +02:00
} // namespace llarp