1 |
|
%% @doc Utilities related to listener configuration options |
2 |
|
|
3 |
|
-module(mongoose_listener_config). |
4 |
|
|
5 |
|
-export([ensure_ip_options/1, |
6 |
|
verify_unique_listeners/1, |
7 |
|
address_family/1, |
8 |
|
listener_id/1]). |
9 |
|
|
10 |
|
%% @doc Fill in IP-related options that can be calculated automatically. |
11 |
|
%% Apart from these options, the input should be a complete listener configuration. |
12 |
|
-spec ensure_ip_options(map()) -> mongoose_listener:options(). |
13 |
|
ensure_ip_options(Opts = #{ip_address := IPAddr, ip_version := 4}) -> |
14 |
:-( |
{ok, IPTuple} = inet:parse_ipv4_address(IPAddr), |
15 |
:-( |
Opts#{ip_tuple => IPTuple}; |
16 |
|
ensure_ip_options(Opts = #{ip_address := IPAddr, ip_version := 6}) -> |
17 |
:-( |
{ok, IPTuple} = inet:parse_ipv6_address(IPAddr), |
18 |
:-( |
Opts#{ip_tuple => IPTuple}; |
19 |
|
ensure_ip_options(Opts = #{ip_address := IPAddr}) -> |
20 |
449 |
{ok, IPTuple} = inet:parse_address(IPAddr), |
21 |
449 |
Opts#{ip_tuple => IPTuple, |
22 |
|
ip_version => ip_version(IPTuple)}; |
23 |
|
ensure_ip_options(Opts = #{ip_version := 6}) -> |
24 |
:-( |
ensure_ip_options(Opts#{ip_address => "::"}); |
25 |
|
ensure_ip_options(Opts) -> |
26 |
229 |
ensure_ip_options(Opts#{ip_address => "0"}). |
27 |
|
|
28 |
449 |
ip_version(T) when tuple_size(T) =:= 4 -> 4; |
29 |
:-( |
ip_version(T) when tuple_size(T) =:= 8 -> 6. |
30 |
|
|
31 |
|
%% @doc Verify that all listeners have unique socket addresses |
32 |
|
-spec verify_unique_listeners([mongoose_listener:options()]) -> [mongoose_listener:options()]. |
33 |
|
verify_unique_listeners(Listeners) -> |
34 |
33 |
Counts = lists:foldl(fun(L, Cts) -> |
35 |
449 |
maps:update_with(listener_id(L), fun(Ct) -> Ct + 1 end, 1, Cts) |
36 |
|
end, #{}, Listeners), |
37 |
33 |
case [K || {K, V} <- maps:to_list(Counts), V > 1] of |
38 |
33 |
[] -> Listeners; |
39 |
:-( |
Dups -> error(#{what => duplicate_listeners, duplicates => Dups, |
40 |
|
text => <<"Some listeners have duplicate listening socket addresses">>}) |
41 |
|
end. |
42 |
|
|
43 |
|
-spec address_family(4 | 6) -> inet:address_family(). |
44 |
238 |
address_family(4) -> inet; |
45 |
:-( |
address_family(6) -> inet6. |
46 |
|
|
47 |
|
%% @doc Create a unique ID based on the listening socket address |
48 |
|
-spec listener_id(mongoose_listener:options()) -> mongoose_listener:id(). |
49 |
|
listener_id(#{port := Port, ip_tuple := IPTuple, proto := Proto}) -> |
50 |
13886 |
{Port, IPTuple, Proto}. |