lokinet/llarp/exit_info.cpp
despair86 bdc54835c2 initial windows server port. Requires Windows 2000 Server or later.
- updated CMake build script
- builds with Microsoft C++ 19.1x. such builds require Windows 8.1 or later
  unless you have the .NET Server 2003-toolset (v141_xp)
- windows port requires a C++17 compiler since cpp17::filesystem is POSIX-only
- HAVE_CXX17_FILESYSTEM manual toggle in CMake. You must manually specify where
  std::[experimental::]filesystem is defined in LDFLAGS or CMAKE_x_LINKER_FLAGS.
- IPv6 support can be added at any time, and the windows sdk still has that
  inline getaddrinfo(3) if it can't find a suitable IPv6 stack.
- inline code for mingw-w64: there's a few bits and pieces still missing simply because
  mingw-w64 derives its windows sdk from wine and reactos, and then writing all the newer
  stuff into it by hand straight from the MSDN manpages.
- misc. C++11 stuff (nullptr and friends)
- Internal file handling code takes UTF-8 or plain 8-bit text, NTFS is UTF-16, so
  std::filesystem::path::c_str() is wchar_t. That's no good unless you first
  call std::filesystem::path::string().
- implemented getifaddrs(3) and if_nametoindex(3) on top of GetAdapters[Info|Addresses](2).
- updated readme with new info

BONUS: may implement Solaris/illumos IOCP someday...

-despair86
2018-08-01 23:41:02 -05:00

192 lines
4.1 KiB
C++

#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include <llarp/bencode.h>
#include <llarp/exit_info.h>
#include <llarp/mem.h>
#include <llarp/string.h>
#include <list>
struct llarp_xi_list
{
std::list< llarp_xi > list;
};
struct llarp_xi_list *
llarp_xi_list_new()
{
return new llarp_xi_list;
}
void
llarp_xi_list_free(struct llarp_xi_list *l)
{
if(l)
{
delete l;
}
}
static bool
llarp_xi_iter_bencode(struct llarp_xi_list_iter *iter, struct llarp_xi *xi)
{
return llarp_xi_bencode(xi, static_cast< llarp_buffer_t * >(iter->user));
}
bool
llarp_xi_list_bencode(struct llarp_xi_list *l, llarp_buffer_t *buff)
{
if(!bencode_start_list(buff))
return false;
struct llarp_xi_list_iter xi_itr = {buff, nullptr, &llarp_xi_iter_bencode};
llarp_xi_list_iterate(l, &xi_itr);
return bencode_end(buff);
}
void
llarp_xi_list_iterate(struct llarp_xi_list *l, struct llarp_xi_list_iter *iter)
{
iter->list = l;
for(auto &item : l->list)
if(!iter->visit(iter, &item))
return;
}
bool
llarp_xi_bencode(struct llarp_xi *xi, llarp_buffer_t *buff)
{
char addr_buff[128] = {0};
const char *addr;
if(!bencode_start_dict(buff))
return false;
/** address */
addr = inet_ntop(AF_INET6, &xi->address, addr_buff, sizeof(addr_buff));
if(!addr)
return false;
if(!bencode_write_bytestring(buff, "a", 1))
return false;
if(!bencode_write_bytestring(buff, addr, strnlen(addr, sizeof(addr_buff))))
return false;
/** netmask */
addr = inet_ntop(AF_INET6, &xi->netmask, addr_buff, sizeof(addr_buff));
if(!addr)
return false;
if(!bencode_write_bytestring(buff, "b", 1))
return false;
if(!bencode_write_bytestring(buff, addr, strnlen(addr, sizeof(addr_buff))))
return false;
/** public key */
if(!bencode_write_bytestring(buff, "k", 1))
return false;
if(!bencode_write_bytestring(buff, xi->pubkey, PUBKEYSIZE))
return false;
/** version */
if(!bencode_write_version_entry(buff))
return false;
return bencode_end(buff);
}
static bool
llarp_xi_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
{
if(!key)
return true;
llarp_xi *xi = static_cast< llarp_xi * >(r->user);
llarp_buffer_t strbuf;
uint64_t v;
char tmp[128] = {0};
// address
if(llarp_buffer_eq(*key, "a"))
{
if(!bencode_read_string(r->buffer, &strbuf))
return false;
if(strbuf.sz >= sizeof(tmp))
return false;
memcpy(tmp, strbuf.base, strbuf.sz);
return inet_pton(AF_INET6, tmp, xi->address.s6_addr) == 1;
}
if(llarp_buffer_eq(*key, "b"))
{
if(!bencode_read_string(r->buffer, &strbuf))
return false;
if(strbuf.sz >= sizeof(tmp))
return false;
memcpy(tmp, strbuf.base, strbuf.sz);
return inet_pton(AF_INET6, tmp, xi->netmask.s6_addr) == 1;
}
if(llarp_buffer_eq(*key, "k"))
{
if(!bencode_read_string(r->buffer, &strbuf))
return false;
if(strbuf.sz != PUBKEYSIZE)
return false;
memcpy(xi->pubkey, strbuf.base, PUBKEYSIZE);
return true;
}
if(llarp_buffer_eq(*key, "v"))
{
if(!bencode_read_integer(r->buffer, &v))
return false;
return v == LLARP_PROTO_VERSION;
}
return false;
}
bool
llarp_xi_bdecode(struct llarp_xi *xi, llarp_buffer_t *buf)
{
struct dict_reader r = {buf, xi, &llarp_xi_decode_dict};
return bencode_read_dict(buf, &r);
}
void
llarp_xi_list_pushback(struct llarp_xi_list *l, struct llarp_xi *xi)
{
l->list.emplace_back();
llarp_xi_copy(&l->list.back(), xi);
}
void
llarp_xi_copy(struct llarp_xi *dst, struct llarp_xi *src)
{
memcpy(dst, src, sizeof(struct llarp_xi));
}
static bool
llarp_xi_list_decode_item(struct list_reader *r, bool more)
{
if(!more)
return true;
llarp_xi_list *l = static_cast< llarp_xi_list * >(r->user);
l->list.emplace_back();
return llarp_xi_bdecode(&l->list.back(), r->buffer);
}
void
llarp_xi_list_copy(struct llarp_xi_list *dst, struct llarp_xi_list *src)
{
dst->list.clear();
for(auto &itr : src->list)
dst->list.emplace_back(itr);
}
bool
llarp_xi_list_bdecode(struct llarp_xi_list *l, llarp_buffer_t *buff)
{
list_reader r = {buff, l, &llarp_xi_list_decode_item};
return bencode_read_list(buff, &r);
}