diff --git a/.ci/compatibility_tests/docker-compose-pgsql-tls.yaml b/.ci/compatibility_tests/docker-compose-pgsql-tls.yaml index d3d9d93b5..6bb3d321e 100644 --- a/.ci/compatibility_tests/docker-compose-pgsql-tls.yaml +++ b/.ci/compatibility_tests/docker-compose-pgsql-tls.yaml @@ -24,9 +24,9 @@ services: image: emqx_pgsql:${PGSQL_TAG} restart: always environment: - POSTGRES_DB: postgres - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres + POSTGRES_DB: mqtt + POSTGRES_USER: root + POSTGRES_PASSWORD: public ports: - "5432:5432" command: diff --git a/.github/workflows/run_cts_tests.yaml b/.github/workflows/run_cts_tests.yaml index fdca76a7c..f5ad55183 100644 --- a/.github/workflows/run_cts_tests.yaml +++ b/.github/workflows/run_cts_tests.yaml @@ -194,15 +194,9 @@ jobs: run: | docker-compose -f .ci/compatibility_tests/docker-compose-pgsql-tls.yaml build --no-cache docker-compose -f .ci/compatibility_tests/docker-compose-pgsql-tls.yaml up -d - if [ "$PGSQL_TAG" = "12" ] || [ "$PGSQL_TAG" = "13" ]; then - sed -i 's|^[#[:space:]]*auth.pgsql.ssl.tls_versions[ \t]*=.*|auth.pgsql.ssl.tls_versions = tlsv1.3,tlsv1.2|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf - else - sed -i 's|^[#[:space:]]*auth.pgsql.ssl.tls_versions[ \t]*=.*|auth.pgsql.ssl.tls_versions = tlsv1.2,tlsv1.1|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf - fi - - sed -i 's|^[#[:space:]]*auth.pgsql.username[ \t]*=.*|auth.pgsql.username = postgres|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf - sed -i 's|^[#[:space:]]*auth.pgsql.password[ \t]*=.*|auth.pgsql.password = postgres|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf - sed -i 's|^[#[:space:]]*auth.pgsql.database[ \t]*=.*|auth.pgsql.database = postgres|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf + sed -i 's|^[#[:space:]]*auth.pgsql.username[ \t]*=.*|auth.pgsql.username = root|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf + sed -i 's|^[#[:space:]]*auth.pgsql.password[ \t]*=.*|auth.pgsql.password = public|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf + sed -i 's|^[#[:space:]]*auth.pgsql.database[ \t]*=.*|auth.pgsql.database = mqtt|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf sed -i 's|^[#[:space:]]*auth.pgsql.ssl[ \t]*=.*|auth.pgsql.ssl = on|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf sed -i 's|^[#[:space:]]*auth.pgsql.cacertfile[ \t]*=.*|auth.pgsql.cacertfile = /emqx/apps/emqx_auth_pgsql/test/emqx_auth_pgsql_SUITE_data/root.crt|g' apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf - name: setup diff --git a/.gitignore b/.gitignore index d320582c5..51b4acf83 100644 --- a/.gitignore +++ b/.gitignore @@ -41,5 +41,5 @@ tmp/ _packages elvis emqx_dialyzer_*_plt -apps/emqx_dashboard/priv/www +*/emqx_dashboard/priv/www dist.zip diff --git a/Makefile b/Makefile index 76e3802bd..81b8b4fb0 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ REBAR_VERSION = 3.14.3-emqx-4 DASHBOARD_VERSION = v4.3.0 REBAR = $(CURDIR)/rebar3 BUILD = $(CURDIR)/build +export EMQX_ENTERPRISE=false export PKG_VSN ?= $(shell $(CURDIR)/pkg-vsn.sh) PROFILE ?= emqx diff --git a/apps/emqx_auth_http/src/emqx_auth_http_app.erl b/apps/emqx_auth_http/src/emqx_auth_http_app.erl index ba88ca3be..9b6b265d4 100644 --- a/apps/emqx_auth_http/src/emqx_auth_http_app.erl +++ b/apps/emqx_auth_http/src/emqx_auth_http_app.erl @@ -74,11 +74,10 @@ translate_env(EnvName) -> (_) -> true end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]), - TlsVers = ['tlsv1.2','tlsv1.1',tlsv1], - NTLSOpts = [{versions, TlsVers}, - {ciphers, lists:foldl(fun(TlsVer, Ciphers) -> - Ciphers ++ ssl:cipher_suites(all, TlsVer) - end, [], TlsVers)} | TLSOpts], + NTLSOpts = [ {versions, emqx_tls_lib:default_versions()} + , {ciphers, emqx_tls_lib:default_ciphers()} + | TLSOpts + ], [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}] end, PoolOpts = [{host, Host}, diff --git a/apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf b/apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf index ef8e7533a..d27956b16 100644 --- a/apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf +++ b/apps/emqx_auth_pgsql/etc/emqx_auth_pgsql.conf @@ -22,7 +22,7 @@ auth.pgsql.username = root ## PostgreSQL password. ## ## Value: String -# auth.pgsql.password = +#auth.pgsql.password = ## PostgreSQL database. ## @@ -39,13 +39,13 @@ auth.pgsql.encoding = utf8 ## Value: on | off auth.pgsql.ssl = off -## TLS version -## You can configure multi-version use "," split, -## default value is :tlsv1.2 -## Example: -## tlsv1.1,tlsv1.2,tlsv1.3 +## TLS version. ## -#auth.pgsql.ssl.tls_versions = tlsv1.2 +## Available enum values: +## tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 +## +## Value: String, seperated by ',' +#auth.pgsql.ssl.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1 ## SSL keyfile. ## diff --git a/apps/emqx_auth_pgsql/priv/emqx_auth_pgsql.schema b/apps/emqx_auth_pgsql/priv/emqx_auth_pgsql.schema index 859495a60..77a239ba9 100644 --- a/apps/emqx_auth_pgsql/priv/emqx_auth_pgsql.schema +++ b/apps/emqx_auth_pgsql/priv/emqx_auth_pgsql.schema @@ -36,7 +36,7 @@ ]}. {mapping, "auth.pgsql.ssl.tls_versions", "emqx_auth_pgsql.server", [ - {default, "tlsv1.2"}, + {default, "tlsv1.3,tlsv1.2,tlsv1.1"}, {datatype, string} ]}. @@ -92,9 +92,9 @@ SslOpts = fun(Prefix) -> Filter([{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)}, {certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)}, - {cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined), + {cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)}, {versions, [list_to_existing_atom(Value) - ||Value <- string:tokens(cuttlefish:conf_get(Prefix ++ ".tls_versions", Conf), " ,")]}}]) + || Value <- string:tokens(cuttlefish:conf_get(Prefix ++ ".tls_versions", Conf), " ,")]}]) end, %% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0 diff --git a/apps/emqx_bridge_mqtt/README.md b/apps/emqx_bridge_mqtt/README.md index 6656aa36f..456fae584 100644 --- a/apps/emqx_bridge_mqtt/README.md +++ b/apps/emqx_bridge_mqtt/README.md @@ -126,7 +126,7 @@ bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-S bridge.mqtt.emqx2.keepalive = 60s ## Supported TLS version -bridge.mqtt.emqx2.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +bridge.mqtt.emqx2.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## Forwarding topics of the message bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/# diff --git a/apps/emqx_bridge_mqtt/docs/guide.rst b/apps/emqx_bridge_mqtt/docs/guide.rst index 73350ca1f..47235aa7d 100644 --- a/apps/emqx_bridge_mqtt/docs/guide.rst +++ b/apps/emqx_bridge_mqtt/docs/guide.rst @@ -133,9 +133,6 @@ EMQ X MQTT bridging principle: Create an MQTT client on the EMQ X broker, and co ## Key file of Client SSL connection bridge.mqtt.emqx2.keyfile = etc/certs/client-key.pem - ## SSL encryption - bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384 - ## TTLS PSK password ## Note 'listener.ssl.external.ciphers' and 'listener.ssl.external.psk_ciphers' cannot be configured at the same time ## @@ -146,7 +143,10 @@ EMQ X MQTT bridging principle: Create an MQTT client on the EMQ X broker, and co bridge.mqtt.emqx2.keepalive = 60s ## Supported TLS version - bridge.mqtt.emqx2.tls_versions = tlsv1.2,tlsv1.1,tlsv1 + bridge.mqtt.emqx2.tls_versions = tlsv1.2 + + ## SSL encryption + bridge.mqtt.emqx2.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384 ## Forwarding topics of the message bridge.mqtt.emqx2.forwards = sensor1/#,sensor2/# diff --git a/apps/emqx_bridge_mqtt/etc/emqx_bridge_mqtt.conf b/apps/emqx_bridge_mqtt/etc/emqx_bridge_mqtt.conf index ec5656af4..db59270c0 100644 --- a/apps/emqx_bridge_mqtt/etc/emqx_bridge_mqtt.conf +++ b/apps/emqx_bridge_mqtt/etc/emqx_bridge_mqtt.conf @@ -128,6 +128,7 @@ bridge.mqtt.aws.keepalive = 60s ## TLS versions used by the bridge. ## +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier ## Value: String bridge.mqtt.aws.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 diff --git a/apps/emqx_bridge_mqtt/priv/emqx_bridge_mqtt.schema b/apps/emqx_bridge_mqtt/priv/emqx_bridge_mqtt.schema index 301737afd..3168bfc14 100644 --- a/apps/emqx_bridge_mqtt/priv/emqx_bridge_mqtt.schema +++ b/apps/emqx_bridge_mqtt/priv/emqx_bridge_mqtt.schema @@ -90,7 +90,7 @@ {mapping, "bridge.mqtt.$name.tls_versions", "emqx_bridge_mqtt.bridges", [ {datatype, string}, - {default, "tlsv1,tlsv1.1,tlsv1.2"} + {default, "tlsv1.3,tlsv1.2,tlsv1.1,tlsv1"} ]}. {mapping, "bridge.mqtt.$name.reconnect_interval", "emqx_bridge_mqtt.bridges", [ diff --git a/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_actions.erl b/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_actions.erl index d63f20141..87bc6c694 100644 --- a/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_actions.erl +++ b/apps/emqx_bridge_mqtt/src/emqx_bridge_mqtt_actions.erl @@ -671,12 +671,6 @@ format_data([], Msg) -> format_data(Tokens, Msg) -> emqx_rule_utils:proc_tmpl(Tokens, Msg). -tls_versions() -> - ['tlsv1.2','tlsv1.1', tlsv1]. - -ciphers(Ciphers) -> - string:tokens(str(Ciphers), ", "). - subscriptions(Subscriptions) -> scan_binary(<<"[", Subscriptions/binary, "].">>). @@ -749,6 +743,8 @@ options(Options, PoolName) -> Topic -> [{subscriptions, [{Topic, Get(<<"qos">>)}]} | Subscriptions] end, + %% TODO check why only ciphers are configurable but not versions + TlsVersions = emqx_tls_lib:default_versions(), [{address, binary_to_list(Address)}, {bridge_mode, GetD(<<"bridge_mode">>, true)}, {clean_start, true}, @@ -761,12 +757,13 @@ options(Options, PoolName) -> {proto_ver, mqtt_ver(Get(<<"proto_ver">>))}, {retry_interval, cuttlefish_duration:parse(str(GetD(<<"retry_interval">>, "30s")), s)}, {ssl, cuttlefish_flag:parse(str(Get(<<"ssl">>)))}, - {ssl_opts, [{versions, tls_versions()}, - {ciphers, ciphers(Get(<<"ciphers">>))}, - {keyfile, str(Get(<<"keyfile">>))}, - {certfile, str(Get(<<"certfile">>))}, - {cacertfile, str(Get(<<"cacertfile">>))} - ]}] ++ Subscriptions1 + {ssl_opts, [ {keyfile, str(Get(<<"keyfile">>))} + , {certfile, str(Get(<<"certfile">>))} + , {cacertfile, str(Get(<<"cacertfile">>))} + , {versions, TlsVersions} + , {ciphers, emqx_tls_lib:integral_ciphers(TlsVersions, Get(<<"ciphers">>))} + ]} + ] ++ Subscriptions1 end. diff --git a/apps/emqx_coap/priv/emqx_coap.schema b/apps/emqx_coap/priv/emqx_coap.schema index 465979964..da367f098 100644 --- a/apps/emqx_coap/priv/emqx_coap.schema +++ b/apps/emqx_coap/priv/emqx_coap.schema @@ -75,10 +75,7 @@ end}. Ciphers = case cuttlefish:conf_get("coap.dtls.ciphers", Conf, undefined) of undefined -> - lists:foldl( - fun(TlsVer, Ciphers) -> - Ciphers ++ ssl:cipher_suites(all, TlsVer) - end, [], ['dtlsv1', 'dtlsv1.2']); + lists:append([ssl:cipher_suites(all, V, openssl) || V <- ['dtlsv1.2', 'dtlsv1']]); C -> SplitFun(C) end, diff --git a/apps/emqx_exproto/test/emqx_exproto_SUITE.erl b/apps/emqx_exproto/test/emqx_exproto_SUITE.erl index 2ad79b77d..c5cabe154 100644 --- a/apps/emqx_exproto/test/emqx_exproto_SUITE.erl +++ b/apps/emqx_exproto/test/emqx_exproto_SUITE.erl @@ -425,8 +425,8 @@ udp_opts() -> ssl_opts() -> Certs = certs("key.pem", "cert.pem", "cacert.pem"), - [{versions, ['tlsv1.2','tlsv1.1',tlsv1]}, - {ciphers, ciphers('tlsv1.2')}, + [{versions, emqx_tls_lib:default_versions()}, + {ciphers, emqx_tls_lib:default_ciphers()}, {verify, verify_peer}, {fail_if_no_peer_cert, true}, {secure_renegotiate, false}, @@ -437,9 +437,6 @@ dtls_opts() -> Opts = ssl_opts(), lists:keyreplace(versions, 1, Opts, {versions, ['dtlsv1.2', 'dtlsv1']}). -ciphers(Version) -> - proplists:get_value(ciphers, emqx_ct_helpers:client_ssl(Version)). - %%-------------------------------------------------------------------- %% Client-Opts diff --git a/apps/emqx_stomp/etc/emqx_stomp.conf b/apps/emqx_stomp/etc/emqx_stomp.conf index def48fbc8..b404e99ee 100644 --- a/apps/emqx_stomp/etc/emqx_stomp.conf +++ b/apps/emqx_stomp/etc/emqx_stomp.conf @@ -58,7 +58,8 @@ stomp.listener.max_connections = 512 ## TLS versions only to protect from POODLE attack. ## ## Value: String, seperated by ',' -## stomp.listener.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier +## stomp.listener.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## SSL Handshake timeout. ## diff --git a/apps/emqx_web_hook/src/emqx_web_hook_actions.erl b/apps/emqx_web_hook/src/emqx_web_hook_actions.erl index bcd29bd28..f5d27f09c 100644 --- a/apps/emqx_web_hook/src/emqx_web_hook_actions.erl +++ b/apps/emqx_web_hook/src/emqx_web_hook_actions.erl @@ -354,12 +354,11 @@ pool_opts(Params = #{<<"url">> := URL}) -> (_) -> true end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]), - TlsVers = ['tlsv1.2', 'tlsv1.1', tlsv1], - NTLSOpts = [{verify, VerifyType}, - {versions, TlsVers}, - {ciphers, lists:foldl(fun(TlsVer, Ciphers) -> - Ciphers ++ ssl:cipher_suites(all, TlsVer) - end, [], TlsVers)} | TLSOpts], + NTLSOpts = [ {verify, VerifyType} + , {versions, emqx_tls_lib:default_versions()} + , {ciphers, emqx_tls_lib:default_ciphers()} + | TLSOpts + ], [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}] end, [{host, Host}, @@ -397,4 +396,4 @@ test_http_connect(Conf) -> Err:Reason:ST -> ?LOG(error, "check http_connectivity failed: ~p, ~0p", [Conf, {Err, Reason, ST}]), false - end. \ No newline at end of file + end. diff --git a/apps/emqx_web_hook/src/emqx_web_hook_app.erl b/apps/emqx_web_hook/src/emqx_web_hook_app.erl index c8083e195..d31df9b93 100644 --- a/apps/emqx_web_hook/src/emqx_web_hook_app.erl +++ b/apps/emqx_web_hook/src/emqx_web_hook_app.erl @@ -75,12 +75,11 @@ translate_env() -> TLSOpts = lists:filter(fun({_K, V}) -> V /= <<>> andalso V /= undefined andalso V /= "" andalso true end, [{keyfile, KeyFile}, {certfile, CertFile}, {cacertfile, CACertFile}]), - TlsVers = ['tlsv1.2','tlsv1.1',tlsv1], - NTLSOpts = [{verify, VerifyType}, - {versions, TlsVers}, - {ciphers, lists:foldl(fun(TlsVer, Ciphers) -> - Ciphers ++ ssl:cipher_suites(all, TlsVer) - end, [], TlsVers)} | TLSOpts], + NTLSOpts = [ {verify, VerifyType} + , {versions, emqx_tls_lib:default_versions()} + , {ciphers, emqx_tls_lib:default_ciphers()} + | TLSOpts + ], [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}] end, PoolOpts = [{host, Host}, @@ -114,4 +113,4 @@ parse_host(Host) -> {ok, _} -> {inet6, Host}; {error, _} -> {inet, Host} end - end. \ No newline at end of file + end. diff --git a/elvis.config b/elvis.config index 42f67e40f..bb551e81a 100644 --- a/elvis.config +++ b/elvis.config @@ -5,7 +5,7 @@ [ {config, [ - #{dirs => ["apps/**/src", "src"], + #{dirs => ["src", "apps/**/src", "lib-opensource/**/src"], filter => "*.erl", ruleset => erl_files, rules => [ @@ -16,7 +16,7 @@ ]}} ] }, - #{dirs => ["apps/**/test", "test"], + #{dirs => ["test", "apps/**/test", "lib-opensource/**/src"], filter => "*.erl", rules => [ {elvis_text_style, line_length, #{ limit => 100 diff --git a/etc/emqx.conf b/etc/emqx.conf index 80166d11b..33db7abb6 100644 --- a/etc/emqx.conf +++ b/etc/emqx.conf @@ -1317,7 +1317,8 @@ listener.ssl.external.access.1 = allow all ## See: http://erlang.org/doc/man/ssl.html ## ## Value: String, seperated by ',' -## listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier +## listener.ssl.external.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## TLS Handshake timeout. ## @@ -1806,7 +1807,8 @@ listener.wss.external.access.1 = allow all ## See: listener.ssl.$name.tls_versions ## ## Value: String, seperated by ',' -## listener.wss.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier +## listener.wss.external.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## Path to the file containing the user's private PEM-encoded key. ## diff --git a/get-dashboard.sh b/get-dashboard.sh index 08879351d..885a68f77 100755 --- a/get-dashboard.sh +++ b/get-dashboard.sh @@ -1,6 +1,5 @@ -#!/bin/sh +#!/bin/bash -#set -euo pipefail set -eu VERSION="$1" @@ -10,7 +9,11 @@ cd -P -- "$(dirname -- "$0")" DOWNLOAD_URL='https://github.com/emqx/emqx-dashboard-frontend/releases/download' -DASHBOARD_PATH='apps/emqx_dashboard/priv' +if [ "$EMQX_ENTERPRISE" = 'true' ] || [ "$EMQX_ENTERPRISE" == '1' ]; then + DASHBOARD_PATH='lib-enterprise/emqx_dashboard/priv' +else + DASHBOARD_PATH='lib-opensource/emqx_dashboard/priv' +fi case $(uname) in *Darwin*) SED="sed -E";; diff --git a/apps/emqx_dashboard/.gitignore b/lib-opensource/emqx_dashboard/.gitignore similarity index 100% rename from apps/emqx_dashboard/.gitignore rename to lib-opensource/emqx_dashboard/.gitignore diff --git a/apps/emqx_dashboard/README.md b/lib-opensource/emqx_dashboard/README.md similarity index 100% rename from apps/emqx_dashboard/README.md rename to lib-opensource/emqx_dashboard/README.md diff --git a/apps/emqx_dashboard/etc/emqx_dashboard.conf b/lib-opensource/emqx_dashboard/etc/emqx_dashboard.conf similarity index 96% rename from apps/emqx_dashboard/etc/emqx_dashboard.conf rename to lib-opensource/emqx_dashboard/etc/emqx_dashboard.conf index 21dbbd04a..933b9885d 100644 --- a/apps/emqx_dashboard/etc/emqx_dashboard.conf +++ b/lib-opensource/emqx_dashboard/etc/emqx_dashboard.conf @@ -105,7 +105,8 @@ dashboard.listener.http.ipv6_v6only = false ## TLS versions only to protect from POODLE attack. ## ## Value: String, seperated by ',' -## dashboard.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier +## dashboard.listener.https.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## See: 'listener.ssl..ciphers' in emq.conf ## diff --git a/apps/emqx_dashboard/include/emqx_dashboard.hrl b/lib-opensource/emqx_dashboard/include/emqx_dashboard.hrl similarity index 100% rename from apps/emqx_dashboard/include/emqx_dashboard.hrl rename to lib-opensource/emqx_dashboard/include/emqx_dashboard.hrl diff --git a/apps/emqx_dashboard/priv/emqx_dashboard.schema b/lib-opensource/emqx_dashboard/priv/emqx_dashboard.schema similarity index 100% rename from apps/emqx_dashboard/priv/emqx_dashboard.schema rename to lib-opensource/emqx_dashboard/priv/emqx_dashboard.schema diff --git a/apps/emqx_dashboard/rebar.config b/lib-opensource/emqx_dashboard/rebar.config similarity index 100% rename from apps/emqx_dashboard/rebar.config rename to lib-opensource/emqx_dashboard/rebar.config diff --git a/apps/emqx_dashboard/src/emqx_dashboard.app.src b/lib-opensource/emqx_dashboard/src/emqx_dashboard.app.src similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard.app.src rename to lib-opensource/emqx_dashboard/src/emqx_dashboard.app.src diff --git a/apps/emqx_dashboard/src/emqx_dashboard.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard.erl diff --git a/apps/emqx_dashboard/src/emqx_dashboard_admin.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard_admin.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard_admin.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard_admin.erl diff --git a/apps/emqx_dashboard/src/emqx_dashboard_api.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard_api.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard_api.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard_api.erl diff --git a/apps/emqx_dashboard/src/emqx_dashboard_app.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard_app.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard_app.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard_app.erl diff --git a/apps/emqx_dashboard/src/emqx_dashboard_cli.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard_cli.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard_cli.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard_cli.erl diff --git a/apps/emqx_dashboard/src/emqx_dashboard_sup.erl b/lib-opensource/emqx_dashboard/src/emqx_dashboard_sup.erl similarity index 100% rename from apps/emqx_dashboard/src/emqx_dashboard_sup.erl rename to lib-opensource/emqx_dashboard/src/emqx_dashboard_sup.erl diff --git a/apps/emqx_dashboard/test/.placeholder b/lib-opensource/emqx_dashboard/test/.placeholder similarity index 100% rename from apps/emqx_dashboard/test/.placeholder rename to lib-opensource/emqx_dashboard/test/.placeholder diff --git a/apps/emqx_dashboard/test/emqx_dashboard_SUITE.erl b/lib-opensource/emqx_dashboard/test/emqx_dashboard_SUITE.erl similarity index 100% rename from apps/emqx_dashboard/test/emqx_dashboard_SUITE.erl rename to lib-opensource/emqx_dashboard/test/emqx_dashboard_SUITE.erl diff --git a/apps/emqx_management/.gitignore b/lib-opensource/emqx_management/.gitignore similarity index 100% rename from apps/emqx_management/.gitignore rename to lib-opensource/emqx_management/.gitignore diff --git a/apps/emqx_management/README.md b/lib-opensource/emqx_management/README.md similarity index 100% rename from apps/emqx_management/README.md rename to lib-opensource/emqx_management/README.md diff --git a/apps/emqx_management/etc/emqx_management.conf b/lib-opensource/emqx_management/etc/emqx_management.conf similarity index 94% rename from apps/emqx_management/etc/emqx_management.conf rename to lib-opensource/emqx_management/etc/emqx_management.conf index 4bb3f83dc..aa737add9 100644 --- a/apps/emqx_management/etc/emqx_management.conf +++ b/lib-opensource/emqx_management/etc/emqx_management.conf @@ -45,7 +45,8 @@ management.listener.http.ipv6_v6only = false ## management.listener.https.keyfile = etc/certs/key.pem ## management.listener.https.cacertfile = etc/certs/cacert.pem ## management.listener.https.verify = verify_peer -## management.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1 +## NOTE: Do not use tlsv1.3 if emqx is running on OTP-22 or earlier +## management.listener.https.tls_versions = tlsv1.3,tlsv1.2,tlsv1.1,tlsv1 ## management.listener.https.ciphers = TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_AES_128_CCM_SHA256,TLS_AES_128_CCM_8_SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA ## management.listener.https.fail_if_no_peer_cert = true ## management.listener.https.inet6 = false diff --git a/apps/emqx_management/include/emqx_mgmt.hrl b/lib-opensource/emqx_management/include/emqx_mgmt.hrl similarity index 100% rename from apps/emqx_management/include/emqx_mgmt.hrl rename to lib-opensource/emqx_management/include/emqx_mgmt.hrl diff --git a/apps/emqx_management/priv/emqx_management.schema b/lib-opensource/emqx_management/priv/emqx_management.schema similarity index 100% rename from apps/emqx_management/priv/emqx_management.schema rename to lib-opensource/emqx_management/priv/emqx_management.schema diff --git a/apps/emqx_management/rebar.config b/lib-opensource/emqx_management/rebar.config similarity index 100% rename from apps/emqx_management/rebar.config rename to lib-opensource/emqx_management/rebar.config diff --git a/apps/emqx_management/src/emqx_management.app.src b/lib-opensource/emqx_management/src/emqx_management.app.src similarity index 100% rename from apps/emqx_management/src/emqx_management.app.src rename to lib-opensource/emqx_management/src/emqx_management.app.src diff --git a/apps/emqx_management/src/emqx_mgmt.erl b/lib-opensource/emqx_management/src/emqx_mgmt.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt.erl rename to lib-opensource/emqx_management/src/emqx_mgmt.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_alarms.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_alarms.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_alarms.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_alarms.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_apps.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_apps.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_apps.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_apps.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_banned.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_banned.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_banned.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_banned.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_brokers.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_brokers.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_brokers.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_brokers.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_clients.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_clients.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_clients.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_data.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_data.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_data.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_data.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_listeners.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_listeners.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_listeners.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_metrics.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_metrics.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_metrics.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_metrics.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_modules.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_modules.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_modules.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_modules.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_nodes.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_nodes.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_nodes.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_nodes.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_plugins.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_plugins.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_plugins.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_plugins.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_pubsub.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_pubsub.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_pubsub.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_pubsub.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_routes.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_routes.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_routes.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_routes.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_stats.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_stats.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_stats.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_stats.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_subscriptions.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_subscriptions.erl diff --git a/apps/emqx_management/src/emqx_mgmt_api_topic_metrics.erl b/lib-opensource/emqx_management/src/emqx_mgmt_api_topic_metrics.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_api_topic_metrics.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_api_topic_metrics.erl diff --git a/apps/emqx_management/src/emqx_mgmt_app.erl b/lib-opensource/emqx_management/src/emqx_mgmt_app.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_app.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_app.erl diff --git a/apps/emqx_management/src/emqx_mgmt_auth.erl b/lib-opensource/emqx_management/src/emqx_mgmt_auth.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_auth.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_auth.erl diff --git a/apps/emqx_management/src/emqx_mgmt_cli.erl b/lib-opensource/emqx_management/src/emqx_mgmt_cli.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_cli.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_cli.erl diff --git a/apps/emqx_management/src/emqx_mgmt_http.erl b/lib-opensource/emqx_management/src/emqx_mgmt_http.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_http.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_http.erl diff --git a/apps/emqx_management/src/emqx_mgmt_sup.erl b/lib-opensource/emqx_management/src/emqx_mgmt_sup.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_sup.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_sup.erl diff --git a/apps/emqx_management/src/emqx_mgmt_util.erl b/lib-opensource/emqx_management/src/emqx_mgmt_util.erl similarity index 100% rename from apps/emqx_management/src/emqx_mgmt_util.erl rename to lib-opensource/emqx_management/src/emqx_mgmt_util.erl diff --git a/apps/emqx_management/test/emqx_mgmt_SUITE.erl b/lib-opensource/emqx_management/test/emqx_mgmt_SUITE.erl similarity index 100% rename from apps/emqx_management/test/emqx_mgmt_SUITE.erl rename to lib-opensource/emqx_management/test/emqx_mgmt_SUITE.erl diff --git a/apps/emqx_management/test/emqx_mgmt_api_SUITE.erl b/lib-opensource/emqx_management/test/emqx_mgmt_api_SUITE.erl similarity index 100% rename from apps/emqx_management/test/emqx_mgmt_api_SUITE.erl rename to lib-opensource/emqx_management/test/emqx_mgmt_api_SUITE.erl diff --git a/apps/emqx_management/test/etc/emqx_management.conf b/lib-opensource/emqx_management/test/etc/emqx_management.conf similarity index 100% rename from apps/emqx_management/test/etc/emqx_management.conf rename to lib-opensource/emqx_management/test/etc/emqx_management.conf diff --git a/apps/emqx_management/test/etc/emqx_reloader.conf b/lib-opensource/emqx_management/test/etc/emqx_reloader.conf similarity index 100% rename from apps/emqx_management/test/etc/emqx_reloader.conf rename to lib-opensource/emqx_management/test/etc/emqx_reloader.conf diff --git a/apps/emqx_management/test/rfc6455_client.erl b/lib-opensource/emqx_management/test/rfc6455_client.erl similarity index 100% rename from apps/emqx_management/test/rfc6455_client.erl rename to lib-opensource/emqx_management/test/rfc6455_client.erl diff --git a/apps/emqx_rule_engine/.gitignore b/lib-opensource/emqx_rule_engine/.gitignore similarity index 100% rename from apps/emqx_rule_engine/.gitignore rename to lib-opensource/emqx_rule_engine/.gitignore diff --git a/apps/emqx_rule_engine/README.md b/lib-opensource/emqx_rule_engine/README.md similarity index 100% rename from apps/emqx_rule_engine/README.md rename to lib-opensource/emqx_rule_engine/README.md diff --git a/apps/emqx_rule_engine/docs/api_examples.md b/lib-opensource/emqx_rule_engine/docs/api_examples.md similarity index 100% rename from apps/emqx_rule_engine/docs/api_examples.md rename to lib-opensource/emqx_rule_engine/docs/api_examples.md diff --git a/apps/emqx_rule_engine/docs/cli_examples.md b/lib-opensource/emqx_rule_engine/docs/cli_examples.md similarity index 100% rename from apps/emqx_rule_engine/docs/cli_examples.md rename to lib-opensource/emqx_rule_engine/docs/cli_examples.md diff --git a/apps/emqx_rule_engine/docs/design.md b/lib-opensource/emqx_rule_engine/docs/design.md similarity index 100% rename from apps/emqx_rule_engine/docs/design.md rename to lib-opensource/emqx_rule_engine/docs/design.md diff --git a/apps/emqx_rule_engine/etc/emqx_rule_engine.conf b/lib-opensource/emqx_rule_engine/etc/emqx_rule_engine.conf similarity index 100% rename from apps/emqx_rule_engine/etc/emqx_rule_engine.conf rename to lib-opensource/emqx_rule_engine/etc/emqx_rule_engine.conf diff --git a/apps/emqx_rule_engine/include/rule_actions.hrl b/lib-opensource/emqx_rule_engine/include/rule_actions.hrl similarity index 100% rename from apps/emqx_rule_engine/include/rule_actions.hrl rename to lib-opensource/emqx_rule_engine/include/rule_actions.hrl diff --git a/apps/emqx_rule_engine/include/rule_engine.hrl b/lib-opensource/emqx_rule_engine/include/rule_engine.hrl similarity index 100% rename from apps/emqx_rule_engine/include/rule_engine.hrl rename to lib-opensource/emqx_rule_engine/include/rule_engine.hrl diff --git a/apps/emqx_rule_engine/priv/emqx_rule_engine.schema b/lib-opensource/emqx_rule_engine/priv/emqx_rule_engine.schema similarity index 100% rename from apps/emqx_rule_engine/priv/emqx_rule_engine.schema rename to lib-opensource/emqx_rule_engine/priv/emqx_rule_engine.schema diff --git a/apps/emqx_rule_engine/rebar.config b/lib-opensource/emqx_rule_engine/rebar.config similarity index 100% rename from apps/emqx_rule_engine/rebar.config rename to lib-opensource/emqx_rule_engine/rebar.config diff --git a/apps/emqx_rule_engine/src/emqx_rule_actions.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_actions.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_actions.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_actions.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_actions_trans.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_actions_trans.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_actions_trans.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_actions_trans.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.app.src b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine.app.src similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine.app.src rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine.app.src diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine_api.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine_api.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine_api.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_app.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine_app.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine_app.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine_app.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine_cli.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine_cli.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine_cli.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_sup.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_engine_sup.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_engine_sup.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_engine_sup.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_events.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_events.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_events.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_events.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_funcs.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_funcs.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_funcs.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_funcs.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_id.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_id.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_id.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_id.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_locker.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_locker.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_locker.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_locker.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_maps.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_maps.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_maps.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_maps.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_metrics.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_metrics.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_metrics.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_registry.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_registry.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_registry.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_registry.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_runtime.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_runtime.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_runtime.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_sqlparser.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_sqlparser.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_sqlparser.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_sqlparser.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_sqltester.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_sqltester.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_sqltester.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_sqltester.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_utils.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_utils.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_utils.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_utils.erl diff --git a/apps/emqx_rule_engine/src/emqx_rule_validator.erl b/lib-opensource/emqx_rule_engine/src/emqx_rule_validator.erl similarity index 100% rename from apps/emqx_rule_engine/src/emqx_rule_validator.erl rename to lib-opensource/emqx_rule_engine/src/emqx_rule_validator.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_events_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_events_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_events_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_events_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_funcs_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_id_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_id_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_id_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_id_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_maps_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_maps_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_maps_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_maps_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_registry_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_registry_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_registry_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_registry_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_utils_SUITE.erl diff --git a/apps/emqx_rule_engine/test/emqx_rule_validator_SUITE.erl b/lib-opensource/emqx_rule_engine/test/emqx_rule_validator_SUITE.erl similarity index 100% rename from apps/emqx_rule_engine/test/emqx_rule_validator_SUITE.erl rename to lib-opensource/emqx_rule_engine/test/emqx_rule_validator_SUITE.erl diff --git a/apps/emqx_rule_engine/test/prop_rule_maps.erl b/lib-opensource/emqx_rule_engine/test/prop_rule_maps.erl similarity index 100% rename from apps/emqx_rule_engine/test/prop_rule_maps.erl rename to lib-opensource/emqx_rule_engine/test/prop_rule_maps.erl diff --git a/rebar.config.erl b/rebar.config.erl index d68d46b9b..08b3e2be9 100644 --- a/rebar.config.erl +++ b/rebar.config.erl @@ -279,7 +279,7 @@ provide_bcrypt_release(ReleaseType) -> %% rebar3 does not handle umberella project's cross-app parse_transform well compile_and_load_pase_transforms(Dir) -> PtFiles = - [ "apps/emqx_rule_engine/src/emqx_rule_actions_trans.erl" + [ "lib-opensource/emqx_rule_engine/src/emqx_rule_actions_trans.erl" ], CompileOpts = [verbose,report_errors,report_warnings,return_errors,debug_info], lists:foreach(fun(PtFile) -> {ok, _Mod} = compile:file(path(Dir, PtFile), CompileOpts) end, PtFiles). @@ -291,8 +291,8 @@ str(B) when is_binary(B) -> unicode:characters_to_list(B, utf8). erl_opts_i() -> [{i, "apps"}] ++ - [{i, Dir} || Dir <- filelib:wildcard(filename:join(["apps", "**", "include"]))] ++ - [{i, Dir} || Dir <- filelib:wildcard(filename:join([extra_lib_dir(), "**", "include"]))]. + [{i, Dir} || Dir <- filelib:wildcard(filename:join(["apps", "*", "include"]))] ++ + [{i, Dir} || Dir <- filelib:wildcard(filename:join([extra_lib_dir(), "*", "include"]))]. dialyzer(Config) -> {dialyzer, OldDialyzerConfig} = lists:keyfind(dialyzer, 1, Config), diff --git a/scripts/elvis-check.sh b/scripts/elvis-check.sh index 0e105bf99..e367dbfa9 100755 --- a/scripts/elvis-check.sh +++ b/scripts/elvis-check.sh @@ -23,10 +23,17 @@ if [ ! -f ./elvis ] || [ "$(./elvis -v | grep -oE '[1-9]+\.[0-9]+\.[0-9]+\-emqx- chmod +x ./elvis fi -git fetch origin "$base" +if [[ "$base" =~ [0-9a-f]{8,40} ]]; then + # base is a commit sha1 + compare_base="$base" +else + remote="$(git remote -v | grep -E 'github\.com(.|/)emqx' | grep fetch | awk '{print $1}')" + git fetch "$remote" "$base" + compare_base="$remote/$base" +fi git_diff() { - git diff --name-only origin/"$base"...HEAD + git diff --name-only "$compare_base"...HEAD } bad_file_count=0 diff --git a/src/emqx_access_rule.erl b/src/emqx_access_rule.erl index f0c6bcea9..2931bc9f2 100644 --- a/src/emqx_access_rule.erl +++ b/src/emqx_access_rule.erl @@ -69,14 +69,13 @@ compile(topic, {eq, Topic}) -> {eq, emqx_topic:words(bin(Topic))}; compile(topic, Topic) -> Words = emqx_topic:words(bin(Topic)), - case 'pattern?'(Words) of + case pattern(Words) of true -> {pattern, Words}; false -> Words end. -'pattern?'(Words) -> - lists:member(<<"%u">>, Words) - orelse lists:member(<<"%c">>, Words). +pattern(Words) -> + lists:member(<<"%u">>, Words) orelse lists:member(<<"%c">>, Words). bin(L) when is_list(L) -> list_to_binary(L); diff --git a/src/emqx_app.erl b/src/emqx_app.erl index 7b53bbb26..cf4f8753d 100644 --- a/src/emqx_app.erl +++ b/src/emqx_app.erl @@ -32,11 +32,11 @@ start(_Type, _Args) -> print_banner(), ekka:start(), {ok, Sup} = emqx_sup:start_link(), - start_autocluster(), - emqx_boot:is_enabled(listeners) - andalso (ok = emqx_listeners:start()), + ok = start_autocluster(), ok = emqx_plugins:init(), _ = emqx_plugins:load(), + emqx_boot:is_enabled(listeners) + andalso (ok = emqx_listeners:start()), register(emqx, self()), ok = emqx_alarm_handler:load(), print_vsn(), @@ -63,12 +63,8 @@ print_vsn() -> %%-------------------------------------------------------------------- %% Autocluster %%-------------------------------------------------------------------- - --ifdef(EMQX_ENTERPRISE). start_autocluster() -> ekka:callback(prepare, fun emqx:shutdown/1), ekka:callback(reboot, fun emqx:reboot/0), - ekka:autocluster(?APP). --else. -start_autocluster() -> ok. --endif. + _ = ekka:autocluster(?APP), %% returns 'ok' or a pid or 'any()' as in spec + ok. diff --git a/src/emqx_congestion.erl b/src/emqx_congestion.erl index 36dc7ac9f..0e7992f2e 100644 --- a/src/emqx_congestion.erl +++ b/src/emqx_congestion.erl @@ -23,15 +23,18 @@ , cancel_alarms/3 ]). --define(ALARM_CONN_CONGEST(Channel, Reason), - list_to_binary(io_lib:format("mqtt_conn/congested/~s/~s/~s", [emqx_channel:info(clientid, Channel), - maps:get(username, emqx_channel:info(clientinfo, Channel), <<"undefined">>), - Reason]))). +-elvis([{elvis_style, invalid_dynamic_call, #{ignore => [emqx_congestion]}}]). --define(ALARM_CONN_INFO_KEYS, [ - socktype, sockname, peername, clientid, username, proto_name, proto_ver, - connected_at, conn_state -]). +-define(ALARM_CONN_CONGEST(Channel, Reason), + list_to_binary( + io_lib:format("mqtt_conn/congested/~s/~s/~s", + [emqx_channel:info(clientid, Channel), + maps:get(username, emqx_channel:info(clientinfo, Channel), + <<"undefined">>), + Reason]))). + +-define(ALARM_CONN_INFO_KEYS, [socktype, sockname, peername, clientid, username, + proto_name, proto_ver, connected_at, conn_state]). -define(ALARM_SOCK_STATS_KEYS, [send_pend, recv_cnt, recv_oct, send_cnt, send_oct]). -define(ALARM_SOCK_OPTS_KEYS, [high_watermark, high_msgq_watermark, sndbuf, recbuf, buffer]). -define(PROC_INFO_KEYS, [message_queue_len, memory, reductions]). @@ -156,6 +159,6 @@ tcp_congestion_alarm_details(Socket, Transport, Channel) -> conn_info(Key, Channel) when Key =:= sockname; Key =:= peername -> {IPStr, Port} = emqx_channel:info(Key, Channel), - {Key, iolist_to_binary([inet:ntoa(IPStr),":",integer_to_list(Port)])}; + {Key, iolist_to_binary([inet:ntoa(IPStr), ":", integer_to_list(Port)])}; conn_info(Key, Channel) -> {Key, emqx_channel:info(Key, Channel)}. diff --git a/src/emqx_connection.erl b/src/emqx_connection.erl index fba26676f..eb9a95dc4 100644 --- a/src/emqx_connection.erl +++ b/src/emqx_connection.erl @@ -29,6 +29,8 @@ -compile(nowarn_export_all). -endif. +-elvis([{elvis_style, invalid_dynamic_call, #{ignore => [emqx_connection]}}]). + %% API -export([ start_link/3 , stop/1 @@ -506,7 +508,7 @@ system_code_change(State, _Mod, Vsn, _Extra) Ps when is_function(Ps) -> case erlang:fun_info(Ps, env) of {_, [Hdr, Opts]} -> - {{len, #{hdr => Hdr, len => {1,0}}}, Opts}; + {{len, #{hdr => Hdr, len => {1, 0}}}, Opts}; {_, [Bin, Hdr, Len, Opts]} when is_binary(Bin) -> {{body, #{hdr => Hdr, len => Len, rest => Bin}}, Opts}; {_, [Hdr, Multip, Len, Opts]} -> @@ -689,57 +691,15 @@ send(IoData, #state{transport = Transport, socket = Socket, channel = Channel}) ok end. -maybe_warn_congestion(Socket, Transport, Channel) -> - IsCongestAlarmSet = is_congestion_alarm_set(), - case is_congested(Socket, Transport) of - true when not IsCongestAlarmSet -> - ok = set_congestion_alarm(), - emqx_alarm:activate(?ALARM_TCP_CONGEST(Channel), - tcp_congestion_alarm_details(Socket, Transport, Channel)); - false when IsCongestAlarmSet -> - ok = clear_congestion_alarm(), - emqx_alarm:deactivate(?ALARM_TCP_CONGEST(Channel)); - _ -> ok - end. - -is_congested(Socket, Transport) -> - case Transport:getstat(Socket, [send_pend]) of - {ok, [{send_pend, N}]} when N > 0 -> true; - _ -> false - end. - -is_congestion_alarm_set() -> - case erlang:get(conn_congested) of - true -> true; - _ -> false - end. -set_congestion_alarm() -> - erlang:put(conn_congested, true), ok. -clear_congestion_alarm() -> - erlang:put(conn_congested, false), ok. - -tcp_congestion_alarm_details(Socket, Transport, Channel) -> - {ok, Stat} = Transport:getstat(Socket, ?ALARM_SOCK_STATS_KEYS), - {ok, Opts} = Transport:getopts(Socket, ?ALARM_SOCK_OPTS_KEYS), - SockInfo = maps:from_list(Stat ++ Opts), - ConnInfo = maps:from_list([conn_info(Key, Channel) || Key <- ?ALARM_CONN_INFO_KEYS]), - maps:merge(ConnInfo, SockInfo). - -conn_info(Key, Channel) when Key =:= sockname; Key =:= peername -> - {IPStr, Port} = emqx_channel:info(Key, Channel), - {Key, iolist_to_binary([inet:ntoa(IPStr),":",integer_to_list(Port)])}; -conn_info(Key, Channel) -> - {Key, emqx_channel:info(Key, Channel)}. - %%-------------------------------------------------------------------- %% Handle Info handle_info(activate_socket, State = #state{sockstate = OldSst}) -> case activate_socket(State) of {ok, NState = #state{sockstate = NewSst}} -> - if OldSst =/= NewSst -> - {ok, {event, NewSst}, NState}; - true -> {ok, NState} + case OldSst =/= NewSst of + true -> {ok, {event, NewSst}, NState}; + false -> {ok, NState} end; {error, Reason} -> handle_info({sock_error, Reason}, State) diff --git a/src/emqx_os_mon.erl b/src/emqx_os_mon.erl index 2852c917b..0b057e1f8 100644 --- a/src/emqx_os_mon.erl +++ b/src/emqx_os_mon.erl @@ -81,7 +81,7 @@ get_mem_check_interval() -> set_mem_check_interval(Seconds) when Seconds < 60 -> memsup:set_check_interval(1); -set_mem_check_interval(Seconds) -> +set_mem_check_interval(Seconds) -> memsup:set_check_interval(Seconds div 60). get_sysmem_high_watermark() -> diff --git a/src/emqx_tls_lib.erl b/src/emqx_tls_lib.erl new file mode 100644 index 000000000..6153160e7 --- /dev/null +++ b/src/emqx_tls_lib.erl @@ -0,0 +1,98 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_tls_lib). + +-export([ default_versions/0 + , integral_versions/1 + , default_ciphers/0 + , default_ciphers/1 + , integral_ciphers/2 + ]). + +-define(IS_STRING_LIST(L), (is_list(L) andalso L =/= [] andalso is_list(hd(L)))). + +%% @doc Returns the default supported tls versions. +-spec default_versions() -> [atom()]. +default_versions() -> + OtpRelease = list_to_integer(erlang:system_info(otp_release)), + integral_versions(default_versions(OtpRelease)). + +%% @doc Validate a given list of desired tls versions. +%% raise an error exception if non of them are available. +-spec integral_versions([ssl:tls_version()]) -> [ssl:tls_version()]. +integral_versions(Desired) -> + {_, Available} = lists:keyfind(available, 1, ssl:versions()), + case lists:filter(fun(V) -> lists:member(V, Available) end, Desired) of + [] -> erlang:error(#{ reason => no_available_tls_version + , desired => Desired + , available => Available + }); + Filtered -> + Filtered + end. + +%% @doc Return a list of default (openssl string format) cipher suites. +-spec default_ciphers() -> [string()]. +default_ciphers() -> default_ciphers(default_versions()). + +%% @doc Return a list of (openssl string format) cipher suites. +-spec default_ciphers([ssl:tls_version()]) -> [string()]. +default_ciphers(['tlsv1.3']) -> + %% When it's only tlsv1.3 wanted, use 'exclusive' here + %% because 'all' returns legacy cipher suites too, + %% which does not make sense since tlsv1.3 can not use + %% legacy cipher suites. + ssl:cipher_suites(exclusive, 'tlsv1.3', openssl); +default_ciphers(Versions) -> + %% assert non-empty + [_ | _] = dedup(lists:append([ssl:cipher_suites(all, V, openssl) || V <- Versions])). + +%% @doc Ensure version & cipher-suites integrity. +-spec integral_ciphers([ssl:tls_version()], binary() | string() | [string()]) -> [string()]. +integral_ciphers(Versions, Ciphers) when Ciphers =:= [] orelse Ciphers =:= undefined -> + %% not configured + integral_ciphers(Versions, default_ciphers(Versions)); +integral_ciphers(Versions, Ciphers) when ?IS_STRING_LIST(Ciphers) -> + %% ensure tlsv1.3 ciphers if none of them is found in Ciphers + dedup(ensure_tls13_cipher(lists:member('tlsv1.3', Versions), Ciphers)); +integral_ciphers(Versions, Ciphers) when is_binary(Ciphers) -> + %% parse binary + integral_ciphers(Versions, binary_to_list(Ciphers)); +integral_ciphers(Versions, Ciphers) -> + %% parse comma separated cipher suite names + integral_ciphers(Versions, string:tokens(Ciphers, ", ")). + +%% In case tlsv1.3 is present, ensure tlsv1.3 cipher is added if user +%% did not provide it from config --- which is a common mistake +ensure_tls13_cipher(true, Ciphers) -> + Tls13Ciphers = default_ciphers(['tlsv1.3']), + case lists:any(fun(C) -> lists:member(C, Tls13Ciphers) end, Ciphers) of + true -> Ciphers; + false -> Tls13Ciphers ++ Ciphers + end; +ensure_tls13_cipher(false, Ciphers) -> + Ciphers. + +%% tlsv1.3 is available from OTP-22 but we do not want to use until 23. +default_versions(OtpRelease) when OtpRelease >= 23 -> + ['tlsv1.3' | default_versions(22)]; +default_versions(_) -> + ['tlsv1.2', 'tlsv1.1', tlsv1]. + +%% Deduplicate a list without re-ordering the elements. +dedup([]) -> []; +dedup([H | T]) -> [H | dedup([I || I <- T, I =/= H])]. diff --git a/sync-apps.sh b/sync-apps.sh index 1b4b8fcc2..e5c36228f 100755 --- a/sync-apps.sh +++ b/sync-apps.sh @@ -15,17 +15,17 @@ apps=( "emqx_auth_redis" "emqx_bridge_mqtt" "emqx_coap" -"emqx_dashboard" +# "emqx_dashboard" # moved to lib-opensource "emqx_exhook" "emqx_exproto" "emqx_lua_hook" "emqx_lwm2m" -"emqx_management" +# "emqx_management" # moved to lib-opensource "emqx_prometheus" "emqx_psk_file" "emqx_recon" "emqx_retainer" -"emqx_rule_engine" +# "emqx_rule_engine" # moved to lib-opensource "emqx_sasl" "emqx_sn" "emqx_stomp" diff --git a/test/emqx_acl_cache_SUITE.erl b/test/emqx_acl_cache_SUITE.erl index 2adbed03c..8c7685aa2 100644 --- a/test/emqx_acl_cache_SUITE.erl +++ b/test/emqx_acl_cache_SUITE.erl @@ -62,7 +62,8 @@ t_reload_aclfile_and_cleanall(_Config) -> disconnected => fun(_) -> ok end, publish => fun(_) -> ok end } end, - {ok, Client} = emqtt:start_link([{clientid, <<"emqx_c">>}, {proto_ver, v5}, {msg_handler, RasieMsg()}]), + {ok, Client} = emqtt:start_link([{clientid, <<"emqx_c">>}, {proto_ver, v5}, + {msg_handler, RasieMsg()}]), {ok, _} = emqtt:connect(Client), {ok, PktId} = emqtt:publish(Client, <<"t1">>, <<"{\"x\":1}">>, qos1), diff --git a/test/emqx_connection_SUITE.erl b/test/emqx_connection_SUITE.erl index 121b63934..b011c6978 100644 --- a/test/emqx_connection_SUITE.erl +++ b/test/emqx_connection_SUITE.erl @@ -166,86 +166,99 @@ t_append_msg(_) -> t_handle_msg(_) -> From = {make_ref(), self()}, - ?assertMatch({ok, _St}, emqx_connection:handle_msg({'$gen_call', From, for_testing}, st())), - ?assertMatch({stop, {shutdown,discarded}, _St}, emqx_connection:handle_msg({'$gen_call', From, discard}, st())), - ?assertMatch({stop, {shutdown,discarded}, _St}, emqx_connection:handle_msg({'$gen_call', From, discard}, st())), - ?assertMatch({ok, [], _St}, emqx_connection:handle_msg({tcp, From, <<"for_testing">>}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg(for_testing, st())). + ?assertMatch({ok, _St}, handle_msg({'$gen_call', From, for_testing}, st())), + ?assertMatch({stop, {shutdown,discarded}, _St}, handle_msg({'$gen_call', From, discard}, st())), + ?assertMatch({stop, {shutdown,discarded}, _St}, handle_msg({'$gen_call', From, discard}, st())), + ?assertMatch({ok, [], _St}, handle_msg({tcp, From, <<"for_testing">>}, st())), + ?assertMatch({ok, _St}, handle_msg(for_testing, st())). t_handle_msg_incoming(_) -> - ?assertMatch({ok, _Out, _St}, emqx_connection:handle_msg({incoming, ?CONNECT_PACKET(#mqtt_packet_connect{})}, st())), - ?assertEqual(ok, emqx_connection:handle_msg({incoming, ?PACKET(?PINGREQ)}, st())), + ?assertMatch({ok, _Out, _St}, + handle_msg({incoming, ?CONNECT_PACKET(#mqtt_packet_connect{})}, st())), + ?assertEqual(ok, handle_msg({incoming, ?PACKET(?PINGREQ)}, st())), ok = meck:expect(emqx_channel, handle_in, fun(_Packet, Channel) -> {ok, Channel} end), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({incoming, ?PUBLISH_PACKET(?QOS_1, <<"t">>, 1, <<"payload">>)}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({incoming, <>}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({incoming, <>}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({incoming, undefined}, st())). + ?assertMatch({ok, _St}, + handle_msg({incoming, ?PUBLISH_PACKET(?QOS_1, <<"t">>, 1, <<"payload">>)}, st())), + Sub1 = <>, + ?assertMatch({ok, _St}, handle_msg({incoming, Sub1}, st())), + Sub2 = <>, + ?assertMatch({ok, _St}, handle_msg({incoming, Sub2}, st())), + ?assertMatch({ok, _St}, handle_msg({incoming, undefined}, st())). t_handle_msg_outgoing(_) -> - ?assertEqual(ok, emqx_connection:handle_msg({outgoing, ?PUBLISH_PACKET(?QOS_2, <<"Topic">>, 1, <<>>)}, st())), - ?assertEqual(ok, emqx_connection:handle_msg({outgoing, ?PUBREL_PACKET(1)}, st())), - ?assertEqual(ok, emqx_connection:handle_msg({outgoing, ?PUBCOMP_PACKET(1)}, st())). + ?assertEqual(ok, handle_msg({outgoing, ?PUBLISH_PACKET(?QOS_2, <<"Topic">>, 1, <<>>)}, st())), + ?assertEqual(ok, handle_msg({outgoing, ?PUBREL_PACKET(1)}, st())), + ?assertEqual(ok, handle_msg({outgoing, ?PUBCOMP_PACKET(1)}, st())). t_handle_msg_tcp_error(_) -> - ?assertMatch({stop, {shutdown, econnreset}, _St}, emqx_connection:handle_msg({tcp_error, sock, econnreset}, st())). + ?assertMatch({stop, {shutdown, econnreset}, _St}, + handle_msg({tcp_error, sock, econnreset}, st())). t_handle_msg_tcp_closed(_) -> - ?assertMatch({stop, {shutdown, tcp_closed}, _St}, emqx_connection:handle_msg({tcp_closed, sock}, st())). + ?assertMatch({stop, {shutdown, tcp_closed}, _St}, handle_msg({tcp_closed, sock}, st())). t_handle_msg_passive(_) -> - ?assertMatch({ok, _Event, _St}, emqx_connection:handle_msg({tcp_passive, sock}, st())). - + ?assertMatch({ok, _Event, _St}, handle_msg({tcp_passive, sock}, st())). + t_handle_msg_deliver(_) -> ok = meck:expect(emqx_channel, handle_deliver, fun(_, Channel) -> {ok, Channel} end), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({deliver, topic, msg}, st())). - + ?assertMatch({ok, _St}, handle_msg({deliver, topic, msg}, st())). + t_handle_msg_inet_reply(_) -> ok = meck:expect(emqx_pd, get_counter, fun(_) -> 10 end), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({inet_reply, for_testing, ok}, st(#{active_n => 0}))), - ?assertEqual(ok, emqx_connection:handle_msg({inet_reply, for_testing, ok}, st(#{active_n => 100}))), - ?assertMatch({stop, {shutdown, for_testing}, _St}, emqx_connection:handle_msg({inet_reply, for_testing, {error, for_testing}}, st())). + ?assertMatch({ok, _St}, handle_msg({inet_reply, for_testing, ok}, st(#{active_n => 0}))), + ?assertEqual(ok, handle_msg({inet_reply, for_testing, ok}, st(#{active_n => 100}))), + ?assertMatch({stop, {shutdown, for_testing}, _St}, + handle_msg({inet_reply, for_testing, {error, for_testing}}, st())). t_handle_msg_connack(_) -> - ?assertEqual(ok, emqx_connection:handle_msg({connack, ?CONNACK_PACKET(?CONNACK_ACCEPT)}, st())). + ?assertEqual(ok, handle_msg({connack, ?CONNACK_PACKET(?CONNACK_ACCEPT)}, st())). t_handle_msg_close(_) -> - ?assertMatch({stop, {shutdown, normal}, _St}, emqx_connection:handle_msg({close, normal}, st())). - + ?assertMatch({stop, {shutdown, normal}, _St}, handle_msg({close, normal}, st())). + t_handle_msg_event(_) -> ok = meck:expect(emqx_cm, register_channel, fun(_, _, _) -> ok end), ok = meck:expect(emqx_cm, insert_channel_info, fun(_, _, _) -> ok end), ok = meck:expect(emqx_cm, set_chan_info, fun(_, _) -> ok end), ok = meck:expect(emqx_cm, connection_closed, fun(_) -> ok end), - ?assertEqual(ok, emqx_connection:handle_msg({event, connected}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({event, disconnected}, st())), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({event, undefined}, st())). - + ?assertEqual(ok, handle_msg({event, connected}, st())), + ?assertMatch({ok, _St}, handle_msg({event, disconnected}, st())), + ?assertMatch({ok, _St}, handle_msg({event, undefined}, st())). + t_handle_msg_timeout(_) -> - ?assertMatch({ok, _St}, emqx_connection:handle_msg({timeout, make_ref(), for_testing}, st())). + ?assertMatch({ok, _St}, handle_msg({timeout, make_ref(), for_testing}, st())). t_handle_msg_shutdown(_) -> - ?assertMatch({stop, {shutdown, for_testing}, _St}, emqx_connection:handle_msg({shutdown, for_testing}, st())). + ?assertMatch({stop, {shutdown, for_testing}, _St}, handle_msg({shutdown, for_testing}, st())). t_handle_call(_) -> St = st(), - ?assertMatch({ok, _St}, emqx_connection:handle_msg({event, undefined}, St)), - ?assertMatch({reply, _Info, _NSt}, emqx_connection:handle_call(self(), info, St)), - ?assertMatch({reply, _Stats, _NSt}, emqx_connection:handle_call(self(), stats, St)), - ?assertMatch({reply, ok, _NSt}, emqx_connection:handle_call(self(), {ratelimit, []}, St)), - ?assertMatch({reply, ok, _NSt}, emqx_connection:handle_call(self(), {ratelimit, [{conn_messages_in, {100, 1}}]}, St)), - ?assertEqual({reply, ignored, St}, emqx_connection:handle_call(self(), for_testing, St)), - ?assertMatch({stop, {shutdown,kicked}, ok, _NSt}, emqx_connection:handle_call(self(), kick, St)). + ?assertMatch({ok, _St}, handle_msg({event, undefined}, St)), + ?assertMatch({reply, _Info, _NSt}, handle_call(self(), info, St)), + ?assertMatch({reply, _Stats, _NSt}, handle_call(self(), stats, St)), + ?assertMatch({reply, ok, _NSt}, handle_call(self(), {ratelimit, []}, St)), + ?assertMatch({reply, ok, _NSt}, + handle_call(self(), {ratelimit, [{conn_messages_in, {100, 1}}]}, St)), + ?assertEqual({reply, ignored, St}, handle_call(self(), for_testing, St)), + ?assertMatch({stop, {shutdown,kicked}, ok, _NSt}, + handle_call(self(), kick, St)). t_handle_timeout(_) -> TRef = make_ref(), State = st(#{idle_timer => TRef, limit_timer => TRef, stats_timer => TRef}), - ?assertMatch({stop, {shutdown,idle_timeout}, _NState}, emqx_connection:handle_timeout(TRef, idle_timeout, State)), - ?assertMatch({ok, {event,running}, _NState}, emqx_connection:handle_timeout(TRef, limit_timeout, State)), - ?assertMatch({ok, _NState}, emqx_connection:handle_timeout(TRef, emit_stats, State)), - ?assertMatch({ok, _NState}, emqx_connection:handle_timeout(TRef, keepalive, State)), + ?assertMatch({stop, {shutdown,idle_timeout}, _NState}, + emqx_connection:handle_timeout(TRef, idle_timeout, State)), + ?assertMatch({ok, {event,running}, _NState}, + emqx_connection:handle_timeout(TRef, limit_timeout, State)), + ?assertMatch({ok, _NState}, + emqx_connection:handle_timeout(TRef, emit_stats, State)), + ?assertMatch({ok, _NState}, + emqx_connection:handle_timeout(TRef, keepalive, State)), ok = meck:expect(emqx_transport, getstat, fun(_Sock, _Options) -> {error, for_testing} end), - ?assertMatch({stop, {shutdown,for_testing}, _NState}, emqx_connection:handle_timeout(TRef, keepalive, State)), + ?assertMatch({stop, {shutdown,for_testing}, _NState}, + emqx_connection:handle_timeout(TRef, keepalive, State)), ?assertMatch({ok, _NState}, emqx_connection:handle_timeout(TRef, undefined, State)). t_parse_incoming(_) -> @@ -254,10 +267,12 @@ t_parse_incoming(_) -> t_next_incoming_msgs(_) -> ?assertEqual({incoming, packet}, emqx_connection:next_incoming_msgs([packet])), - ?assertEqual([{incoming, packet2}, {incoming, packet1}], emqx_connection:next_incoming_msgs([packet1, packet2])). + ?assertEqual([{incoming, packet2}, {incoming, packet1}], + emqx_connection:next_incoming_msgs([packet1, packet2])). t_handle_incoming(_) -> - ?assertMatch({ok, _Out, _NState}, emqx_connection:handle_incoming(?CONNECT_PACKET(#mqtt_packet_connect{}), st())), + ?assertMatch({ok, _Out, _NState}, + emqx_connection:handle_incoming(?CONNECT_PACKET(#mqtt_packet_connect{}), st())), ?assertMatch({ok, _Out, _NState}, emqx_connection:handle_incoming(frame_error, st())). t_with_channel(_) -> @@ -269,33 +284,46 @@ t_with_channel(_) -> ok = meck:expect(emqx_channel, handle_in, fun(_, _) -> Channel = channel(), {ok, Channel} end), ?assertMatch({ok, _NState}, emqx_connection:with_channel(handle_in, [for_testing], State)), - ok = meck:expect(emqx_channel, handle_in, fun(_, _) -> Channel = channel(), {ok, ?DISCONNECT_PACKET(),Channel} end), - ?assertMatch({ok, _Out, _NChannel}, emqx_connection:with_channel(handle_in, [for_testing], State)), + ok = meck:expect(emqx_channel, handle_in, + fun(_, _) -> Channel = channel(), {ok, ?DISCONNECT_PACKET(),Channel} end), + ?assertMatch({ok, _Out, _NChannel}, + emqx_connection:with_channel(handle_in, [for_testing], State)), - ok = meck:expect(emqx_channel, handle_in, fun(_, _) -> Channel = channel(), {shutdown, [for_testing], Channel} end), - ?assertMatch({stop, {shutdown,[for_testing]}, _NState}, emqx_connection:with_channel(handle_in, [for_testing], State)), + ok = meck:expect(emqx_channel, handle_in, + fun(_, _) -> Channel = channel(), {shutdown, [for_testing], Channel} end), + ?assertMatch({stop, {shutdown,[for_testing]}, _NState}, + emqx_connection:with_channel(handle_in, [for_testing], State)), - ok = meck:expect(emqx_channel, handle_in, fun(_, _) -> Channel = channel(), {shutdown, [for_testing], ?DISCONNECT_PACKET(), Channel} end), - ?assertMatch({stop, {shutdown,[for_testing]}, _NState}, emqx_connection:with_channel(handle_in, [for_testing], State)). + ok = meck:expect(emqx_channel, handle_in, + fun(_, _) -> + Channel = channel(), + {shutdown, [for_testing], ?DISCONNECT_PACKET(), Channel} + end), + ?assertMatch({stop, {shutdown,[for_testing]}, _NState}, + emqx_connection:with_channel(handle_in, [for_testing], State)). t_handle_outgoing(_) -> ?assertEqual(ok, emqx_connection:handle_outgoing(?PACKET(?PINGRESP), st())), ?assertEqual(ok, emqx_connection:handle_outgoing([?PACKET(?PINGRESP)], st())). t_handle_info(_) -> - ?assertMatch({ok, {event,running}, _NState}, emqx_connection:handle_info(activate_socket, st())), - ?assertMatch({stop, {shutdown, for_testing}, _NStats}, emqx_connection:handle_info({sock_error, for_testing}, st())), + ?assertMatch({ok, {event,running}, _NState}, + emqx_connection:handle_info(activate_socket, st())), + ?assertMatch({stop, {shutdown, for_testing}, _NStats}, + emqx_connection:handle_info({sock_error, for_testing}, st())), ?assertMatch({ok, _NState}, emqx_connection:handle_info(for_testing, st())). t_ensure_rate_limit(_) -> State = emqx_connection:ensure_rate_limit(#{}, st(#{limiter => undefined})), ?assertEqual(undefined, emqx_connection:info(limiter, State)), - ok = meck:expect(emqx_limiter, check, fun(_, _) -> {ok, emqx_limiter:init(external, [])} end), + ok = meck:expect(emqx_limiter, check, + fun(_, _) -> {ok, emqx_limiter:init(external, [])} end), State1 = emqx_connection:ensure_rate_limit(#{}, st(#{limiter => #{}})), ?assertEqual(undefined, emqx_connection:info(limiter, State1)), - ok = meck:expect(emqx_limiter, check, fun(_, _) -> {pause, 3000, emqx_limiter:init(external, [])} end), + ok = meck:expect(emqx_limiter, check, + fun(_, _) -> {pause, 3000, emqx_limiter:init(external, [])} end), State2 = emqx_connection:ensure_rate_limit(#{}, st(#{limiter => #{}})), ?assertEqual(undefined, emqx_connection:info(limiter, State2)), ?assertEqual(blocked, emqx_connection:info(sockstate, State2)). @@ -446,3 +474,7 @@ channel(InitFields) -> session => Session, conn_state => connected }, InitFields)). + +handle_msg(Msg, St) -> emqx_connection:handle_msg(Msg, St). + +handle_call(Pid, Call, St) -> emqx_connection:handle_call(Pid, Call, St). diff --git a/test/emqx_tls_lib_tests.erl b/test/emqx_tls_lib_tests.erl new file mode 100644 index 000000000..452909db2 --- /dev/null +++ b/test/emqx_tls_lib_tests.erl @@ -0,0 +1,64 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + +-module(emqx_tls_lib_tests). + +-include_lib("eunit/include/eunit.hrl"). + +%% one of the cipher suite from tlsv1.2 and tlsv1.3 each +-define(TLS_12_CIPHER, "ECDHE-ECDSA-AES256-GCM-SHA384"). +-define(TLS_13_CIPHER, "TLS_AES_256_GCM_SHA384"). + +ensure_tls13_ciphers_added_test() -> + Ciphers = emqx_tls_lib:integral_ciphers(['tlsv1.3'], [?TLS_12_CIPHER]), + ?assert(lists:member(?TLS_12_CIPHER, Ciphers)), + ?assert(lists:member(?TLS_13_CIPHER, Ciphers)). + +legacy_cipher_suites_test() -> + Ciphers = emqx_tls_lib:integral_ciphers(['tlsv1.2'], [?TLS_12_CIPHER]), + ?assertEqual([?TLS_12_CIPHER], Ciphers). + +use_default_ciphers_test() -> + Ciphers = emqx_tls_lib:integral_ciphers(['tlsv1.3', 'tlsv1.2'], ""), + ?assert(lists:member(?TLS_12_CIPHER, Ciphers)), + ?assert(lists:member(?TLS_13_CIPHER, Ciphers)). + +ciphers_format_test_() -> + String = ?TLS_13_CIPHER ++ "," ++ ?TLS_12_CIPHER, + Binary = iolist_to_binary(String), + List = [?TLS_13_CIPHER, ?TLS_12_CIPHER], + [ {"string", fun() -> test_cipher_format(String) end} + , {"binary", fun() -> test_cipher_format(Binary) end} + , {"string-list", fun() -> test_cipher_format(List) end} + ]. + +test_cipher_format(Input) -> + Ciphers = emqx_tls_lib:integral_ciphers(['tlsv1.3', 'tlsv1.2'], Input), + ?assertEqual([?TLS_13_CIPHER, ?TLS_12_CIPHER], Ciphers). + +tls_versions_test() -> + ?assert(lists:member('tlsv1.3', emqx_tls_lib:default_versions())). + +tls_version_unknown_test() -> + ?assertError(#{reason := no_available_tls_version}, + emqx_tls_lib:integral_versions([])), + ?assertError(#{reason := no_available_tls_version}, + emqx_tls_lib:integral_versions([foo])). + +cipher_suites_no_duplication_test() -> + AllCiphers = emqx_tls_lib:default_ciphers(), + ?assertEqual(length(AllCiphers), length(lists:usort(AllCiphers))). + diff --git a/test/mqtt_protocol_v5_SUITE.erl b/test/mqtt_protocol_v5_SUITE.erl index 11fe32507..814162a4a 100644 --- a/test/mqtt_protocol_v5_SUITE.erl +++ b/test/mqtt_protocol_v5_SUITE.erl @@ -111,11 +111,13 @@ t_basic_test(_) -> t_connect_clean_start(_) -> process_flag(trap_exit, true), - {ok, Client1} = emqtt:start_link([{clientid, <<"t_connect_clean_start">>},{proto_ver, v5},{clean_start, true}]), + {ok, Client1} = emqtt:start_link([{clientid, <<"t_connect_clean_start">>}, + {proto_ver, v5},{clean_start, true}]), {ok, _} = emqtt:connect(Client1), ?assertEqual(0, client_info(session_present, Client1)), %% [MQTT-3.1.2-4] ok = emqtt:pause(Client1), - {ok, Client2} = emqtt:start_link([{clientid, <<"t_connect_clean_start">>},{proto_ver, v5},{clean_start, false}]), + {ok, Client2} = emqtt:start_link([{clientid, <<"t_connect_clean_start">>}, + {proto_ver, v5},{clean_start, false}]), {ok, _} = emqtt:connect(Client2), ?assertEqual(1, client_info(session_present, Client2)), %% [MQTT-3.1.2-5] ?assertEqual(142, receive_disconnect_reasoncode()), @@ -124,7 +126,8 @@ t_connect_clean_start(_) -> ok = emqtt:disconnect(Client2), waiting_client_process_exit(Client2), - {ok, Client3} = emqtt:start_link([{clientid, <<"new_client">>},{proto_ver, v5},{clean_start, false}]), + {ok, Client3} = emqtt:start_link([{clientid, <<"new_client">>}, + {proto_ver, v5},{clean_start, false}]), {ok, _} = emqtt:connect(Client3), ?assertEqual(0, client_info(session_present, Client3)), %% [MQTT-3.1.2-6] ok = emqtt:disconnect(Client3), @@ -145,7 +148,8 @@ t_connect_will_message(_) -> ]), {ok, _} = emqtt:connect(Client1), [ClientPid] = emqx_cm:lookup_channels(client_info(clientid, Client1)), - ?assertNotEqual(undefined, maps:find(will_msg, emqx_connection:info(sys:get_state(ClientPid)))), %% [MQTT-3.1.2-7] + Info = emqx_connection:info(sys:get_state(ClientPid)), + ?assertNotEqual(undefined, maps:find(will_msg, Info)), %% [MQTT-3.1.2-7] {ok, Client2} = emqtt:start_link([{proto_ver, v5}]), {ok, _} = emqtt:connect(Client2), @@ -192,7 +196,6 @@ t_batch_subscribe(_) -> <<"t3">>]), application:set_env(emqx, acl_nomatch, allow), emqtt:disconnect(Client). - t_connect_will_retain(_) -> Topic = nth(1, ?TOPICS), @@ -259,9 +262,10 @@ t_connect_limit_timeout(_) -> [ClientPid] = emqx_cm:lookup_channels(client_info(clientid, Client)), ?assertEqual(undefined, emqx_connection:info(limit_timer, sys:get_state(ClientPid))), - ok = emqtt:publish(Client, Topic, <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, 0), - ok = emqtt:publish(Client, Topic, <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, 0), - ok = emqtt:publish(Client, Topic, <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, 0), + Payload = <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, + ok = emqtt:publish(Client, Topic, Payload, 0), + ok = emqtt:publish(Client, Topic, Payload, 0), + ok = emqtt:publish(Client, Topic, Payload, 0), timer:sleep(200), ?assert(is_reference(emqx_connection:info(limit_timer, sys:get_state(ClientPid)))), @@ -520,7 +524,8 @@ t_publish_rap(_) -> {ok, Client1} = emqtt:start_link([{proto_ver, v5}]), {ok, _} = emqtt:connect(Client1), {ok, _, [2]} = emqtt:subscribe(Client1, #{}, [{Topic, [{rap, true}, {qos, 2}]}]), - {ok, _} = emqtt:publish(Client1, Topic, #{}, <<"retained message">>, [{qos, ?QOS_1}, {retain, true}]), + {ok, _} = emqtt:publish(Client1, Topic, #{}, <<"retained message">>, + [{qos, ?QOS_1}, {retain, true}]), [Msg1 | _] = receive_messages(1), ?assertEqual(true, maps:get(retain, Msg1)), %% [MQTT-3.3.1-12] ok = emqtt:disconnect(Client1), @@ -528,7 +533,8 @@ t_publish_rap(_) -> {ok, Client2} = emqtt:start_link([{proto_ver, v5}]), {ok, _} = emqtt:connect(Client2), {ok, _, [2]} = emqtt:subscribe(Client2, #{}, [{Topic, [{rap, false}, {qos, 2}]}]), - {ok, _} = emqtt:publish(Client2, Topic, #{}, <<"retained message">>, [{qos, ?QOS_1}, {retain, true}]), + {ok, _} = emqtt:publish(Client2, Topic, #{}, <<"retained message">>, + [{qos, ?QOS_1}, {retain, true}]), [Msg2 | _] = receive_messages(1), ?assertEqual(false, maps:get(retain, Msg2)), %% [MQTT-3.3.1-13] ok = emqtt:disconnect(Client2), @@ -572,8 +578,10 @@ t_publish_topic_alias(_) -> {ok, Client2} = emqtt:start_link([{proto_ver, v5}]), {ok, _} = emqtt:connect(Client2), {ok, _, [2]} = emqtt:subscribe(Client2, Topic, qos2), - ok = emqtt:publish(Client2, Topic, #{'Topic-Alias' => 233}, <<"Topic-Alias">>, [{qos, ?QOS_0}]), - ok = emqtt:publish(Client2, <<"">>, #{'Topic-Alias' => 233}, <<"Topic-Alias">>, [{qos, ?QOS_0}]), + ok = emqtt:publish(Client2, Topic, #{'Topic-Alias' => 233}, + <<"Topic-Alias">>, [{qos, ?QOS_0}]), + ok = emqtt:publish(Client2, <<"">>, #{'Topic-Alias' => 233}, + <<"Topic-Alias">>, [{qos, ?QOS_0}]), ?assertEqual(2, length(receive_messages(2))), %% [MQTT-3.3.2-12] ok = emqtt:disconnect(Client2), waiting_client_process_exit(Client2), @@ -586,7 +594,8 @@ t_publish_response_topic(_) -> {ok, Client1} = emqtt:start_link([{proto_ver, v5}]), {ok, _} = emqtt:connect(Client1), - ok = emqtt:publish(Client1, Topic, #{'Response-Topic' => nth(1, ?WILD_TOPICS)}, <<"Response-Topic">>, [{qos, ?QOS_0}]), + ok = emqtt:publish(Client1, Topic, #{'Response-Topic' => nth(1, ?WILD_TOPICS)}, + <<"Response-Topic">>, [{qos, ?QOS_0}]), ?assertEqual(130, receive_disconnect_reasoncode()), %% [MQTT-3.3.2-14] waiting_client_process_exit(Client1), @@ -617,7 +626,8 @@ t_publish_overlapping_subscriptions(_) -> {ok, _} = emqtt:connect(Client1), {ok, _, [1]} = emqtt:subscribe(Client1, Properties, nth(1, ?WILD_TOPICS), qos1), {ok, _, [0]} = emqtt:subscribe(Client1, Properties, nth(3, ?WILD_TOPICS), qos0), - {ok, _} = emqtt:publish(Client1, Topic, #{}, <<"t_publish_overlapping_subscriptions">>, [{qos, ?QOS_2}]), + {ok, _} = emqtt:publish(Client1, Topic, #{}, + <<"t_publish_overlapping_subscriptions">>, [{qos, ?QOS_2}]), [Msg1 | _ ] = receive_messages(2), ?assert( maps:get(qos, Msg1) < 2 ), %% [MQTT-3.3.4-2] @@ -681,8 +691,9 @@ t_subscribe_actions(_) -> {ok, _} = emqtt:publish(Client1, Topic, <<"t_subscribe_actions">>, 2), [Msg1 | _ ] = receive_messages(1), ?assertEqual(1, maps:get(qos, Msg1)), %% [MQTT-3.8.4-3] [MQTT-3.8.4-8] - - {ok, _, [2,2]} = emqtt:subscribe(Client1, [{nth(1, ?TOPICS), qos2}, {nth(2, ?TOPICS), qos2}] ), %% [MQTT-3.8.4-5] [MQTT-3.8.4-6] [MQTT-3.8.4-7] + %% [MQTT-3.8.4-5] [MQTT-3.8.4-6] [MQTT-3.8.4-7] + {ok, _, [2,2]} = emqtt:subscribe(Client1, [{nth(1, ?TOPICS), qos2}, + {nth(2, ?TOPICS), qos2}] ), ok = emqtt:disconnect(Client1). %%-------------------------------------------------------------------- %% Unsubsctibe Unsuback @@ -699,7 +710,8 @@ t_unscbsctibe(_) -> {ok, _, [17]} = emqtt:unsubscribe(Client1, <<"noExistTopic">>), %% [MQTT-3.10.4-5] {ok, _, [2, 2]} = emqtt:subscribe(Client1, [{Topic1, qos2}, {Topic2, qos2}]), - {ok, _, [0, 0, 17]} = emqtt:unsubscribe(Client1, [Topic1, Topic2, <<"noExistTopic">>]), %% [[MQTT-3.10.4-6]] [MQTT-3.11.3-1] [MQTT-3.11.3-2] + %% [[MQTT-3.10.4-6]] [MQTT-3.11.3-1] [MQTT-3.11.3-2] + {ok, _, [0, 0, 17]} = emqtt:unsubscribe(Client1, [Topic1, Topic2, <<"noExistTopic">>]), ok = emqtt:disconnect(Client1). %%-------------------------------------------------------------------- @@ -745,7 +757,8 @@ t_shared_subscriptions_client_terminates_when_qos_eq_2(_) -> {ok, Pub} = emqtt:start_link([{proto_ver, v5}, {clientid, <<"pub_client">>}]), {ok, _} = emqtt:connect(Pub), - {ok, _} = emqtt:publish(Pub, Topic, <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, 2), + {ok, _} = emqtt:publish(Pub, Topic, + <<"t_shared_subscriptions_client_terminates_when_qos_eq_2">>, 2), receive {'EXIT', _,{shutdown, for_testiong}} ->