Skip to content

Commit

Permalink
Merge pull request #554 from h2o/kazuho/path-migration
Browse files Browse the repository at this point in the history
implement path migration
  • Loading branch information
kazuho authored May 14, 2024
2 parents 052eae2 + 6481c0f commit 6a90372
Show file tree
Hide file tree
Showing 13 changed files with 1,273 additions and 531 deletions.
69 changes: 43 additions & 26 deletions include/quicly.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ struct st_quicly_context_t {
* the connection.
*/
uint64_t max_initial_handshake_packets;
/**
* maximum number of probe packets (i.e., packets carrying PATH_CHALLENGE frames) to be sent before calling a path unreachable
*/
uint64_t max_probe_packets;
/**
* Once path validation fails for the specified number of paths, packets arriving on new tuples will be dropped. Setting this
* value to zero effectively disables the endpoint responding to path migration attempts.
*/
uint64_t max_path_validation_failures;
/**
* Jumpstart CWND to be used when there is no previous information. If set to zero, slow start is used. Note jumpstart is
* possible only when the use_pacing flag is set.
Expand Down Expand Up @@ -484,6 +493,14 @@ struct st_quicly_conn_streamgroup_state_t {
* connection-wide ack-received counters for ECT(0), ECT(1), CE \
*/ \
uint64_t acked_ecn_counts[3]; \
/** \
* Total number of packets sent on promoted paths. \
*/ \
uint64_t sent_promoted_paths; \
/** \
* Total number of acked packets that were sent on promoted. \
*/ \
uint64_t ack_received_promoted_paths; \
} num_packets; \
struct { \
/** \
Expand Down Expand Up @@ -512,6 +529,30 @@ struct st_quicly_conn_streamgroup_state_t {
uint64_t stream_data_resent; \
} num_bytes; \
struct { \
/** \
* number of alternate paths created \
*/ \
uint64_t created; \
/** \
* number alternate paths validated \
*/ \
uint64_t validated; \
/** \
* number of alternate paths that were created but failed to validate \
*/ \
uint64_t validation_failed; \
/** \
* number of paths on which migration has been elicited (i.e., received non-probing packets) \
*/ \
uint64_t migration_elicited; \
/** \
* number of migrations \
*/ \
uint64_t promoted; \
/** \
* number of alternate paths that were closed due to Connection ID being unavailable \
*/ \
uint64_t closed_no_dcid; \
/** \
* number of paths that were ECN-capable \
*/ \
Expand Down Expand Up @@ -625,10 +666,6 @@ struct _st_quicly_conn_public_t {
* on that assumption.
*/
quicly_local_cid_set_t cid_set;
/**
* the local address (may be AF_UNSPEC)
*/
quicly_address_t address;
/**
* the SCID used in long header packets. Equivalent to local_cid[seq=0]. Retaining the value separately is the easiest way
* of staying away from the complexity caused by remote peer sending RCID frames before the handshake concludes.
Expand All @@ -644,20 +681,12 @@ struct _st_quicly_conn_public_t {
* CIDs received from the remote peer
*/
quicly_remote_cid_set_t cid_set;
/**
* the remote address (cannot be AF_UNSPEC)
*/
quicly_address_t address;
struct st_quicly_conn_streamgroup_state_t bidi, uni;
quicly_transport_parameters_t transport_params;
struct {
unsigned validated : 1;
unsigned send_probe : 1;
} address_validation;
/**
* largest value of Retire Prior To field observed so far
*/
uint64_t largest_retire_prior_to;
} remote;
/**
* Retains the original DCID used by the client. Servers use this to route packets incoming packets. Clients use this when
Expand Down Expand Up @@ -998,11 +1027,11 @@ static quicly_stream_id_t quicly_get_remote_next_stream_id(quicly_conn_t *conn,
/**
* Returns the local address of the connection. This may be AF_UNSPEC, indicating that the operating system is choosing the address.
*/
static struct sockaddr *quicly_get_sockname(quicly_conn_t *conn);
struct sockaddr *quicly_get_sockname(quicly_conn_t *conn);
/**
* Returns the remote address of the connection. This would never be AF_UNSPEC.
*/
static struct sockaddr *quicly_get_peername(quicly_conn_t *conn);
struct sockaddr *quicly_get_peername(quicly_conn_t *conn);
/**
*
*/
Expand Down Expand Up @@ -1429,18 +1458,6 @@ inline quicly_stream_id_t quicly_get_remote_next_stream_id(quicly_conn_t *conn,
return uni ? c->remote.uni.next_stream_id : c->remote.bidi.next_stream_id;
}

inline struct sockaddr *quicly_get_sockname(quicly_conn_t *conn)
{
struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
return &c->local.address.sa;
}

inline struct sockaddr *quicly_get_peername(quicly_conn_t *conn)
{
struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
return &c->remote.address.sa;
}

inline uint32_t quicly_get_protocol_version(quicly_conn_t *conn)
{
struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
Expand Down
40 changes: 28 additions & 12 deletions include/quicly/remote_cid.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,40 @@
extern "C" {
#endif

/**
* state of `quicly_remote_cid_t`
*/
typedef enum en_quicly_remote_cid_state_t {
/**
* cid and stateless reset token have not been received for the sequence number
*/
QUICLY_REMOTE_CID_UNAVAILABLE,
/**
* cid is in use
*/
QUICLY_REMOTE_CID_IN_USE,
/**
* cid has been receive but has not been used yet
*/
QUICLY_REMOTE_CID_AVAILABLE
} quicly_remote_cid_state_t;

/**
* records a CID given by the remote peer
*/
typedef struct st_quicly_remote_cid_t {
/**
* indicates whether this record holds an active (given by remote peer and not retired) CID
* state
*/
int is_active;
quicly_remote_cid_state_t state;
/**
* sequence number of the CID
*
* If is_active, this represents the sequence number associated with the CID.
* If !is_active, this represents a "reserved" slot, meaning that we are expecting to receive a NEW_CONNECTION_ID frame
* with this sequence number. This helps determine if a received frame is carrying a CID that is already retired.
* sequence number of the CID; if `state` is UNAVAILABLE, this is a reserved slot meaning that we are expecting to receive a
* NEW_CONNECTION_ID frame with this sequence number. This helps determine if a received frame is carrying a CID that is already
* retired.
*/
uint64_t sequence;
/**
* CID; only usable if `is_active` is true
* CID; available unless `state` is UNAVAILABLE
*/
struct st_quicly_cid_t cid;
/**
Expand All @@ -59,8 +75,9 @@ typedef struct st_quicly_remote_cid_t {
*/
typedef struct st_quicly_remote_cid_set_t {
/**
* we retain QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT active connection IDs
* cids[0] holds the current (in use) CID which is used when emitting packets
* We retain QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT active connection IDs. `cids[0]` used to retain the current DCID, but it is
* no longer the case. DCID of the non-probing path should now be obtained via `get_dcid(conn->paths[0])` where `paths[0]` is
* the non-probing path.
*/
quicly_remote_cid_t cids[QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT];
/**
Expand All @@ -84,9 +101,8 @@ int quicly_remote_cid_register(quicly_remote_cid_set_t *set, uint64_t sequence,
uint64_t unregistered_seqs[QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT], size_t *num_unregistered_seqs);
/**
* unregisters specified CID from the store
* returns 0 if success, 1 if failure
*/
int quicly_remote_cid_unregister(quicly_remote_cid_set_t *set, uint64_t sequence);
void quicly_remote_cid_unregister(quicly_remote_cid_set_t *set, uint64_t sequence);

#ifdef __cplusplus
}
Expand Down
12 changes: 9 additions & 3 deletions include/quicly/sentmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,13 @@ typedef struct st_quicly_sent_packet_t {
*/
uint8_t frames_in_flight : 1;
/**
*
*
*/
uint8_t cc_limited : 1;
/**
* if sent on a promoted path
*/
uint8_t promoted_path : 1;
/**
* number of bytes in-flight for the packet, from the context of CC (becomes zero when deemed lost, but not when PTO fires)
*/
Expand Down Expand Up @@ -256,7 +260,7 @@ int quicly_sentmap_prepare(quicly_sentmap_t *map, uint64_t packet_number, int64_
/**
* commits a write
*/
static void quicly_sentmap_commit(quicly_sentmap_t *map, uint16_t bytes_in_flight, int cc_limited);
static void quicly_sentmap_commit(quicly_sentmap_t *map, uint16_t bytes_in_flight, int cc_limited, int promoted_path);
/**
* Allocates a slot to contain a callback for a frame. The function MUST be called after _prepare but before _commit.
*/
Expand Down Expand Up @@ -294,7 +298,7 @@ inline int quicly_sentmap_is_open(quicly_sentmap_t *map)
return map->_pending_packet != NULL;
}

inline void quicly_sentmap_commit(quicly_sentmap_t *map, uint16_t bytes_in_flight, int cc_limited)
inline void quicly_sentmap_commit(quicly_sentmap_t *map, uint16_t bytes_in_flight, int cc_limited, int promoted_path)
{
assert(quicly_sentmap_is_open(map));

Expand All @@ -305,6 +309,8 @@ inline void quicly_sentmap_commit(quicly_sentmap_t *map, uint16_t bytes_in_fligh
map->bytes_in_flight += bytes_in_flight;
}
map->_pending_packet->data.packet.frames_in_flight = 1;
if (promoted_path)
map->_pending_packet->data.packet.promoted_path = 1;
map->_pending_packet = NULL;

++map->num_packets;
Expand Down
6 changes: 6 additions & 0 deletions lib/defaults.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#define DEFAULT_PRE_VALIDATION_AMPLIFICATION_LIMIT 3
#define DEFAULT_HANDSHAKE_TIMEOUT_RTT_MULTIPLIER 400
#define DEFAULT_MAX_INITIAL_HANDSHAKE_PACKETS 1000
#define DEFAULT_MAX_PROBE_PACKETS 5
#define DEFAULT_MAX_PATH_VALIDATION_FAILURES 100

/* profile that employs IETF specified values */
const quicly_context_t quicly_spec_context = {NULL, /* tls */
Expand All @@ -49,6 +51,8 @@ const quicly_context_t quicly_spec_context = {NULL,
0, /* ack_frequency */
DEFAULT_HANDSHAKE_TIMEOUT_RTT_MULTIPLIER,
DEFAULT_MAX_INITIAL_HANDSHAKE_PACKETS,
DEFAULT_MAX_PROBE_PACKETS,
DEFAULT_MAX_PATH_VALIDATION_FAILURES,
0, /* default_jumpstart_cwnd_bytes */
0, /* max_jumpstart_cwnd_bytes */
0, /* enlarge_client_hello */
Expand Down Expand Up @@ -84,6 +88,8 @@ const quicly_context_t quicly_performant_context = {NULL,
0, /* ack_frequency */
DEFAULT_HANDSHAKE_TIMEOUT_RTT_MULTIPLIER,
DEFAULT_MAX_INITIAL_HANDSHAKE_PACKETS,
DEFAULT_MAX_PROBE_PACKETS,
DEFAULT_MAX_PATH_VALIDATION_FAILURES,
0, /* default_jumpstart_cwnd_bytes */
0, /* max_jumpstart_cwnd_bytes */
0, /* enlarge_client_hello */
Expand Down
Loading

0 comments on commit 6a90372

Please sign in to comment.