lokinet/llarp/quic/client.cpp
Jeff 871c3e3281
changeset for windows port
* wintun vpn platform for windows
* bundle config snippets into nsis installer for exit node, keyfile persisting, reduced hops mode.
* use wintun for vpn platform
* isolate all windows platform specific code into their own compilation units and libraries
* split up internal libraries into more specific components
* rename liblokinet.a target to liblokinet-amalgum.a to elimiate ambiguity with liblokinet.so
* DNS platform for win32
* rename llarp/ev/ev_libuv.{c,h}pp to llarp/ev/libuv.{c,h}pp as the old name was idiotic
* split up net platform into win32 and posix specific compilation units
* rename lokinet_init.c to easter_eggs.cpp as that is what they are for and it does not need to be a c compilation target
* add cmake option STRIP_SYMBOLS for seperating out debug symbols for windows builds
* intercept dns traffic on all interfaces on windows using windivert and feed it into lokinet
2022-09-08 14:24:59 -04:00

68 lines
2.1 KiB
C++

#include "client.hpp"
#include "tunnel.hpp"
#include <llarp/util/logging/buffer.hpp>
#include <llarp/util/logging.hpp>
#include <oxenc/variant.h>
#include <llarp/service/address.hpp>
#include <llarp/service/endpoint.hpp>
#include <llarp/ev/libuv.hpp>
#include <variant>
namespace llarp::quic
{
Client::Client(EndpointBase& ep, const SockAddr& remote, uint16_t pseudo_port) : Endpoint{ep}
{
default_stream_buffer_size =
0; // We steal uvw's provided buffers so don't need an outgoing data buffer
// *Our* port; we stuff this in the llarp quic header so it knows how to target quic packets
// back to *this* client.
local_addr.port(ToNet(huint16_t{pseudo_port}));
uint16_t tunnel_port = remote.getPort();
if (tunnel_port == 0)
throw std::logic_error{"Cannot tunnel to port 0"};
// TODO: need timers for:
//
// - timeout (to disconnect if idle for too long)
//
// - probably don't need for lokinet tunnel: change local addr -- attempts to re-bind the local
// socket
//
// - key_update_timer
Path path{local_addr, remote};
llarp::LogDebug("Connecting to ", remote);
auto conn = std::make_shared<Connection>(*this, ConnectionID::random(), path, tunnel_port);
conn->io_ready();
conns.emplace(conn->base_cid, std::move(conn));
}
std::shared_ptr<Connection>
Client::get_connection()
{
// A client only has one outgoing connection, so everything in conns should either be a
// shared_ptr or weak_ptr to that same outgoing connection so we can just use the first one.
auto it = conns.begin();
if (it == conns.end())
return nullptr;
if (auto* wptr = std::get_if<alias_conn_ptr>(&it->second))
return wptr->lock();
return var::get<primary_conn_ptr>(it->second);
}
size_t
Client::write_packet_header(nuint16_t, uint8_t ecn)
{
buf_[0] = CLIENT_TO_SERVER;
auto pseudo_port = local_addr.port();
std::memcpy(&buf_[1], &pseudo_port.n, 2); // remote quic pseudo-port (network order u16)
buf_[3] = std::byte{ecn};
return 4;
}
} // namespace llarp::quic