2021-03-10 15:11:42 +00:00
|
|
|
#pragma once
|
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
#include <llarp/net/sock_addr.hpp>
|
|
|
|
#include <llarp/service/convotag.hpp>
|
2021-03-10 15:11:42 +00:00
|
|
|
|
|
|
|
#include <charconv>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <chrono>
|
2021-03-10 15:11:42 +00:00
|
|
|
#include <cstdint>
|
2023-10-19 11:49:46 +00:00
|
|
|
#include <queue>
|
2021-03-10 15:11:42 +00:00
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <unordered_set>
|
2021-03-10 15:11:42 +00:00
|
|
|
|
2023-10-23 22:58:58 +00:00
|
|
|
// #include <uvw/tcp.h>
|
2021-03-10 15:11:42 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
class EndpointBase;
|
|
|
|
}
|
|
|
|
|
2023-10-12 20:37:45 +00:00
|
|
|
namespace llarp::link
|
2021-03-10 15:11:42 +00:00
|
|
|
{
|
2023-10-19 21:59:57 +00:00
|
|
|
// struct Endpoint;
|
2023-10-12 20:37:45 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
using namespace std::chrono_literals;
|
|
|
|
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
namespace tunnel
|
|
|
|
{
|
|
|
|
// The server sends back a 0x00 to signal that the remote TCP connection was established and
|
|
|
|
// that it is now accepting stream data; the client is not allowed to send any other data down
|
|
|
|
// the stream until this comes back (any data sent down the stream before then is discarded.)
|
|
|
|
inline constexpr std::byte CONNECT_INIT{0x00};
|
|
|
|
// QUIC application error codes we sent on failures:
|
|
|
|
// Failure to establish an initial connection:
|
|
|
|
inline constexpr uint64_t ERROR_CONNECT{0x5471907};
|
|
|
|
// Error if we receive something other than CONNECT_INIT as the initial stream data from the
|
|
|
|
// server
|
|
|
|
inline constexpr uint64_t ERROR_BAD_INIT{0x5471908};
|
|
|
|
// Close error code sent if we get an error on the TCP socket (other than an initial connect
|
|
|
|
// failure)
|
|
|
|
inline constexpr uint64_t ERROR_TCP{0x5471909};
|
|
|
|
|
|
|
|
// We pause reading from the local TCP socket if we have more than this amount of outstanding
|
|
|
|
// unacked data in the quic tunnel, then resume once it drops below this.
|
|
|
|
inline constexpr size_t PAUSE_SIZE = 64 * 1024;
|
|
|
|
} // namespace tunnel
|
|
|
|
|
|
|
|
/// Manager class for incoming and outgoing QUIC tunnels.
|
|
|
|
class TunnelManager
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ListenHandler = std::function<std::optional<SockAddr>(
|
|
|
|
std::string_view lokinet_addr, // The remote's full lokinet address
|
|
|
|
uint16_t port // The requested port the tunnel wants to reach
|
|
|
|
)>;
|
|
|
|
|
|
|
|
// Timeout for the next `open()`. Note that when `open()` is given a ONS name to resolve this
|
|
|
|
// includes the resolution time.
|
2021-03-27 18:54:09 +00:00
|
|
|
std::chrono::milliseconds open_timeout = 4s;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
2021-03-26 13:16:43 +00:00
|
|
|
TunnelManager(EndpointBase& endpoint);
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
/// Adds an incoming listener callback. When a new incoming quic connection is initiated to us
|
|
|
|
/// by some remote we invoke these callback(s) in order of registration. Each one has three
|
|
|
|
/// options:
|
|
|
|
/// - return a concrete llarp::SockAddr giving the TCP address/port to which we should connect
|
|
|
|
/// new incoming streams over the connection.
|
|
|
|
/// - returns std::nullopt to decline handling the connection (we will try the next listen
|
|
|
|
/// handler, in order of registration).
|
|
|
|
/// - throws an exception (derived from std::exception) in which case we refuse the connection
|
|
|
|
/// without trying any additional handlers.
|
|
|
|
///
|
|
|
|
/// If `listen()` is not called at all then new incoming connections will be immediately
|
|
|
|
/// dropped.
|
|
|
|
///
|
|
|
|
/// For plain-C wrappers around this see [FIXME].
|
|
|
|
int
|
|
|
|
listen(ListenHandler handler);
|
|
|
|
|
|
|
|
/// Simple wrapper around `listen(...)` that adds a handler that accepts all incoming
|
|
|
|
/// connections trying to tunnel to port `port` and maps them to `localhost:port`.
|
|
|
|
int
|
2021-03-31 10:57:06 +00:00
|
|
|
listen(SockAddr port);
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
/// Removes an incoming connection handler; takes the ID returned by `listen()`.
|
|
|
|
void
|
|
|
|
forget(int id);
|
|
|
|
|
|
|
|
/// Called when open succeeds or times out.
|
|
|
|
using OpenCallback = std::function<void(bool success)>;
|
|
|
|
|
|
|
|
/// Opens a quic tunnel to some remote lokinet address. (Should only be called from the event
|
|
|
|
/// loop thread.)
|
|
|
|
///
|
|
|
|
/// \param remote_addr is the lokinet address or ONS name (e.g. `azfojblahblahblah.loki` or
|
|
|
|
/// `blocks.loki`) that the tunnel should connect to.
|
|
|
|
/// \param port is the tunneled port on the remote that the client wants to reach. (This is
|
|
|
|
/// *not* the quic pseudo-port, which is always 0).
|
|
|
|
/// \param callback callback invoked when the quic connection has been established, or has timed
|
|
|
|
/// out.
|
|
|
|
/// \param bind_addr is the bind address and port that we should use for the localhost TCP
|
|
|
|
/// connection. Use port 0 to let the OS choose a random high port. Defaults to `127.0.0.1:0`.
|
|
|
|
///
|
|
|
|
/// This call immediately opens the local TCP socket, and initiates the lokinet connection and
|
|
|
|
/// QUIC tunnel to the remote. If the connection fails, the TCP socket will be closed. Note,
|
|
|
|
/// however, that this TCP socket will block until the underlying quic connection is
|
|
|
|
/// established.
|
|
|
|
///
|
|
|
|
/// Each connection to the local TCP socket establishes a new stream over the QUIC connection.
|
|
|
|
///
|
|
|
|
/// \return a pair:
|
|
|
|
/// - SockAddr containing the just-opened localhost socket that tunnels to the remote. This is
|
|
|
|
/// typically the same IP as `bind_addr`, with the port filled in (if bind_addr had a 0 port).
|
|
|
|
/// Note that, while you can connect to this socket immediately, it will block until the actual
|
|
|
|
/// connection and streams are established (and will be closed if they fail).
|
|
|
|
/// - unique integer that can be passed to close() to stop listening for new connections. This
|
|
|
|
/// also serves as a unique internal "pseudo-port" number to route returned quic packets to the
|
|
|
|
/// right connection.
|
|
|
|
///
|
|
|
|
/// TODO: add a callback to invoke when QUIC connection succeeds or fails.
|
|
|
|
/// TODO: add a plain C wrapper around this
|
|
|
|
std::pair<SockAddr, uint16_t>
|
|
|
|
open(
|
|
|
|
std::string_view remote_addr,
|
|
|
|
uint16_t port,
|
|
|
|
OpenCallback on_open = {},
|
|
|
|
SockAddr bind_addr = {127, 0, 0, 1});
|
|
|
|
|
|
|
|
/// Start closing an outgoing tunnel; takes the ID returned by `open()`. Note that an existing
|
|
|
|
/// established tunneled connections will not be forcibly closed; this simply stops accepting
|
|
|
|
/// new tunnel connections.
|
|
|
|
void
|
|
|
|
close(int id);
|
|
|
|
|
|
|
|
/// Called from tun code to deliver a quic packet.
|
|
|
|
///
|
|
|
|
/// \param dest - the convotag for which the packet arrived
|
|
|
|
/// \param buf - the raw arriving packet
|
|
|
|
///
|
|
|
|
void
|
|
|
|
receive_packet(const service::ConvoTag& tag, const llarp_buffer_t& buf);
|
|
|
|
|
2021-04-14 15:07:06 +00:00
|
|
|
/// return true if we have any listeners added
|
|
|
|
inline bool
|
|
|
|
hasListeners() const
|
|
|
|
{
|
|
|
|
return not incoming_handlers_.empty();
|
|
|
|
}
|
|
|
|
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
private:
|
2021-03-26 13:16:43 +00:00
|
|
|
EndpointBase& service_endpoint_;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
struct ClientTunnel
|
|
|
|
{
|
|
|
|
// quic endpoint
|
2023-10-19 21:59:57 +00:00
|
|
|
// std::unique_ptr<Endpoint> client;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
// Callback to invoke on quic connection established (true argument) or failed (false arg)
|
|
|
|
OpenCallback open_cb;
|
|
|
|
// TCP listening socket
|
2023-10-23 22:58:58 +00:00
|
|
|
// std::shared_ptr<uvw::TCPHandle> tcp;
|
|
|
|
// // Accepted TCP connections
|
|
|
|
// std::unordered_set<std::shared_ptr<uvw::TCPHandle>> conns;
|
|
|
|
// // Queue of incoming connections that are waiting for a stream to become available (either
|
|
|
|
// // because we are still handshaking, or we reached the stream limit).
|
|
|
|
// std::queue<std::weak_ptr<uvw::TCPHandle>> pending_incoming;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
2023-10-19 21:59:57 +00:00
|
|
|
~ClientTunnel()
|
|
|
|
{
|
|
|
|
// if (tcp)
|
|
|
|
// {
|
|
|
|
// tcp->close();
|
|
|
|
// tcp->data(nullptr);
|
|
|
|
// tcp.reset();
|
|
|
|
// }
|
|
|
|
// for (auto& conn : conns)
|
|
|
|
// conn->close();
|
|
|
|
// conns.clear();
|
|
|
|
|
|
|
|
// while (not pending_incoming.empty())
|
|
|
|
// {
|
|
|
|
// if (auto tcp = pending_incoming.front().lock())
|
|
|
|
// {
|
|
|
|
// tcp->clear();
|
|
|
|
// tcp->close();
|
|
|
|
// }
|
|
|
|
// pending_incoming.pop();
|
|
|
|
// }
|
|
|
|
}
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// pseudo-port -> Client instance (the "port" is used to route incoming quic packets to the
|
|
|
|
// right quic endpoint); pseudo-ports start at 1.
|
|
|
|
std::map<uint16_t, ClientTunnel> client_tunnels_;
|
|
|
|
|
|
|
|
uint16_t next_pseudo_port_ = 0;
|
2021-03-26 15:28:26 +00:00
|
|
|
// bool pport_wrapped_ = false;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
continue_connecting(
|
|
|
|
uint16_t pseudo_port, bool step_success, std::string_view step_name, std::string_view addr);
|
|
|
|
|
|
|
|
void
|
|
|
|
make_client(const SockAddr& remote, std::pair<const uint16_t, ClientTunnel>& row);
|
|
|
|
|
|
|
|
void
|
2021-03-30 02:35:30 +00:00
|
|
|
flush_pending_incoming(ClientTunnel& ct);
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
// Server instance; this listens on pseudo-port 0 (if it listens). This is automatically
|
|
|
|
// instantiated the first time `listen()` is called; if not instantiated we simply drop any
|
|
|
|
// inbound client-to-server quic packets.
|
2023-10-19 11:49:46 +00:00
|
|
|
// std::unique_ptr<Server> server_;
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
make_server();
|
|
|
|
|
|
|
|
// Called when a new during connection handshaking once we have the established transport
|
|
|
|
// parameters (which include the port) if this is an incoming connection (and this endpoint is a
|
|
|
|
// server). This checks handlers to see whether the stream is allowed and, if so, returns a
|
|
|
|
// SockAddr containing the IP/port the tunnel should map to. Returns nullopt if the connection
|
|
|
|
// should be rejected.
|
|
|
|
std::optional<SockAddr>
|
|
|
|
allow_connection(std::string_view lokinet_addr, uint16_t port);
|
|
|
|
|
|
|
|
// Incoming stream handlers
|
|
|
|
std::map<int, ListenHandler> incoming_handlers_;
|
|
|
|
int next_handler_id_ = 1;
|
|
|
|
|
2023-10-23 22:58:58 +00:00
|
|
|
// std::shared_ptr<uvw::Loop>
|
|
|
|
// get_loop();
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
|
|
|
|
// Cleanup member
|
|
|
|
std::shared_ptr<int> timer_keepalive_ = std::make_shared<int>(0);
|
|
|
|
};
|
|
|
|
|
2023-10-12 20:37:45 +00:00
|
|
|
} // namespace llarp::link
|