Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] QUIC on Streams #574

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
df9cef5
it works?
kazuho Mar 17, 2024
c598fde
add test
kazuho Mar 17, 2024
34524ab
missing proto
kazuho Mar 17, 2024
1255c32
let `quicly_get_first_timeout` be usable with QoS
kazuho Mar 18, 2024
30429d0
QUICv1 payload cannot be empty but `quicly_qos_receive` should accept…
kazuho Mar 18, 2024
ffdc224
otherwise QoS connections cannot be freed
kazuho Mar 18, 2024
35a4dce
QoS uses idle timeout
kazuho Mar 18, 2024
a3bc946
[QoS] data can be sent without application space
kazuho Mar 18, 2024
0920322
remove unused property
kazuho Mar 18, 2024
939684e
respect idle timeout in QoS
kazuho Mar 18, 2024
04c8415
If the STREAM frame is emitted as the 2nd frame of the buffer provide…
kazuho Jul 22, 2024
c9e968b
Merge branch 'master' into kazuho/quic-on-streams
kazuho Aug 3, 2024
46b62ad
revert 04c8415 to add failing test
kazuho Aug 4, 2024
1f531c3
[QoS] when decoding STREAM frames, respect max_frame_size currently h…
kazuho Aug 4, 2024
1de8f38
add test
kazuho Aug 4, 2024
02300e9
When sending QUIC frames on QoS, always use STREAM frame with the len…
kazuho Aug 5, 2024
557aad4
to suppress signed comparison warning, follow the convention of casti…
kazuho Aug 12, 2024
02c3e4e
Merge branch 'master' into kazuho/quic-on-streams
kazuho Jan 14, 2025
e940034
amend merge
kazuho Jan 14, 2025
3ab06ca
send CONNECTION_CLOSE then immediately indicate freeable
kazuho Jan 22, 2025
0a9e6e2
Merge branch 'master' into kazuho/quic-on-streams
kazuho Jan 22, 2025
2d72c84
Merge branch 'master' into kazuho/quic-on-streams
kazuho Jan 28, 2025
ac34018
Merge branch 'master' into kazuho/quic-on-streams
kazuho Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion include/quicly.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ QUICLY_CALLBACK_TYPE(void, update_open_count, ssize_t delta);
* is complete.
*/
QUICLY_CALLBACK_TYPE(void, async_handshake, ptls_t *tls);
/**
*
*/
QUICLY_CALLBACK_TYPE(int, qos_is_writing, quicly_conn_t *conn);

/**
* crypto offload API
Expand Down Expand Up @@ -417,6 +421,10 @@ struct st_quicly_context_t {
*
*/
quicly_async_handshake_t *async_handshake;
/**
*
*/
quicly_qos_is_writing_t *qos_is_writing;
};

/**
Expand Down Expand Up @@ -597,7 +605,7 @@ struct st_quicly_conn_streamgroup_state_t {
uint64_t padding, ping, ack, reset_stream, stop_sending, crypto, new_token, stream, max_data, max_stream_data, \
max_streams_bidi, max_streams_uni, data_blocked, stream_data_blocked, streams_blocked, new_connection_id, \
retire_connection_id, path_challenge, path_response, transport_close, application_close, handshake_done, datagram, \
ack_frequency; \
ack_frequency, qs_transport_parameters; \
} num_frames_sent, num_frames_received; \
/** \
* Total number of PTOs observed during the connection. \
Expand Down Expand Up @@ -1024,6 +1032,10 @@ static const quicly_cid_t *quicly_get_remote_cid(quicly_conn_t *conn);
*
*/
static const quicly_transport_parameters_t *quicly_get_remote_transport_parameters(quicly_conn_t *conn);
/**
*
*/
int quicly_is_on_streams(quicly_conn_t *conn);
/**
*
*/
Expand Down Expand Up @@ -1429,6 +1441,10 @@ extern const quicly_stream_callbacks_t quicly_stream_noop_callbacks;
}); \
} while (0)

