Skip to content

Commit 10a67ed

Browse files
committed
[+] beta/multipath-ietf-draft-01
1 parent 15aa3e8 commit 10a67ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+6874
-2554
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,19 @@ set(
163163
"src/transport/xqc_packet_out.c"
164164
"src/transport/xqc_packet_in.c"
165165
"src/transport/xqc_send_ctl.c"
166+
"src/transport/xqc_send_queue.c"
166167
"src/transport/xqc_packet.c"
167168
"src/transport/xqc_frame.c"
168169
"src/transport/xqc_recv_record.c"
169170
"src/transport/xqc_pacing.c"
170171
"src/transport/xqc_utils.c"
172+
"src/transport/xqc_multipath.c"
171173
"src/transport/xqc_defs.c"
172174
"src/transport/xqc_transport_params.c"
173175
"src/transport/xqc_quic_lb.c"
176+
"src/transport/xqc_timer.c"
177+
"src/transport/xqc_reinjection.c"
178+
"src/transport/scheduler/xqc_scheduler_minrtt.c"
174179
)
175180

176181
# TLS source

cmake/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,19 @@ set(
164164
"src/transport/xqc_packet_out.c"
165165
"src/transport/xqc_packet_in.c"
166166
"src/transport/xqc_send_ctl.c"
167+
"src/transport/xqc_send_queue.c"
167168
"src/transport/xqc_packet.c"
168169
"src/transport/xqc_frame.c"
169170
"src/transport/xqc_recv_record.c"
170171
"src/transport/xqc_pacing.c"
171172
"src/transport/xqc_utils.c"
173+
"src/transport/xqc_multipath.c"
172174
"src/transport/xqc_defs.c"
173175
"src/transport/xqc_transport_params.c"
174176
"src/transport/xqc_quic_lb.c"
177+
"src/transport/xqc_timer.c"
178+
"src/transport/xqc_reinjection.c"
179+
"src/transport/scheduler/xqc_scheduler_minrtt.c"
175180
)
176181

177182
# TLS source

