Skip to content

Commit

Permalink
[+] add available path count API (#363)
Browse files Browse the repository at this point in the history
* [+] add path status cases

* [~] fix function declaration

* [+] add logs

* [+] update the client option

* [+] add threshold option for path standby and available

* [~] fix log format

* [=] format fix

* [=] log format

* [+] add logs

* [+] add more logs

* [=] delete unused logs

* [=] log format

* [+] fix million seconds

* [+] add trigger for both hq and h3

* [=] delete unused logs
  • Loading branch information
Yanmei-Liu authored Nov 5, 2023
1 parent 5bac338 commit e1695fa
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 13 deletions.
68 changes: 55 additions & 13 deletions demo/demo_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ typedef struct xqc_demo_cli_quic_config_s {

uint8_t mp_version;

uint8_t test_path_status;
uint8_t send_path_standby;
xqc_msec_t path_status_timer_threshold;

} xqc_demo_cli_quic_config_t;

Expand Down Expand Up @@ -397,7 +398,10 @@ typedef struct xqc_demo_cli_user_conn_s {
xqc_demo_cli_ctx_t *ctx;
xqc_demo_cli_task_t *task;

int send_path_available;
int send_path_standby;
int path_status; /* 0:available 1:standby */
xqc_msec_t path_status_time;
xqc_msec_t path_status_timer_threshold;
} xqc_demo_cli_user_conn_t;

static void
Expand Down Expand Up @@ -958,6 +962,40 @@ xqc_demo_cli_hq_req_write_notify(xqc_hq_request_t *hqr, void *req_user_data)
return 0;
}

void
xqc_demo_path_status_trigger(xqc_demo_cli_user_conn_t *user_conn)
{
xqc_msec_t ts_now = xqc_demo_now(), path_status_time = 0;

if (user_conn->send_path_standby) {

/* set initial path standby here */
if (user_conn->path_status == 0
&& xqc_conn_available_paths(user_conn->ctx->engine, &user_conn->cid) >= 2)
{
if (ts_now > user_conn->path_status_time + user_conn->path_status_timer_threshold) {
xqc_conn_mark_path_standby(user_conn->ctx->engine, &user_conn->cid, 0);
user_conn->path_status = 1; /* 1:standby */

user_conn->path_status_time = ts_now;
printf("mark_path_standby: path_id=0 path_status=%d now=%"PRIu64" pre=%"PRIu64" threshold=%"PRIu64"\n",
user_conn->path_status, ts_now, user_conn->path_status_time, user_conn->path_status_timer_threshold);
}

} else if (user_conn->path_status == 1) {

if (ts_now > user_conn->path_status_time + user_conn->path_status_timer_threshold) {
xqc_conn_mark_path_available(user_conn->ctx->engine, &user_conn->cid, 0);
user_conn->path_status = 0; /* 0:available */

user_conn->path_status_time = ts_now;
printf("mark_path_available: path_id=0 path_status=%d now=%"PRIu64" pre=%"PRIu64" threshold=%"PRIu64"\n",
user_conn->path_status, ts_now, user_conn->path_status_time, user_conn->path_status_timer_threshold);
}
}
}
}

