Skip to content

Commit 4ff9ee6

Browse files
authored
[+] Add support for Multipath-QUIC, optimize performance, and fix some bugs (#287)
1 parent 917ac4a commit 4ff9ee6

File tree

135 files changed

+12003
-4105
lines changed

Some content is hidden

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

135 files changed

+12003
-4105
lines changed

CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,22 @@ 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/reinjection_control/xqc_reinj_xlink.c"
179+
"src/transport/scheduler/xqc_scheduler_minrtt.c"
180+
"src/transport/scheduler/xqc_scheduler_common.c"
181+
"src/transport/scheduler/xqc_scheduler_backup.c"
174182
)
175183

176184
# TLS source
@@ -225,7 +233,6 @@ set(
225233
CONGESTION_CONTROL_SOURCES
226234
"src/congestion_control/xqc_cubic.c"
227235
"src/congestion_control/xqc_bbr.c"
228-
"src/congestion_control/xqc_copa.c"
229236
"src/congestion_control/xqc_window_filter.c"
230237
"src/congestion_control/xqc_sample.c"
231238
)

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,7 @@ In no particular order, thanks to these excellent individuals who contributed co
215215
* @CherylQL
216216
* @wangweiwei1188
217217
* @yunwei37
218+
* @keengo99
219+
* @ruanshanshan
218220

219221
This list will be continuously updated. Contributions are welcome!

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ XQUIC Library released by Alibaba is …
1616

1717
**a client and server implementation of QUIC and HTTP/3 as specified by the IETF.** Currently supported QUIC versions are v1 and draft-29.
1818

19-
**OS and platform agnostic.** It currently supports Android, iOS, Linux, macOS and Windows. Most of the code is used in our own products, and has been tested at scale on android, iOS apps, as well as servers.
19+
**OS and platform agnostic.** It currently supports Android, iOS, Linux, macOS and Windows(v1.2.0). Most of the code is used in our own products, and has been tested at scale on android, iOS apps, as well as servers.
2020

