1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

Addressing fix

client->server:

  pseudo-port = 0
  Path =
      local = [::1]:0
      remote = [::1]:12345 <-- remote-port

server receives:

  pseudo-port = 0
  Path =
      local = [::1]:0 <-- port is pseudo-port, set in quic/endpoint.cpp
      remote = [::1]:0 <-- port is pseudo-port, set in quic/tunnel.cpp

server sends:

  pseudo-port = 0
  Path =
      local = [::1]:0 <-- is what it saved above
      remote = [::1]:0 <-- is what it saved above

client receives:

  pseudo-port = 0
  Path =
      local = [::1]:12345 <-- port is remote-port, set in quic/endpoint.cpp
      remote = [::1]:12345 <-- port is remote-port, set in quic/tunnel.cpp

  ^^^^^^ This does not match the stored Path, so dropped.
This commit is contained in:
dan 2023-03-08 09:12:57 -08:00
parent 1b31fb15f6
commit 6c6e705862
21 changed files with 273 additions and 158 deletions

53
delete_me Normal file
View file

@ -0,0 +1,53 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".cache/">.cache/</a></li>
<li><a href=".clang-format">.clang-format</a></li>
<li><a href=".clang-tidy">.clang-tidy</a></li>
<li><a href=".dir-locals.el">.dir-locals.el</a></li>
<li><a href=".dockerignore">.dockerignore</a></li>
<li><a href=".drone.jsonnet">.drone.jsonnet</a></li>
<li><a href=".git/">.git/</a></li>
<li><a href=".gitattributes">.gitattributes</a></li>
<li><a href=".github/">.github/</a></li>
<li><a href=".gitignore">.gitignore</a></li>
<li><a href=".gitmodules">.gitmodules</a></li>
<li><a href=".swift-version">.swift-version</a></li>
<li><a href=".vscode/">.vscode/</a></li>
<li><a href="build/">build/</a></li>
<li><a href="cmake/">cmake/</a></li>
<li><a href="CMakeLists.txt">CMakeLists.txt</a></li>
<li><a href="contrib/">contrib/</a></li>
<li><a href="CONTRIBUTING.md">CONTRIBUTING.md</a></li>
<li><a href="CONTRIBUTING_es.md">CONTRIBUTING_es.md</a></li>
<li><a href="crypto/">crypto/</a></li>
<li><a href="daemon/">daemon/</a></li>
<li><a href="delete_me">delete_me</a></li>
<li><a href="docs/">docs/</a></li>
<li><a href="external/">external/</a></li>
<li><a href="gui/">gui/</a></li>
<li><a href="https%3A/">https:/</a></li>
<li><a href="include/">include/</a></li>
<li><a href="jni/">jni/</a></li>
<li><a href="LICENSE">LICENSE</a></li>
<li><a href="llarp/">llarp/</a></li>
<li><a href="misc_notes.txt">misc_notes.txt</a></li>
<li><a href="pybind/">pybind/</a></li>
<li><a href="readme.md">readme.md</a></li>
<li><a href="readme_es.md">readme_es.md</a></li>
<li><a href="readme_fr.md">readme_fr.md</a></li>
<li><a href="readme_ru.md">readme_ru.md</a></li>
<li><a href="rebuild.sh">rebuild.sh</a></li>
<li><a href="test/">test/</a></li>
<li><a href="win32-setup/">win32-setup/</a></li>
</ul>
<hr>
</body>
</html>

View file

@ -134,7 +134,9 @@ namespace llarp
virtual bool
SendToOrQueue(
std::variant<service::Address, RouterID> addr, const llarp_buffer_t& payload, service::ProtocolType t) = 0;
std::variant<service::Address, RouterID> addr,
const llarp_buffer_t& payload,
service::ProtocolType t) = 0;
/// lookup srv records async
virtual void

View file

@ -120,7 +120,6 @@ namespace llarp
return false;
m_TxRate += buf.size();
std::variant<service::Address, RouterID> addr;
if (auto maybe = m_Parent->GetEndpointWithConvoTag(tag))

View file

@ -209,7 +209,7 @@ namespace llarp
return false;
std::variant<service::Address, RouterID> addr;
if (auto maybe = m_Parent->GetEndpointWithConvoTag(tag))
addr = *maybe;
else

View file

