diff --git a/c_src/quicer_nif.c b/c_src/quicer_nif.c index 98fd259c..f7b7af9b 100644 --- a/c_src/quicer_nif.c +++ b/c_src/quicer_nif.c @@ -1186,10 +1186,29 @@ openLib(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) env, argv[0], ATOM_QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE, &eterm) && enif_get_uint(env, eterm, &lb_mode)) { - MsQuic->SetParam(NULL, - QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE, - sizeof(uint16_t), - (uint16_t *)&lb_mode); + + if (lb_mode > QUIC_LOAD_BALANCING_COUNT) + { + // quicer specific load balancing settings + // use FixedServerID + QUIC_GLOBAL_SETTINGS global_settings; + global_settings.IsSet.LoadBalancingMode = TRUE; + global_settings.IsSet.FixedServerID = TRUE; + global_settings.LoadBalancingMode + = QUIC_LOAD_BALANCING_SERVER_ID_FIXED; + global_settings.FixedServerID = lb_mode; + MsQuic->SetParam(NULL, + QUIC_PARAM_GLOBAL_GLOBAL_SETTINGS, + sizeof(global_settings), + &global_settings); + } + else + { + MsQuic->SetParam(NULL, + QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE, + sizeof(uint16_t), + (uint16_t *)&lb_mode); + } } if (enif_get_map_value(env, argv[0], ATOM_TRACE, &eterm) diff --git a/include/quicer.hrl b/include/quicer.hrl index ea4788dc..bf578c8e 100644 --- a/include/quicer.hrl +++ b/include/quicer.hrl @@ -17,6 +17,8 @@ -ifndef(QUICER_HRL). -define(QUICER_HRL, true). +-define(DEFAULT_LB_DEV, "eth0"). + %%% ======================================== %%% mirror macro from NIF code %%% ======================================== @@ -140,4 +142,10 @@ bin :: binary() }). +-define(QUIC_LOAD_BALANCING_DISABLED, 0). +-define(QUIC_LOAD_BALANCING_SERVER_ID_IP, 1). +-define(QUIC_LOAD_BALANCING_SERVER_ID_FIXED, 2). +-define(QUIC_LOAD_BALANCING_COUNT, 3). +-define(QUICER_LOAD_BALANCING_IFIP_AS_SERVER_ID, 100). %% User Network Interface IP as Server ID + -endif. %% QUICER_HRL diff --git a/src/quicer_nif.erl b/src/quicer_nif.erl index cae58c66..81633182 100644 --- a/src/quicer_nif.erl +++ b/src/quicer_nif.erl @@ -156,8 +156,15 @@ open_lib() -> {error, _} -> priv_dir() end, + LBMode = + case application:get_env(quicer, lb_mode, 0) of + ?QUICER_LOAD_BALANCING_IFIP_AS_SERVER_ID -> + lb_server_id(ipv4, application:get_env(quicer, lb_dev, ?DEFAULT_LB_DEV)); + X -> + X + end, open_lib(#{ - load_balacing_mode => application:get_env(quicer, lb_mode, 0), + load_balacing_mode => LBMode, trace => LibFile }). @@ -424,3 +431,20 @@ priv_dir() -> Dir -> Dir end. + +%% @doc Get the load balancing server id from the given device name. ipv4 only. +-spec lb_server_id(ipv4, string()) -> non_neg_integer(). +lb_server_id(ipv4, DevName) -> + try + {ok, IfList} = inet:getifaddrs(), + %% @NOTE Be aware of the order of the bytes in the address + lists:foldr( + fun(I, V) -> V bsl 8 bor I end, + 0, + tuple_to_list(proplists:get_value(addr, proplists:get_value(DevName, IfList))) + ) + catch + _:E -> + logger:error("Failed to set lb mode from ~s, fallback to disabled: ~p", [DevName, E]), + ?QUIC_LOAD_BALANCING_DISABLED + end.