2121
**still in active development.** [Interoperability](https://interop.seemann.io/) is regularly tested with other QUIC implementations.
2222

@@ -40,7 +40,7 @@ XQUIC Library released by Alibaba is …
4040

4141
#### Not Yet Standardized Features
4242

43-
* [Multipath QUIC](https://tools.ietf.org/html/draft-ietf-quic-multipath-01) (beta version)
43+
* [Multipath QUIC](https://tools.ietf.org/html/draft-ietf-quic-multipath-02)
4444

4545
* [QUIC-LB](https://tools.ietf.org/html/draft-ietf-quic-load-balancers-13)
4646

@@ -50,7 +50,7 @@ XQUIC Library released by Alibaba is …
5050

5151
* Pluggable cryptography, integration with BoringSSL and BabaSSL
5252

53-
* Cross-platform implementation, support Android, iOS, Linux, macOS and Windows
53+
* Cross-platform implementation, support Android, iOS, Linux, macOS and Windows(v1.2.0)
5454

5555
## Requirements
5656

cmake/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,22 @@ 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/reinjection_control/xqc_reinj_xlink.c"
180+
"src/transport/scheduler/xqc_scheduler_minrtt.c"
181+
"src/transport/scheduler/xqc_scheduler_common.c"
182+
"src/transport/scheduler/xqc_scheduler_backup.c"
175183
)
176184

177185
# TLS source
@@ -226,7 +234,6 @@ set(
226234
CONGESTION_CONTROL_SOURCES
227235
"src/congestion_control/xqc_cubic.c"
228236
"src/congestion_control/xqc_bbr.c"
229-
"src/congestion_control/xqc_copa.c"
230237
"src/congestion_control/xqc_window_filter.c"
231238
"src/congestion_control/xqc_sample.c"
232239
)

demo/common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,16 @@ xqc_demo_read_file_data(char * data, size_t data_len, char *filename)
9494
return ret;
9595
}
9696

97+
98+
static inline uint64_t
99+
xqc_demo_now()
100+
{
101+
/* get microsecond unit time */
102+
struct timeval tv;
103+
gettimeofday(&tv, NULL);
104+
uint64_t ul = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec;
105+
return ul;
106+
}
107+
108+
97109
#endif

demo/demo_client.c

Lines changed: 37 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,20 @@
88
#include <xquic/xquic_typedef.h>
99
#include <xquic/xqc_http3.h>
1010
#include <stdio.h>
11-
11+
#include <event2/event.h>
1212
#include <memory.h>
13+
#include <sys/socket.h>
14+
#include <unistd.h>
1315
#include <errno.h>
1416
#include <signal.h>
1517
#include <fcntl.h>
1618
#include <stdlib.h>
1719
#include <time.h>
1820
#include <inttypes.h>
21+
#include <netdb.h>
1922
#include <string.h>
20-
#include <event2/event.h>
2123
#include "common.h"
2224
#include "xqc_hq.h"
23-
#include "../tests/platform.h"
24-
25-
#ifdef XQC_SYS_WINDOWS
26-
#pragma comment(lib,"ws2_32.lib")
27-
#pragma comment(lib,"event.lib")
28-
#pragma comment(lib, "Iphlpapi.lib")
29-
#include <third_party/wingetopt/src/getopt.h>
30-
#else
31-
#include <sys/socket.h>
32-
#include <unistd.h>
33-
#include <netdb.h>
34-
#endif
3525

3626

3727
#define XQC_PACKET_TMP_BUF_LEN 1600
@@ -406,7 +396,7 @@ void
406396
xqc_demo_cli_set_event_timer(xqc_usec_t wake_after, void *eng_user_data)
407397
{
408398
xqc_demo_cli_ctx_t *ctx = (xqc_demo_cli_ctx_t *) eng_user_data;
409-
//printf("xqc_engine_wakeup_after %llu us, now %llu\n", wake_after, xqc_now());
399+
//printf("xqc_engine_wakeup_after %llu us, now %llu\n", wake_after, xqc_demo_now());
410400

411401
struct timeval tv;
412402
tv.tv_sec = wake_after / 1000000;
@@ -446,12 +436,12 @@ xqc_demo_cli_write_log_file(xqc_log_level_t lvl, const void *buf, size_t size, v
446436
//printf("%s", (char *)buf);
447437
int write_len = write(ctx->log_fd, buf, size);
448438
if (write_len < 0) {
449-
printf("write log failed, errno: %d\n", get_last_sys_errno());
439+
printf("write log failed, errno: %d\n", errno);
450440
return;
451441
}
452442
write_len = write(ctx->log_fd, line_break, 1);
453443
if (write_len < 0) {
454-
printf("write log failed, errno: %d\n", get_last_sys_errno());
444+
printf("write log failed, errno: %d\n", errno);
455445
}
456446
}
457447

@@ -489,12 +479,12 @@ xqc_demo_cli_keylog_cb(const char *line, void *engine_user_data)
489479

490480
int write_len = write(ctx->keylog_fd, line, strlen(line));
491481
if (write_len < 0) {
492-
printf("write keys failed, errno: %d\n", get_last_sys_errno());
482+
printf("write keys failed, errno: %d\n", errno);
493483
return;
494484
}
495485
write_len = write(ctx->keylog_fd, line_break, 1);
496486
if (write_len < 0) {
497-
printf("write keys failed, errno: %d\n", get_last_sys_errno());
487+
printf("write keys failed, errno: %d\n", errno);
498488
}
499489
}
500490

@@ -545,7 +535,7 @@ xqc_demo_cli_save_token(const unsigned char *token, uint32_t token_len, void *co
545535
{
546536
xqc_demo_cli_user_conn_t *user_conn = (xqc_demo_cli_user_conn_t*)conn_user_data;
547537

548-
int fd = open(TOKEN_FILE, O_TRUNC | O_CREAT | O_WRONLY, 0666);
538+
int fd = open(TOKEN_FILE, O_TRUNC | O_CREAT | O_WRONLY, S_IRWXU);
549539
if (fd < 0) {
550540
return;
551541
}
@@ -579,25 +569,23 @@ xqc_demo_cli_write_socket(const unsigned char *buf, size_t size, const struct so
579569
xqc_demo_cli_user_conn_t *user_conn = (xqc_demo_cli_user_conn_t *)conn_user_data;
580570
ssize_t res = 0;
581571
do {
582-
set_last_sys_errno(0);
572+
errno = 0;
583573
res = sendto(user_conn->fd, buf, size, 0, peer_addr, peer_addrlen);
584574
if (res < 0) {
585575
printf("xqc_demo_cli_write_socket err %zd %s, fd: %d, buf: %p, size: %zu, "
586-
"server_addr: %s\n", res, strerror(get_last_sys_errno()), user_conn->fd,
587-
buf, size, user_conn->ctx->args->net_cfg.server_addr);
588-
if (get_last_sys_errno() == EAGAIN) {
576+
"server_addr: %s\n", res, strerror(errno), user_conn->fd, buf, size,
577+
user_conn->ctx->args->net_cfg.server_addr);
578+
if (errno == EAGAIN) {
589579
res = XQC_SOCKET_EAGAIN;
590580
}
591581
}
592-
user_conn->last_sock_op_time = xqc_now();
593-
594-
} while ((res < 0) && (get_last_sys_errno() == EINTR));
582+
user_conn->last_sock_op_time = xqc_demo_now();
583+
} while ((res < 0) && (errno == EINTR));
595584

596585
return res;
597586
}
598587

599588

600-
#ifndef XQC_SYS_WINDOWS
601589
#if defined(XQC_SUPPORT_SENDMMSG)
602590
ssize_t
603591
xqc_demo_cli_write_mmsg(void *conn_user_data, struct iovec *msg_iov, unsigned int vlen,
@@ -622,12 +610,11 @@ xqc_demo_cli_write_mmsg(void *conn_user_data, struct iovec *msg_iov, unsigned in
622610
res = XQC_SOCKET_EAGAIN;
623611
}
624612
}
625-
626-
} while ((res < 0) && (get_last_sys_errno() == EINTR));
613+
} while ((res < 0) && (errno == EINTR));
627614
return res;
628615
}
629616
#endif
630-
#endif
617+
631618

