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 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -1421,6 +1433,10 @@ extern const quicly_stream_callbacks_t quicly_stream_noop_callbacks;
}); \
} while (0)

int quicly_qos_send(quicly_conn_t *conn, void *buf, size_t *bufsize);
int 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

/* coexists with picotls error codes, assuming that int is at least 32-bits */
#define QUICLY_ERROR_IS_QUIC(e) (((e) & ~0x1ffff) == 0x20000)
Expand Down Expand Up @@ -108,6 +110,7 @@ extern "C" {
#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
48 changes: 30 additions & 18 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,7 +106,8 @@ typedef struct st_quicly_stream_frame_t {
ptls_iovec_t data;
} quicly_stream_frame_t;

static int quicly_decode_stream_frame(uint8_t type_flags, const uint8_t **src, const uint8_t *end, quicly_stream_frame_t *frame);
static int 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 int quicly_decode_crypto_frame(const uint8_t **src, const uint8_t *end, quicly_stream_frame_t *frame);

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

inline int quicly_decode_stream_frame(uint8_t type_flags, const uint8_t **src, const uint8_t *end, quicly_stream_frame_t *frame)
inline int 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 @@ -386,22 +389,31 @@ inline int quicly_decode_stream_frame(uint8_t type_flags, const uint8_t **src, c
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 @@ -470,7 +482,7 @@ inline int quicly_decode_reset_stream_frame(const uint8_t **src, const uint8_t *
frame->final_size = quicly_decodev(src, end);
return 0;
Error:
return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
return QUICLY_ERROR_PARTIAL_FRAME;
}

inline int quicly_decode_application_close_frame(const uint8_t **src, const uint8_t *end, quicly_application_close_frame_t *frame)
Expand Down Expand Up @@ -508,7 +520,7 @@ inline int quicly_decode_transport_close_frame(const uint8_t **src, const uint8_
*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 @@ -526,7 +538,7 @@ inline uint8_t *quicly_encode_max_data_frame(uint8_t *dst, uint64_t max_data)
inline int 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 @@ -546,7 +558,7 @@ inline int quicly_decode_max_stream_data_frame(const uint8_t **src, const uint8_
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 @@ -559,7 +571,7 @@ inline uint8_t *quicly_encode_max_streams_frame(uint8_t *dst, int uni, uint64_t
inline int 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 @@ -588,7 +600,7 @@ inline uint8_t *quicly_encode_data_blocked_frame(uint8_t *dst, uint64_t offset)
inline int 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 @@ -622,7 +634,7 @@ inline uint8_t *quicly_encode_streams_blocked_frame(uint8_t *dst, int uni, uint6
inline int quicly_decode_streams_blocked_frame(const uint8_t **src, const uint8_t *end, 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 @@ -727,7 +739,7 @@ inline int quicly_decode_stop_sending_frame(const uint8_t **src, const uint8_t *
frame->app_error_code = (uint16_t)error_code;
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
Loading