int
xqc_demo_cli_hq_req_read_notify(xqc_hq_request_t *hqr, void *req_user_data)
{
Expand All @@ -967,6 +1005,8 @@ xqc_demo_cli_hq_req_read_notify(xqc_hq_request_t *hqr, void *req_user_data)
char buff[4096] = {0};
size_t buff_size = 4096;

xqc_demo_path_status_trigger(user_stream->user_conn);

ssize_t read = 0;
ssize_t read_sum = 0;
do {
Expand Down Expand Up @@ -1074,6 +1114,7 @@ xqc_demo_cli_h3_request_write_notify(xqc_h3_request_t *h3_request, void *user_da
return 0;
}


int
xqc_demo_cli_h3_request_read_notify(xqc_h3_request_t *h3_request, xqc_request_notify_flag_t flag,
void *user_data)
Expand All @@ -1084,6 +1125,9 @@ xqc_demo_cli_h3_request_read_notify(xqc_h3_request_t *h3_request, xqc_request_no
xqc_demo_cli_task_ctx_t *ctx = &user_stream->user_conn->ctx->task_ctx;
xqc_demo_cli_user_conn_t *user_conn = user_stream->user_conn;
uint32_t task_idx = user_conn->task->task_idx;

xqc_demo_path_status_trigger(user_conn);

// printf("xqc_demo_cli_h3_request_read_notify, h3_request: %p, user_stream: %p\n", h3_request, user_stream);
if (flag & XQC_REQ_NOTIFY_READ_HEADER) {
xqc_http_headers_t *headers;
Expand Down Expand Up @@ -1721,7 +1765,7 @@ xqc_demo_cli_usage(int argc, char *argv[])
" -T Throttle recving rate (Bps)\n"
" -R Reinjection (1,2,4) \n"
" -V Multipath Version (4,5,6)\n"
" -B Set path B standby after 600ms\n"
" -B Set initial path standby after recvd first application data, and set initial path available after X ms\n"
" -I Idle interval between requests (ms)\n"
" -n Throttling the {1,2,...}xn-th requests\n"
" -e NAT rebinding on path 0\n"
Expand Down Expand Up @@ -1936,8 +1980,9 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args
break;

case 'B':
printf("option multipath set path status: %s\n", optarg);
args->quic_cfg.test_path_status = 1;
printf("option multipath set path status: %s ms\n", optarg);
args->quic_cfg.send_path_standby = 1;
args->quic_cfg.path_status_timer_threshold = atoi(optarg) * 1000;
break;

case 'I':
Expand Down Expand Up @@ -2199,12 +2244,6 @@ xqc_demo_cli_h3_conn_handshake_finished(xqc_h3_conn_t *h3_conn, void *user_data)
xqc_conn_stats_t stats = xqc_conn_get_stats(user_conn->ctx->engine, &user_conn->cid);
printf("0rtt_flag:%d\n", stats.early_data_flag);

if (user_conn->send_path_available) {
/* set initial path available here */
xqc_conn_mark_path_standby(user_conn->ctx->engine, &user_conn->cid, 0);
xqc_conn_mark_path_available(user_conn->ctx->engine, &user_conn->cid, 0);
}

}

void
Expand Down Expand Up @@ -2391,9 +2430,12 @@ xqc_demo_cli_init_xquic_connection(xqc_demo_cli_user_conn_t *user_conn,

if (conn_settings.enable_multipath
&& conn_settings.multipath_version >= XQC_MULTIPATH_06
&& args->quic_cfg.test_path_status == 1)
&& args->quic_cfg.send_path_standby == 1)
{
user_conn->send_path_available = 1;
user_conn->send_path_standby = 1;
user_conn->path_status = 0;
user_conn->path_status_timer_threshold = args->quic_cfg.path_status_timer_threshold;
user_conn->path_status_time = 0;
}

return 0;
Expand Down
9 changes: 9 additions & 0 deletions include/xquic/xquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1867,6 +1867,15 @@ XQC_EXPORT_PUBLIC_API
xqc_int_t xqc_conn_mark_path_frozen(xqc_engine_t *engine, const xqc_cid_t *cid, uint64_t path_id);


/**
* Calculate how many available paths on the current connection, i.e., paths which finished validation and is marked "available" status.
* @param engine xquic engine ctx
* @param cid scid for connection
* @return number of available paths when success, <0 for error
*/
XQC_EXPORT_PUBLIC_API xqc_int_t xqc_conn_available_paths(xqc_engine_t *engine, const xqc_cid_t *cid);


XQC_EXPORT_PUBLIC_API
xqc_conn_type_t xqc_conn_get_type(xqc_connection_t *conn);

Expand Down
1 change: 1 addition & 0 deletions scripts/xquic.lds
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ XQUIC_VERS_1.0 {
xqc_conn_mark_path_standby;
xqc_conn_mark_path_available;
xqc_conn_mark_path_frozen;
xqc_conn_available_paths;
xqc_dcid_str_by_scid;
xqc_h3_ctx_init;
xqc_h3_ctx_destroy;
Expand Down
28 changes: 28 additions & 0 deletions src/transport/xqc_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -5595,6 +5595,34 @@ xqc_conn_handle_stateless_reset(xqc_connection_t *conn,
}


xqc_int_t
xqc_conn_available_paths(xqc_engine_t *engine, const xqc_cid_t *cid)
{
xqc_int_t available_paths = 0;
xqc_connection_t *conn = xqc_engine_conns_hash_find(engine, cid, 's');
if (conn == NULL) {
/* no connection found */
return available_paths;
}

xqc_path_ctx_t *path;
xqc_list_head_t *path_pos, *path_next;

xqc_list_for_each_safe(path_pos, path_next, &conn->conn_paths_list) {
path = xqc_list_entry(path_pos, xqc_path_ctx_t, path_list);
if (path->path_state < XQC_PATH_STATE_VALIDATING) {
continue;
}
if (path->path_state == XQC_PATH_STATE_ACTIVE) {
available_paths++;
}
}

xqc_log(conn->log, XQC_LOG_DEBUG, "|xqc_conn_available_paths|%" PRId32 "|", available_paths);
return available_paths;
}


#ifdef XQC_COMPAT_GENERATE_SR_PKT

xqc_int_t
Expand Down
1 change: 1 addition & 0 deletions src/transport/xqc_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,4 +666,5 @@ void xqc_conn_destroy_ping_notification_list(xqc_connection_t *conn);

xqc_int_t xqc_conn_send_ping_internal(xqc_connection_t *conn, void *ping_user_data, xqc_bool_t notify);


#endif /* _XQC_CONN_H_INCLUDED_ */

0 comments on commit e1695fa

Please sign in to comment.