Skip to content

Commit 6cb5666

Browse files
committed
Make the packets flow
Makes initial packets flow from client to server; server connection setup still needs fixing.
1 parent 6de8884 commit 6cb5666

13 files changed

+558
-128
lines changed

Diff for: CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_library(quictest
2828
connection.cpp
2929
endpoint.cpp
3030
server.cpp
31+
stream.cpp
3132
)
3233

3334
add_library(ngtcp2 STATIC IMPORTED GLOBAL)

Diff for: address.h

+14-8
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,26 @@ class Address {
5050
// Implicitly convertable to a ngtcp2_path* so that this can be passed wherever a ngtcp2_path* is
5151
// taken in the ngtcp2 API.
5252
struct Path {
53-
Address local{}, remote{};
53+
private:
54+
Address local_{}, remote_{};
55+
public:
5456
ngtcp2_path path{
55-
{0, local, nullptr},
56-
{0, remote, nullptr}};
57+
{local_.sockaddr_size(), local_, nullptr},
58+
{remote_.sockaddr_size(), remote_, nullptr}};
59+
60+
// Public accessors are const:
61+
const Address& local = local_;
62+
const Address& remote = remote_;
5763

5864
Path() = default;
59-
Path(const Address& local, const Address& remote) : local{local}, remote{remote} {}
65+
Path(const Address& local, const Address& remote) : local_{local}, remote_{remote} {}
6066
Path(const Address& local, const sockaddr_any* remote_addr, size_t remote_len)
61-
: local{local}, remote{remote_addr, remote_len} {}
62-
Path(const Path& p) : local{p.local}, remote{p.remote} {}
67+
: local_{local}, remote_{remote_addr, remote_len} {}
68+
Path(const Path& p) : local_{p.local_}, remote_{p.remote_} {}
6369

6470
Path& operator=(const Path& p) {
65-
local = p.local;
66-
remote = p.remote;
71+
local_ = p.local_;
72+
remote_ = p.remote_;
6773
return *this;
6874
}
6975

Diff for: client.cpp

+53-17
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@
44

55
namespace quic {
66

7-
Client::Client(Address remote, uv_loop_t* loop, std::optional<Address> local)
8-
: Endpoint{std::move(local), loop} {
7+
// Cranks a value to 11, i.e. set it to its maximum
8+
template <typename T>
9+
void crank_to_eleven(T& val) { val = std::numeric_limits<T>::max(); }
10+
11+
static std::array<uint8_t, 32> null_secret{};
12+
static std::array<uint8_t, 16> null_iv{};
13+
static std::array<uint8_t, 4096> null_data{};
14+
15+
Client::Client(Address remote, uv_loop_t* loop_, std::optional<Address> local_)
16+
: Endpoint{std::move(local_), loop_} {
17+
918
// Our UDP socket is now set up, so now we initiate contact with the remote QUIC
19+
Path path{local, remote};
1020
Debug("Connecting to ", remote);
1121

1222
// TODO: need timers for:
@@ -20,28 +30,52 @@ Client::Client(Address remote, uv_loop_t* loop, std::optional<Address> local)
2030
// - delay_stream_timer
2131

2232

23-
conns_iterator it = conns.end();
24-
try {
25-
auto* s = dynamic_cast<Server*>(this);
26-
assert(s);
27-
auto [insit, ins] = conns.emplace(std::piecewise_construct,
28-
std::forward_as_tuple(local_cid),
29-
std::forward_as_tuple(*s, local_cid, hd, p.path));
30-
if (!ins)
31-
Warn("Internal error: duplicate connection id?");
32-
else
33-
it = insit;
34-
} catch (const std::exception& e) {
35-
Warn("Failed to create Connection: ", e.what());
36-
}
33+
auto local_cid = ConnectionID::random(rng);
34+
auto [it, ins] = conns.emplace(std::piecewise_construct,
35+
std::forward_as_tuple(local_cid),
36+
std::forward_as_tuple(*this, local_cid, path));
37+
assert(ins);
38+
auto& conn = it->second;
39+
40+
// FIXME: likely need to move this crap info connection.cpp, or maybe a "null_crypto.cpp"?
41+
ngtcp2_crypto_ctx null_crypto{};
42+
crank_to_eleven(null_crypto.max_encryption);
43+
crank_to_eleven(null_crypto.max_decryption_failure);
44+
45+
Debug("set crypto ctx");
3746

47+
ngtcp2_crypto_aead_ctx null_aead_ctx{};
48+
ngtcp2_crypto_aead retry_aead{0, 16}; // FIXME: 16 overhead is for AES-128-GCM AEAD, but do we need it?
49+
ngtcp2_crypto_cipher_ctx null_cipher_ctx{};
3850

51+
ngtcp2_conn_set_initial_crypto_ctx(conn, &null_crypto);
52+
ngtcp2_conn_install_initial_key(conn, &null_aead_ctx, null_iv.data(), &null_cipher_ctx, &null_aead_ctx, null_iv.data(), &null_cipher_ctx, null_iv.size());
53+
ngtcp2_conn_set_retry_aead(conn, &retry_aead, &null_aead_ctx);
54+
ngtcp2_conn_set_crypto_ctx(conn, &null_crypto);
55+
ngtcp2_conn_install_rx_handshake_key(conn, &null_aead_ctx, null_iv.data(), null_iv.size(), &null_cipher_ctx);
56+
ngtcp2_conn_install_tx_handshake_key(conn, &null_aead_ctx, null_iv.data(), null_iv.size(), &null_cipher_ctx);
57+
ngtcp2_conn_install_rx_key(conn, null_secret.data(), null_secret.size(), &null_aead_ctx, null_iv.data(), null_iv.size(), &null_cipher_ctx);
58+
ngtcp2_conn_install_tx_key(conn, null_secret.data(), null_secret.size(), &null_aead_ctx, null_iv.data(), null_iv.size(), &null_cipher_ctx);
59+
60+
auto x = ngtcp2_conn_get_max_data_left(conn);
61+
Debug("mdl = ", x);
62+
63+
conn.flush_streams();
64+
65+
Debug("Opening bidi stream");
66+
int64_t stream_id;
67+
if (auto rv = ngtcp2_conn_open_bidi_stream(conn, &stream_id, nullptr);
68+
rv != 0) {
69+
Debug("Opening bidi stream failed: ", ngtcp2_strerror(rv));
70+
assert(rv == NGTCP2_ERR_STREAM_ID_BLOCKED);
71+
}
72+
else { Debug("Opening bidi stream good"); }
3973
}
4074

4175
void Client::handle_packet(const Packet& p) {
4276
version_info vi;
4377
auto rv = ngtcp2_pkt_decode_version_cid(&vi.version, &vi.dcid, &vi.dcid_len, &vi.scid, &vi.scid_len,
44-
reinterpret_cast<const uint8_t*>(p.data.data()), p.data.size(), NGTCP2_MAX_CIDLEN);
78+
u8data(p.data), p.data.size(), NGTCP2_MAX_CIDLEN);
4579
if (rv == 1) // 1 means Version Negotiation should be sent
4680
return send_version_negotiation(vi, p.path.remote);
4781
else if (rv != 0) {
@@ -55,3 +89,5 @@ void Client::handle_packet(const Packet& p) {
5589
}
5690

5791
}
92+
93+
}

0 commit comments

Comments
 (0)