mirror of
https://gitee.com/dgiiot/dgiot.git
synced 2024-12-10 08:08:20 +08:00
365 lines
15 KiB
Plaintext
365 lines
15 KiB
Plaintext
%% -*-: erlang -*-
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% Services
|
|
|
|
{mapping, "exproto.server.http.port", "emqx_exproto.servers", [
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.server.https.port", "emqx_exproto.servers", [
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.server.https.cacertfile", "emqx_exproto.servers", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.server.https.certfile", "emqx_exproto.servers", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.server.https.keyfile", "emqx_exproto.servers", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{translation, "emqx_exproto.servers", fun(Conf) ->
|
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
|
Http = case cuttlefish:conf_get("exproto.server.http.port", Conf, undefined) of
|
|
undefined -> [];
|
|
P1 -> [{http, P1, []}]
|
|
end,
|
|
Https = case cuttlefish:conf_get("exproto.server.https.port", Conf, undefined) of
|
|
undefined -> [];
|
|
P2 ->
|
|
[{https, P2,
|
|
Filter([{ssl, true},
|
|
{certfile, cuttlefish:conf_get("exproto.server.https.certfile", Conf)},
|
|
{keyfile, cuttlefish:conf_get("exproto.server.https.keyfile", Conf)},
|
|
{cacertfile, cuttlefish:conf_get("exproto.server.https.cacertfile", Conf)}])}]
|
|
end,
|
|
Http ++ Https
|
|
end}.
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% Listeners
|
|
|
|
{mapping, "exproto.listener.$proto", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.connection_handler_url", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.connection_handler_certfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.connection_handler_cacertfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.connection_handler_keyfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.acceptors", "emqx_exproto.listeners", [
|
|
{default, 8},
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.max_connections", "emqx_exproto.listeners", [
|
|
{default, 1024},
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.max_conn_rate", "emqx_exproto.listeners", [
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.active_n", "emqx_exproto.listeners", [
|
|
{default, 100},
|
|
{datatype, integer}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.idle_timeout", "emqx_exproto.listeners", [
|
|
{default, "30s"},
|
|
{datatype, {duration, ms}}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.access.$id", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.proxy_protocol", "emqx_exproto.listeners", [
|
|
{datatype, flag}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.proxy_protocol_timeout", "emqx_exproto.listeners", [
|
|
{datatype, {duration, ms}}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.backlog", "emqx_exproto.listeners", [
|
|
{datatype, integer},
|
|
{default, 1024}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.send_timeout", "emqx_exproto.listeners", [
|
|
{datatype, {duration, ms}},
|
|
{default, "15s"}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.send_timeout_close", "emqx_exproto.listeners", [
|
|
{datatype, flag},
|
|
{default, on}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.recbuf", "emqx_exproto.listeners", [
|
|
{datatype, bytesize},
|
|
hidden
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.sndbuf", "emqx_exproto.listeners", [
|
|
{datatype, bytesize},
|
|
hidden
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.buffer", "emqx_exproto.listeners", [
|
|
{datatype, bytesize},
|
|
hidden
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.tune_buffer", "emqx_exproto.listeners", [
|
|
{datatype, flag},
|
|
hidden
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.nodelay", "emqx_exproto.listeners", [
|
|
{datatype, {enum, [true, false]}},
|
|
hidden
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.reuseaddr", "emqx_exproto.listeners", [
|
|
{datatype, {enum, [true, false]}},
|
|
hidden
|
|
]}.
|
|
|
|
%%--------------------------------------------------------------------
|
|
%% TLS Options
|
|
|
|
{mapping, "exproto.listener.$proto.tls_versions", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.ciphers", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.psk_ciphers", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.dhfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.keyfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.certfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.cacertfile", "emqx_exproto.listeners", [
|
|
{datatype, string}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.verify", "emqx_exproto.listeners", [
|
|
{datatype, atom}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.fail_if_no_peer_cert", "emqx_exproto.listeners", [
|
|
{datatype, {enum, [true, false]}}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.secure_renegotiate", "emqx_exproto.listeners", [
|
|
{datatype, flag}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.reuse_sessions", "emqx_exproto.listeners", [
|
|
{default, on},
|
|
{datatype, flag}
|
|
]}.
|
|
|
|
{mapping, "exproto.listener.$proto.honor_cipher_order", "emqx_exproto.listeners", [
|
|
{datatype, flag}
|
|
]}.
|
|
|
|
{translation, "emqx_exproto.listeners", fun(Conf) ->
|
|
|
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
|
|
|
Atom = fun(undefined) -> undefined; (S) -> list_to_atom(S) end,
|
|
|
|
Access = fun(S) ->
|
|
[A, CIDR] = string:tokens(S, " "),
|
|
{list_to_atom(A), case CIDR of "all" -> all; _ -> CIDR end}
|
|
end,
|
|
|
|
AccOpts = fun(Prefix) ->
|
|
case cuttlefish_variable:filter_by_prefix(Prefix ++ ".access", Conf) of
|
|
[] -> [];
|
|
Rules -> [{access_rules, [Access(Rule) || {_, Rule} <- Rules]}]
|
|
end
|
|
end,
|
|
|
|
RateLimit = fun(undefined) ->
|
|
undefined;
|
|
(Val) ->
|
|
[L, D] = string:tokens(Val, ", "),
|
|
Limit = case cuttlefish_bytesize:parse(L) of
|
|
Sz when is_integer(Sz) -> Sz;
|
|
{error, Reason} -> error(Reason)
|
|
end,
|
|
Duration = case cuttlefish_duration:parse(D, s) of
|
|
Secs when is_integer(Secs) -> Secs;
|
|
{error, Reason1} -> error(Reason1)
|
|
end,
|
|
Rate = Limit / Duration,
|
|
{Rate, Limit}
|
|
end,
|
|
|
|
HandlerOpts = fun(Prefix) ->
|
|
Opts =
|
|
case http_uri:parse(cuttlefish:conf_get(Prefix ++ ".connection_handler_url", Conf)) of
|
|
{ok, {http, _, Host, Port, _, _}} ->
|
|
[{scheme, http}, {host, Host}, {port, Port}];
|
|
{ok, {https, _, Host, Port, _, _}} ->
|
|
[{scheme, https}, {host, Host}, {port, Port},
|
|
{ssl_options,
|
|
Filter([{certfile, cuttlefish:conf_get(Prefix ++ ".connection_handler_certfile", Conf)},
|
|
{keyfile, cuttlefish:conf_get(Prefix ++ ".connection_handler_keyfile", Conf)},
|
|
{cacertfile, cuttlefish:conf_get(Prefix ++ ".connection_handler_cacertfile", Conf)}
|
|
])}];
|
|
_ ->
|
|
error(invaild_connection_handler_url)
|
|
end,
|
|
[{handler, Opts}]
|
|
end,
|
|
|
|
ConnOpts = fun(Prefix) ->
|
|
Filter([{active_n, cuttlefish:conf_get(Prefix ++ ".active_n", Conf, undefined)},
|
|
{idle_timeout, cuttlefish:conf_get(Prefix ++ ".idle_timeout", Conf, undefined)}])
|
|
end,
|
|
|
|
LisOpts = fun(Prefix) ->
|
|
Filter([{acceptors, cuttlefish:conf_get(Prefix ++ ".acceptors", Conf)},
|
|
{max_connections, cuttlefish:conf_get(Prefix ++ ".max_connections", Conf)},
|
|
{max_conn_rate, cuttlefish:conf_get(Prefix ++ ".max_conn_rate", Conf, undefined)},
|
|
{tune_buffer, cuttlefish:conf_get(Prefix ++ ".tune_buffer", Conf, undefined)},
|
|
{proxy_protocol, cuttlefish:conf_get(Prefix ++ ".proxy_protocol", Conf, undefined)},
|
|
{proxy_protocol_timeout, cuttlefish:conf_get(Prefix ++ ".proxy_protocol_timeout", Conf, undefined)} | AccOpts(Prefix)])
|
|
end,
|
|
|
|
TcpOpts = fun(Prefix) ->
|
|
Filter([{backlog, cuttlefish:conf_get(Prefix ++ ".backlog", Conf, undefined)},
|
|
{send_timeout, cuttlefish:conf_get(Prefix ++ ".send_timeout", Conf, undefined)},
|
|
{send_timeout_close, cuttlefish:conf_get(Prefix ++ ".send_timeout_close", Conf, undefined)},
|
|
{recbuf, cuttlefish:conf_get(Prefix ++ ".recbuf", Conf, undefined)},
|
|
{sndbuf, cuttlefish:conf_get(Prefix ++ ".sndbuf", Conf, undefined)},
|
|
{buffer, cuttlefish:conf_get(Prefix ++ ".buffer", Conf, undefined)},
|
|
{nodelay, cuttlefish:conf_get(Prefix ++ ".nodelay", Conf, true)},
|
|
{reuseaddr, cuttlefish:conf_get(Prefix ++ ".reuseaddr", Conf, undefined)}])
|
|
end,
|
|
SplitFun = fun(undefined) -> undefined; (S) -> string:tokens(S, ",") end,
|
|
MapPSKCiphers = fun(PSKCiphers) ->
|
|
lists:map(
|
|
fun("PSK-AES128-CBC-SHA") -> {psk, aes_128_cbc, sha};
|
|
("PSK-AES256-CBC-SHA") -> {psk, aes_256_cbc, sha};
|
|
("PSK-3DES-EDE-CBC-SHA") -> {psk, '3des_ede_cbc', sha};
|
|
("PSK-RC4-SHA") -> {psk, rc4_128, sha}
|
|
end, PSKCiphers)
|
|
end,
|
|
SslOpts = fun(Prefix) ->
|
|
Versions = case SplitFun(cuttlefish:conf_get(Prefix ++ ".tls_versions", Conf, undefined)) of
|
|
undefined -> undefined;
|
|
L -> [list_to_atom(V) || V <- L]
|
|
end,
|
|
TLSCiphers = cuttlefish:conf_get(Prefix++".ciphers", Conf, undefined),
|
|
PSKCiphers = cuttlefish:conf_get(Prefix++".psk_ciphers", Conf, undefined),
|
|
Ciphers =
|
|
case {TLSCiphers, PSKCiphers} of
|
|
{undefined, undefined} ->
|
|
cuttlefish:invalid(Prefix++".ciphers or "++Prefix++".psk_ciphers is absent");
|
|
{TLSCiphers, undefined} ->
|
|
SplitFun(TLSCiphers);
|
|
{undefined, PSKCiphers} ->
|
|
MapPSKCiphers(SplitFun(PSKCiphers));
|
|
{_TLSCiphers, _PSKCiphers} ->
|
|
cuttlefish:invalid(Prefix++".ciphers and "++Prefix++".psk_ciphers cannot be configured at the same time")
|
|
end,
|
|
UserLookupFun =
|
|
case PSKCiphers of
|
|
undefined -> undefined;
|
|
_ -> {fun emqx_psk:lookup/3, <<>>}
|
|
end,
|
|
Filter([{versions, Versions},
|
|
{ciphers, Ciphers},
|
|
{user_lookup_fun, UserLookupFun},
|
|
%{handshake_timeout, cuttlefish:conf_get(Prefix ++ ".handshake_timeout", Conf, undefined)},
|
|
{dhfile, cuttlefish:conf_get(Prefix ++ ".dhfile", Conf, undefined)},
|
|
{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
|
|
{certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
|
|
{cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)},
|
|
{verify, cuttlefish:conf_get(Prefix ++ ".verify", Conf, undefined)},
|
|
{fail_if_no_peer_cert, cuttlefish:conf_get(Prefix ++ ".fail_if_no_peer_cert", Conf, undefined)},
|
|
{secure_renegotiate, cuttlefish:conf_get(Prefix ++ ".secure_renegotiate", Conf, undefined)},
|
|
{reuse_sessions, cuttlefish:conf_get(Prefix ++ ".reuse_sessions", Conf, undefined)},
|
|
{honor_cipher_order, cuttlefish:conf_get(Prefix ++ ".honor_cipher_order", Conf, undefined)}])
|
|
end,
|
|
|
|
UdpOpts = fun(Prefix) ->
|
|
Filter([{recbuf, cuttlefish:conf_get(Prefix ++ ".recbuf", Conf, undefined)},
|
|
{sndbuf, cuttlefish:conf_get(Prefix ++ ".sndbuf", Conf, undefined)},
|
|
{buffer, cuttlefish:conf_get(Prefix ++ ".buffer", Conf, undefined)},
|
|
{reuseaddr, cuttlefish:conf_get(Prefix ++ ".reuseaddr", Conf, undefined)}])
|
|
end,
|
|
|
|
ParseListenOn = fun(ListenOn) ->
|
|
case string:tokens(ListenOn, "://") of
|
|
[Port] -> {tcp, list_to_integer(Port)};
|
|
[T, Ip, Port]
|
|
when T =:= "tcp"; T =:= "ssl";
|
|
T =:= "udp"; T =:= "dtls" ->
|
|
{Atom(T), {Ip, list_to_integer(Port)}}
|
|
end
|
|
end,
|
|
|
|
Listeners = fun(Proto) ->
|
|
Prefix = string:join(["exproto","listener", Proto], "."),
|
|
Opts = HandlerOpts(Prefix) ++ ConnOpts(Prefix) ++ LisOpts(Prefix),
|
|
case cuttlefish:conf_get(Prefix, Conf, undefined) of
|
|
undefined -> [];
|
|
ListenOn0 ->
|
|
case ParseListenOn(ListenOn0) of
|
|
{tcp, ListenOn} ->
|
|
[{Proto, tcp, ListenOn, [{tcp_options, TcpOpts(Prefix)} | Opts]}];
|
|
{ssl, ListenOn} ->
|
|
[{Proto, ssl, ListenOn, [{tcp_options, TcpOpts(Prefix)},
|
|
{ssl_options, SslOpts(Prefix)} | Opts]}];
|
|
{udp, ListenOn} ->
|
|
[{Proto, udp, ListenOn, [{udp_options, UdpOpts(Prefix)} | Opts]}];
|
|
{dtls, ListenOn} ->
|
|
[{Proto, dtls, ListenOn, [{udp_options, UdpOpts(Prefix)},
|
|
{dtls_options, SslOpts(Prefix)} | Opts]}];
|
|
{_, _} ->
|
|
cuttlefish:invalid("Not supported listener type")
|
|
end
|
|
end
|
|
end,
|
|
lists:flatten([Listeners(Proto) || {[_, "listener", Proto], ListenOn}
|
|
<- cuttlefish_variable:filter_by_prefix("exproto.listener", Conf)])
|
|
end}.
|