Skip to content

Commit

Permalink
fix(conn): deadlock when async_connect with 0-RTT
Browse files Browse the repository at this point in the history
msquic does conn callback with StreamsAvailable event in the same code
path of set conn param session ticket.

This causes deadlock when callback handler wait for quicer async_connect to
release the lock of c_ctx when it is called with an opened handle.

solution is to either do set session ticket in open_connection
Or set session ticket in async_connect without an opened handle

callstack:
    at /home/ubuntu/repo/quic/msquic/src/core/stream_set.c:343
  • Loading branch information
qzhuyan committed Sep 8, 2023
1 parent a92e4f4 commit 649c81b
Showing 1 changed file with 24 additions and 20 deletions.
44 changes: 24 additions & 20 deletions c_src/quicer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ open_connectionX(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
ERL_NIF_TERM res = ERROR_TUPLE_2(ATOM_ERROR_INTERNAL_ERROR);
QuicerRegistrationCTX *r_ctx = NULL;
HQUIC registration = NULL;
ERL_NIF_TERM options = argv[1];

if (argc == 0)
{
Expand All @@ -516,7 +517,6 @@ open_connectionX(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
else
{
assert(argc == 1);
ERL_NIF_TERM options = argv[1];
if (!parse_registration(env, options, &r_ctx))
{
return ERROR_TUPLE_2(ATOM_QUIC_REGISTRATION);
Expand Down Expand Up @@ -562,6 +562,12 @@ open_connectionX(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
goto exit;
}

if (!IS_SAME_TERM(ATOM_OK,
(res = parse_conn_resume_ticket(env, options, c_ctx))))
{
goto exit;
}

eHandle = enif_make_resource(env, c_ctx);
return SUCCESS(eHandle);

Expand Down Expand Up @@ -666,12 +672,10 @@ async_connect3(ErlNifEnv *env,
}
}


if (is_reuse_handle)
{
enif_mutex_lock(c_ctx->lock);
}

{
enif_mutex_lock(c_ctx->lock);
}

assert(c_ctx->owner);
// allocate config_resource for client connection
Expand Down Expand Up @@ -723,6 +727,12 @@ async_connect3(ErlNifEnv *env,
res = ERROR_TUPLE_2(ATOM_CONN_OPEN_ERROR);
goto Error;
}

if (!IS_SAME_TERM(
ATOM_OK, (res = parse_conn_resume_ticket(env, eoptions, c_ctx))))
{
goto Error;
}
}

assert(c_ctx->is_closed);
Expand All @@ -737,12 +747,6 @@ async_connect3(ErlNifEnv *env,
goto Error;
}

if (!IS_SAME_TERM(ATOM_OK,
(res = parse_conn_resume_ticket(env, eoptions, c_ctx))))
{
goto Error;
}

if (!IS_SAME_TERM(
ATOM_OK,
(res = parse_conn_disable_1rtt_encryption(env, eoptions, c_ctx))))
Expand Down Expand Up @@ -789,10 +793,10 @@ async_connect3(ErlNifEnv *env,
enif_monitor_process(NULL, c_ctx, &c_ctx->owner->Pid, &c_ctx->owner_mon);
eHandle = enif_make_resource(env, c_ctx);

if(is_reuse_handle)
{
enif_mutex_unlock(c_ctx->lock);
}
if (is_reuse_handle)
{
enif_mutex_unlock(c_ctx->lock);
}
return SUCCESS(eHandle);

Error:
Expand Down Expand Up @@ -842,10 +846,10 @@ async_connect3(ErlNifEnv *env,
// Error exit, it must be closed or Handle is NULL
assert(c_ctx->is_closed || NULL == c_ctx->Connection);

if(is_reuse_handle)
{
enif_mutex_unlock(c_ctx->lock);
}
if (is_reuse_handle)
{
enif_mutex_unlock(c_ctx->lock);
}

return res;
}
Expand Down

0 comments on commit 649c81b

Please sign in to comment.