632619
void
633620
xqc_demo_cli_conn_update_cid_notify(xqc_connection_t *conn, const xqc_cid_t *retire_cid,
@@ -681,7 +668,7 @@ xqc_demo_cli_hq_req_send(xqc_hq_request_t *hqr, xqc_demo_cli_user_stream_t *user
681668
ssize_t ret = 0;
682669

683670
if (user_stream->start_time == 0) {
684-
user_stream->start_time = xqc_now();
671+
user_stream->start_time = xqc_demo_now();
685672
}
686673

687674
ret = xqc_hq_request_send_req(hqr, user_stream->send_buf);
@@ -755,7 +742,7 @@ xqc_demo_cli_hq_req_read_notify(xqc_hq_request_t *hqr, void *req_user_data)
755742

756743
if (fin) {
757744
user_stream->recv_fin = 1;
758-
xqc_msec_t now_us = xqc_now();
745+
xqc_msec_t now_us = xqc_demo_now();
759746
printf("\033[33m>>>>>>>> request time cost:%"PRIu64" us, speed:%"PRIu64" K/s \n"
760747
">>>>>>>> user_stream[%p], req: %s, send_body_size:%zu, recv_body_size:%zu \033[0m\n",
761748
now_us - user_stream->start_time,
@@ -800,7 +787,7 @@ xqc_demo_cli_h3_request_send(xqc_demo_cli_user_stream_t *user_stream)
800787
if (!user_stream->hdr_sent)
801788
{
802789
if (user_stream->start_time == 0) {
803-
user_stream->start_time = xqc_now();
790+
user_stream->start_time = xqc_demo_now();
804791
}
805792

806793
ret = xqc_h3_request_send_headers(user_stream->h3_request, &user_stream->h3_hdrs, 1);
@@ -893,7 +880,7 @@ xqc_demo_cli_h3_request_read_notify(xqc_h3_request_t *h3_request, xqc_request_no
893880
user_stream->recv_fin = 1;
894881
xqc_request_stats_t stats;
895882
stats = xqc_h3_request_get_stats(h3_request);
896-
xqc_msec_t now_us = xqc_now();
883+
xqc_msec_t now_us = xqc_demo_now();
897884
printf("\033[33m>>>>>>>> request time cost:%"PRIu64" us, speed:%"PRIu64" K/s \n"
898885
">>>>>>>> send_body_size:%zu, recv_body_size:%zu \033[0m\n",
899886
now_us - user_stream->start_time,
@@ -959,7 +946,7 @@ xqc_demo_cli_socket_read_handler(xqc_demo_cli_user_conn_t *user_conn)
959946
do {
960947
recv_size = recvfrom(user_conn->fd, packet_buf, sizeof(packet_buf), 0,
961948
(struct sockaddr *)&addr, &addr_len);
962-
if (recv_size < 0 && get_last_sys_errno() == EAGAIN) {
949+
if (recv_size < 0 && errno == EAGAIN) {
963950
break;
964951
}
965952

@@ -971,11 +958,11 @@ xqc_demo_cli_socket_read_handler(xqc_demo_cli_user_conn_t *user_conn)
971958
xqc_int_t ret = getsockname(user_conn->fd, (struct sockaddr*)&user_conn->local_addr,
972959
&user_conn->local_addrlen);
973960
if (ret != 0) {
974-
printf("getsockname error, errno: %d\n", get_last_sys_errno());
961+
printf("getsockname error, errno: %d\n", errno);
975962
}
976963

977964
recv_sum += recv_size;
978-
uint64_t recv_time = xqc_now();
965+
uint64_t recv_time = xqc_demo_now();
979966
user_conn->last_sock_op_time = recv_time;
980967
if (xqc_engine_packet_process(user_conn->ctx->engine, packet_buf, recv_size,
981968
(struct sockaddr *)(&user_conn->local_addr),
@@ -1015,7 +1002,7 @@ xqc_demo_cli_socket_event_callback(int fd, short what, void *arg)
10151002
static void
10161003
xqc_demo_cli_engine_callback(int fd, short what, void *arg)
10171004
{
1018-
// printf("timer wakeup now:%"PRIu64"\n", xqc_now());
1005+
// printf("timer wakeup now:%"PRIu64"\n", xqc_demo_now());
10191006
xqc_demo_cli_ctx_t *ctx = (xqc_demo_cli_ctx_t *) arg;
10201007
xqc_engine_main_logic(ctx->engine);
10211008
}
@@ -1026,7 +1013,7 @@ xqc_demo_cli_idle_callback(int fd, short what, void *arg)
10261013
{
10271014
int rc = 0;
10281015
xqc_demo_cli_user_conn_t *user_conn = (xqc_demo_cli_user_conn_t *) arg;
1029-
if (xqc_now() - user_conn->last_sock_op_time < (uint64_t)user_conn->ctx->args->net_cfg.conn_timeout * 1000000) {
1016+
if (xqc_demo_now() - user_conn->last_sock_op_time < (uint64_t)user_conn->ctx->args->net_cfg.conn_timeout * 1000000) {
10301017
struct timeval tv;
10311018
tv.tv_sec = user_conn->ctx->args->net_cfg.conn_timeout;
10321019
tv.tv_usec = 0;
@@ -1123,11 +1110,11 @@ xqc_demo_cli_init_conneciton_settings(xqc_conn_settings_t* settings,
11231110
break;
11241111

11251112
case CC_TYPE_CUBIC:
1126-
cong_ctrl = xqc_cubic_cb;
1113+
cong_ctrl = xqc_reno_cb;
11271114
break;
11281115

11291116
case CC_TYPE_RENO:
1130-
cong_ctrl = xqc_reno_cb;
1117+
cong_ctrl = xqc_cubic_cb;
11311118
break;
11321119

11331120
default:
@@ -1265,6 +1252,7 @@ xqc_demo_cli_usage(int argc, char *argv[])
12651252
, prog);
12661253
}
12671254

1255+
12681256
void
12691257
xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args)
12701258
{
@@ -1879,35 +1867,30 @@ xqc_demo_cli_create_socket(xqc_demo_cli_user_conn_t *user_conn, xqc_demo_cli_net
18791867
int size;
18801868
int fd = 0;
18811869
int ret;
1882-
int flags = 1;
18831870
struct sockaddr *addr = (struct sockaddr*)&cfg->addr;
18841871
fd = socket(addr->sa_family, SOCK_DGRAM, 0);
18851872
if (fd < 0) {
1886-
printf("create socket failed, errno: %d\n", get_last_sys_errno());
1873+
printf("create socket failed, errno: %d\n", errno);
18871874
return -1;
18881875
}
1889-
#ifdef XQC_SYS_WINDOWS
1890-
if (ioctlsocket(fd, FIONBIO, &flags) == SOCKET_ERROR) {
1891-
goto err;
1892-
}
1893-
#else
1876+
18941877
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
1895-
printf("set socket nonblock failed, errno: %d\n", get_last_sys_errno());
1878+
printf("set socket nonblock failed, errno: %d\n", errno);
18961879
goto err;
18971880
}
1898-
#endif
1881+
18991882
size = 1 * 1024 * 1024;
19001883
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(int)) < 0) {
1901-
printf("setsockopt failed, errno: %d\n", get_last_sys_errno());
1884+
printf("setsockopt failed, errno: %d\n", errno);
19021885
goto err;
19031886
}
19041887

19051888
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int)) < 0) {
1906-
printf("setsockopt failed, errno: %d\n", get_last_sys_errno());
1889+
printf("setsockopt failed, errno: %d\n", errno);
19071890
goto err;
19081891
}
19091892

1910-
user_conn->last_sock_op_time = xqc_now();
1893+
user_conn->last_sock_op_time = xqc_demo_now();
19111894

19121895
return fd;
19131896

@@ -2138,9 +2121,6 @@ xqc_demo_cli_free_ctx(xqc_demo_cli_ctx_t *ctx)
21382121
int
21392122
main(int argc, char *argv[])
21402123
{
2141-
/* init env if necessary */
2142-
xqc_platform_init_env();
2143-
21442124
/* get input client args */
21452125
xqc_demo_cli_client_args_t *args = calloc(1, sizeof(xqc_demo_cli_client_args_t));
21462126
xqc_demo_cli_init_args(args);

0 commit comments

Comments
 (0)