@ -97,7 +97,9 @@ namespace llarp
bool
ExitEndpoint::SendToOrQueue(
std::variant<service::Address, RouterID> addr, const llarp_buffer_t& payload, service::ProtocolType type)
std::variant<service::Address, RouterID> addr,
const llarp_buffer_t& payload,
service::ProtocolType type)
{
if (std::holds_alternative<service::Address>(addr))
return false;
@ -151,7 +153,7 @@ namespace llarp
else
{
// probably a client
if (auto maybe_tag = GetBestConvoTagFor(addr);
if (auto maybe_tag = GetBestConvoTagFor(addr);
auto maybe_addr = GetEndpointWithConvoTag(*maybe_tag))
{
hook(maybe_addr);

View file

@ -64,7 +64,9 @@ namespace llarp
bool
SendToOrQueue(
std::variant<service::Address, RouterID> addr, const llarp_buffer_t& payload, service::ProtocolType t) override;
std::variant<service::Address, RouterID> addr,
const llarp_buffer_t& payload,
service::ProtocolType t) override;
void
Tick(llarp_time_t now);

View file

@ -1255,7 +1255,8 @@ namespace llarp
}
// try sending it on an existing convotag
// this succeds for inbound convos, probably.
if (auto maybe_tag = GetBestConvoTagFor(to); auto maybe_addr = GetEndpointWithConvoTag(*maybe_tag))
if (auto maybe_tag = GetBestConvoTagFor(to);
auto maybe_addr = GetEndpointWithConvoTag(*maybe_tag))
{
if (SendToOrQueue(*maybe_addr, pkt.ConstBuffer(), type))
{
@ -1321,7 +1322,7 @@ namespace llarp
}
else
return false;
if (t == service::ProtocolType::QUIC)
{
auto* quic = GetQUICTunnel();
@ -1336,7 +1337,7 @@ namespace llarp
return false;
}
log::trace(logcat, "tag active T={}", tag);
quic->receive_packet(std::move(addr), buf);
return true;
}

View file

@ -998,7 +998,8 @@ extern "C"
ctx->impl->router->loop()->call([addr = *maybe, pkt = std::move(pkt), ep, &ret]() {
if (auto tag = ep->GetBestConvoTagFor(addr); auto addr = ep->GetEndpointWithConvoTag(*tag))
{
if (ep->SendToOrQueue(std::move(*addr), pkt.ConstBuffer(), llarp::service::ProtocolType::TrafficV4))
if (ep->SendToOrQueue(
std::move(*addr), pkt.ConstBuffer(), llarp::service::ProtocolType::TrafficV4))
{
ret.set_value(0);
return;

View file

@ -72,7 +72,7 @@ namespace llarp
init();
fromString(addr);
}
SockAddr::SockAddr(std::string_view addr, huint16_t port)
{
init();

View file

@ -27,13 +27,15 @@ namespace llarp::quic
public:
Address() = default;
Address(const SockAddr& addr, std::optional<std::variant<service::Address, RouterID>> ep = std::nullopt);
Address(
const SockAddr& addr,
std::optional<std::variant<service::Address, RouterID>> ep = std::nullopt);
Address(const Address& other)
{
*this = other;
}
std::optional<std::variant<service::Address, RouterID>> endpoint{};
Address&

View file

@ -16,10 +16,11 @@ namespace llarp::quic
static auto logcat = log::Cat("quic");
Client::Client(
EndpointBase& ep,
const uint16_t port,
std::variant<service::Address, RouterID>&& remote,
uint16_t pseudo_port) : Endpoint{ep}
EndpointBase& ep,
const uint16_t port,
std::variant<service::Address, RouterID>&& 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
@ -40,14 +41,22 @@ namespace llarp::quic
//
// - key_update_timer
// to try: set ports to 0
Path path{
Address{SockAddr{"::1"sv, huint16_t{pseudo_port}}, std::nullopt},
Address{SockAddr{"::1"sv, huint16_t{port}}, std::move(remote)}
};
Address{SockAddr{"::1"sv, huint16_t{0}}, std::nullopt},
Address{SockAddr{"::1"sv, huint16_t{0}}, std::move(remote)}};
log::debug(logcat, "Connecting to {} with addr_variant {}", path.remote, *path.remote.endpoint);
log::debug(logcat, "psuedo_port = {}, port = {} at {}", port, __LINE__);
auto conn = std::make_shared<Connection>(*this, ConnectionID::random(), std::move(path), port);
log::debug(
logcat,
"Made connection object with path.remote = {} and addr_variant {} ",
conn->path.remote,
*conn->path.remote.endpoint);
auto conn = std::make_shared<Connection>(*this, ConnectionID::random(), path, port);
conn->io_ready();
conns.emplace(conn->base_cid, std::move(conn));
}

View file

@ -15,9 +15,9 @@ namespace llarp::quic
// identifier which we include in outgoing packets (so that the remote server knows where to
// send the back to *this* client).
Client(
EndpointBase& ep,
const uint16_t port,
std::variant<service::Address, RouterID>&& remote,
EndpointBase& ep,
const uint16_t port,
std::variant<service::Address, RouterID>&& remote,
uint16_t pseudo_port);
// Returns a reference to the client's connection to the server. Returns a nullptr if there is

View file

@ -3,6 +3,7 @@
#include "external/ngtcp2/lib/ngtcp2_conn.h"
#include "llarp/crypto/crypto.hpp"
#include "llarp/quic/stream.hpp"
#include "oxen/log.hpp"
#include "server.hpp"
#include <ngtcp2/ngtcp2.h>
#include <external/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto.h>
@ -175,7 +176,7 @@ namespace llarp::quic
if (auto rv = conn.complete_handshake(); rv != 0)
return rv;
break;
case NGTCP2_CRYPTO_LEVEL_APPLICATION:
@ -423,7 +424,7 @@ namespace llarp::quic
va_list ap;
va_start(ap, fmt);
if (vsnprintf(buf.data(), buf.size(), fmt, ap) >= 0)
log::trace(logcat, "{}", buf.data());
log::debug(logcat, "{}", buf.data());
va_end(ap);
}
#endif
@ -437,6 +438,12 @@ namespace llarp::quic
if (!send_data.empty())
{
log::debug(
logcat,
"Sending packet to {} at port {} on {}",
*path.remote.endpoint,
path.remote.port(),
__LINE__);
rv = endpoint.send_packet(path.remote, send_data, send_pkt_info.ecn);
}
return rv;
@ -561,7 +568,7 @@ namespace llarp::quic
tparams.stateless_reset_token_present = 1;
ngtcp2_conn* connptr;
log::debug(logcat, "server_new, path={}", path);
log::debug(logcat, "server_new, path = {}", path);
if (auto rv = ngtcp2_conn_server_new(
&connptr,
&dest_cid,
@ -594,9 +601,9 @@ namespace llarp::quic
cb.client_initial = client_initial;
cb.recv_retry = recv_retry;
//cb.handshake_confirmed = handshake_confirmed;
// cb.extend_max_local_streams_bidi = extend_max_local_streams_bidi;
// cb.recv_new_token = recv_new_token;
// cb.handshake_confirmed = handshake_confirmed;
// cb.extend_max_local_streams_bidi = extend_max_local_streams_bidi;
// cb.recv_new_token = recv_new_token;
ngtcp2_conn* connptr;
@ -666,7 +673,7 @@ namespace llarp::quic
if (sent.blocked())
{
log::debug(logcat, "Packet send blocked, scheduling retransmit");
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
schedule_retransmit();
return 0;
@ -677,7 +684,7 @@ namespace llarp::quic
{
log::warning(logcat, "I/O error while trying to send packet: {}", sent.str());
// FIXME: disconnect?
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
return 0;
}
@ -703,17 +710,22 @@ namespace llarp::quic
}
}
}
while (!strs.empty() && stream_packets < max_stream_packets)
{
for (auto it = strs.begin(); it != strs.end();)
{
log::debug(logcat, "Max stream packets: {}\nCurrent stream packets: {}", max_stream_packets, stream_packets);
log::debug(
logcat,
"Max stream packets: {}\nCurrent stream packets: {}",
max_stream_packets,
stream_packets);
auto& stream = **it;
auto bufs = stream.pending();
if (bufs.empty()) {
if (bufs.empty())
{
log::debug(logcat, "Stream buffer empty, have you considered moving on");
}
@ -723,7 +735,7 @@ namespace llarp::quic
return ngtcp2_vec{const_cast<uint8_t*>(u8data(buf)), buf.size()};
});
#ifndef NDEBUG
#ifndef NDEBUG
{
std::string buf_sizes;
for (auto& b : bufs)
@ -735,7 +747,7 @@ namespace llarp::quic
log::debug(
logcat, "Sending {} data for {}", buf_sizes.empty() ? "no" : buf_sizes, stream.id());
}
#endif
#endif
// debug
fprintf(
@ -753,29 +765,31 @@ namespace llarp::quic
}
auto nwrite = ngtcp2_conn_writev_stream(
conn.get(),
&path.path,
&send_pkt_info,
u8data(send_buffer),
send_buffer.size(),
&ndatalen,
flags,
stream.id().id,
reinterpret_cast<const ngtcp2_vec*>(vecs.data()),
vecs.size(),
conn.get(),
&path.path,
&send_pkt_info,
u8data(send_buffer),
send_buffer.size(),
&ndatalen,
flags,
stream.id().id,
reinterpret_cast<const ngtcp2_vec*>(vecs.data()),
vecs.size(),
(!ts) ? get_timestamp() : ts);
log::debug(logcat,
log::debug(
logcat,
"add_stream_data for stream {} returned [{},{}]",
stream.id(),
nwrite,
ndatalen);
if (nwrite < 0)
{
if (nwrite == -240) // NGTCP2_ERR_WRITE_MORE
{
log::debug(logcat,
log::debug(
logcat,
"Consumed {} bytes from stream {} and have space left",
ndatalen,
stream.id());
@ -817,16 +831,20 @@ namespace llarp::quic
if (nwrite == 0) // we are probably done, but maybe congested
{
log::debug(logcat,
log::debug(
logcat,
"Done stream writing to {} (either stream is congested or we have nothing else to "
"send right now)",
stream.id());
ngtcp2_conn_stat cstat;
ngtcp2_conn_get_conn_stat(conn.get(), &cstat);
log::debug(logcat, "Current unacked bytes in flight: {}, Congestion window: {}",
cstat.bytes_in_flight, cstat.cwnd);
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(
logcat,
"Current unacked bytes in flight: {}, Congestion window: {}",
cstat.bytes_in_flight,
cstat.cwnd);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
it = strs.erase(it);
continue;
@ -836,16 +854,16 @@ namespace llarp::quic
if (!send_packet(nwrite))
return;
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts); // so far always useful
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts); // so far always useful
//++stream_packets;
//std::advance(it, 1);
// std::advance(it, 1);
it = strs.erase(it);
if (++stream_packets == max_stream_packets)
{
log::debug(logcat, "Max stream packets ({}) reached", max_stream_packets);
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
return;
}
@ -860,17 +878,17 @@ namespace llarp::quic
fprintf(stderr, "Calling add_stream_data for empty stream\n");
auto nwrite = ngtcp2_conn_writev_stream(
conn.get(),
&path.path,
&send_pkt_info,
u8data(send_buffer),
send_buffer.size(),
&ndatalen,
flags,
-1,
nullptr,
0,
(!ts) ? get_timestamp() : ts);
conn.get(),
&path.path,
&send_pkt_info,
u8data(send_buffer),
send_buffer.size(),
&ndatalen,
flags,
-1,
nullptr,
0,
(!ts) ? get_timestamp() : ts);
log::debug(logcat, "add_stream_data for non-stream returned [{},{}]", nwrite, ndatalen);
// debug
@ -880,31 +898,34 @@ namespace llarp::quic
if (nwrite == 0)
{
log::debug(
logcat, "Nothing else to write for non-stream data for now (or we are congested)");
logcat, "Nothing else to write for non-stream data for now (or we are congested)");
ngtcp2_conn_stat cstat;
ngtcp2_conn_get_conn_stat(conn.get(), &cstat);
log::debug(logcat, "Current unacked bytes in flight: {}, Congestion window: {}",
cstat.bytes_in_flight, cstat.cwnd);
log::debug(
logcat,
"Current unacked bytes in flight: {}, Congestion window: {}",
cstat.bytes_in_flight,
cstat.cwnd);
break;
}
if (nwrite < 0)
{
if (nwrite == -240) // NGTCP2_ERR_WRITE_MORE
if (nwrite == -240) // NGTCP2_ERR_WRITE_MORE
{
log::debug(logcat, "Writing non-stream data frames, and have space left");
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
continue;
}
if (nwrite == -230) // NGTCP2_ERR_CLOSING
if (nwrite == -230) // NGTCP2_ERR_CLOSING
{
log::warning(logcat, "Error writing non-stream data: {}", ngtcp2_strerror(nwrite));
break;
}
if (nwrite == -210) // NGTCP2_ERR_STREAM_DATA_BLOCKED
if (nwrite == -210) // NGTCP2_ERR_STREAM_DATA_BLOCKED
{
log::debug(logcat, "cannot add to empty stream right now: stream is blocked");
break;
@ -917,13 +938,13 @@ namespace llarp::quic
log::debug(logcat, "Sending data packet with non-stream data frames");
if (auto rv = send_packet(nwrite); rv != 0)
return;
log::debug(logcat, "Updating pkt tx time at {}" ,__LINE__);
log::debug(logcat, "Updating pkt tx time at {}", __LINE__);
ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
}
log::debug(logcat, "Exiting flush_streams()");
//ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
//schedule_retransmit();
// ngtcp2_conn_update_pkt_tx_time(conn.get(), ts);
// schedule_retransmit();
}
void
@ -1155,7 +1176,8 @@ namespace llarp::quic
{
std::shared_ptr<Stream> stream{new Stream{
*this, std::move(data_cb), std::move(close_cb), endpoint.default_stream_buffer_size}};
if (int rv = ngtcp2_conn_open_bidi_stream(conn.get(), &stream->stream_id.id, stream.get()); rv != 0)
if (int rv = ngtcp2_conn_open_bidi_stream(conn.get(), &stream->stream_id.id, stream.get());
rv != 0)
throw std::runtime_error{"Stream creation failed: "s + ngtcp2_strerror(rv)};
auto& str = streams[stream->stream_id];
@ -1170,9 +1192,9 @@ namespace llarp::quic
{
std::shared_ptr<Stream> stream{new Stream{
*this, std::move(data_cb), std::move(close_cb), endpoint.default_stream_buffer_size}};
if (int rv = ngtcp2_conn_open_bidi_stream(conn.get(),
&stream->stream_id.id,
std::get<0>(stream->user_data).get());
if (int rv = ngtcp2_conn_open_bidi_stream(conn.get(),
&stream->stream_id.id,
std::get<0>(stream->user_data).get());
rv != 0)
throw std::runtime_error{"Stream creation failed: "s + ngtcp2_strerror(rv)};
@ -1245,7 +1267,6 @@ namespace llarp::quic
return 0;
}
// ngtcp2 doesn't expose the varint encoding, but it's fairly simple:
// 0bXXyyyyyy -- XX indicates the encoded size (00=1, 01=2, 10=4, 11=8) and the rest of the bits
// (6, 14, 30, or 62) are the number, with bytes in network order for >6-bit values.
@ -1351,9 +1372,14 @@ namespace llarp::quic
const bool is_server = ngtcp2_conn_is_server(conn.get());
// debug
log::debug(logcat, "Transport param port = {} at line {}", tunnel_port, __LINE__);
if (is_server)
{
tunnel_port = port;
// debug
log::debug(logcat, "Transport param tunnel_port = {} at line {}", tunnel_port, __LINE__);
}
else
{
@ -1457,7 +1483,8 @@ namespace llarp::quic
return nwrite;
}
log::debug(logcat, "encoded transport params: {}", buffer_printer{conn_buffer});
return ngtcp2_conn_submit_crypto_data(conn.get(), level, u8data(conn_buffer), conn_buffer.size());
return ngtcp2_conn_submit_crypto_data(
conn.get(), level, u8data(conn_buffer), conn_buffer.size());
}
} // namespace llarp::quic

View file

@ -245,7 +245,7 @@ namespace llarp::quic
int
setup_server_crypto_initial();
int
int
get_handshake_confirmed();
// Flush any streams with pending data. Note that, depending on available ngtcp2 state, we may
@ -330,8 +330,8 @@ namespace llarp::quic
send_magic(ngtcp2_crypto_level level);
int
send_transport_params(ngtcp2_crypto_level level);
//void
//complete_handshake();
// void
// complete_handshake();
};
} // namespace llarp::quic

View file

@ -722,7 +722,7 @@ namespace llarp::quic
}
}
}
while (!strs.empty() && stream_packets < max_stream_packets)
{
for (auto it = strs.begin(); it != strs.end();)
@ -730,10 +730,11 @@ namespace llarp::quic
auto& stream = **it;
auto bufs = stream.pending();
if (bufs.empty()) {
if (bufs.empty())
{
log::debug(logcat, "Stream empty, moving on");
//it = strs.erase(it);
//continue;
// it = strs.erase(it);
// continue;
}
std::vector<ngtcp2_vec> vecs;
@ -895,7 +896,7 @@ namespace llarp::quic
fprintf(stderr, "add_stream_data for non-stream returned [%ld,%ld]\n", nwrite, consumed);
assert(consumed <= 0);
if (nwrite == -240) // NGTCP2_ERR_WRITE_MORE
if (nwrite == -240) // NGTCP2_ERR_WRITE_MORE
{
log::trace(logcat, "Writing non-stream data frames, and have space left");
// debug
@ -903,16 +904,14 @@ namespace llarp::quic
ngtcp2_conn_update_pkt_tx_time(*this, *ts);
continue;
}
if (nwrite == -210) // NGTCP2_ERR_STREAM_DATA_BLOCKED
if (nwrite == -210) // NGTCP2_ERR_STREAM_DATA_BLOCKED
{
log::debug(logcat, "cannot add to empty stream right now: stream is blocked");
fprintf(
stderr,
"cannot add to empty stream right now: stream is blocked\n");
fprintf(stderr, "cannot add to empty stream right now: stream is blocked\n");
ngtcp2_conn_update_pkt_tx_time(*this, *ts);
break;
}
if (nwrite == -230) // NGTCP2_ERR_CLOSING
if (nwrite == -230) // NGTCP2_ERR_CLOSING
{
log::warning(logcat, "Error writing non-stream data: {}", ngtcp2_strerror(nwrite));
fprintf(stderr, "Error writing non-stream data: %s\n", ngtcp2_strerror(nwrite));
@ -922,7 +921,7 @@ namespace llarp::quic
if (nwrite == 0)
{
log::trace(
logcat, "Nothing else to write for non-stream data for now (or we are congested)");
logcat, "Nothing else to write for non-stream data for now (or we are congested)");
// debug
fprintf(
stderr, "Nothing else to write for non-stream data for now (or we are congested)\n");

View file

@ -1,5 +1,6 @@
#include "endpoint.hpp"
#include "client.hpp"
#include "llarp/net/net_int.hpp"
#include "ngtcp2/ngtcp2.h"
#include "server.hpp"
#include "uvw/async.h"
@ -53,17 +54,20 @@ namespace llarp::quic
// TODO: does the lookup need to be done every single packet?
// revisit this during libQUICinet
//Endpoint::receive_packet(const SockAddr& src, uint8_t ecn, bstring_view data)
// Endpoint::receive_packet(const SockAddr& src, uint8_t ecn, bstring_view data)
void
Endpoint::receive_packet(Address remote, uint8_t ecn, bstring_view data, uint16_t remote_port)
{
// ngtcp2 wants a local address but we don't necessarily have something so just set it to
// IPv4 or IPv6 "unspecified" address (0.0.0.0 or ::)
//SockAddr local = src.isIPv6() ? SockAddr{in6addr_any} : SockAddr{nuint32_t{INADDR_ANY}};
// SockAddr local = src.isIPv6() ? SockAddr{in6addr_any} : SockAddr{nuint32_t{INADDR_ANY}};
// to try: set remote port to 0
remote_port = 0;
Packet pkt{
Path{Address{SockAddr{"::1"sv, huint16_t{remote_port}}, std::nullopt}, remote},
data,
Path{Address{SockAddr{"::1"sv, huint16_t{remote_port}}, std::nullopt}, remote},
data,
ngtcp2_pkt_info{.ecn = ecn}};
log::trace(logcat, "[{},ecn={}]: received {} bytes", pkt.path, pkt.info.ecn, data.size());
@ -164,9 +168,13 @@ namespace llarp::quic
io_result
Endpoint::read_packet(const Packet& p, Connection& conn)
{
log::trace(logcat, "Reading packet from {}", p.path);
// debug
log::debug(logcat, "Reading packet from {}", p.path);
log::debug(
logcat,
"Reading packet from {} with path.remote = {}, path.remote.endpoint = {}",
p.path,
p.path.remote,
*p.path.remote.endpoint);
auto rv =
ngtcp2_conn_read_pkt(conn, p.path, &p.info, u8data(p.data), p.data.size(), get_timestamp());
@ -187,7 +195,7 @@ namespace llarp::quic
"Immediate Close-ing connection {} due to error {}",
conn.base_cid,
ngtcp2_strerror(rv));
//close_connection(conn, rv, "ERR_PROTO"sv);
// close_connection(conn, rv, "ERR_PROTO"sv);
close_connection(conn, ngtcp2_err_infer_quic_transport_error_code(rv), "ERR_PROTO"sv);
}
else if (rv == NGTCP2_ERR_DROP_CONN)
@ -214,9 +222,10 @@ namespace llarp::quic
log::debug(logcat, "to.port: {}, to.remote: {}", to.port(), *to.endpoint);
if (service_endpoint.SendToOrQueue(
*to.endpoint, llarp_buffer_t{outgoing.data(), outgoing.size()}, service::ProtocolType::QUIC))
*to.endpoint,
llarp_buffer_t{outgoing.data(), outgoing.size()},
service::ProtocolType::QUIC))
{
log::trace(logcat, "[{}]: sent {}", to, buffer_printer{outgoing});
// debug
log::debug(logcat, "[{}]: sent {}", to, buffer_printer{outgoing});
}
@ -254,6 +263,9 @@ namespace llarp::quic
if (nwrote <= 0)
return;
log::debug(
logcat, "Sending packet to {} at port {} on {}", *source.endpoint, source.port(), __LINE__);
send_packet(source, bstring_view{buf.data(), static_cast<size_t>(nwrote)}, 0);
}
@ -262,8 +274,8 @@ namespace llarp::quic
{
log::debug(logcat, "Closing connection {}", conn.base_cid);
if (!conn || conn.closing || conn.draining)
return;
if (!conn || conn.closing || conn.draining)
return;
ngtcp2_connection_close_error err;
ngtcp2_connection_close_error_set_transport_error_liberr(
@ -277,23 +289,14 @@ namespace llarp::quic
ngtcp2_pkt_info pi;
auto written = ngtcp2_conn_write_connection_close(
conn,
path,
&pi,
u8data(conn.conn_buffer),
conn.conn_buffer.size(),
&err,
get_timestamp());
conn, path, &pi, u8data(conn.conn_buffer), conn.conn_buffer.size(), &err, get_timestamp());
if (written <= 0)
{
log::warning(
logcat,
"Failed to write connection close packet: {}",
written < 0 ? ngtcp2_strerror(written) : "unknown error: closing is 0 bytes??");
log::warning(
logcat,
"Failed to write packet: removing connection {}",
conn.base_cid);
log::warning(logcat, "Failed to write packet: removing connection {}", conn.base_cid);
delete_conn(conn.base_cid);
return;
}
@ -302,9 +305,16 @@ namespace llarp::quic
conn.closing = true;
conn.path = path;
assert(conn.closing && !conn.conn_buffer.empty());
log::debug(
logcat,
"Sending packet to {} at port {} on {}",
*conn.path.remote.endpoint,
conn.path.remote.port(),
__LINE__);
if (auto sent = send_packet(conn.path.remote, conn.conn_buffer, 0); not sent)
{
log::warning(
@ -359,7 +369,7 @@ namespace llarp::quic
if (cleanup)
clean_alias_conns();
for (auto & it : conns)
for (auto& it : conns)
{
if (auto* conn_ptr = std::get_if<primary_conn_ptr>(&it.second))
{

View file

@ -39,7 +39,7 @@ namespace llarp::quic
null_iv.data(),
&null_cipher_ctx,
null_iv.size());
if (rv != 0)
log::debug(logcat, "Call to ngtcp2_conn_set_initial_crypto_ctx unsuccessful at {}", __LINE__);
@ -61,7 +61,7 @@ namespace llarp::quic
null_iv.data(),
&null_cipher_ctx,
null_iv.size());
if (rv != 0)
log::debug(logcat, "Call to ngtcp2_conn_set_initial_crypto_ctx unsuccessful at {}", __LINE__);
@ -103,13 +103,7 @@ namespace llarp::quic
{
log::debug(logcat, "Calling {}", __PRETTY_FUNCTION__);
return ngtcp2_conn_install_rx_key(
conn,
nullptr,
0,
&null_aead_ctx,
null_iv.data(),
null_iv.size(),
&null_cipher_ctx)
conn, nullptr, 0, &null_aead_ctx, null_iv.data(), null_iv.size(), &null_cipher_ctx)
== 0;
}

View file

@ -263,20 +263,15 @@ namespace llarp::quic
server_->stream_open_callback = [this](Stream& stream, uint16_t port) -> bool {
stream.close_callback = close_tcp_pair;
// FIXME
auto& conn = stream.get_connection();
auto remote = service_endpoint_.GetEndpointWithConvoTag(conn.path.remote);
if (!remote)
{
log::warning(
logcat, "Received new stream open from invalid/unknown convo tag, dropping stream");
return false;
}
auto lokinet_addr = var::visit([](auto&& remote) { return remote.ToString(); }, *remote);
auto lokinet_addr =
var::visit([](auto&& remote) { return remote.ToString(); }, *conn.path.remote.endpoint);
auto tunnel_to = allow_connection(lokinet_addr, port);
if (not tunnel_to)
return false;
log::info(
log::debug(
logcat, "quic stream from {} to {} tunnelling to {}", lokinet_addr, port, *tunnel_to);
auto tcp = get_loop()->resource<uvw::TCPHandle>();
@ -514,7 +509,8 @@ namespace llarp::quic
"Unable to open an outgoing quic connection: too many existing connections"};
(next_pseudo_port_ = pport)++;
log::info(logcat, "Bound TCP tunnel {} for quic client :{}", saddr, pport);
// debug
log::debug(logcat, "Bound TCP tunnel {} for quic client :{}", saddr, pport);
// We are emplacing into client_tunnels_ here: beyond this point we must not throw until we
// return (or if we do, make sure we remove this row from client_tunnels_ first).
@ -556,7 +552,7 @@ namespace llarp::quic
auto& remote = *maybe_remote;
// See if we have an existing convo tag we can use to start things immediately
if (auto maybe_convo = service_endpoint_.GetBestConvoTagFor(remote);
if (auto maybe_convo = service_endpoint_.GetBestConvoTagFor(remote);
auto maybe_addr = service_endpoint_.GetEndpointWithConvoTag(*maybe_convo))
after_path(maybe_addr);
else
@ -604,9 +600,9 @@ namespace llarp::quic
void
TunnelManager::make_client(
const uint16_t port,
std::variant<service::Address, RouterID> remote,
std::pair<const uint16_t, ClientTunnel>& row)
const uint16_t port,
std::variant<service::Address, RouterID> remote,
std::pair<const uint16_t, ClientTunnel>& row)
{
assert(port > 0);
auto& [pport, tunnel] = row;
@ -686,7 +682,8 @@ namespace llarp::quic
}
void
TunnelManager::receive_packet(std::variant<service::Address, RouterID> remote, const llarp_buffer_t& buf)
TunnelManager::receive_packet(
std::variant<service::Address, RouterID> remote, const llarp_buffer_t& buf)
{
if (buf.sz <= 4)
{
@ -700,9 +697,9 @@ namespace llarp::quic
auto ecn = static_cast<uint8_t>(buf.base[3]);
bstring_view data{reinterpret_cast<const std::byte*>(&buf.base[4]), buf.sz - 4};
//auto addr_data = var::visit([](auto& addr) { return addr.as_array(); }, remote);
//huint128_t ip{};
//std::copy_n(addr_data.begin(), sizeof(ip.h), &ip.h);
// auto addr_data = var::visit([](auto& addr) { return addr.as_array(); }, remote);
// huint128_t ip{};
// std::copy_n(addr_data.begin(), sizeof(ip.h), &ip.h);
huint16_t remote_port{pseudo_port};
quic::Endpoint* ep = nullptr;
@ -751,7 +748,25 @@ namespace llarp::quic
return;
}
auto remote_addr = Address{SockAddr{"::1"sv, huint16_t{remote_port}}, std::move(remote)};
log::debug(
logcat,
"remote_port = {}, pseudo_port = {} at line {}",
remote_port,
pseudo_port,
__LINE__);
// to try: set remote_port to 0
remote_port = huint16_t{0};
pseudo_port = 0;
auto remote_addr = Address{SockAddr{"::1"sv, remote_port}, std::move(remote)};
log::debug(
logcat,
"Receiving packet from {} with port = {}, remote = {} at line {}",
remote_addr,
remote_addr.port(),
*remote_addr.endpoint,
__LINE__);
ep->receive_packet(std::move(remote_addr), ecn, data, pseudo_port);
}
} // namespace llarp::quic

View file

@ -177,8 +177,8 @@ namespace llarp::quic
void
make_client(
const uint16_t port,
std::variant<service::Address, RouterID> ep,
const uint16_t port,
std::variant<service::Address, RouterID> ep,
std::pair<const uint16_t, ClientTunnel>& row);
void

View file

@ -1703,7 +1703,6 @@ namespace llarp
return true;
}
bool
Endpoint::SendToOrQueue(const RouterID& addr, const llarp_buffer_t& buf, ProtocolType t)
{
@ -1722,7 +1721,6 @@ namespace llarp
return true;
}
void
Endpoint::Pump(llarp_time_t now)
{

View file

@ -468,8 +468,9 @@ namespace llarp
// Looks up the ConvoTag and, if it exists, calls SendToOrQueue to send it to a remote client
// or a snode (or nothing, if the convo tag is unknown).
//bool
//SendToOrQueue(std::variant<service::Address, RouterID> addr, const llarp_buffer_t& payload, ProtocolType t) override;
// bool
// SendToOrQueue(std::variant<service::Address, RouterID> addr, const llarp_buffer_t& payload,
// ProtocolType t) override;
// Send a to (or queues for sending) to either an address or router id
bool