quicly_error_t quicly_qos_send(quicly_conn_t *conn, void *buf, size_t *bufsize);
quicly_error_t quicly_qos_receive(quicly_conn_t *conn, const void *src, size_t *len);
quicly_conn_t *quicly_qos_new(quicly_context_t *ctx, int is_client, void *appdata);

/* inline definitions */

inline int quicly_is_supported_version(uint32_t version)
Expand Down
3 changes: 3 additions & 0 deletions include/quicly/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ extern "C" {
#define QUICLY_EPOCH_HANDSHAKE 2
#define QUICLY_EPOCH_1RTT 3
#define QUICLY_NUM_EPOCHS 4
#define QUICLY_EPOCH_ON_STREAMS_TP 4 /* used internally */
#define QUICLY_EPOCH_ON_STREAMS_OTHER 5

/**
* Error code used by quicly. The code coalesces the following to an int64_t.
Expand Down Expand Up @@ -118,6 +120,7 @@ typedef int64_t quicly_error_t;
#define QUICLY_ERROR_STATE_EXHAUSTION 0xff07
#define QUICLY_ERROR_INVALID_INITIAL_VERSION 0xff08
#define QUICLY_ERROR_DECRYPTION_FAILED 0xff09
#define QUICLY_ERROR_PARTIAL_FRAME 0xff0a

typedef int64_t quicly_stream_id_t;

Expand Down
50 changes: 30 additions & 20 deletions include/quicly/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extern "C" {
#define QUICLY_FRAME_TYPE_DATAGRAM_NOLEN 48
#define QUICLY_FRAME_TYPE_DATAGRAM_WITHLEN 49
#define QUICLY_FRAME_TYPE_ACK_FREQUENCY 0xaf
#define QUICLY_FRAME_TYPE_QS_TRANSPORT_PARAMETERS 0x3f5153300d0a0d0a

#define QUICLY_FRAME_TYPE_STREAM_BITS 0x7
#define QUICLY_FRAME_TYPE_STREAM_BIT_OFF 0x4
Expand Down Expand Up @@ -105,8 +106,8 @@ typedef struct st_quicly_stream_frame_t {
ptls_iovec_t data;
} quicly_stream_frame_t;

static quicly_error_t quicly_decode_stream_frame(uint8_t type_flags, const uint8_t **src, const uint8_t *end,
quicly_stream_frame_t *frame);
static quicly_error_t quicly_decode_stream_frame(uint8_t type_flags, uint64_t max_frame_size, const uint8_t **src,
const uint8_t *end, quicly_stream_frame_t *frame);
static uint8_t *quicly_encode_crypto_frame_header(uint8_t *dst, uint8_t *dst_end, uint64_t offset, size_t *data_len);
static quicly_error_t quicly_decode_crypto_frame(const uint8_t **src, const uint8_t *end, quicly_stream_frame_t *frame);

Expand Down Expand Up @@ -376,17 +377,17 @@ inline unsigned quicly_clz64(uint64_t v)
return v != 0 ? __builtin_clzll(v) : 64;
}

inline quicly_error_t quicly_decode_stream_frame(uint8_t type_flags, const uint8_t **src, const uint8_t *end,
quicly_stream_frame_t *frame)
inline quicly_error_t quicly_decode_stream_frame(uint8_t type_flags, uint64_t max_frame_size, const uint8_t **src,
const uint8_t *end, quicly_stream_frame_t *frame)
{
/* obtain stream id */
if ((frame->stream_id = quicly_decodev(src, end)) == UINT64_MAX)
goto Error;
return QUICLY_ERROR_PARTIAL_FRAME;

/* obtain offset */
if ((type_flags & QUICLY_FRAME_TYPE_STREAM_BIT_OFF) != 0) {
if ((frame->offset = quicly_decodev(src, end)) == UINT64_MAX)
goto Error;
return QUICLY_ERROR_PARTIAL_FRAME;
} else {
frame->offset = 0;
}
Expand All @@ -395,22 +396,31 @@ inline quicly_error_t quicly_decode_stream_frame(uint8_t type_flags, const uint8
if ((type_flags & QUICLY_FRAME_TYPE_STREAM_BIT_LEN) != 0) {
uint64_t len;
if ((len = quicly_decodev(src, end)) == UINT64_MAX)
goto Error;
return QUICLY_ERROR_PARTIAL_FRAME;
if ((uint64_t)(end - *src) < len)
goto Error;
return QUICLY_ERROR_PARTIAL_FRAME;
if (len > max_frame_size)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
frame->data = ptls_iovec_init(*src, len);
*src += len;
} else {
frame->data = ptls_iovec_init(*src, end - *src);
*src = end;
if (max_frame_size == SIZE_MAX) {
/* QUIC v1 */
frame->data = ptls_iovec_init(*src, end - *src);
*src = end;
} else {
/* QUIC on Streams */
if ((uint64_t)(end - *src) < max_frame_size)
return QUICLY_ERROR_PARTIAL_FRAME;
frame->data = ptls_iovec_init(*src, max_frame_size);
*src += max_frame_size;
}
}

/* fin bit */
frame->is_fin = (type_flags & QUICLY_FRAME_TYPE_STREAM_BIT_FIN) != 0;

return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
}

inline uint8_t *quicly_encode_crypto_frame_header(uint8_t *dst, uint8_t *dst_end, uint64_t offset, size_t *data_len)
Expand Down Expand Up @@ -476,7 +486,7 @@ inline quicly_error_t quicly_decode_reset_stream_frame(const uint8_t **src, cons
frame->final_size = quicly_decodev(src, end);
return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
}

inline quicly_error_t quicly_decode_application_close_frame(const uint8_t **src, const uint8_t *end,
Expand Down Expand Up @@ -514,7 +524,7 @@ inline quicly_error_t quicly_decode_transport_close_frame(const uint8_t **src, c
*src += reason_len;
return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
}

inline size_t quicly_close_frame_capacity(uint64_t error_code, uint64_t offending_frame_type, const char *reason_phrase)
Expand All @@ -532,7 +542,7 @@ inline uint8_t *quicly_encode_max_data_frame(uint8_t *dst, uint64_t max_data)
inline quicly_error_t quicly_decode_max_data_frame(const uint8_t **src, const uint8_t *end, quicly_max_data_frame_t *frame)
{
if ((frame->max_data = quicly_decodev(src, end)) == UINT64_MAX)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
return 0;
}

Expand All @@ -553,7 +563,7 @@ inline quicly_error_t quicly_decode_max_stream_data_frame(const uint8_t **src, c
goto Error;
return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
}

inline uint8_t *quicly_encode_max_streams_frame(uint8_t *dst, int uni, uint64_t count)
Expand All @@ -566,7 +576,7 @@ inline uint8_t *quicly_encode_max_streams_frame(uint8_t *dst, int uni, uint64_t
inline quicly_error_t quicly_decode_max_streams_frame(const uint8_t **src, const uint8_t *end, quicly_max_streams_frame_t *frame)
{
if ((frame->count = quicly_decodev(src, end)) == UINT64_MAX)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
if (frame->count > (uint64_t)1 << 60)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return 0;
Expand Down Expand Up @@ -596,7 +606,7 @@ inline uint8_t *quicly_encode_data_blocked_frame(uint8_t *dst, uint64_t offset)
inline quicly_error_t quicly_decode_data_blocked_frame(const uint8_t **src, const uint8_t *end, quicly_data_blocked_frame_t *frame)
{
if ((frame->offset = quicly_decodev(src, end)) == UINT64_MAX)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
return 0;
}

Expand Down Expand Up @@ -631,7 +641,7 @@ inline quicly_error_t quicly_decode_streams_blocked_frame(const uint8_t **src, c
quicly_streams_blocked_frame_t *frame)
{
if ((frame->count = quicly_decodev(src, end)) == UINT64_MAX)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
if (frame->count > (uint64_t)1 << 60)
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return 0;
Expand Down Expand Up @@ -734,7 +744,7 @@ inline quicly_error_t quicly_decode_stop_sending_frame(const uint8_t **src, cons
goto Error;
return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
}

inline size_t quicly_new_token_frame_capacity(ptls_iovec_t token)
Expand Down
Loading