include/xquic/xqc_errno.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,10 @@ typedef enum {
114114
XQC_EMP_NOT_SUPPORT_MP = 650, /* Multipath - don't support multipath */
115115
XQC_EMP_NO_AVAIL_PATH_ID = 651, /* Multipath - no available path id */
116116
XQC_EMP_CREATE_PATH = 652, /* Multipath - create path error */
117-
XQC_EMP_INVALID_PATH_ID = 653, /* Multipath - invalid path id error */
118-
XQC_EMP_INVALID_FRAME = 654, /* Multipath - invalid frame */
119-
XQC_EMP_INVALID_QOE_SIGNAL = 660, /* Multipath - invalid qoe signal */
117+
XQC_EMP_PATH_NOT_FOUND = 653, /* Multipath - can't find path in paths_list */
118+
XQC_EMP_PATH_STATE_ERROR = 654, /* Multipath - abnormal path status */
119+
XQC_EMP_SCHEDULE_PATH = 655, /* Multipath - fail to schedule path for sending */
120+
XQC_EMP_NO_ACTIVE_PATH = 656, /* Multipath - no another active path */
120121

121122
XQC_EENCRYPT_LB_CID = 670, /* load balance connection ID encryption error */
122123
XQC_EENCRYPT_AES_128_ECB = 671, /* aes_128_ecb algorithm error */

include/xquic/xqc_http3.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ typedef struct xqc_request_stats_s {
128128
xqc_msec_t h3r_end_time; /* time of request fin */
129129
xqc_msec_t h3r_header_begin_time; /* time of receiving HEADERS frame */
130130
xqc_msec_t h3r_header_end_time; /* time of finishing processing HEADERS frame */
131+
132+
int mp_state;
131133
} xqc_request_stats_t;
132134

133135

include/xquic/xquic.h

Lines changed: 135 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ typedef enum xqc_proto_version_s {
6868
#define XQC_MAX_SEND_MSG_ONCE 32
6969

7070

71+
#define XQC_INITIAL_PATH_ID 0
72+
73+
7174
/**
7275
* @brief get timestamp callback function. this might be useful on different platforms
7376
* @return timestamp in microsecond
@@ -287,6 +290,18 @@ typedef int (*xqc_cert_verify_pt)(const unsigned char *certs[], const size_t cer
287290
typedef void (*xqc_conn_peer_addr_changed_nofity_pt)(xqc_connection_t *conn, void *conn_user_data);
288291

289292

293+
/**
294+
* @brief server peer addr changed notify
295+
*
296+
* this function will be trigger after receive peer's changed addr.
297+
*
298+
* @param conn connection handler
299+
* @param path_id id of path
300+
* @param conn_user_data connection level user_data
301+
*/
302+
typedef void (*xqc_path_peer_addr_changed_nofity_pt)(xqc_connection_t *conn, uint64_t path_id, void *conn_user_data);
303+
304+
290305
/**
291306
* @brief return value of xqc_socket_write_pt and xqc_send_mmsg_pt callback function
292307
*/
@@ -359,15 +374,19 @@ typedef void (*xqc_conn_ready_to_create_path_notify_pt)(const xqc_cid_t *scid,
359374
/**
360375
* @brief multi-path create callback function
361376
*
377+
* @param conn connection handler
362378
* @param scid source connection id of endpoint
363379
* @param path_id id of path
364380
* @param conn_user_data user_data of connection
365381
*/
366-
typedef void (*xqc_path_created_notify_pt)(const xqc_cid_t *scid, uint64_t path_id,
367-
void *conn_user_data);
382+
typedef int (*xqc_path_created_notify_pt)(xqc_connection_t *conn,
383+
const xqc_cid_t *scid, uint64_t path_id, void *conn_user_data);
368384

369385
/**
370-
* @brief multi-path remove path callback function. will be triggered when path is destroyed
386+
* @brief multi-path remove path callback function.
387+
*
388+
* this callback function will be triggered when path is closing
389+
* and then the application-layer can release related resource.
371390
*
372391
* @param scid source connection id of endpoint
373392
* @param path_id id of path
@@ -391,8 +410,10 @@ typedef void (*xqc_path_removed_notify_pt)(const xqc_cid_t *scid, uint64_t path_
391410
* XQC_SOCKET_EAGAIN for EAGAIN, we should call xqc_conn_continue_send when socket is ready to write
392411
* Warning: server's user_data is what passed in xqc_engine_packet_process when send a reset packet
393412
*/
394-
typedef ssize_t (*xqc_mp_socket_write_pt)(uint64_t path_id, const unsigned char *buf, size_t size,
395-
const struct sockaddr *peer_addr, socklen_t peer_addrlen, void *conn_user_data);
413+
typedef ssize_t (*xqc_socket_write_ex_pt)(uint64_t path_id,
414+
const unsigned char *buf, size_t size,
415+
const struct sockaddr *peer_addr, socklen_t peer_addrlen,
416+
void *conn_user_data);
396417

397418
/**
398419
* @brief multi-path write socket callback function with sendmmsg
@@ -409,8 +430,9 @@ typedef ssize_t (*xqc_mp_socket_write_pt)(uint64_t path_id, const unsigned char
409430
* XQC_SOCKET_EAGAIN for EAGAIN, we should call xqc_conn_continue_send when socket is ready to write
410431
* Warning: server's user_data is what passed in xqc_engine_packet_process when send a reset packet
411432
*/
412-
typedef ssize_t (*xqc_mp_send_mmsg_pt)(uint64_t path_id, const struct iovec *msg_iov,
413-
unsigned int vlen, const struct sockaddr *peer_addr, socklen_t peer_addrlen,
433+
typedef ssize_t (*xqc_send_mmsg_ex_pt)(uint64_t path_id,
434+
const struct iovec *msg_iov, unsigned int vlen,
435+
const struct sockaddr *peer_addr, socklen_t peer_addrlen,
414436
void *conn_user_data);
415437

416438

@@ -479,6 +501,16 @@ typedef struct xqc_transport_callbacks_s {
479501
*/
480502
xqc_send_mmsg_pt write_mmsg;
481503

504+
/**
505+
* write socket callback, ALTERNATIVE with write_mmsg
506+
*/
507+
xqc_socket_write_ex_pt write_socket_ex;
508+
509+
/**
510+
* write socket with send_mmsg callback, ALTERNATIVE with write_socket
511+
*/
512+
xqc_send_mmsg_ex_pt write_mmsg_ex;
513+
482514
/**
483515
* QUIC connection cid update callback, REQUIRED for both server and client
484516
*/
@@ -529,6 +561,11 @@ typedef struct xqc_transport_callbacks_s {
529561
*/
530562
xqc_conn_peer_addr_changed_nofity_pt conn_peer_addr_changed_notify;
531563

564+
/**
565+
* QUIC path peer addr changed callback, REQUIRED for server.
566+
*/
567+
xqc_path_peer_addr_changed_nofity_pt path_peer_addr_changed_notify;
568+
532569
} xqc_transport_callbacks_t;
533570

534571

@@ -680,6 +717,19 @@ XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_bbr2_cb;
680717
#endif
681718
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_bbr_cb;
682719
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_cong_ctrl_callback_t xqc_cubic_cb;
720+
typedef struct xqc_scheduler_callback_s {
721+
722+
size_t (*xqc_scheduler_size)(void);
723+
724+
void (*xqc_scheduler_init)(void *scheduler, xqc_log_t *log);
725+
726+
xqc_path_ctx_t * (*xqc_scheduler_get_path)(void *scheduler,
727+
xqc_connection_t *conn, xqc_packet_out_t *packet_out,
728+
int check_cwnd, int reinject);
729+
730+
} xqc_scheduler_callback_t;
731+
732+
XQC_EXPORT_PUBLIC_API XQC_EXTERN const xqc_scheduler_callback_t xqc_minrtt_scheduler_cb;
683733

684734

685735
/**
@@ -845,6 +895,27 @@ typedef struct xqc_conn_settings_s {
845895
uint32_t anti_amplification_limit; /* limit of anti-amplification, default 3 */
846896
uint64_t keyupdate_pkt_threshold; /* packet limit of a single 1-rtt key, 0 for unlimited */
847897
size_t max_pkt_out_size;
898+
899+
/*
900+
* multipath option:
901+
* 0: don't support multipath
902+
* 1: only support one PN space for multipath
903+
* 2: only support multiple PN spaces for multipath
904+
* 3: support both one PN space and multiple PN space
905+
* !Attention: don't use xqc_bbr_cb or xqc_bbr2_cb
906+
*/
907+
uint64_t enable_multipath;
908+
/*
909+
* reinjection option:
910+
* 0: default
911+
* 1: try to reinject unacked packets if paths still have cwnd.
912+
* the current reinjection mode is very aggressive, please use with caution.
913+
*/
914+
int mp_enable_reinjection;
915+
916+
/* scheduler callback, default: xqc_minrtt_scheduler_cb */
917+
xqc_scheduler_callback_t scheduler_callback;
918+
848919
} xqc_conn_settings_t;
849920

850921

@@ -854,6 +925,20 @@ typedef enum {
854925
XQC_0RTT_REJECT, /* 0-RTT was rejected */
855926
} xqc_0rtt_flag_t;
856927

928+
929+
#define XQC_MAX_PATHS_COUNT 8
930+
#define XQC_CONN_INFO_LEN 400
931+
932+
typedef struct xqc_path_metrics_s {
933+
uint64_t path_id;
934+
935+
uint64_t path_pkt_recv_count;
936+
uint64_t path_pkt_send_count;
937+
uint64_t path_send_bytes;
938+
uint64_t path_reinject_bytes;
939+
} xqc_path_metrics_t;
940+
941+
857942
typedef struct xqc_conn_stats_s {
858943
uint32_t send_count;
859944
uint32_t lost_count;
@@ -865,6 +950,11 @@ typedef struct xqc_conn_stats_s {
865950
int spurious_loss_detect_on;
866951
int conn_err;
867952
char ack_info[50];
953+
954+
int enable_multipath;
955+
int mp_state;
956+
xqc_path_metrics_t paths_info[XQC_MAX_PATHS_COUNT];
957+
char conn_info[XQC_CONN_INFO_LEN];
868958
} xqc_conn_stats_t;
869959

870960

@@ -1220,9 +1310,47 @@ xqc_int_t xqc_conn_continue_send(xqc_engine_t *engine, const xqc_cid_t *cid);
12201310
XQC_EXPORT_PUBLIC_API
12211311
xqc_conn_stats_t xqc_conn_get_stats(xqc_engine_t *engine, const xqc_cid_t *cid);
12221312

1313+
/**
1314+
* create new path for client
1315+
* @param cid scid for connection
1316+
* @param new_path_id if new path is created successfully, return new_path_id in this param
1317+
* @return XQC_OK (0) when success, <0 for error
1318+
*/
1319+
XQC_EXPORT_PUBLIC_API
1320+
xqc_int_t xqc_conn_create_path(xqc_engine_t *engine,
1321+
const xqc_cid_t *cid, uint64_t *new_path_id);
1322+
1323+
1324+
/**
1325+
* Close a path
1326+
* @param cid scid for connection
1327+
* @param close_path_id path identifier for the closing path
1328+
* @return XQC_OK (0) when success, <0 for error
1329+
*/
1330+
XQC_EXPORT_PUBLIC_API
1331+
xqc_int_t xqc_conn_close_path(xqc_engine_t *engine, const xqc_cid_t *cid, uint64_t closed_path_id);
1332+
12231333
XQC_EXPORT_PUBLIC_API
12241334
xqc_conn_type_t xqc_conn_get_type(xqc_connection_t *conn);
12251335

1336+
/**
1337+
* Server should get peer addr when path_create_notify callbacks
1338+
* @param peer_addr_len is a return value
1339+
* @return XQC_OK for success, others for failure
1340+
*/
1341+
XQC_EXPORT_PUBLIC_API
1342+
xqc_int_t xqc_path_get_peer_addr(xqc_connection_t *conn, uint64_t path_id,
1343+
struct sockaddr *addr, socklen_t addr_cap, socklen_t *peer_addr_len);
1344+
1345+
/**
1346+
* Server should get local addr when path_create_notify callbacks
1347+
* @param local_addr_len is a return value
1348+
* @return XQC_OK for success, others for failure
1349+
*/
1350+
XQC_EXPORT_PUBLIC_API
1351+
xqc_int_t xqc_path_get_local_addr(xqc_connection_t *conn, uint64_t path_id,
1352+
struct sockaddr *addr, socklen_t addr_cap, socklen_t *local_addr_len);
1353+
12261354
/**
12271355
* @brief load balance cid encryption.
12281356
* According to Draft : https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers-13#section-4.3.2

include/xquic/xquic_typedef.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ typedef struct xqc_priority_queue_s xqc_pq_t;
7575
typedef struct xqc_wakeup_pq_s xqc_wakeup_pq_t;
7676
typedef struct xqc_log_s xqc_log_t;
7777
typedef struct xqc_send_ctl_s xqc_send_ctl_t;
78+
typedef struct xqc_send_queue_s xqc_send_queue_t;
79+
typedef struct xqc_pn_ctl_s xqc_pn_ctl_t;
7880
typedef struct xqc_packet_s xqc_packet_t;
7981
typedef struct xqc_packet_in_s xqc_packet_in_t;
8082
typedef struct xqc_packet_out_s xqc_packet_out_t;
@@ -89,6 +91,7 @@ typedef struct xqc_sample_s xqc_sample_t;
8991
typedef struct xqc_memory_pool_s xqc_memory_pool_t;
9092
typedef struct xqc_bbr_info_interface_s xqc_bbr_info_interface_t;
9193
typedef struct xqc_path_ctx_s xqc_path_ctx_t;
94+
typedef struct xqc_timer_manager_s xqc_timer_manager_t;
9295

9396
typedef uint64_t xqc_msec_t; /* store millisecond values */
9497
typedef uint64_t xqc_usec_t; /* store microsecond values */

0 commit comments

Comments
 (0)