lokinet/llarp/address_info.cpp

164 lines
3.5 KiB
C++
Raw Normal View History

2018-12-12 00:26:37 +00:00
#include <address_info.hpp>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include <net/net.hpp>
#include <util/bencode.h>
#include <util/mem.h>
#include <string.h>
2018-08-31 12:46:54 +00:00
namespace llarp
{
2018-08-31 12:46:54 +00:00
AddressInfo::~AddressInfo()
{
}
2018-08-31 13:51:24 +00:00
AddressInfo &
AddressInfo::operator=(const AddressInfo &other)
{
rank = other.rank;
dialect = other.dialect;
pubkey = other.pubkey;
memcpy(ip.s6_addr, other.ip.s6_addr, 16);
port = other.port;
return *this;
}
bool
operator==(const AddressInfo &lhs, const AddressInfo &rhs)
{
// we don't care about rank
2018-12-12 00:26:37 +00:00
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 00:26:37 +00:00
return lhs.rank < rhs.rank || lhs.ip < rhs.ip || lhs.port < rhs.port;
}
2018-08-31 12:46:54 +00:00
bool
AddressInfo::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
{
2018-08-31 12:46:54 +00:00
uint64_t i;
char tmp[128] = {0};
llarp_buffer_t strbuf;
// rank
if(llarp_buffer_eq(key, "c"))
{
if(!bencode_read_integer(buf, &i))
return false;
if(i > 65536 || i <= 0)
return false;
rank = i;
return true;
}
// dialect
if(llarp_buffer_eq(key, "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(llarp_buffer_eq(key, "e"))
{
return pubkey.BDecode(buf);
2018-08-31 12:46:54 +00:00
}
// ip address
if(llarp_buffer_eq(key, "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(llarp_buffer_eq(key, "p"))
{
if(!bencode_read_integer(buf, &i))
return false;
if(i > 65536 || i <= 0)
return false;
port = i;
return true;
}
// version
if(llarp_buffer_eq(key, "v"))
{
if(!bencode_read_integer(buf, &i))
return false;
return i == LLARP_PROTO_VERSION;
}
// bad key
return false;
}
2018-08-31 12:46:54 +00:00
bool
AddressInfo::BEncode(llarp_buffer_t *buff) const
{
2018-08-31 12:46:54 +00:00
char ipbuff[128] = {0};
const char *ipstr;
if(!bencode_start_dict(buff))
return false;
2018-08-31 12:46:54 +00:00
/* rank */
if(!bencode_write_bytestring(buff, "c", 1))
return false;
2018-08-31 12:46:54 +00:00
if(!bencode_write_uint64(buff, rank))
return false;
2018-08-31 12:46:54 +00:00
/* dialect */
if(!bencode_write_bytestring(buff, "d", 1))
return false;
2018-08-31 12:46:54 +00:00
if(!bencode_write_bytestring(buff, dialect.c_str(), dialect.size()))
return false;
2018-08-31 12:46:54 +00:00
/* encryption key */
if(!bencode_write_bytestring(buff, "e", 1))
return false;
if(!bencode_write_bytestring(buff, pubkey.data(), PUBKEYSIZE))
2018-08-31 12:46:54 +00:00
return false;
/** ip */
2018-11-09 14:48:43 +00:00
ipstr = inet_ntop(AF_INET6, (void *)&ip, ipbuff, sizeof(ipbuff));
2018-08-31 12:46:54 +00:00
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;
2018-08-31 12:46:54 +00:00
/** version */
if(!bencode_write_version_entry(buff))
return false;
/** end */
return bencode_end(buff);
}
2018-08-31 12:46:54 +00:00
} // namespace llarp