From 2bbffedb822275bf7d035e8f9ea30e2b7a3954b7 Mon Sep 17 00:00:00 2001 From: William Yang Date: Sun, 10 Oct 2021 22:58:21 +0200 Subject: [PATCH] feat: conn with local addr specified --- c_src/quicer_config.c | 7 +------ c_src/quicer_config.h | 6 ++++++ c_src/quicer_connection.c | 16 ++++++++++++++++ test/quicer_SUITE.erl | 21 +++++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/c_src/quicer_config.c b/c_src/quicer_config.c index c94d0944..2a4a4958 100644 --- a/c_src/quicer_config.c +++ b/c_src/quicer_config.c @@ -35,11 +35,6 @@ static ERL_NIF_TERM get_connection_opt(ErlNifEnv *env, QuicerConnCTX *c_ctx, ERL_NIF_TERM optname, ERL_NIF_TERM elevel); -static ERL_NIF_TERM set_connection_opt(ErlNifEnv *env, - QuicerConnCTX *c_ctx, - ERL_NIF_TERM optname, - ERL_NIF_TERM optval, - ERL_NIF_TERM elevel); static ERL_NIF_TERM get_listener_opt(ErlNifEnv *env, QuicerListenerCTX *l_ctx, @@ -1454,7 +1449,7 @@ get_connection_opt(ErlNifEnv *env, return res; } -static ERL_NIF_TERM +ERL_NIF_TERM set_connection_opt(ErlNifEnv *env, QuicerConnCTX *c_ctx, ERL_NIF_TERM optname, diff --git a/c_src/quicer_config.h b/c_src/quicer_config.h index 2e4c56e2..a4c242d5 100644 --- a/c_src/quicer_config.h +++ b/c_src/quicer_config.h @@ -65,4 +65,10 @@ bool create_settings(ErlNifEnv *env, bool parse_listen_on(ErlNifEnv *env, ERL_NIF_TERM elisten_on, QUIC_ADDR *Address); +ERL_NIF_TERM set_connection_opt(ErlNifEnv *env, + QuicerConnCTX *c_ctx, + ERL_NIF_TERM optname, + ERL_NIF_TERM optval, + ERL_NIF_TERM elevel); + #endif // __QUICER_CONFIG_H_ diff --git a/c_src/quicer_connection.c b/c_src/quicer_connection.c index 57125599..9317edc5 100644 --- a/c_src/quicer_connection.c +++ b/c_src/quicer_connection.c @@ -558,6 +558,22 @@ async_connect3(ErlNifEnv *env, } } + ERL_NIF_TERM evalue; + if (enif_get_map_value( + env, eoptions, ATOM_QUIC_PARAM_CONN_LOCAL_ADDRESS, &evalue)) + { + if (!IS_SAME_TERM(ATOM_OK, + set_connection_opt(env, + c_ctx, + ATOM_QUIC_PARAM_CONN_LOCAL_ADDRESS, + evalue, + ATOM_FALSE))) + { + destroy_c_ctx(c_ctx); + return ERROR_TUPLE_2(ATOM_CONN_OPEN_ERROR); + } + } + if (QUIC_FAILED(Status = MsQuic->ConnectionStart(c_ctx->Connection, c_ctx->Configuration, QUIC_ADDRESS_FAMILY_UNSPEC, diff --git a/test/quicer_SUITE.erl b/test/quicer_SUITE.erl index 4d9a2336..c87504b9 100644 --- a/test/quicer_SUITE.erl +++ b/test/quicer_SUITE.erl @@ -49,6 +49,7 @@ , tc_conn_basic_slow_start/1 , tc_conn_double_close/1 , tc_conn_other_port/1 + , tc_conn_with_localaddr/1 , tc_conn_controlling_process/1 , tc_stream_client_init/1 @@ -373,6 +374,26 @@ tc_conn_other_port(Config)-> ct:fail("timeout") end. +tc_conn_with_localaddr(Config)-> + Port = 5568, + Owner = self(), + {SPid, Ref} = spawn_monitor(fun() -> simple_conn_server(Owner, Config, Port) end), + + {ok, CPort0} = gen_udp:open(0, [{ip, {127, 0, 0, 1}}]), + {ok, {{127, 0, 0, 1}, PortX}} = inet:sockname(CPort0), + ok = gen_udp:close(CPort0), + receive + listener_ready -> + {ok, Conn} = quicer:connect("127.0.0.1", Port, [{param_conn_local_address, "127.0.0.1:" ++ integer_to_list(PortX)} + | default_conn_opts()], 5000), + ?assertEqual({ok, {{127,0,0,1}, PortX}}, quicer:sockname(Conn)), + ok = quicer:close_connection(Conn), + SPid ! done, + ok = ensure_server_exit_normal(Ref) + after 1000 -> + ct:fail("timeout") + end. + tc_stream_client_init(Config) -> Port = 4568, Owner = self(),