From 1f50229dfffa73982244ccfb35a69a07fde10aaa Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 28 Aug 2017 12:19:09 +0800 Subject: [PATCH 01/46] Call 'make deps' before 'rebar get-deps' --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 15834e620..f9502f766 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,9 @@ otp_release: - 19.1 - 19.2 +before_script: + - make deps + script: - make From b5f741391ba249bd08bfdfd077af79fc92731408 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 28 Aug 2017 15:01:50 +0800 Subject: [PATCH 02/46] Add 'make autopatch' to fix the building error of travis CI --- .travis.yml | 6 ++---- Makefile | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index f9502f766..cee696a6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,10 @@ language: erlang otp_release: - - 19.0 - - 19.1 - - 19.2 + - 20.0 before_script: - - make deps + - make autopatch script: - make diff --git a/Makefile b/Makefile index 3ea8fff3d..a0e321df9 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 dep_lager_syslog = git https://github.com/basho/lager_syslog dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master dep_clique = git https://github.com/emqtt/clique -dep_jsx = git https://github.com/talentdeficit/jsx +dep_jsx = git https://github.com/talentdeficit/jsx ERLC_OPTS += +debug_info ERLC_OPTS += +'{parse_transform, lager_transform}' @@ -49,6 +49,9 @@ DIALYZER_OPTS := --verbose --statistics -Werror_handling \ include erlang.mk +autopatch:: + $(call dep_autopatch,goldrush) + app:: rebar.config app.config:: From e1816a5682eec7376e78698ac29579b1927e4b0d Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 28 Aug 2017 17:31:38 +0800 Subject: [PATCH 03/46] Remove rebar.config to fix the building error of CI --- .gitignore | 1 + .travis.yml | 5 +---- Makefile | 3 --- rebar.config | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0aa159fd7..f8f1af339 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ _build .rebar3 rebar3.crashdump .DS_Store +rebar.config diff --git a/.travis.yml b/.travis.yml index cee696a6d..8d4f7acc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,7 @@ language: erlang otp_release: - 20.0 -before_script: - - make autopatch - -script: +script: - make sudo: false diff --git a/Makefile b/Makefile index a0e321df9..2826d547d 100644 --- a/Makefile +++ b/Makefile @@ -49,9 +49,6 @@ DIALYZER_OPTS := --verbose --statistics -Werror_handling \ include erlang.mk -autopatch:: - $(call dep_autopatch,goldrush) - app:: rebar.config app.config:: diff --git a/rebar.config b/rebar.config index 834382f05..8af38d819 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,4 @@ {deps, [ -{goldrush,".*",{git,"https://github.com/basho/goldrush","0.1.9"}},{gproc,".*",{git,"https://github.com/uwiger/gproc",""}},{lager,".*",{git,"https://github.com/basho/lager","master"}},{esockd,".*",{git,"https://github.com/emqtt/esockd","master"}},{ekka,".*",{git,"https://github.com/emqtt/ekka","develop"}},{mochiweb,".*",{git,"https://github.com/emqtt/mochiweb","master"}},{pbkdf2,".*",{git,"https://github.com/emqtt/pbkdf2","2.0.1"}},{lager_syslog,".*",{git,"https://github.com/basho/lager_syslog",""}},{bcrypt,".*",{git,"https://github.com/smarkets/erlang-bcrypt","master"}} +{goldrush,".*",{git,"https://github.com/basho/goldrush","0.1.9"}},{gproc,".*",{git,"https://github.com/uwiger/gproc",""}},{lager,".*",{git,"https://github.com/basho/lager","master"}},{esockd,".*",{git,"https://github.com/emqtt/esockd","master"}},{ekka,".*",{git,"https://github.com/emqtt/ekka","master"}},{mochiweb,".*",{git,"https://github.com/emqtt/mochiweb","master"}},{pbkdf2,".*",{git,"https://github.com/emqtt/pbkdf2","2.0.1"}},{lager_syslog,".*",{git,"https://github.com/basho/lager_syslog",""}},{bcrypt,".*",{git,"https://github.com/smarkets/erlang-bcrypt","master"}},{clique,".*",{git,"https://github.com/emqtt/clique",""}},{jsx,".*",{git,"https://github.com/talentdeficit/jsx",""}} ]}. {erl_opts, [debug_info,{parse_transform,lager_transform}]}. From 68efc71093ac7d9de2be57433de044b7db2ca9b0 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 28 Aug 2017 17:32:04 +0800 Subject: [PATCH 04/46] Remove rebar.config to fix the building error of CI --- rebar.config | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 rebar.config diff --git a/rebar.config b/rebar.config deleted file mode 100644 index 8af38d819..000000000 --- a/rebar.config +++ /dev/null @@ -1,4 +0,0 @@ -{deps, [ -{goldrush,".*",{git,"https://github.com/basho/goldrush","0.1.9"}},{gproc,".*",{git,"https://github.com/uwiger/gproc",""}},{lager,".*",{git,"https://github.com/basho/lager","master"}},{esockd,".*",{git,"https://github.com/emqtt/esockd","master"}},{ekka,".*",{git,"https://github.com/emqtt/ekka","master"}},{mochiweb,".*",{git,"https://github.com/emqtt/mochiweb","master"}},{pbkdf2,".*",{git,"https://github.com/emqtt/pbkdf2","2.0.1"}},{lager_syslog,".*",{git,"https://github.com/basho/lager_syslog",""}},{bcrypt,".*",{git,"https://github.com/smarkets/erlang-bcrypt","master"}},{clique,".*",{git,"https://github.com/emqtt/clique",""}},{jsx,".*",{git,"https://github.com/talentdeficit/jsx",""}} -]}. -{erl_opts, [debug_info,{parse_transform,lager_transform}]}. From b8e0a4d5c4df3c08f7b0ef6ef320abae79eed46e Mon Sep 17 00:00:00 2001 From: HuangDan Date: Sun, 3 Dec 2017 00:16:26 +0800 Subject: [PATCH 05/46] Bump version to 2.3.1 --- Makefile | 2 +- src/emqttd.app.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index de2827e23..a1d77b1a3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PROJECT = emqttd PROJECT_DESCRIPTION = Erlang MQTT Broker -PROJECT_VERSION = 2.3.0 +PROJECT_VERSION = 2.3.1 DEPS = goldrush gproc lager esockd ekka mochiweb pbkdf2 lager_syslog bcrypt clique jsx diff --git a/src/emqttd.app.src b/src/emqttd.app.src index 269601bb8..67af8854e 100644 --- a/src/emqttd.app.src +++ b/src/emqttd.app.src @@ -1,6 +1,6 @@ {application,emqttd, [{description,"Erlang MQTT Broker"}, - {vsn,"2.3.0"}, + {vsn,"2.3.1"}, {modules,[]}, {registered,[emqttd_sup]}, {applications,[kernel,stdlib,gproc,lager,esockd,mochiweb, From 8e41aeeeb8242d630fa699906b0208ed84938cec Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 5 Dec 2017 19:47:17 +0800 Subject: [PATCH 06/46] Add send_timeout, send_timeout_close options --- etc/emq.conf | 36 +++++++++++++++++++++++++++++++ priv/emq.schema | 56 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 9b37860b9..d6dacc8fb 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -343,6 +343,10 @@ listener.tcp.external.access.2 = allow all ## TCP Socket Options listener.tcp.external.backlog = 1024 +listener.tcp.external.send_timeout = 15s + +listener.tcp.external.send_timeout_close = on + #listener.tcp.external.recbuf = 4KB #listener.tcp.external.sndbuf = 4KB @@ -371,6 +375,10 @@ listener.tcp.internal.max_clients = 102400 ## TCP Socket Options listener.tcp.internal.backlog = 512 +listener.tcp.internal.send_timeout = 15s + +listener.tcp.external.send_timeout_close = on + listener.tcp.internal.tune_buffer = on listener.tcp.internal.buffer = 1MB @@ -477,6 +485,10 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## SSL Socket Options ## listener.ssl.external.backlog = 1024 +## listener.ssl.external.send_timeout = 15s + +## listener.ssl.external.send_timeout_close = on + ## listener.ssl.external.recbuf = 4KB ## listener.ssl.external.sndbuf = 4KB @@ -499,6 +511,10 @@ listener.ws.external.access.1 = allow all ## TCP Options listener.ws.external.backlog = 1024 +listener.ws.external.send_timeout = 15s + +listener.ws.external.send_timeout_close = on + listener.ws.external.recbuf = 4KB listener.ws.external.sndbuf = 4KB @@ -531,6 +547,20 @@ listener.wss.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## listener.wss.external.fail_if_no_peer_cert = true +listener.wss.external.backlog = 1024 + +listener.wss.external.send_timeout = 15s + +listener.wss.external.send_timeout_close = on + +## listener.wss.external.recbuf = 4KB + +## listener.wss.external.sndbuf = 4KB + +## listener.wss.external.buffer = 4KB + +## listener.wss.external.nodelay = true + ##-------------------------------------------------------------------- ## HTTP Management API Listener @@ -542,6 +572,12 @@ listener.api.mgmt.max_clients = 64 listener.api.mgmt.access.1 = allow all +listener.api.mgmt.backlog = 512 + +listener.api.mgmt.send_timeout = 15s + +listener.api.mgmt.send_timeout_close = on + ##------------------------------------------------------------------- ## System Monitor ##------------------------------------------------------------------- diff --git a/priv/emq.schema b/priv/emq.schema index d05cc79cf..e8746582b 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -805,8 +805,18 @@ end}. ]}. {mapping, "listener.tcp.$name.backlog", "emqttd.listeners", [ - {default, 1024}, - {datatype, integer} + {datatype, integer}, + {default, 1024} +]}. + +{mapping, "listener.tcp.$name.send_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}}, + {default, "15s"} +]}. + +{mapping, "listener.tcp.$name.send_timeout_close", "emqttd.listeners", [ + {datatype, flag}, + {default, on} ]}. {mapping, "listener.tcp.$name.recbuf", "emqttd.listeners", [ @@ -883,6 +893,16 @@ end}. {datatype, integer} ]}. +{mapping, "listener.ssl.$name.send_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}}, + {default, "15s"} +]}. + +{mapping, "listener.ssl.$name.send_timeout_close", "emqttd.listeners", [ + {datatype, flag}, + {default, on} +]}. + {mapping, "listener.ssl.$name.recbuf", "emqttd.listeners", [ {datatype, bytesize}, hidden @@ -996,6 +1016,16 @@ end}. {datatype, integer} ]}. +{mapping, "listener.ws.$name.send_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}}, + {default, "15s"} +]}. + +{mapping, "listener.ws.$name.send_timeout_close", "emqttd.listeners", [ + {datatype, flag}, + {default, on} +]}. + {mapping, "listener.ws.$name.recbuf", "emqttd.listeners", [ {datatype, bytesize}, hidden @@ -1059,6 +1089,16 @@ end}. {datatype, integer} ]}. +{mapping, "listener.wss.$name.send_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}}, + {default, "15s"} +]}. + +{mapping, "listener.wss.$name.send_timeout_close", "emqttd.listeners", [ + {datatype, flag}, + {default, on} +]}. + {mapping, "listener.wss.$name.recbuf", "emqttd.listeners", [ {datatype, bytesize}, hidden @@ -1145,6 +1185,8 @@ end}. 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)}, @@ -1252,6 +1294,16 @@ end}. {datatype, integer} ]}. +{mapping, "listener.api.$name.send_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}}, + {default, "15s"} +]}. + +{mapping, "listener.api.$name.send_timeout_close", "emqttd.listeners", [ + {datatype, flag}, + {default, on} +]}. + {mapping, "listener.api.$name.recbuf", "emqttd.listeners", [ {datatype, bytesize}, hidden From 51533dbe9eedf79e4a492a74fadc3e3e394fb8a4 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 5 Dec 2017 23:41:40 +0800 Subject: [PATCH 07/46] Shutdown the connection if an error occurred when sending data --- src/emqttd_client.erl | 3 ++- src/emqttd_protocol.erl | 6 ++---- src/emqttd_ws.erl | 1 + src/emqttd_ws_client.erl | 6 +++++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/emqttd_client.erl b/src/emqttd_client.erl index 6631b4566..63bac7c8d 100644 --- a/src/emqttd_client.erl +++ b/src/emqttd_client.erl @@ -140,7 +140,8 @@ send_fun(Conn, Peername) -> ?LOG(debug, "SEND ~p", [Data], #client_state{peername = Peername}), emqttd_metrics:inc('bytes/sent', iolist_size(Data)), try Conn:async_send(Data) of - true -> ok + ok -> ok; + {error, Reason} -> Self ! {shutdown, Reason} catch error:Error -> Self ! {shutdown, Error} end diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index 384f93225..c35e8ae50 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -341,13 +341,11 @@ send(Msg, State = #proto_state{client_id = ClientId, emqttd_hooks:run('message.delivered', [ClientId, Username], Msg), send(emqttd_message:to_packet(unmount(MountPoint, clean_retain(IsBridge, Msg))), State); -send(Packet = ?PACKET(Type), - State = #proto_state{sendfun = SendFun, stats_data = Stats}) -> +send(Packet = ?PACKET(Type), State = #proto_state{sendfun = SendFun, stats_data = Stats}) -> trace(send, Packet, State), emqttd_metrics:sent(Packet), SendFun(Packet), - Stats1 = inc_stats(send, Type, Stats), - {ok, State#proto_state{stats_data = Stats1}}. + {ok, State#proto_state{stats_data = inc_stats(send, Type, Stats)}}. trace(recv, Packet, ProtoState) -> ?LOG(debug, "RECV ~s", [emqttd_packet:format(Packet)], ProtoState); diff --git a/src/emqttd_ws.erl b/src/emqttd_ws.erl index c7d0b2119..35a7f9852 100644 --- a/src/emqttd_ws.erl +++ b/src/emqttd_ws.erl @@ -38,6 +38,7 @@ handle_request(Req) -> %%-------------------------------------------------------------------- %% MQTT Over WebSocket %%-------------------------------------------------------------------- + handle_request('GET', "/mqtt", Req) -> lager:debug("WebSocket Connection from: ~s", [Req:get(peer)]), Upgrade = Req:get_header_value("Upgrade"), diff --git a/src/emqttd_ws_client.erl b/src/emqttd_ws_client.erl index b9d25ad3e..206f461bb 100644 --- a/src/emqttd_ws_client.erl +++ b/src/emqttd_ws_client.erl @@ -272,10 +272,14 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- send_fun(ReplyChannel) -> + Self = self(), fun(Packet) -> Data = emqttd_serializer:serialize(Packet), emqttd_metrics:inc('bytes/sent', iolist_size(Data)), - ReplyChannel({binary, Data}) + case ReplyChannel({binary, Data}) of + ok -> ok; + {error, Reason} -> Self ! {shutdown, Reason} + end end. stat_fun(Conn) -> From c3c55894520d121388c08e8f5546eccc6c471a8b Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 6 Dec 2017 10:01:42 +0800 Subject: [PATCH 08/46] Version 2.3.2 --- Makefile | 2 +- src/emqttd.app.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a1d77b1a3..c42a4a345 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PROJECT = emqttd PROJECT_DESCRIPTION = Erlang MQTT Broker -PROJECT_VERSION = 2.3.1 +PROJECT_VERSION = 2.3.2 DEPS = goldrush gproc lager esockd ekka mochiweb pbkdf2 lager_syslog bcrypt clique jsx diff --git a/src/emqttd.app.src b/src/emqttd.app.src index 67af8854e..e321b73f1 100644 --- a/src/emqttd.app.src +++ b/src/emqttd.app.src @@ -1,6 +1,6 @@ {application,emqttd, [{description,"Erlang MQTT Broker"}, - {vsn,"2.3.1"}, + {vsn,"2.3.2"}, {modules,[]}, {registered,[emqttd_sup]}, {applications,[kernel,stdlib,gproc,lager,esockd,mochiweb, From 9f1c3a589999794bc5f43f336e1a62a2647b88a4 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 6 Dec 2017 14:42:26 +0800 Subject: [PATCH 09/46] Compatible with esockd 4.x --- src/emqttd_client.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/emqttd_client.erl b/src/emqttd_client.erl index 63bac7c8d..5ca450bf5 100644 --- a/src/emqttd_client.erl +++ b/src/emqttd_client.erl @@ -141,6 +141,7 @@ send_fun(Conn, Peername) -> emqttd_metrics:inc('bytes/sent', iolist_size(Data)), try Conn:async_send(Data) of ok -> ok; + true -> ok; %% Compatible with esockd 4.x {error, Reason} -> Self ! {shutdown, Reason} catch error:Error -> Self ! {shutdown, Error} From 4c52d997062920dc1edddc61af65c0ac3faa27aa Mon Sep 17 00:00:00 2001 From: HuangDan Date: Wed, 6 Dec 2017 15:47:46 +0800 Subject: [PATCH 10/46] Fixed test cases for emqttd_router_SUITE --- Makefile | 2 +- test/emqttd_SUITE.erl | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c42a4a345..d529cdbc5 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ dep_cuttlefish = git https://github.com/emqtt/cuttlefish TEST_DEPS = emqttc emq_dashboard dep_emqttc = git https://github.com/emqtt/emqttc -dep_emq_dashboard = git https://github.com/emqtt/emq_dashboard +dep_emq_dashboard = git https://github.com/emqtt/emq_dashboard develop TEST_ERLC_OPTS += +debug_info TEST_ERLC_OPTS += +'{parse_transform, lager_transform}' diff --git a/test/emqttd_SUITE.erl b/test/emqttd_SUITE.erl index fe48fb402..76a8e7614 100644 --- a/test/emqttd_SUITE.erl +++ b/test/emqttd_SUITE.erl @@ -328,7 +328,10 @@ router_print(_) -> #mqtt_route{topic = <<"#">>, node = node()}, #mqtt_route{topic = <<"+/#">>, node = node()}], lists:foreach(fun(R) -> emqttd_router:add_route(R) end, Routes), - emqttd_router:print(<<"a/b/c">>). + emqttd_router:print(<<"a/b/c">>), + emqttd_router:del_route(<<"+/#">>), + emqttd_router:del_route(<<"a/b/c">>), + emqttd_router:del_route(<<"#">>). router_unused(_) -> gen_server:call(emqttd_router, bad_call), @@ -598,6 +601,7 @@ conflict_listeners(_) -> L = proplists:get_value("mqtt:tcp:0.0.0.0:1883", Listeners), ?assertEqual(1, proplists:get_value(current_clients, L)), ?assertEqual(1, proplists:get_value(conflict, proplists:get_value(shutdown_count, L))), + timer:sleep(100), emqttc:disconnect(C2). cli_vm(_) -> From 0ba8d3e11db5dccdaca47a32ab6b8ba5cc0dcee9 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 6 Dec 2017 20:13:27 +0800 Subject: [PATCH 11/46] Depends on develop branch of esockd and mochiweb --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d529cdbc5..1c919bb1e 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,9 @@ dep_goldrush = git https://github.com/basho/goldrush 0.1.9 dep_gproc = git https://github.com/uwiger/gproc dep_getopt = git https://github.com/jcomellas/getopt v0.8.2 dep_lager = git https://github.com/basho/lager master -dep_esockd = git https://github.com/emqtt/esockd master +dep_esockd = git https://github.com/emqtt/esockd develop dep_ekka = git https://github.com/emqtt/ekka master -dep_mochiweb = git https://github.com/emqtt/mochiweb master +dep_mochiweb = git https://github.com/emqtt/mochiweb develop dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 dep_lager_syslog = git https://github.com/basho/lager_syslog dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master From 896088b7e8d41524e8580354262156b6a0863444 Mon Sep 17 00:00:00 2001 From: HuangDan Date: Wed, 6 Dec 2017 21:09:03 +0800 Subject: [PATCH 12/46] Router test cases migration from emqttd_SUITE to emqttd_route_SUITE --- test/emqttd_SUITE.erl | 52 ---------------------------------- test/emqttd_router_SUITE.erl | 54 ++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 58 deletions(-) diff --git a/test/emqttd_SUITE.erl b/test/emqttd_SUITE.erl index 76a8e7614..c5794e5b0 100644 --- a/test/emqttd_SUITE.erl +++ b/test/emqttd_SUITE.erl @@ -58,7 +58,6 @@ all() -> [{group, protocol}, {group, pubsub}, - {group, router}, {group, session}, {group, broker}, {group, metrics}, @@ -81,10 +80,6 @@ groups() -> t_local_subscribe, t_shared_subscribe, 'pubsub#', 'pubsub+']}, - {router, [sequence], - [router_add_del, - router_print, - router_unused]}, {session, [sequence], [start_session]}, {broker, [sequence], @@ -291,53 +286,6 @@ loop_recv(Topic, Timeout, Acc) -> Timeout -> {ok, Acc} end. -%%-------------------------------------------------------------------- -%% Router Test -%%-------------------------------------------------------------------- - -router_add_del(_) -> - %% Add - emqttd_router:add_route(<<"#">>), - emqttd_router:add_route(<<"a/b/c">>), - emqttd_router:add_route(<<"+/#">>), - Routes = [R1, R2 | _] = [ - #mqtt_route{topic = <<"#">>, node = node()}, - #mqtt_route{topic = <<"+/#">>, node = node()}, - #mqtt_route{topic = <<"a/b/c">>, node = node()}], - Routes = lists:sort(emqttd_router:match(<<"a/b/c">>)), - - %% Batch Add - lists:foreach(fun(R) -> emqttd_router:add_route(R) end, Routes), - Routes = lists:sort(emqttd_router:match(<<"a/b/c">>)), - - %% Del - emqttd_router:del_route(<<"a/b/c">>), - [R1, R2] = lists:sort(emqttd_router:match(<<"a/b/c">>)), - {atomic, []} = mnesia:transaction(fun emqttd_trie:lookup/1, [<<"a/b/c">>]), - - %% Batch Del - R3 = #mqtt_route{topic = <<"#">>, node = 'a@127.0.0.1'}, - emqttd_router:add_route(R3), - emqttd_router:del_route(R1), - emqttd_router:del_route(R2), - emqttd_router:del_route(R3), - [] = lists:sort(emqttd_router:match(<<"a/b/c">>)). - -router_print(_) -> - Routes = [#mqtt_route{topic = <<"a/b/c">>, node = node()}, - #mqtt_route{topic = <<"#">>, node = node()}, - #mqtt_route{topic = <<"+/#">>, node = node()}], - lists:foreach(fun(R) -> emqttd_router:add_route(R) end, Routes), - emqttd_router:print(<<"a/b/c">>), - emqttd_router:del_route(<<"+/#">>), - emqttd_router:del_route(<<"a/b/c">>), - emqttd_router:del_route(<<"#">>). - -router_unused(_) -> - gen_server:call(emqttd_router, bad_call), - gen_server:cast(emqttd_router, bad_msg), - emqttd_router ! bad_info. - recv_loop(Msgs) -> receive {dispatch, _Topic, Msg} -> diff --git a/test/emqttd_router_SUITE.erl b/test/emqttd_router_SUITE.erl index addd36288..415550ec3 100644 --- a/test/emqttd_router_SUITE.erl +++ b/test/emqttd_router_SUITE.erl @@ -34,7 +34,8 @@ groups() -> t_add_del_route, t_match_route, t_print, - t_has_route]}, + t_has_route, + router_unused]}, {local_route, [sequence], [t_get_local_topics, t_add_del_local_route, @@ -86,11 +87,6 @@ t_match_route(_) -> #mqtt_route{topic = <<"a/b/c">>, node = Node}], lists:sort(?R:match(<<"a/b/c">>))). -t_print(_) -> - ?R:add_route(<<"topic">>), - ?R:add_route(<<"topic/#">>), - ?R:print(<<"topic">>). - t_has_route(_) -> ?R:add_route(<<"devices/+/messages">>), ?assert(?R:has_route(<<"devices/+/messages">>)). @@ -130,3 +126,49 @@ clear_tables() -> ?R:clean_local_routes(), lists:foreach(fun mnesia:clear_table/1, [mqtt_route, mqtt_trie, mqtt_trie_node]). +%%-------------------------------------------------------------------- +%% Router Test +%%-------------------------------------------------------------------- + +router_add_del(_) -> + %% Add + ?R:add_route(<<"#">>), + ?R:add_route(<<"a/b/c">>), + ?R:add_route(<<"+/#">>), + Routes = [R1, R2 | _] = [ + #mqtt_route{topic = <<"#">>, node = node()}, + #mqtt_route{topic = <<"+/#">>, node = node()}, + #mqtt_route{topic = <<"a/b/c">>, node = node()}], + Routes = lists:sort(?R:match(<<"a/b/c">>)), + + %% Batch Add + lists:foreach(fun(R) -> ?R:add_route(R) end, Routes), + Routes = lists:sort(?R:match(<<"a/b/c">>)), + + %% Del + ?R:del_route(<<"a/b/c">>), + [R1, R2] = lists:sort(?R:match(<<"a/b/c">>)), + {atomic, []} = mnesia:transaction(fun emqttd_trie:lookup/1, [<<"a/b/c">>]), + + %% Batch Del + R3 = #mqtt_route{topic = <<"#">>, node = 'a@127.0.0.1'}, + ?R:add_route(R3), + ?R:del_route(R1), + ?R:del_route(R2), + ?R:del_route(R3), + [] = lists:sort(?R:match(<<"a/b/c">>)). + +t_print(_) -> + Routes = [#mqtt_route{topic = <<"a/b/c">>, node = node()}, + #mqtt_route{topic = <<"#">>, node = node()}, + #mqtt_route{topic = <<"+/#">>, node = node()}], + lists:foreach(fun(R) -> ?R:add_route(R) end, Routes), + ?R:print(<<"a/b/c">>), + ?R:del_route(<<"+/#">>), + ?R:del_route(<<"a/b/c">>), + ?R:del_route(<<"#">>). + +router_unused(_) -> + gen_server:call(emqttd_router, bad_call), + gen_server:cast(emqttd_router, bad_msg), + emqttd_router ! bad_info. From ceafaad6b7c0a4269359e3f8fd046784656f6da7 Mon Sep 17 00:00:00 2001 From: HuangDan Date: Wed, 6 Dec 2017 21:22:36 +0800 Subject: [PATCH 13/46] Update deps branch --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f3407dd9e..55dfd711e 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,9 @@ dep_goldrush = git https://github.com/basho/goldrush 0.1.9 dep_gproc = git https://github.com/uwiger/gproc dep_getopt = git https://github.com/jcomellas/getopt v0.8.2 dep_lager = git https://github.com/basho/lager master -dep_esockd = git https://github.com/emqtt/esockd develop +dep_esockd = git https://github.com/emqtt/esockd v5.1 dep_ekka = git https://github.com/emqtt/ekka master -dep_mochiweb = git https://github.com/emqtt/mochiweb develop +dep_mochiweb = git https://github.com/emqtt/mochiweb v4.2.0 dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 dep_lager_syslog = git https://github.com/basho/lager_syslog dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master From 73836939c80ffe4aa8fdccb62b2beed2b9fe8672 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 7 Dec 2017 17:42:32 +0800 Subject: [PATCH 14/46] Support for TLS with client certificate based authentication --- LICENSE-MPL-RabbitMQ | 455 ++++++++++++++++++++++++++++++++++++++++ src/emqttd_protocol.erl | 44 +++- src/emqttd_ssl.erl | 259 +++++++++++++++++++++++ 3 files changed, 747 insertions(+), 11 deletions(-) create mode 100644 LICENSE-MPL-RabbitMQ create mode 100644 src/emqttd_ssl.erl diff --git a/LICENSE-MPL-RabbitMQ b/LICENSE-MPL-RabbitMQ new file mode 100644 index 000000000..f1ba9a5ca --- /dev/null +++ b/LICENSE-MPL-RabbitMQ @@ -0,0 +1,455 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (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.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is RabbitMQ. + + The Initial Developer of the Original Code is Pivotal Software, Inc. + Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.'' + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index c35e8ae50..4505b73c6 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -44,12 +44,13 @@ clean_sess, proto_ver, proto_name, username, is_superuser, will_msg, keepalive, keepalive_backoff, max_clientid_len, session, stats_data, mountpoint, ws_initial_headers, - is_bridge, connected_at}). + peercert_username, is_bridge, connected_at}). -type(proto_state() :: #proto_state{}). -define(INFO_KEYS, [client_id, username, clean_sess, proto_ver, proto_name, - keepalive, will_msg, ws_initial_headers, mountpoint, connected_at]). + keepalive, will_msg, ws_initial_headers, mountpoint, + peercert_username, connected_at]). -define(STATS_KEYS, [recv_pkt, recv_msg, send_pkt, send_msg]). @@ -68,6 +69,7 @@ init(Peername, SendFun, Opts) -> max_clientid_len = MaxLen, is_superuser = false, client_pid = self(), + peercert_username = false, ws_initial_headers = WsInitialHeaders, keepalive_backoff = Backoff, stats_data = #proto_stats{enable_stats = EnableStats}}. @@ -79,9 +81,28 @@ enrich_opt([], _Conn, State) -> State; enrich_opt([{mountpoint, MountPoint} | ConnOpts], Conn, State) -> enrich_opt(ConnOpts, Conn, State#proto_state{mountpoint = MountPoint}); +enrich_opt([{peer_cert_as_username, N} | ConnOpts], Conn, State) -> + case Conn:type() of + ssl -> enrich_opt(ConnOpts, Conn, State#proto_state{ + peercert_username = peercert_username(N, Conn:peercert())}); + _ -> enrich_opt(ConnOpts, Conn, State) + end; enrich_opt([_ | ConnOpts], Conn, State) -> enrich_opt(ConnOpts, Conn, State). +peercert_username(cn, Cert) -> + case emqttd_ssl:peer_cert_common_name(Cert) of + not_found -> undefined; + CN -> iolist_to_binary(CN) + end; +peercert_username(dn, Cert) -> + iolist_to_binary(emqttd_ssl:peer_cert_subject(Cert)). + +repl_username_with_peercert(State = #proto_state{peercert_username = false}) -> + State; +repl_username_with_peercert(State = #proto_state{peercert_username = PeerCert}) -> + State#proto_state{username = PeerCert}. + info(ProtoState) -> ?record_to_proplist(proto_state, ProtoState, ?INFO_KEYS). @@ -183,15 +204,16 @@ process(?CONNECT_PACKET(Var), State0) -> client_id = ClientId, is_bridge = IsBridge} = Var, - State1 = State0#proto_state{proto_ver = ProtoVer, - proto_name = ProtoName, - username = Username, - client_id = ClientId, - clean_sess = CleanSess, - keepalive = KeepAlive, - will_msg = willmsg(Var, State0), - is_bridge = IsBridge, - connected_at = os:timestamp()}, + State1 = repl_username_with_peercert( + State0#proto_state{proto_ver = ProtoVer, + proto_name = ProtoName, + username = Username, + client_id = ClientId, + clean_sess = CleanSess, + keepalive = KeepAlive, + will_msg = willmsg(Var, State0), + is_bridge = IsBridge, + connected_at = os:timestamp()}), {ReturnCode1, SessPresent, State3} = case validate_connect(Var, State1) of diff --git a/src/emqttd_ssl.erl b/src/emqttd_ssl.erl new file mode 100644 index 000000000..c4126e820 --- /dev/null +++ b/src/emqttd_ssl.erl @@ -0,0 +1,259 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% +%% 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. +%%-------------------------------------------------------------------- +%% +%% @doc SSL Utility Functions. This module is copied from rabbit_ssl.erl +%% + +-module(emqttd_ssl). + +-include_lib("public_key/include/public_key.hrl"). + +-type(certificate() :: binary()). + +-export([peer_cert_issuer/1, peer_cert_subject/1, peer_cert_common_name/1, + peer_cert_subject_items/2, peer_cert_validity/1]). + +%% Return a string describing the certificate's issuer. +-spec(peer_cert_issuer(certificate()) -> string()). +peer_cert_issuer(Cert) -> + cert_info(fun(#'OTPCertificate' { + tbsCertificate = #'OTPTBSCertificate' { + issuer = Issuer }}) -> + format_rdn_sequence(Issuer) + end, Cert). + +%% Return a string describing the certificate's subject, as per RFC4514. +-spec(peer_cert_subject(certificate()) -> string()). +peer_cert_subject(Cert) -> + cert_info(fun(#'OTPCertificate' { + tbsCertificate = #'OTPTBSCertificate' { + subject = Subject }}) -> + format_rdn_sequence(Subject) + end, Cert). + +-spec(peer_cert_common_name(certificate()) -> string() | 'not_found'). +peer_cert_common_name(Cert) -> + case peer_cert_subject_items(Cert, ?'id-at-commonName') of + not_found -> not_found; + CNs -> string:join(CNs, ",") + end. + +%% Return the parts of the certificate's subject. +-spec(peer_cert_subject_items(certificate(), tuple()) -> [string()] | 'undefined'). +peer_cert_subject_items(Cert, Type) -> + cert_info(fun(#'OTPCertificate' { + tbsCertificate = #'OTPTBSCertificate' { + subject = Subject }}) -> + find_by_type(Type, Subject) + end, Cert). + +%% Return a string describing the certificate's validity. +-spec(peer_cert_validity(certificate()) -> string()). +peer_cert_validity(Cert) -> + cert_info(fun(#'OTPCertificate' { + tbsCertificate = #'OTPTBSCertificate' { + validity = {'Validity', Start, End} }}) -> + format("~s - ~s", [format_asn1_value(Start), + format_asn1_value(End)]) + end, Cert). + +cert_info(F, {ok, Cert}) -> + F(case public_key:pkix_decode_cert(Cert, otp) of + {ok, DecCert} -> DecCert; %%pre R14B + DecCert -> DecCert %%R14B onwards + end). + +find_by_type(Type, {rdnSequence, RDNs}) -> + case [V || #'AttributeTypeAndValue'{type = T, value = V} + <- lists:flatten(RDNs), + T == Type] of + [] -> not_found; + L -> [format_asn1_value(V) || V <- L] + end. + +%%-------------------------------------------------------------------------- +%% Formatting functions. +%%-------------------------------------------------------------------------- + +%% Format and rdnSequence as a RFC4514 subject string. +format_rdn_sequence({rdnSequence, Seq}) -> + string:join(lists:reverse([format_complex_rdn(RDN) || RDN <- Seq]), ","). + +%% Format an RDN set. +format_complex_rdn(RDNs) -> + string:join([format_rdn(RDN) || RDN <- RDNs], "+"). + +%% Format an RDN. If the type name is unknown, use the dotted decimal +%% representation. See RFC4514, section 2.3. +format_rdn(#'AttributeTypeAndValue'{type = T, value = V}) -> + FV = escape_rdn_value(format_asn1_value(V)), + Fmts = [{?'id-at-surname' , "SN"}, + {?'id-at-givenName' , "GIVENNAME"}, + {?'id-at-initials' , "INITIALS"}, + {?'id-at-generationQualifier' , "GENERATIONQUALIFIER"}, + {?'id-at-commonName' , "CN"}, + {?'id-at-localityName' , "L"}, + {?'id-at-stateOrProvinceName' , "ST"}, + {?'id-at-organizationName' , "O"}, + {?'id-at-organizationalUnitName' , "OU"}, + {?'id-at-title' , "TITLE"}, + {?'id-at-countryName' , "C"}, + {?'id-at-serialNumber' , "SERIALNUMBER"}, + {?'id-at-pseudonym' , "PSEUDONYM"}, + {?'id-domainComponent' , "DC"}, + {?'id-emailAddress' , "EMAILADDRESS"}, + {?'street-address' , "STREET"}, + {{0,9,2342,19200300,100,1,1} , "UID"}], %% Not in public_key.hrl + case proplists:lookup(T, Fmts) of + {_, Fmt} -> + format(Fmt ++ "=~s", [FV]); + none when is_tuple(T) -> + TypeL = [format("~w", [X]) || X <- tuple_to_list(T)], + format("~s=~s", [string:join(TypeL, "."), FV]); + none -> + format("~p=~s", [T, FV]) + end. + +%% Escape a string as per RFC4514. +escape_rdn_value(V) -> + escape_rdn_value(V, start). + +escape_rdn_value([], _) -> + []; +escape_rdn_value([C | S], start) when C =:= $ ; C =:= $# -> + [$\\, C | escape_rdn_value(S, middle)]; +escape_rdn_value(S, start) -> + escape_rdn_value(S, middle); +escape_rdn_value([$ ], middle) -> + [$\\, $ ]; +escape_rdn_value([C | S], middle) when C =:= $"; C =:= $+; C =:= $,; C =:= $;; + C =:= $<; C =:= $>; C =:= $\\ -> + [$\\, C | escape_rdn_value(S, middle)]; +escape_rdn_value([C | S], middle) when C < 32 ; C >= 126 -> + %% Of ASCII characters only U+0000 needs escaping, but for display + %% purposes it's handy to escape all non-printable chars. All non-ASCII + %% characters get converted to UTF-8 sequences and then escaped. We've + %% already got a UTF-8 sequence here, so just escape it. + rabbit_misc:format("\\~2.16.0B", [C]) ++ escape_rdn_value(S, middle); +escape_rdn_value([C | S], middle) -> + [C | escape_rdn_value(S, middle)]. + +%% Get the string representation of an OTPCertificate field. +format_asn1_value({ST, S}) when ST =:= teletexString; ST =:= printableString; + ST =:= universalString; ST =:= utf8String; + ST =:= bmpString -> + format_directory_string(ST, S); +format_asn1_value({utcTime, [Y1, Y2, M1, M2, D1, D2, H1, H2, + Min1, Min2, S1, S2, $Z]}) -> + format("20~c~c-~c~c-~c~cT~c~c:~c~c:~c~cZ", + [Y1, Y2, M1, M2, D1, D2, H1, H2, Min1, Min2, S1, S2]); +%% We appear to get an untagged value back for an ia5string +%% (e.g. domainComponent). +format_asn1_value(V) when is_list(V) -> + V; +format_asn1_value(V) when is_binary(V) -> + %% OTP does not decode some values when combined with an unknown + %% type. That's probably wrong, so as a last ditch effort let's + %% try manually decoding. 'DirectoryString' is semi-arbitrary - + %% but it is the type which covers the various string types we + %% handle below. + try + {ST, S} = public_key:der_decode('DirectoryString', V), + format_directory_string(ST, S) + catch _:_ -> + format("~p", [V]) + end; +format_asn1_value(V) -> + format("~p", [V]). + +%% DirectoryString { INTEGER : maxSize } ::= CHOICE { +%% teletexString TeletexString (SIZE (1..maxSize)), +%% printableString PrintableString (SIZE (1..maxSize)), +%% bmpString BMPString (SIZE (1..maxSize)), +%% universalString UniversalString (SIZE (1..maxSize)), +%% uTF8String UTF8String (SIZE (1..maxSize)) } +%% +%% Precise definitions of printable / teletexString are hard to come +%% by. This is what I reconstructed: +%% +%% printableString: +%% "intended to represent the limited character sets available to +%% mainframe input terminals" +%% A-Z a-z 0-9 ' ( ) + , - . / : = ? [space] +%% http://msdn.microsoft.com/en-us/library/bb540814(v=vs.85).aspx +%% +%% teletexString: +%% "a sizable volume of software in the world treats TeletexString +%% (T61String) as a simple 8-bit string with mostly Windows Latin 1 +%% (superset of iso-8859-1) encoding" +%% http://www.mail-archive.com/asn1@asn1.org/msg00460.html +%% +%% (However according to that link X.680 actually defines +%% TeletexString in some much more involved and crazy way. I suggest +%% we treat it as ISO-8859-1 since Erlang does not support Windows +%% Latin 1). +%% +%% bmpString: +%% UCS-2 according to RFC 3641. Hence cannot represent Unicode +%% characters above 65535 (outside the "Basic Multilingual Plane"). +%% +%% universalString: +%% UCS-4 according to RFC 3641. +%% +%% utf8String: +%% UTF-8 according to RFC 3641. +%% +%% Within Rabbit we assume UTF-8 encoding. Since printableString is a +%% subset of ASCII it is also a subset of UTF-8. The others need +%% converting. Fortunately since the Erlang SSL library does the +%% decoding for us (albeit into a weird format, see below), we just +%% need to handle encoding into UTF-8. Note also that utf8Strings come +%% back as binary. +%% +%% Note for testing: the default Ubuntu configuration for openssl will +%% only create printableString or teletexString types no matter what +%% you do. Edit string_mask in the [req] section of +%% /etc/ssl/openssl.cnf to change this (see comments there). You +%% probably also need to set utf8 = yes to get it to accept UTF-8 on +%% the command line. Also note I could not get openssl to generate a +%% universalString. + +format_directory_string(printableString, S) -> S; +format_directory_string(teletexString, S) -> utf8_list_from(S); +format_directory_string(bmpString, S) -> utf8_list_from(S); +format_directory_string(universalString, S) -> utf8_list_from(S); +format_directory_string(utf8String, S) -> binary_to_list(S). + +utf8_list_from(S) -> + binary_to_list( + unicode:characters_to_binary(flatten_ssl_list(S), utf32, utf8)). + +%% The Erlang SSL implementation invents its own representation for +%% non-ascii strings - looking like [97,{0,0,3,187}] (that's LATIN +%% SMALL LETTER A followed by GREEK SMALL LETTER LAMDA). We convert +%% this into a list of unicode characters, which we can tell +%% unicode:characters_to_binary is utf32. + +flatten_ssl_list(L) -> [flatten_ssl_list_item(I) || I <- L]. + +flatten_ssl_list_item({A, B, C, D}) -> + A * (1 bsl 24) + B * (1 bsl 16) + C * (1 bsl 8) + D; +flatten_ssl_list_item(N) when is_number (N) -> + N. + +format(Fmt, Args) -> + lists:flatten(io_lib:format(Fmt, Args)). + From db954aeb6d9a1a31d04508f130142f1a9f3c2d4d Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Fri, 15 Dec 2017 19:23:50 +0800 Subject: [PATCH 15/46] Support X.509 certificate based authentication with HAProxy --- etc/emq.conf | 3 + priv/emq.schema | 4 + src/emqttd_protocol.erl | 21 ++-- src/emqttd_ssl.erl | 259 ---------------------------------------- 4 files changed, 14 insertions(+), 273 deletions(-) delete mode 100644 src/emqttd_ssl.erl diff --git a/etc/emq.conf b/etc/emq.conf index d6dacc8fb..2698da935 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -340,6 +340,9 @@ listener.tcp.external.access.2 = allow all ## listener.tcp.external.proxy_protocol = on ## listener.tcp.external.proxy_protocol_timeout = 3s +### Use the PP2_SUBTYPE_SSL_CN field from Proxy Protocol V2 as a username. +## listener.tcp.external.peer_cert_as_username = cn + ## TCP Socket Options listener.tcp.external.backlog = 1024 diff --git a/priv/emq.schema b/priv/emq.schema index e8746582b..73d8d2e3a 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -804,6 +804,10 @@ end}. {datatype, {duration, ms}} ]}. +{mapping, "listener.tcp.$name.peer_cert_as_username", "emqttd.listeners", [ + {datatype, {enum, [cn, dn]}} +]}. + {mapping, "listener.tcp.$name.backlog", "emqttd.listeners", [ {datatype, integer}, {default, 1024} diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index 4505b73c6..d021c9e1f 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -69,7 +69,7 @@ init(Peername, SendFun, Opts) -> max_clientid_len = MaxLen, is_superuser = false, client_pid = self(), - peercert_username = false, + peercert_username = undefined, ws_initial_headers = WsInitialHeaders, keepalive_backoff = Backoff, stats_data = #proto_stats{enable_stats = EnableStats}}. @@ -82,23 +82,16 @@ enrich_opt([], _Conn, State) -> enrich_opt([{mountpoint, MountPoint} | ConnOpts], Conn, State) -> enrich_opt(ConnOpts, Conn, State#proto_state{mountpoint = MountPoint}); enrich_opt([{peer_cert_as_username, N} | ConnOpts], Conn, State) -> - case Conn:type() of - ssl -> enrich_opt(ConnOpts, Conn, State#proto_state{ - peercert_username = peercert_username(N, Conn:peercert())}); - _ -> enrich_opt(ConnOpts, Conn, State) - end; + enrich_opt(ConnOpts, Conn, State#proto_state{peercert_username = peercert_username(N, Conn)}); enrich_opt([_ | ConnOpts], Conn, State) -> enrich_opt(ConnOpts, Conn, State). -peercert_username(cn, Cert) -> - case emqttd_ssl:peer_cert_common_name(Cert) of - not_found -> undefined; - CN -> iolist_to_binary(CN) - end; -peercert_username(dn, Cert) -> - iolist_to_binary(emqttd_ssl:peer_cert_subject(Cert)). +peercert_username(cn, Conn) -> + Conn:peer_cert_common_name(); +peercert_username(dn, Conn) -> + Conn:peer_cert_subject(). -repl_username_with_peercert(State = #proto_state{peercert_username = false}) -> +repl_username_with_peercert(State = #proto_state{peercert_username = undefined}) -> State; repl_username_with_peercert(State = #proto_state{peercert_username = PeerCert}) -> State#proto_state{username = PeerCert}. diff --git a/src/emqttd_ssl.erl b/src/emqttd_ssl.erl deleted file mode 100644 index c4126e820..000000000 --- a/src/emqttd_ssl.erl +++ /dev/null @@ -1,259 +0,0 @@ -%%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) -%% -%% 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. -%%-------------------------------------------------------------------- -%% -%% @doc SSL Utility Functions. This module is copied from rabbit_ssl.erl -%% - --module(emqttd_ssl). - --include_lib("public_key/include/public_key.hrl"). - --type(certificate() :: binary()). - --export([peer_cert_issuer/1, peer_cert_subject/1, peer_cert_common_name/1, - peer_cert_subject_items/2, peer_cert_validity/1]). - -%% Return a string describing the certificate's issuer. --spec(peer_cert_issuer(certificate()) -> string()). -peer_cert_issuer(Cert) -> - cert_info(fun(#'OTPCertificate' { - tbsCertificate = #'OTPTBSCertificate' { - issuer = Issuer }}) -> - format_rdn_sequence(Issuer) - end, Cert). - -%% Return a string describing the certificate's subject, as per RFC4514. --spec(peer_cert_subject(certificate()) -> string()). -peer_cert_subject(Cert) -> - cert_info(fun(#'OTPCertificate' { - tbsCertificate = #'OTPTBSCertificate' { - subject = Subject }}) -> - format_rdn_sequence(Subject) - end, Cert). - --spec(peer_cert_common_name(certificate()) -> string() | 'not_found'). -peer_cert_common_name(Cert) -> - case peer_cert_subject_items(Cert, ?'id-at-commonName') of - not_found -> not_found; - CNs -> string:join(CNs, ",") - end. - -%% Return the parts of the certificate's subject. --spec(peer_cert_subject_items(certificate(), tuple()) -> [string()] | 'undefined'). -peer_cert_subject_items(Cert, Type) -> - cert_info(fun(#'OTPCertificate' { - tbsCertificate = #'OTPTBSCertificate' { - subject = Subject }}) -> - find_by_type(Type, Subject) - end, Cert). - -%% Return a string describing the certificate's validity. --spec(peer_cert_validity(certificate()) -> string()). -peer_cert_validity(Cert) -> - cert_info(fun(#'OTPCertificate' { - tbsCertificate = #'OTPTBSCertificate' { - validity = {'Validity', Start, End} }}) -> - format("~s - ~s", [format_asn1_value(Start), - format_asn1_value(End)]) - end, Cert). - -cert_info(F, {ok, Cert}) -> - F(case public_key:pkix_decode_cert(Cert, otp) of - {ok, DecCert} -> DecCert; %%pre R14B - DecCert -> DecCert %%R14B onwards - end). - -find_by_type(Type, {rdnSequence, RDNs}) -> - case [V || #'AttributeTypeAndValue'{type = T, value = V} - <- lists:flatten(RDNs), - T == Type] of - [] -> not_found; - L -> [format_asn1_value(V) || V <- L] - end. - -%%-------------------------------------------------------------------------- -%% Formatting functions. -%%-------------------------------------------------------------------------- - -%% Format and rdnSequence as a RFC4514 subject string. -format_rdn_sequence({rdnSequence, Seq}) -> - string:join(lists:reverse([format_complex_rdn(RDN) || RDN <- Seq]), ","). - -%% Format an RDN set. -format_complex_rdn(RDNs) -> - string:join([format_rdn(RDN) || RDN <- RDNs], "+"). - -%% Format an RDN. If the type name is unknown, use the dotted decimal -%% representation. See RFC4514, section 2.3. -format_rdn(#'AttributeTypeAndValue'{type = T, value = V}) -> - FV = escape_rdn_value(format_asn1_value(V)), - Fmts = [{?'id-at-surname' , "SN"}, - {?'id-at-givenName' , "GIVENNAME"}, - {?'id-at-initials' , "INITIALS"}, - {?'id-at-generationQualifier' , "GENERATIONQUALIFIER"}, - {?'id-at-commonName' , "CN"}, - {?'id-at-localityName' , "L"}, - {?'id-at-stateOrProvinceName' , "ST"}, - {?'id-at-organizationName' , "O"}, - {?'id-at-organizationalUnitName' , "OU"}, - {?'id-at-title' , "TITLE"}, - {?'id-at-countryName' , "C"}, - {?'id-at-serialNumber' , "SERIALNUMBER"}, - {?'id-at-pseudonym' , "PSEUDONYM"}, - {?'id-domainComponent' , "DC"}, - {?'id-emailAddress' , "EMAILADDRESS"}, - {?'street-address' , "STREET"}, - {{0,9,2342,19200300,100,1,1} , "UID"}], %% Not in public_key.hrl - case proplists:lookup(T, Fmts) of - {_, Fmt} -> - format(Fmt ++ "=~s", [FV]); - none when is_tuple(T) -> - TypeL = [format("~w", [X]) || X <- tuple_to_list(T)], - format("~s=~s", [string:join(TypeL, "."), FV]); - none -> - format("~p=~s", [T, FV]) - end. - -%% Escape a string as per RFC4514. -escape_rdn_value(V) -> - escape_rdn_value(V, start). - -escape_rdn_value([], _) -> - []; -escape_rdn_value([C | S], start) when C =:= $ ; C =:= $# -> - [$\\, C | escape_rdn_value(S, middle)]; -escape_rdn_value(S, start) -> - escape_rdn_value(S, middle); -escape_rdn_value([$ ], middle) -> - [$\\, $ ]; -escape_rdn_value([C | S], middle) when C =:= $"; C =:= $+; C =:= $,; C =:= $;; - C =:= $<; C =:= $>; C =:= $\\ -> - [$\\, C | escape_rdn_value(S, middle)]; -escape_rdn_value([C | S], middle) when C < 32 ; C >= 126 -> - %% Of ASCII characters only U+0000 needs escaping, but for display - %% purposes it's handy to escape all non-printable chars. All non-ASCII - %% characters get converted to UTF-8 sequences and then escaped. We've - %% already got a UTF-8 sequence here, so just escape it. - rabbit_misc:format("\\~2.16.0B", [C]) ++ escape_rdn_value(S, middle); -escape_rdn_value([C | S], middle) -> - [C | escape_rdn_value(S, middle)]. - -%% Get the string representation of an OTPCertificate field. -format_asn1_value({ST, S}) when ST =:= teletexString; ST =:= printableString; - ST =:= universalString; ST =:= utf8String; - ST =:= bmpString -> - format_directory_string(ST, S); -format_asn1_value({utcTime, [Y1, Y2, M1, M2, D1, D2, H1, H2, - Min1, Min2, S1, S2, $Z]}) -> - format("20~c~c-~c~c-~c~cT~c~c:~c~c:~c~cZ", - [Y1, Y2, M1, M2, D1, D2, H1, H2, Min1, Min2, S1, S2]); -%% We appear to get an untagged value back for an ia5string -%% (e.g. domainComponent). -format_asn1_value(V) when is_list(V) -> - V; -format_asn1_value(V) when is_binary(V) -> - %% OTP does not decode some values when combined with an unknown - %% type. That's probably wrong, so as a last ditch effort let's - %% try manually decoding. 'DirectoryString' is semi-arbitrary - - %% but it is the type which covers the various string types we - %% handle below. - try - {ST, S} = public_key:der_decode('DirectoryString', V), - format_directory_string(ST, S) - catch _:_ -> - format("~p", [V]) - end; -format_asn1_value(V) -> - format("~p", [V]). - -%% DirectoryString { INTEGER : maxSize } ::= CHOICE { -%% teletexString TeletexString (SIZE (1..maxSize)), -%% printableString PrintableString (SIZE (1..maxSize)), -%% bmpString BMPString (SIZE (1..maxSize)), -%% universalString UniversalString (SIZE (1..maxSize)), -%% uTF8String UTF8String (SIZE (1..maxSize)) } -%% -%% Precise definitions of printable / teletexString are hard to come -%% by. This is what I reconstructed: -%% -%% printableString: -%% "intended to represent the limited character sets available to -%% mainframe input terminals" -%% A-Z a-z 0-9 ' ( ) + , - . / : = ? [space] -%% http://msdn.microsoft.com/en-us/library/bb540814(v=vs.85).aspx -%% -%% teletexString: -%% "a sizable volume of software in the world treats TeletexString -%% (T61String) as a simple 8-bit string with mostly Windows Latin 1 -%% (superset of iso-8859-1) encoding" -%% http://www.mail-archive.com/asn1@asn1.org/msg00460.html -%% -%% (However according to that link X.680 actually defines -%% TeletexString in some much more involved and crazy way. I suggest -%% we treat it as ISO-8859-1 since Erlang does not support Windows -%% Latin 1). -%% -%% bmpString: -%% UCS-2 according to RFC 3641. Hence cannot represent Unicode -%% characters above 65535 (outside the "Basic Multilingual Plane"). -%% -%% universalString: -%% UCS-4 according to RFC 3641. -%% -%% utf8String: -%% UTF-8 according to RFC 3641. -%% -%% Within Rabbit we assume UTF-8 encoding. Since printableString is a -%% subset of ASCII it is also a subset of UTF-8. The others need -%% converting. Fortunately since the Erlang SSL library does the -%% decoding for us (albeit into a weird format, see below), we just -%% need to handle encoding into UTF-8. Note also that utf8Strings come -%% back as binary. -%% -%% Note for testing: the default Ubuntu configuration for openssl will -%% only create printableString or teletexString types no matter what -%% you do. Edit string_mask in the [req] section of -%% /etc/ssl/openssl.cnf to change this (see comments there). You -%% probably also need to set utf8 = yes to get it to accept UTF-8 on -%% the command line. Also note I could not get openssl to generate a -%% universalString. - -format_directory_string(printableString, S) -> S; -format_directory_string(teletexString, S) -> utf8_list_from(S); -format_directory_string(bmpString, S) -> utf8_list_from(S); -format_directory_string(universalString, S) -> utf8_list_from(S); -format_directory_string(utf8String, S) -> binary_to_list(S). - -utf8_list_from(S) -> - binary_to_list( - unicode:characters_to_binary(flatten_ssl_list(S), utf32, utf8)). - -%% The Erlang SSL implementation invents its own representation for -%% non-ascii strings - looking like [97,{0,0,3,187}] (that's LATIN -%% SMALL LETTER A followed by GREEK SMALL LETTER LAMDA). We convert -%% this into a list of unicode characters, which we can tell -%% unicode:characters_to_binary is utf32. - -flatten_ssl_list(L) -> [flatten_ssl_list_item(I) || I <- L]. - -flatten_ssl_list_item({A, B, C, D}) -> - A * (1 bsl 24) + B * (1 bsl 16) + C * (1 bsl 8) + D; -flatten_ssl_list_item(N) when is_number (N) -> - N. - -format(Fmt, Args) -> - lists:flatten(io_lib:format(Fmt, Args)). - From d7e56fa9719352841c50f03a2a7db89031ca9444 Mon Sep 17 00:00:00 2001 From: HuangDan Date: Mon, 25 Dec 2017 17:31:23 +0800 Subject: [PATCH 16/46] Upgrade the esockd library to v5.2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1c919bb1e..233f542d7 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ dep_goldrush = git https://github.com/basho/goldrush 0.1.9 dep_gproc = git https://github.com/uwiger/gproc dep_getopt = git https://github.com/jcomellas/getopt v0.8.2 dep_lager = git https://github.com/basho/lager master -dep_esockd = git https://github.com/emqtt/esockd develop +dep_esockd = git https://github.com/emqtt/esockd v5.2 dep_ekka = git https://github.com/emqtt/ekka master dep_mochiweb = git https://github.com/emqtt/mochiweb develop dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 From d5222dcc9b79fd47626cacaf75f8ae38f465dce1 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 25 Dec 2017 20:38:09 +0800 Subject: [PATCH 17/46] Add proxy_protocol, proxy_protocol_timeout options for ws/wss --- etc/emq.conf | 8 ++++++++ priv/emq.schema | 20 ++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 2698da935..db62e1d49 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -511,6 +511,10 @@ listener.ws.external.max_clients = 64 listener.ws.external.access.1 = allow all +## Proxy Protocol V1/2 +## listener.ws.external.proxy_protocol = on +## listener.ws.external.proxy_protocol_timeout = 3s + ## TCP Options listener.ws.external.backlog = 1024 @@ -537,6 +541,10 @@ listener.wss.external.max_clients = 64 listener.wss.external.access.1 = allow all +## Proxy Protocol V1/2 +## listener.wss.external.proxy_protocol = on +## listener.wss.external.proxy_protocol_timeout = 3s + ## SSL Options listener.wss.external.handshake_timeout = 15s diff --git a/priv/emq.schema b/priv/emq.schema index 73d8d2e3a..aaefce4c2 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -795,12 +795,10 @@ end}. ]}. {mapping, "listener.tcp.$name.proxy_protocol", "emqttd.listeners", [ - %%{default, off}, {datatype, flag} ]}. {mapping, "listener.tcp.$name.proxy_protocol_timeout", "emqttd.listeners", [ - %%{default, "5s"}, {datatype, {duration, ms}} ]}. @@ -883,12 +881,10 @@ end}. ]}. {mapping, "listener.ssl.$name.proxy_protocol", "emqttd.listeners", [ - %%{default, off}, {datatype, flag} ]}. {mapping, "listener.ssl.$name.proxy_protocol_timeout", "emqttd.listeners", [ - %%{default, "5s"}, {datatype, {duration, ms}} ]}. @@ -1015,6 +1011,14 @@ end}. {datatype, string} ]}. +{mapping, "listener.ws.$name.proxy_protocol", "emqttd.listeners", [ + {datatype, flag} +]}. + +{mapping, "listener.ws.$name.proxy_protocol_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}} +]}. + {mapping, "listener.ws.$name.backlog", "emqttd.listeners", [ {default, 1024}, {datatype, integer} @@ -1088,6 +1092,14 @@ end}. {datatype, string} ]}. +{mapping, "listener.wss.$name.proxy_protocol", "emqttd.listeners", [ + {datatype, flag} +]}. + +{mapping, "listener.wss.$name.proxy_protocol_timeout", "emqttd.listeners", [ + {datatype, {duration, ms}} +]}. + {mapping, "listener.wss.$name.backlog", "emqttd.listeners", [ {default, 1024}, {datatype, integer} From 985ab723dfb48ff053570e8de8aca3b54b0c8608 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 26 Dec 2017 21:01:03 +0800 Subject: [PATCH 18/46] Support for zone configuration --- etc/emq.conf | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index db62e1d49..68cf8b6b7 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1,6 +1,6 @@ -##=================================================================== +##==================================================================== ## EMQ Configuration R2.3.0 -##=================================================================== +##==================================================================== ##-------------------------------------------------------------------- ## Cluster @@ -327,6 +327,9 @@ listener.tcp.external.acceptors = 16 ## Maximum number of concurrent clients listener.tcp.external.max_clients = 102400 +## TODO: +## listener.tcp.external.zone = external + #listener.tcp.external.mountpoint = external/ ## Rate Limit. Format is 'burst,rate', Unit is KB/Sec @@ -370,6 +373,8 @@ listener.tcp.internal.acceptors = 16 ## Maximum number of concurrent clients listener.tcp.internal.max_clients = 102400 +#listener.tcp.internal.zone = internal + #listener.tcp.external.mountpoint = internal/ ## Rate Limit. Format is 'burst,rate', Unit is KB/Sec @@ -404,6 +409,9 @@ listener.ssl.external.acceptors = 16 ## Maximum number of concurrent clients listener.ssl.external.max_clients = 1024 +## Authentication Zone +## listener.ssl.external.zone = external + ## listener.ssl.external.mountpoint = inbound/ ## Rate Limit. Format is 'burst,rate', Unit is KB/Sec @@ -509,6 +517,8 @@ listener.ws.external.acceptors = 4 listener.ws.external.max_clients = 64 +## listener.ws.external.zone = external + listener.ws.external.access.1 = allow all ## Proxy Protocol V1/2 @@ -539,6 +549,8 @@ listener.wss.external.acceptors = 4 listener.wss.external.max_clients = 64 +## listener.wss.external.zone = external + listener.wss.external.access.1 = allow all ## Proxy Protocol V1/2 From 013cc9705e1e1953d873e8cb637c581cfbec8e9a Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 26 Dec 2017 22:15:09 +0800 Subject: [PATCH 19/46] Depends on ekka v0.2.1 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 233f542d7..b0fac24b8 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ dep_gproc = git https://github.com/uwiger/gproc dep_getopt = git https://github.com/jcomellas/getopt v0.8.2 dep_lager = git https://github.com/basho/lager master dep_esockd = git https://github.com/emqtt/esockd v5.2 -dep_ekka = git https://github.com/emqtt/ekka master +dep_ekka = git https://github.com/emqtt/ekka v0.2.1 dep_mochiweb = git https://github.com/emqtt/mochiweb develop dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 dep_lager_syslog = git https://github.com/basho/lager_syslog From d5c54276e212e14128002a803e96c365874548d1 Mon Sep 17 00:00:00 2001 From: HeeeJianBo Date: Wed, 27 Dec 2017 14:55:36 +0800 Subject: [PATCH 20/46] Fix issue #1398 --- src/emqttd_topic.erl | 8 ++++---- test/emqttd_topic_SUITE.erl | 16 ++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/emqttd_topic.erl b/src/emqttd_topic.erl index 458a41f7d..934362499 100644 --- a/src/emqttd_topic.erl +++ b/src/emqttd_topic.erl @@ -61,18 +61,18 @@ wildcard([_H|T]) -> -spec(match(Name, Filter) -> boolean() when Name :: topic() | words(), Filter :: topic() | words()). +match(<<"$", _/binary>>, <<"+", _/binary>>) -> + false; +match(<<"$", _/binary>>, <<"#", _/binary>>) -> + false; match(Name, Filter) when is_binary(Name) and is_binary(Filter) -> match(words(Name), words(Filter)); match([], []) -> true; match([H|T1], [H|T2]) -> match(T1, T2); -match([<<$$, _/binary>>|_], ['+'|_]) -> - false; match([_H|T1], ['+'|T2]) -> match(T1, T2); -match([<<$$, _/binary>>|_], ['#']) -> - false; match(_, ['#']) -> true; match([_H1|_], [_H2|_]) -> diff --git a/test/emqttd_topic_SUITE.erl b/test/emqttd_topic_SUITE.erl index b1ea4d8ed..9ec7736bd 100644 --- a/test/emqttd_topic_SUITE.erl +++ b/test/emqttd_topic_SUITE.erl @@ -73,10 +73,10 @@ t_match2(_) -> t_match3(_) -> true = match(<<"device/60019423a83c/fw">>, <<"device/60019423a83c/#">>), - false = match(<<"device/60019423a83c/$fw">>, <<"device/60019423a83c/#">>), + true = match(<<"device/60019423a83c/$fw">>, <<"device/60019423a83c/#">>), true = match(<<"device/60019423a83c/$fw/fw">>, <<"device/60019423a83c/$fw/#">>), true = match(<<"device/60019423a83c/fw/checksum">>, <<"device/60019423a83c/#">>), - false = match(<<"device/60019423a83c/$fw/checksum">>, <<"device/60019423a83c/#">>), + true = match(<<"device/60019423a83c/$fw/checksum">>, <<"device/60019423a83c/#">>), true = match(<<"device/60019423a83c/dust/type">>, <<"device/60019423a83c/#">>). t_sigle_level_match(_) -> @@ -86,7 +86,9 @@ t_sigle_level_match(_) -> true = match(<<"sport/">>, <<"sport/+">>), true = match(<<"/finance">>, <<"+/+">>), true = match(<<"/finance">>, <<"/+">>), - false = match(<<"/finance">>, <<"+">>). + false = match(<<"/finance">>, <<"+">>), + true = match(<<"/devices/$dev1">>, <<"/devices/+">>), + true = match(<<"/devices/$dev1/online">>, <<"/devices/+/online">>). t_sys_match(_) -> true = match(<<"$SYS/broker/clients/testclient">>, <<"$SYS/#">>), @@ -95,9 +97,11 @@ t_sys_match(_) -> false = match(<<"$SYS/broker">>, <<"#">>). 't_#_match'(_) -> - true = match(<<"a/b/c">>, <<"#">>), - true = match(<<"a/b/c">>, <<"+/#">>), - false = match(<<"$SYS/brokers">>, <<"#">>). + true = match(<<"a/b/c">>, <<"#">>), + true = match(<<"a/b/c">>, <<"+/#">>), + false = match(<<"$SYS/brokers">>, <<"#">>), + true = match(<<"a/b/$c">>, <<"a/b/#">>), + true = match(<<"a/b/$c">>, <<"a/#">>). t_match_perf(_) -> true = match(<<"a/b/ccc">>, <<"a/#">>), From 4c8b43e05d2c2666a079f3b385606f11544cbf61 Mon Sep 17 00:00:00 2001 From: HeeeJianBo Date: Wed, 27 Dec 2017 15:11:55 +0800 Subject: [PATCH 21/46] Improve impletament of emqttd_topic:match/2 --- src/emqttd_topic.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emqttd_topic.erl b/src/emqttd_topic.erl index 934362499..91cd0ff08 100644 --- a/src/emqttd_topic.erl +++ b/src/emqttd_topic.erl @@ -61,9 +61,9 @@ wildcard([_H|T]) -> -spec(match(Name, Filter) -> boolean() when Name :: topic() | words(), Filter :: topic() | words()). -match(<<"$", _/binary>>, <<"+", _/binary>>) -> +match(<<$$, _/binary>>, <<$+, _/binary>>) -> false; -match(<<"$", _/binary>>, <<"#", _/binary>>) -> +match(<<$$, _/binary>>, <<$#, _/binary>>) -> false; match(Name, Filter) when is_binary(Name) and is_binary(Filter) -> match(words(Name), words(Filter)); From ed5e4d185763977b17bd95094d579fac85c2c115 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 27 Dec 2017 21:30:17 +0800 Subject: [PATCH 22/46] Change the default value of mqtt.keepalive_backoff to 0.75 --- etc/emq.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 68cf8b6b7..677eca905 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1,5 +1,5 @@ ##==================================================================== -## EMQ Configuration R2.3.0 +## EMQ Configuration R2.3.3 ##==================================================================== ##-------------------------------------------------------------------- @@ -196,7 +196,7 @@ mqtt.max_packet_size = 64KB mqtt.websocket_protocol_header = on ## The Keepalive timeout: Keepalive * backoff * 2 -mqtt.keepalive_backoff = 1.25 +mqtt.keepalive_backoff = 0.75 ##-------------------------------------------------------------------- ## MQTT Connection From 953a7628a305c8745fed2a1445dac51ee71a6148 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 28 Dec 2017 11:34:29 +0800 Subject: [PATCH 23/46] Version 2.3.3 --- Makefile | 8 ++++---- src/emqttd.app.src | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index b0fac24b8..8ad0dbe5b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PROJECT = emqttd PROJECT_DESCRIPTION = Erlang MQTT Broker -PROJECT_VERSION = 2.3.2 +PROJECT_VERSION = 2.3.3 DEPS = goldrush gproc lager esockd ekka mochiweb pbkdf2 lager_syslog bcrypt clique jsx @@ -8,14 +8,14 @@ dep_goldrush = git https://github.com/basho/goldrush 0.1.9 dep_gproc = git https://github.com/uwiger/gproc dep_getopt = git https://github.com/jcomellas/getopt v0.8.2 dep_lager = git https://github.com/basho/lager master -dep_esockd = git https://github.com/emqtt/esockd v5.2 -dep_ekka = git https://github.com/emqtt/ekka v0.2.1 +dep_esockd = git https://github.com/emqtt/esockd develop +dep_ekka = git https://github.com/emqtt/ekka develop dep_mochiweb = git https://github.com/emqtt/mochiweb develop dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1 dep_lager_syslog = git https://github.com/basho/lager_syslog dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master dep_clique = git https://github.com/emqtt/clique -dep_jsx = git https://github.com/talentdeficit/jsx +dep_jsx = git https://github.com/talentdeficit/jsx ERLC_OPTS += +debug_info ERLC_OPTS += +'{parse_transform, lager_transform}' diff --git a/src/emqttd.app.src b/src/emqttd.app.src index e321b73f1..4ff79090a 100644 --- a/src/emqttd.app.src +++ b/src/emqttd.app.src @@ -1,6 +1,6 @@ {application,emqttd, [{description,"Erlang MQTT Broker"}, - {vsn,"2.3.2"}, + {vsn,"2.3.3"}, {modules,[]}, {registered,[emqttd_sup]}, {applications,[kernel,stdlib,gproc,lager,esockd,mochiweb, From 5fbbff46b1e3bd68e89f086b8c48167ea8d3a09f Mon Sep 17 00:00:00 2001 From: HeeeJianBo Date: Thu, 28 Dec 2017 17:57:32 +0800 Subject: [PATCH 24/46] Fix issue #1216, redeliver pubrel packet now --- src/emqttd_session.erl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/emqttd_session.erl b/src/emqttd_session.erl index 854dee0a5..aa1a027a4 100644 --- a/src/emqttd_session.erl +++ b/src/emqttd_session.erl @@ -453,6 +453,8 @@ handle_cast({pubrel, PacketId}, State = #state{awaiting_rel = AwaitingRel}) -> {noreply, case maps:take(PacketId, AwaitingRel) of {Msg, AwaitingRel1} -> + %% Implement Qos2 by method A [MQTT 4.33] + %% Dispatch to subscriber when received PUBREL spawn(emqttd_server, publish, [Msg]), %%:) gc(State#state{awaiting_rel = AwaitingRel1}); error -> @@ -628,8 +630,10 @@ retry_delivery(Force, [{Type, Msg, Ts} | Msgs], Now, redeliver(Msg, State), Inflight1 = Inflight:update(PacketId, {publish, Msg, Now}), retry_delivery(Force, Msgs, Now, State#state{inflight = Inflight1}); - {pubrel, PacketId} -> %% remove 'pubrel' directly? - retry_delivery(Force, Msgs, Now, State#state{inflight = Inflight:delete(PacketId)}) + {pubrel, PacketId} -> + redeliver({pubrel, PacketId}, State), + Inflight1 = Inflight:update(PacketId, {pubrel, PacketId, Now}), + retry_delivery(Force, Msgs, Now, State#state{inflight = Inflight1}) end; true -> State#state{retry_timer = start_timer(Interval - Diff, retry_delivery)} @@ -649,11 +653,13 @@ expire_awaiting_rel(State = #state{awaiting_rel = AwaitingRel}) -> expire_awaiting_rel([], _Now, State) -> State#state{await_rel_timer = undefined}; -expire_awaiting_rel([{PacketId, #mqtt_message{timestamp = TS}} | Msgs], +expire_awaiting_rel([{PacketId, Msg = #mqtt_message{timestamp = TS}} | Msgs], Now, State = #state{awaiting_rel = AwaitingRel, await_rel_timeout = Timeout}) -> case (timer:now_diff(Now, TS) div 1000) of Diff when Diff >= Timeout -> + ?LOG(warning, "Dropped Qos2 Message for await_rel_timeout: ~p", [Msg], State), + emqttd_metrics:inc('messages/qos2/dropped'), expire_awaiting_rel(Msgs, Now, State#state{awaiting_rel = maps:remove(PacketId, AwaitingRel)}); Diff -> State#state{await_rel_timer = start_timer(Timeout - Diff, check_awaiting_rel)} @@ -714,7 +720,10 @@ enqueue_msg(Msg, State = #state{mqueue = Q}) -> %%-------------------------------------------------------------------- redeliver(Msg = #mqtt_message{qos = QoS}, State) -> - deliver(Msg#mqtt_message{dup = if QoS =:= ?QOS2 -> false; true -> true end}, State). + deliver(Msg#mqtt_message{dup = if QoS =:= ?QOS2 -> false; true -> true end}, State); + +redeliver({pubrel, PacketId}, #state{client_pid = Pid}) -> + Pid ! {redeliver, {?PUBREL, PacketId}}. deliver(Msg, #state{client_pid = Pid}) -> inc_stats(deliver_msg), From 10ed4219dbd1f5dcdbe7f5a80b8b6a53070115a0 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Sun, 31 Dec 2017 15:10:45 +0800 Subject: [PATCH 25/46] Update documentation for R2 configurations --- etc/emq.conf | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 677eca905..898a94576 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1,5 +1,5 @@ ##==================================================================== -## EMQ Configuration R2.3.3 +## EMQ Configuration R2 ##==================================================================== ##-------------------------------------------------------------------- @@ -9,7 +9,17 @@ ## Cluster name cluster.name = emqcl -## Cluster discovery strategy: manual | static | mcast | dns | etcd | k8s +## Cluster auto-discovery strategy. +## +## Enum Values: +## - manual: Manual join command +## - static: Static node list +## - mcast: IP Multicast +## - dns: DNS A Record +## - etcd: etcd +## - k8s: Kubernates +## +## Default: manual cluster.discovery = manual ## Cluster Autoheal: on | off @@ -557,7 +567,9 @@ listener.wss.external.access.1 = allow all ## listener.wss.external.proxy_protocol = on ## listener.wss.external.proxy_protocol_timeout = 3s -## SSL Options +## SSL Option +### SSL Options. See http://erlang.org/doc/man/ssl.html + listener.wss.external.handshake_timeout = 15s listener.wss.external.keyfile = {{ platform_etc_dir }}/certs/key.pem From 052f9638cb907d58c786a953a50de73ed312a50f Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 2 Jan 2018 20:47:25 +0800 Subject: [PATCH 26/46] Add more documentation for emq.conf --- etc/emq.conf | 367 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 292 insertions(+), 75 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 898a94576..74f2b8a88 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -6,12 +6,12 @@ ## Cluster ##-------------------------------------------------------------------- -## Cluster name +## Cluster name. cluster.name = emqcl ## Cluster auto-discovery strategy. ## -## Enum Values: +## Value: Enum ## - manual: Manual join command ## - static: Static node list ## - mcast: IP Multicast @@ -22,106 +22,229 @@ cluster.name = emqcl ## Default: manual cluster.discovery = manual -## Cluster Autoheal: on | off +## Enable cluster autoheal from network partition. +## +## Value: on | off +## +## Default: on cluster.autoheal = on -## Clean down node of the cluster +## AutoClean down node after this duration. +## +## Value: time duration with units +## -h: hour, e.g. '2h' for 2 hours +## -m: minute, e.g. '5m' for 5 minutes +## -s: second, e.g. '30s' for 30 seconds +## +## Default: 5m cluster.autoclean = 5m ##-------------------------------------------------------------------- -## Cluster with static node list +## Cluster using static node list +## Node list of the cluster. +## +## Value: String ## cluster.static.seeds = emq1@127.0.0.1,emq2@127.0.0.1 ##-------------------------------------------------------------------- -## Cluster with multicast +## Cluster using IP Multicast. +## IP Multicast Address. +## +## Value: IP Address ## cluster.mcast.addr = 239.192.0.1 +## Multicast Ports. +## +## Value: Port List ## cluster.mcast.ports = 4369,4370 +## Multicast Iface. +## +## Value: Iface Address +## +## Default: 0.0.0.0 ## cluster.mcast.iface = 0.0.0.0 +## Multicast Ttl. +## +## Value: 0-255 +## +## Default: 255 ## cluster.mcast.ttl = 255 +## Multicast loop. +## +## Value: on | off ## cluster.mcast.loop = on ##-------------------------------------------------------------------- -## Cluster with DNS +## Cluster using DNS A records. +## DNS name. +## +## Value: String ## cluster.dns.name = localhost +## The App name is used to build 'node.name' with IP address. +## +## Value: String ## cluster.dns.app = emq ##-------------------------------------------------------------------- -## Cluster with Etcd +## Cluster using etcd +## Etcd server list, seperated by ','. +## +## Value: String ## cluster.etcd.server = http://127.0.0.1:2379 +## The prefix helps build nodes path in etcd. Each node in the cluster +## will create a path in etcd: v2/keys/{prefix}/{cluster.name}/{node.name} +## +## Value: String ## cluster.etcd.prefix = emqcl +## The TTL for node's path in etcd. +## +## Value: Duration +## +## Default: 1m, 1 minute ## cluster.etcd.node_ttl = 1m ##-------------------------------------------------------------------- -## Cluster with k8s +## Cluster using Kubernates +## Kubernates API server list, seperated by ','. +## +## Value: String ## cluster.k8s.apiserver = http://10.110.111.204:8080 +## The service name helps build node name: {service_name}@{ip} +## +## Value: String ## cluster.k8s.service_name = emq -## Address Type: ip | dns +## The address type is used to extract host from k8s service. +## +## Value: ip | dns ## cluster.k8s.address_type = ip -## The Erlang application name +## The app name helps build 'node.name'. +## +## Value: String ## cluster.k8s.app_name = emq ##-------------------------------------------------------------------- ## Node Args ##-------------------------------------------------------------------- -## Node name +## Node name. +## +## Value: {name}@{host} +## +## Default: emq@127.0.0.1 node.name = emq@127.0.0.1 -## Cookie for distributed node +## Cookie for distributed node communication. +## +## Value: String node.cookie = emqsecretcookie -## SMP support: enable, auto, disable +## Enable SMP support of Erlang VM. +## +## Value: enable | auto | disable node.smp = auto +## Heartbeat monitoring of an Erlang runtime system. Comment the line to disable +## heartbeat, or set the value as 'on' +## or the line comment. +## +## Value: on +## ## vm.args: -heart -## Heartbeat monitoring of an Erlang runtime system -## Value should be 'on' or comment the line ## node.heartbeat = on -## Enable kernel poll +## Enable Kernel Poll. +## +## Value: on | off +## +## Default: on node.kernel_poll = on -## async thread pool +## Sets the number of threads in async thread pool. Valid range is 0-1024. +## More information at: http://erlang.org/doc/man/erl.html +## +## Value: 0-1024 +## +## vm.args: +A Number node.async_threads = 32 -## Erlang Process Limit +## Sets the maximum number of simultaneously existing processes for this +## system if a Number is passed as value. +## More information at: http://erlang.org/doc/man/erl.html +## +## Value: Number [1024-134217727] +## +## vm.args: +P Number node.process_limit = 256000 ## Sets the maximum number of simultaneously existing ports for this system +## if a Number is passed as value. +## More information at: http://erlang.org/doc/man/erl.html +## +## Value: Number [1024-134217727] +## +## vm.args: +Q Number node.max_ports = 65536 -## Set the distribution buffer busy limit (dist_buf_busy_limit) -node.dist_buffer_size = 32MB +## Set the distribution buffer busy limit (dist_buf_busy_limit). +## More information at: http://erlang.org/doc/man/erl.html +## +## Value: Number [1KB-2GB] +## +## vm.args: +zdbbl size +node.dist_buffer_size = 16MB -## Max ETS Tables. -## Note that mnesia and SSL will create temporary ets tables. +## Sets the maximum number of ETS tables. Note that mnesia and SSL +## will create temporary ETS tables. +## +## Value: Number +## +## vm.args: +e Number node.max_ets_tables = 256000 -## Tweak GC to run more often +## Tweak GC to run more often. +## +## Value: Number [0-65535] +## +## vm.args: -env ERL_FULLSWEEP_AFTER Number node.fullsweep_after = 1000 -## Crash dump +## Crash dump log file. +## +## Value: Log file node.crash_dump = {{ platform_log_dir }}/crash.dump -## Distributed node ticktime +## Specifies the net_kernel tick time. TickTime is specified in seconds. +## Notice that all communicating nodes are to have the same TickTime +## value specified. +## +## More information at: http://www.erlang.org/doc/man/kernel_app.html#net_ticktime +## +## Value: Number +## +## vm.args: -kernel net_ticktime Number node.dist_net_ticktime = 60 -## Distributed node port range +## Sets the port range for the listener socket of a distributed Erlang node. +## Note that if there is a firewall between clustered nodes, this port segment +## for nodes’ communication should be allowed. +## +## More information at: http://www.erlang.org/doc/man/kernel_app.html +## +## Value: Port [1024-65535] node.dist_listen_min = 6369 node.dist_listen_max = 6379 @@ -129,150 +252,244 @@ node.dist_listen_max = 6379 ## Log ##-------------------------------------------------------------------- -## Set the log dir +## Sets the log dir. +## +## Value: Folder log.dir = {{ platform_log_dir }} -## Console log. Enum: off, file, console, both +## Where to emit the console logs. +## +## Value: off | file | console | both +## - off: disabled +## - file: write to file +## - console: write to stdout +## - both: file and stdout log.console = console -## Console log level. Enum: debug, info, notice, warning, error, critical, alert, emergency +## Sets the severity level of console log. +## +## Value: debug | info | notice | warning | error | critical | alert | emergency +## +## Default: error log.console.level = error -## Console log file +## The file where console logs will be writed to, when 'log.console' is set to 'file'. +## +## Value: File Name ## log.console.file = {{ platform_log_dir }}/console.log -## Console log file size +## Maximum file size for console log. +## +## Value: Number(bytes) ## log.console.size = 10485760 -## Console log count size +## The rotation count for console log. +## +## Value: Number ## log.console.count = 5 -## Info log file +## The file where info logs will be writed to. +## +## Value: File Name ## log.info.file = {{ platform_log_dir }}/info.log -## Info log file size +## Maximum file size for info log. +## +## Value: Number(bytes) ## log.info.size = 10485760 -## Info log file count +## The rotation count for info log. +## +## Value: Number ## log.info.count = 5 -## Error log file +## The file where error logs will be writed to. +## +## Value: File Name log.error.file = {{ platform_log_dir }}/error.log -## Error log file size +## Maximum file size for error log. +## +## Value: Number(bytes) log.error.size = 10485760 -## Error log file count +## The rotation count for error log. +## +## Value: Number log.error.count = 5 -## Enable the crash log. Enum: on, off +## Enable the crash log. +## +## Value: on | off log.crash = on +## The file for crash log. +## +## Value: File Name log.crash.file = {{ platform_log_dir }}/crash.log -## Syslog. Enum: on, off +## Enable Syslog. +## +## Values: on | off log.syslog = on -## syslog level. Enum: debug, info, notice, warning, error, critical, alert, emergency +## The severity level for syslog. +## +## Value: debug | info | notice | warning | error | critical | alert | emergency log.syslog.level = error ##-------------------------------------------------------------------- -## Allow Anonymous and Default ACL +## Allow Anonymous Authentication and Default ACL ##-------------------------------------------------------------------- -## Allow Anonymous authentication +## Allow Anonymous Authentication. +## !!! Notice: Should disable the config for production deployment. +## +## Value: true | false mqtt.allow_anonymous = true -## ACL nomatch +## Default behaviour when ACL nomatch. +## +## Value: allow | deny mqtt.acl_nomatch = allow -## Default ACL File +## Default ACL File. +## +## Value: File Name mqtt.acl_file = {{ platform_etc_dir }}/acl.conf -## Cache ACL for PUBLISH +## Cache ACL for PUBLISH Messages. +## +## Value: true | false mqtt.cache_acl = true ##-------------------------------------------------------------------- ## MQTT Protocol ##-------------------------------------------------------------------- -## Max ClientId Length Allowed. +## Maximum MQTT clientId length allowed. +## +## Value: Number [23-65535] mqtt.max_clientid_len = 1024 -## Max Packet Size Allowed, 64K by default. +## Maximum MQTT packet size allowed. +## +## Value: Bytes +## +## Default: 64K mqtt.max_packet_size = 64KB -## Check Websocket Protocol Header. Enum: on, off +## Check if the websocket protocol header is valid. +## Turn off the config when developing WeChat App. +## +## Value: on | off mqtt.websocket_protocol_header = on -## The Keepalive timeout: Keepalive * backoff * 2 +## The backoff for MQTT keepalive timeout. +## The broker will kick a MQTT connection out until 'Keepalive * backoff * 2' timeout. +## +## Value: Float > 0.5 mqtt.keepalive_backoff = 0.75 ##-------------------------------------------------------------------- ## MQTT Connection ##-------------------------------------------------------------------- -## Force GC: integer. Value 0 disabled the Force GC. +## Force GC the MQTT connection. Value 0 will disable the Force GC. +## +## Value: Number >= 0 mqtt.conn.force_gc_count = 100 ##-------------------------------------------------------------------- ## MQTT Client ##-------------------------------------------------------------------- -## Client Idle Timeout (Second) +## MQTT client idle timeout, specified in seconds. +## +## Value: Duration mqtt.client.idle_timeout = 30s -## Max publish rate of Messages +## Maximum publish rate of MQTT messages per second. +## TODO: R2.4 release +## +## Value: Number ## mqtt.client.max_publish_rate = 5 -## Enable client Stats: on | off +## Enable per client statistics. +## +## Value: on | off mqtt.client.enable_stats = off ##-------------------------------------------------------------------- ## MQTT Session ##-------------------------------------------------------------------- -## Max Number of Subscriptions, 0 means no limit. +## Maximum number of subscriptions allowed, 0 means no limit. +## +## Value: Number mqtt.session.max_subscriptions = 0 -## Upgrade QoS? +## Force to upgrade QoS according to subscription. +## +## Value: on | off mqtt.session.upgrade_qos = off -## Max Size of the Inflight Window for QoS1 and QoS2 messages -## 0 means no limit +## Maximum size of the Inflight Window storing QoS1/2 messages delivered but unacked. +## +## Value: Number mqtt.session.max_inflight = 32 -## Retry Interval for redelivering QoS1/2 messages. +## Retry interval for QoS1/2 message redelivering. +## +## Value: Duration mqtt.session.retry_interval = 20s -## Client -> Broker: Max Packets Awaiting PUBREL, 0 means no limit -mqtt.session.max_awaiting_rel = 100 +## Maximum QoS2 packets (Client -> Broker) awaiting PUBREL, 0 means no limit. +## +## Value: Number +mqtt.session.max_awaiting_rel = 1000 -## Awaiting PUBREL Timeout -mqtt.session.await_rel_timeout = 20s +## The QoS2 messages (Client -> Broker) will be dropped if awaiting PUBREL timeout. +## +## Value: Duration +mqtt.session.await_rel_timeout = 30s -## Enable Statistics: on | off +## Enable per session statistics. +## +## Value: on | off mqtt.session.enable_stats = on -## Expired after 1 day: -## w - week -## d - day -## h - hour -## m - minute -## s - second +## Session expiration time. +## +## Value: Duration +## -d: day +## -h: hour +## -m: minute +## -s: second +## +## Default: 2h, 2 hours mqtt.session.expiry_interval = 2h -## Ignore message from self publish +## Ignore loop delivery of messages. +## +## Value: true | false +## +## Default: false mqtt.session.ignore_loop_deliver = false ##-------------------------------------------------------------------- ## MQTT Message Queue ##-------------------------------------------------------------------- -## Type: simple | priority +## Message Queue Type. +## +## Value: simple | priority mqtt.mqueue.type = simple -## Topic Priority: 0~255, Default is 0 +## Topic Priority. Default is 0. +## +## Value: Number [0-255] +## ## mqtt.mqueue.priority = topic/1=10,topic/2=8 ## Max queue length. Enqueued messages when persistent client disconnected, @@ -474,7 +691,7 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ### algorithm and the message digest algorithm. Selecting a good cipher suite is critical ### for the application’s data security, confidentiality and performance. ### The cipher list above offers: -### +### ### A good balance between compatibility with older browsers. It can get stricter for Machine-To-Machine scenarios. ### Perfect Forward Secrecy. ### No old/insecure encryption and HMAC algorithms From ad26eff4215e9ab9ce66fa34a59c0c2a8fe9b552 Mon Sep 17 00:00:00 2001 From: turtled Date: Wed, 3 Jan 2018 10:27:51 +0800 Subject: [PATCH 27/46] Format print log --- src/emqttd_ws.erl | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/emqttd_ws.erl b/src/emqttd_ws.erl index 35a7f9852..798c4d69b 100644 --- a/src/emqttd_ws.erl +++ b/src/emqttd_ws.erl @@ -45,14 +45,22 @@ handle_request('GET', "/mqtt", Req) -> Proto = check_protocol_header(Req), case {is_websocket(Upgrade), Proto} of {true, "mqtt" ++ _Vsn} -> - {ok, ProtoEnv} = emqttd:env(protocol), - PacketSize = get_value(max_packet_size, ProtoEnv, ?MAX_PACKET_SIZE), - Parser = emqttd_parser:initial_state(PacketSize), - %% Upgrade WebSocket. - {ReentryWs, ReplyChannel} = mochiweb_websocket:upgrade_connection(Req, fun ?MODULE:ws_loop/3), - {ok, ClientPid} = emqttd_ws_client_sup:start_client(self(), Req, ReplyChannel), - ReentryWs(#wsocket_state{peername = Req:get(peername), parser = Parser, - max_packet_size = PacketSize, client_pid = ClientPid}); + case Req:get(peername) of + {ok, Peername} -> + {ok, ProtoEnv} = emqttd:env(protocol), + PacketSize = get_value(max_packet_size, ProtoEnv, ?MAX_PACKET_SIZE), + Parser = emqttd_parser:initial_state(PacketSize), + %% Upgrade WebSocket. + {ReentryWs, ReplyChannel} = mochiweb_websocket:upgrade_connection(Req, fun ?MODULE:ws_loop/3), + {ok, ClientPid} = emqttd_ws_client_sup:start_client(self(), Req, ReplyChannel), + ReentryWs(#wsocket_state{peername = Peername, + parser = Parser, + max_packet_size = PacketSize, + client_pid = ClientPid}); + {error, Reason} -> + lager:error("Get peername with error ~s", [Reason]), + Req:respond({400, [], <<"Bad Request">>}) + end; {false, _} -> lager:error("Not WebSocket: Upgrade = ~s", [Upgrade]), Req:respond({400, [], <<"Bad Request">>}); From 0a7e93ea9076719c112990a14b3871935060f8fb Mon Sep 17 00:00:00 2001 From: turtled Date: Wed, 3 Jan 2018 10:29:51 +0800 Subject: [PATCH 28/46] Export funtion fix #1428 --- src/emqttd_mgmt.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emqttd_mgmt.erl b/src/emqttd_mgmt.erl index 01dd50b1e..1a608968e 100644 --- a/src/emqttd_mgmt.erl +++ b/src/emqttd_mgmt.erl @@ -45,7 +45,7 @@ -export([publish/1, subscribe/1, unsubscribe/1]). --export([kick_client/1, clean_acl_cache/2]). +-export([kick_client/1, kick_client/2, clean_acl_cache/2, clean_acl_cache/3]). -export([modify_config/2, modify_config/3, modify_config/4, get_configs/0, get_config/1, get_plugin_config/1, get_plugin_config/2, modify_plugin_config/2, modify_plugin_config/3]). From a17fae30e2fe58ad2cbc42d75b09fa95a5c62c6c Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 3 Jan 2018 22:44:54 +0800 Subject: [PATCH 29/46] Add more documentation for MQTT listeners --- etc/emq.conf | 375 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 299 insertions(+), 76 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 74f2b8a88..4cb8fc04b 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -492,50 +492,76 @@ mqtt.mqueue.type = simple ## ## mqtt.mqueue.priority = topic/1=10,topic/2=8 -## Max queue length. Enqueued messages when persistent client disconnected, +## Maximum queue length. Enqueued messages when persistent client disconnected, ## or inflight window is full. 0 means no limit. +## +## Value: Number >= 0 mqtt.mqueue.max_length = 1000 -## Low-water mark of queued messages +## Low-water mark of queued messages. +## +## Value: Percent mqtt.mqueue.low_watermark = 20% -## High-water mark of queued messages +## High-water mark of queued messages. +## +## Value: Percent mqtt.mqueue.high_watermark = 60% ## Queue Qos0 messages? +## +## Value: false | true mqtt.mqueue.store_qos0 = true ##-------------------------------------------------------------------- ## MQTT Broker and PubSub ##-------------------------------------------------------------------- -## System Interval of publishing broker $SYS Messages -mqtt.broker.sys_interval = 60 +## System Interval of publishing $SYS Messages. +## +## Value: Duration +## +## Default: 1m, 1 minute +mqtt.broker.sys_interval = 1m -## PubSub Pool Size. Default should be scheduler numbers. +## The PubSub pool size. Default value should be scheduler numbers. +## +## Value: Number > 1 mqtt.pubsub.pool_size = 8 -## Subscribe Asynchronously +## TODO: Subscribe Asynchronously. +## +## Value: true | false mqtt.pubsub.async = true ##-------------------------------------------------------------------- ## MQTT Bridge ##-------------------------------------------------------------------- -## Bridge Queue Size +## The pending message queue size of bridge. +## +## Value: Number mqtt.bridge.max_queue_len = 10000 -## Ping Interval of bridge node. Unit: Second -mqtt.bridge.ping_down_interval = 1 +## Ping interval of bridge node. +## +## Value: Duration +## +## Default: 1s, 1 second +mqtt.bridge.ping_down_interval = 1s ##------------------------------------------------------------------- ## MQTT Plugins ##------------------------------------------------------------------- -## Dir of plugins' config +## The etc dir for plugins' config. +## +## Value: Folder mqtt.plugins.etc_dir ={{ platform_etc_dir }}/plugins/ -## File to store loaded plugin names. +## The file to store loaded plugin names. +## +## Value: File mqtt.plugins.loaded_file = {{ platform_data_dir }}/loaded_plugins ##-------------------------------------------------------------------- @@ -543,134 +569,276 @@ mqtt.plugins.loaded_file = {{ platform_data_dir }}/loaded_plugins ##-------------------------------------------------------------------- ##-------------------------------------------------------------------- -## External TCP Listener +## MQTT/TCP - External TCP Listener for MQTT Protocol -## External TCP Listener: 1883, 127.0.0.1:1883, ::1:1883 +## listener.tcp. is the IP address and port that the MQTT/TCP +## listener will bind. +## +## Value: IP:Port | Port +## +## Examples: 1883, 127.0.0.1:1883, ::1:1883 listener.tcp.external = 0.0.0.0:1883 -## Size of acceptor pool +## The acceptor pool for external MQTT/TCP listener. +## +## Value: Number listener.tcp.external.acceptors = 16 -## Maximum number of concurrent clients +## Maximum number of concurrent MQTT/TCP connections. +## +## Value: Number listener.tcp.external.max_clients = 102400 -## TODO: +## TODO: Zone of the external MQTT/TCP listener belonged to. +## +## Value: String ## listener.tcp.external.zone = external -#listener.tcp.external.mountpoint = external/ +## Mountpoint of the MQTT/TCP Listener. All the topics of this +## listener will be prefixed with the mount point if this option +## is enabled. +## +## Value: String +## listener.tcp.external.mountpoint = external/ -## Rate Limit. Format is 'burst,rate', Unit is KB/Sec -#listener.tcp.external.rate_limit = 100,10 - -#listener.tcp.external.access.1 = allow 192.168.0.0/24 +## Rate limit for the external MQTT/TCP connections. +## Format is 'burst,rate'. +## +## Value: burst,rate +## Unit: KB/sec +## listener.tcp.external.rate_limit = 100,10 +## The access control rules for the MQTT/TCP listener. +## More information at: https://github.com/emqtt/esockd#allowdeny +## +## Value: ACL Rule +## listener.tcp.external.access.1 = allow 192.168.0.0/24 listener.tcp.external.access.2 = allow all -## Proxy Protocol V1/2 +## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind +## HAProxy or Nginx. +## More information at: https://www.haproxy.com/blog/haproxy/proxy-protocol/ +## +## Value: on | off ## listener.tcp.external.proxy_protocol = on + +## Sets the timeout for proxy protocol. EMQ will close the TCP connection +## if no proxy protocol packet recevied within the timeout. +## +## Value: Duration ## listener.tcp.external.proxy_protocol_timeout = 3s -### Use the PP2_SUBTYPE_SSL_CN field from Proxy Protocol V2 as a username. +## Enable the option for X.509 certificate based authentication. +## EMQ will Use the PP2_SUBTYPE_SSL_CN field in Proxy Protocol V2 +## as MQTT username. +## +## Value: cn ## listener.tcp.external.peer_cert_as_username = cn -## TCP Socket Options +## TCP socket options for the MQTT listener. + +## The TCP backlog defines the maximum length that the queue of pending +## connections can grow to. +## +## Value: Number >= 0 listener.tcp.external.backlog = 1024 +## The TCP send timeout for external MQTT connections. +## +## Value: Duration listener.tcp.external.send_timeout = 15s +## Close the TCP connection if send timeout. +## +## Value: on | off listener.tcp.external.send_timeout_close = on -#listener.tcp.external.recbuf = 4KB +## The TCP receive buffer(os kernel) for MQTT connections. +## More information at: http://erlang.org/doc/man/inet.html +## +## Value: Bytes +## listener.tcp.external.recbuf = 4KB -#listener.tcp.external.sndbuf = 4KB +## The TCP send buffer(os kernel) for MQTT connections. +## More information at: http://erlang.org/doc/man/inet.html +## +## Value: Bytes +## listener.tcp.external.sndbuf = 4KB -listener.tcp.external.buffer = 4KB +## The size of the user-level software buffer used by the driver. +## Not to be confused with options sndbuf and recbuf, which correspond +## to the Kernel socket buffers. It is recommended to have val(buffer) +## >= max(val(sndbuf),val(recbuf)) to avoid performance issues because +## of unnecessary copying. val(buffer) is automatically set to the above +## maximum when values sndbuf or recbuf are set. +## More information at: http://erlang.org/doc/man/inet.html +## +## Value: Bytes +## listener.tcp.external.buffer = 4KB +## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled. +## +## Value: on | off +listener.tcp.external.tune_buffer = on + +## The TCP_NODELAY flag for MQTT connections. Small amounts of data are +## sent immediately if the option is enabled. +## +## Value: true | false listener.tcp.external.nodelay = true ##-------------------------------------------------------------------- -## Internal TCP Listener +## Internal TCP Listener for MQTT Protocol -## Internal TCP Listener: 11883, 127.0.0.1:11883, ::1:11883 +## The IP address and port that the internal MQTT/TCP protocol listener will +## bind. +## +## Value: IP:Port, Port +## +## Examples: 11883, 127.0.0.1:11883, ::1:11883 listener.tcp.internal = 127.0.0.1:11883 -## Size of acceptor pool -listener.tcp.internal.acceptors = 16 +## The acceptor pool for internal MQTT/TCP listener. +## +## Value: Number +listener.tcp.internal.acceptors = 4 -## Maximum number of concurrent clients +## Maximum number of concurrent MQTT/TCP connections. +## +## Value: Number listener.tcp.internal.max_clients = 102400 -#listener.tcp.internal.zone = internal +## TODO: Zone of the internal MQTT/TCP listener belonged to. +## +## Value: String +## listener.tcp.internal.zone = internal -#listener.tcp.external.mountpoint = internal/ +## Mountpoint of the MQTT/TCP Listener. All the topics will +## be prefixed with the mount point if this option is enabled. +## +## Value: String +## listener.tcp.external.mountpoint = internal/ -## Rate Limit. Format is 'burst,rate', Unit is KB/Sec +## Rate limit for the internal MQTT/TCP connections. +## Format is 'burst,rate'. +## +## Value: burst,rate +## Unit: KB/sec ## listener.tcp.internal.rate_limit = 1000,100 -## TCP Socket Options +## The TCP backlog defines the maximum length that the queue of +## pending connections can grow to. +## +## Value: Number >= 0 listener.tcp.internal.backlog = 512 -listener.tcp.internal.send_timeout = 15s +## The TCP send timeout for internal MQTT connections. +## +## Value: Duration +listener.tcp.internal.send_timeout = 5s +## Close the MQTT/TCP connection if send timeout. +## +## Value: on | off listener.tcp.external.send_timeout_close = on +## The TCP receive buffer(os kernel) for MQTT connections. +## More information at: http://erlang.org/doc/man/inet.html +## +## Value: Bytes +listener.tcp.internal.recbuf = 16KB + +## The TCP send buffer(os kernel) for MQTT connections. +## More information at: http://erlang.org/doc/man/inet.html +## +## Value: Bytes +listener.tcp.internal.sndbuf = 16KB + +## The size of the user-level software buffer used by the driver. +## See: listener.tcp.external.buffer +## +## Value: Bytes +listener.tcp.internal.buffer = 16KB + +## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled. +## +## Value: on | off listener.tcp.internal.tune_buffer = on -listener.tcp.internal.buffer = 1MB - -listener.tcp.internal.recbuf = 4KB - -listener.tcp.internal.sndbuf = 1MB - -listener.tcp.internal.nodelay = true +## The TCP_NODELAY flag for MQTT connections. +## See: listener.tcp.external.nodelay +# +## Value: true | false +listener.tcp.internal.nodelay = false ##-------------------------------------------------------------------- -## External SSL Listener +## MQTT/SSL - External SSL Listener for MQTT Protocol -## SSL Listener: 8883, 127.0.0.1:8883, ::1:8883 +## listener.ssl. is the IP address and port that the MQTT/SSL +## listener will bind. +## +## Value: IP:Port | Port +## +## Examples: 8883, 127.0.0.1:8883, ::1:8883 listener.ssl.external = 8883 -## Size of acceptor pool +## The acceptor pool for external MQTT/SSL listener. +## +## Value: Number listener.ssl.external.acceptors = 16 -## Maximum number of concurrent clients +## Maximum number of concurrent MQTT/SSL connections. +## +## Value: Number listener.ssl.external.max_clients = 1024 -## Authentication Zone +## TODO: Zone of the external MQTT/SSL listener belonged to. +## +## Value: String ## listener.ssl.external.zone = external +## Mountpoint of the MQTT/SSL Listener. All the topics of this +## listener will be prefixed with the mount point if this option +## is enabled. +## +## Value: String ## listener.ssl.external.mountpoint = inbound/ -## Rate Limit. Format is 'burst,rate', Unit is KB/Sec +## Rate limit for the external MQTT/SSL connections. +## Format is 'burst,rate'. +## +## Value: burst,rate +## Unit: KB/sec ## listener.ssl.external.rate_limit = 100,10 -## Proxy Protocol V1/2 +## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind +## HAProxy or Nginx. +## More information at: https://www.haproxy.com/blog/haproxy/proxy-protocol/ +## +## Value: on | off ## listener.ssl.external.proxy_protocol = on + +## Sets the timeout for proxy protocol. EMQ will close the TCP connection +## if no proxy protocol packet recevied within the timeout. +## +## Value: Duration ## listener.ssl.external.proxy_protocol_timeout = 3s +## The access control rules for the MQTT/SSL listener. +## More information at: https://github.com/emqtt/esockd#allowdeny +## +## Value: ACL Rule listener.ssl.external.access.1 = allow all -### SSL Options. See http://erlang.org/doc/man/ssl.html - -## Configuring SSL Options. See http://erlang.org/doc/man/ssl.html -### TLS only for POODLE attack +## TLS versions only to protect from POODLE attack. +## See http://erlang.org/doc/man/ssl.html +## +## Value: String ## listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 -### The Ephemeral Diffie-Helman key exchange is a very effective way of -### ensuring Forward Secrecy by exchanging a set of keys that never hit -### the wire. Since the DH key is effectively signed by the private key, -### it needs to be at least as strong as the private key. In addition, -### the default DH groups that most of the OpenSSL installations have -### are only a handful (since they are distributed with the OpenSSL -### package that has been built for the operating system it’s running on) -### and hence predictable (not to mention, 1024 bits only). - -### In order to escape this situation, first we need to generate a fresh, -### strong DH group, store it in a file and then use the option above, -### to force our SSL application to use the new DH group. Fortunately, -### OpenSSL provides us with a tool to do that. Simply run: -### openssl dhparam -out dh-params.pem 2048 - +## TLS Handshake timeout. +## +## Value: Duration listener.ssl.external.handshake_timeout = 15s listener.ssl.external.keyfile = {{ platform_etc_dir }}/certs/key.pem @@ -679,6 +847,19 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## listener.ssl.external.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem +## The Ephemeral Diffie-Helman key exchange is a very effective way of +## ensuring Forward Secrecy by exchanging a set of keys that never hit +## the wire. Since the DH key is effectively signed by the private key, +## it needs to be at least as strong as the private key. In addition, +## the default DH groups that most of the OpenSSL installations have +## are only a handful (since they are distributed with the OpenSSL +## package that has been built for the operating system it’s running on) +## and hence predictable (not to mention, 1024 bits only). +## In order to escape this situation, first we need to generate a fresh, +## strong DH group, store it in a file and then use the option above, +## to force our SSL application to use the new DH group. Fortunately, +## OpenSSL provides us with a tool to do that. Simply run: +## openssl dhparam -out dh-params.pem 2048 ## listener.ssl.external.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem ## listener.ssl.external.verify = verify_peer @@ -816,37 +997,79 @@ listener.wss.external.send_timeout_close = on ##-------------------------------------------------------------------- ## HTTP Management API Listener +## The IP Address and Port that the EMQ HTTP API will bind. +## +## Value: IP:Port | Port +## +## Default: 0.0.0.0:8080 listener.api.mgmt = 0.0.0.0:8080 +## The TCP Acceptor pool size. +## +## Value: Number listener.api.mgmt.acceptors = 4 +## Maximum concurrent HTTP clients allowed. +## +## Value: Number listener.api.mgmt.max_clients = 64 +## The access control rules for the listener. +## More information at: https://github.com/emqtt/esockd#allowdeny +## +## Value: ACL Rule listener.api.mgmt.access.1 = allow all +## The TCP backlog defines the maximum length that the queue of pending +## connections can grow to. +## +## Value: Number >= 0 listener.api.mgmt.backlog = 512 +## The TCP send timeout. +## +## Value: Duration listener.api.mgmt.send_timeout = 15s +## Close the TCP connection if send timeout. +## +## Value: on | off listener.api.mgmt.send_timeout_close = on ##------------------------------------------------------------------- ## System Monitor ##------------------------------------------------------------------- -## Long GC, don't monitor in production mode for: +## Enable Long GC monitoring. +## Notice: don't enable the monitor in production for: ## https://github.com/erlang/otp/blob/feb45017da36be78d4c5784d758ede619fa7bfd3/erts/emulator/beam/erl_gc.c#L421 +## +## Value: true | false sysmon.long_gc = false -## Long Schedule(ms) +## Enable Long Schedule(ms) monitoring. +## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## Value: Number sysmon.long_schedule = 240 -## 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM. +## Enable Large Heap monitoring. +## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## Value: bytes +## +## Default: 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM. sysmon.large_heap = 8MB -## Busy Port +## Enable Busy Port monitoring. +## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## Value: true | false sysmon.busy_port = false -## Busy Dist Port +## Enable Busy Dist Port monitoring. +## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## Value: true | false sysmon.busy_dist_port = true From 00760328157634a88cdc90ac87bc37fff7d17c99 Mon Sep 17 00:00:00 2001 From: "mingchun.or" Date: Thu, 4 Jan 2018 11:36:33 +0800 Subject: [PATCH 30/46] fix wrong link in emq-retainer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83fe86177..e0ecc1fe1 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Plugin | Descrip -----------------------------------------------------------------------|-------------------------------------- [emq_plugin_template](https://github.com/emqtt/emq_plugin_template) | Plugin template and demo [emq_dashboard](https://github.com/emqtt/emq_dashboard) | Web Dashboard -[emq_retainer](https://github.com/emqtt/emq_retainer) | Store MQTT Retained Messages +[emq_retainer](https://github.com/emqtt/emq-retainer) | Store MQTT Retained Messages [emq_modules](https://github.com/emqtt/emq-modules) | Presence, Subscription and Rewrite Modules [emq_auth_username](https://github.com/emqtt/emq_auth_username) | Username/Password Authentication Plugin [emq_auth_clientid](https://github.com/emqtt/emq_auth_clientid) | ClientId Authentication Plugin From b2b78c178cd73583c1d3760c38de39d04084f10c Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 12:25:05 +0800 Subject: [PATCH 31/46] Add documenation for SSL configurations --- etc/emq.conf | 220 ++++++++++++++++++++++++++++++++++++++++-------- priv/emq.schema | 8 +- 2 files changed, 188 insertions(+), 40 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 4cb8fc04b..ef16ecc6b 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -841,10 +841,21 @@ listener.ssl.external.access.1 = allow all ## Value: Duration listener.ssl.external.handshake_timeout = 15s +## Path to the file containing the user's private PEM-encoded key. +## More information at: http://erlang.org/doc/man/ssl.html +## +## Value: File listener.ssl.external.keyfile = {{ platform_etc_dir }}/certs/key.pem +## Path to a file containing the user certificate. +## +## Value: File listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem +## Path to a file containing PEM-encoded CA certificates. The CA certificates +## are used during server authentication and when building the client certificate chain. +## +## Value: File ## listener.ssl.external.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem ## The Ephemeral Diffie-Helman key exchange is a very effective way of @@ -860,114 +871,238 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## to force our SSL application to use the new DH group. Fortunately, ## OpenSSL provides us with a tool to do that. Simply run: ## openssl dhparam -out dh-params.pem 2048 +## +## Value: File ## listener.ssl.external.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem +## A server only does x509-path validation in mode verify_peer, +## as it then sends a certificate request to the client (this +## message is not sent if the verify option is verify_none). +## You can then also want to specify option fail_if_no_peer_cert. +## More information at: http://erlang.org/doc/man/ssl.html +## +## Value: verify_peer | verify_none ## listener.ssl.external.verify = verify_peer +## Used together with {verify, verify_peer} by an SSL server. If set to true, +## the server fails if the client does not have a certificate to send, that is, +## sends an empty certificate. +## +## Value: true | false ## listener.ssl.external.fail_if_no_peer_cert = true -### This is the single most important configuration option of an Erlang SSL application. -### Ciphers (and their ordering) define the way the client and server encrypt information -### over the wire, from the initial Diffie-Helman key exchange, the session key encryption -### algorithm and the message digest algorithm. Selecting a good cipher suite is critical -### for the application’s data security, confidentiality and performance. -### The cipher list above offers: -### -### A good balance between compatibility with older browsers. It can get stricter for Machine-To-Machine scenarios. -### Perfect Forward Secrecy. -### No old/insecure encryption and HMAC algorithms -### -### Most of it was copied from Mozilla’s Server Side TLS article +## This is the single most important configuration option of an Erlang SSL application. +## Ciphers (and their ordering) define the way the client and server encrypt information +## over the wire, from the initial Diffie-Helman key exchange, the session key encryption +## algorithm and the message digest algorithm. Selecting a good cipher suite is critical +## for the application’s data security, confidentiality and performance. +## The cipher list above offers: +## +## A good balance between compatibility with older browsers. It can get stricter for Machine-To-Machine scenarios. +## Perfect Forward Secrecy. +## No old/insecure encryption and HMAC algorithms +## +## Most of it was copied from Mozilla’s Server Side TLS article +## +## Value: Ciphers ## listener.ssl.external.ciphers = 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 -### SSL parameter renegotiation is a feature that allows a client and -### a server to renegotiate the parameters of the SSL connection on the fly. -### RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation, -### you drop support for the insecure renegotiation, prone to MitM attacks. +## SSL parameter renegotiation is a feature that allows a client and +## a server to renegotiate the parameters of the SSL connection on the fly. +## RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation, +## you drop support for the insecure renegotiation, prone to MitM attacks. +## +## Value: on | off ## listener.ssl.external.secure_renegotiate = off -### A performance optimization setting, it allows clients to reuse -### pre-existing sessions, instead of initializing new ones. -### Read more about it here. +## A performance optimization setting, it allows clients to reuse +## pre-existing sessions, instead of initializing new ones. +## Read more about it here. +## More information at: http://erlang.org/doc/man/ssl.html +## +## Value: on | off ## listener.ssl.external.reuse_sessions = on -### An important security setting, it forces the cipher to be set based on -### the server-specified order instead of the client-specified order, -### hence enforcing the (usually more properly configured) security -### ordering of the server administrator. +## An important security setting, it forces the cipher to be set based +## on the server-specified order instead of the client-specified order, +## hence enforcing the (usually more properly configured) security +## ordering of the server administrator. +## +## Value: on | off ## listener.ssl.external.honor_cipher_order = on -### Use the CN or DN value from the client certificate as a username. -### Notice: 'verify' should be configured as 'verify_peer' +## Use the CN or DN value from the client certificate as a username. +## Notice that 'verify' should be set as 'verify_peer'. +## +## Value: cn | dn ## listener.ssl.external.peer_cert_as_username = cn -## SSL Socket Options +## TCP backlog for the SSL connection. +## See 'listener.tcp.external.backlog' +## +## Value: Number >= 0 ## listener.ssl.external.backlog = 1024 +## The TCP send timeout for the SSL connection. +## See 'listener.tcp.external.send_timeout' +## +## Value: Duration ## listener.ssl.external.send_timeout = 15s +## See 'listener.tcp.external.send_timeout_close' +## +## Value: on | off ## listener.ssl.external.send_timeout_close = on +## See 'listener.tcp.external.recbuf' +## +## Value: Bytes ## listener.ssl.external.recbuf = 4KB +## See 'listener.tcp.external.sndbuf' +## +## Value: Bytes ## listener.ssl.external.sndbuf = 4KB +## See 'listener.tcp.external.buffer' +## +## Value: Bytes ## listener.ssl.external.buffer = 4KB +## See 'listener.tcp.external.nodelay' +## +## Value: true | false ## listener.ssl.external.nodelay = true ##-------------------------------------------------------------------- -## External MQTT/WebSocket Listener +## External WebSocket Listener for MQTT Protocol +## listener.ws. is the IP address and port that the MQTT/Websocket +## listener will bind. +## +## Value: IP:Port | Port +## +## Examples: 8083, 127.0.0.1:8083, ::1:8083 listener.ws.external = 8083 +## The acceptor pool for external MQTT/Websocket listener. +## +## Value: Number listener.ws.external.acceptors = 4 +## Maximum number of concurrent MQTT/Websocket connections. +## +## Value: Number listener.ws.external.max_clients = 64 +## TODO: Zone of the external MQTT/Websocket listener belonged to. +## +## Value: String ## listener.ws.external.zone = external +## Mountpoint of the MQTT/Websocket Listener. All the topics of +## this listener will be prefixed with the mount point if this +## option is enabled. +## +## Value: String +## listener.ws.external.mountpoint = external/ + +## The access control rules for the MQTT/Websocket listener. +## +## Value: ACL Rule listener.ws.external.access.1 = allow all -## Proxy Protocol V1/2 +## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind +## HAProxy or Nginx. +## +## Value: on | off ## listener.ws.external.proxy_protocol = on + +## See 'listener.tcp.external.proxy_protocol_timeout' +## +## Value: Duration ## listener.ws.external.proxy_protocol_timeout = 3s ## TCP Options listener.ws.external.backlog = 1024 +## See 'listener.tcp.external.send_timeout' +## +## Value: Duration listener.ws.external.send_timeout = 15s +## See 'listener.tcp.external.send_timeout_close' +## +## Value: on | off listener.ws.external.send_timeout_close = on -listener.ws.external.recbuf = 4KB +## See 'listener.tcp.external.recbuf' +## +## Value: Bytes +## listener.ws.external.recbuf = 4KB -listener.ws.external.sndbuf = 4KB +## See 'listener.tcp.external.sndbuf' +## +## Value: Bytes +## listener.ws.external.sndbuf = 4KB -listener.ws.external.buffer = 4KB +## See 'listener.tcp.external.buffer' +## +## Value: Bytes +## listener.ws.external.buffer = 4KB +## See 'listener.tcp.external.nodelay' +## +## Value: true | false listener.ws.external.nodelay = true ##-------------------------------------------------------------------- -## External MQTT/WebSocket/SSL Listener +## External WebSocket/SSL listener for MQTT Protocol +## listener.wss. is the IP address and port that the MQTT/Websocket/SSL +## listener will bind. +## +## Value: IP:Port | Port +## +## Examples: 8084, 127.0.0.1:8084, ::1:8084 listener.wss.external = 8084 +## The acceptor pool for external MQTT/Websocket/SSL listener. +## +## Value: Number listener.wss.external.acceptors = 4 +## Maximum number of concurrent MQTT/Webwocket/SSL connections. +## +## Value: Number listener.wss.external.max_clients = 64 +## TODO: Zone of the external MQTT/Websocket/SSL listener belonged to. +## +## Value: String ## listener.wss.external.zone = external +## See 'listener.ssl.external.mountpoint' +## +## Value: String +## listener.wss.external.mountpoint = inbound/ + +## See 'listener.ssl.external.acess.1' +## +## Value: ACL Rule listener.wss.external.access.1 = allow all -## Proxy Protocol V1/2 +## See 'listener.ssl.external.proxy_protocol' +## +## Value: on | off ## listener.wss.external.proxy_protocol = on + +## See 'listener.ssl.external.proxy_protocol_timeout' +## +## Value: Duration ## listener.wss.external.proxy_protocol_timeout = 3s -## SSL Option -### SSL Options. See http://erlang.org/doc/man/ssl.html - +## SSL Options. Same to 'listener.ssl.*' listener.wss.external.handshake_timeout = 15s listener.wss.external.keyfile = {{ platform_etc_dir }}/certs/key.pem @@ -976,10 +1111,23 @@ listener.wss.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## listener.wss.external.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem +## listener.ssl.external.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem + ## listener.wss.external.verify = verify_peer ## listener.wss.external.fail_if_no_peer_cert = true +## listener.wss.external.ciphers = + +## listener.wss.external.secure_renegotiate = off + +## listener.wss.external.reuse_sessions = on + +## listener.wss.external.honor_cipher_order = on + +## listener.wss.external.peer_cert_as_username = cn + +## TCP Options. Same to 'listener.tcp.*' listener.wss.external.backlog = 1024 listener.wss.external.send_timeout = 15s diff --git a/priv/emq.schema b/priv/emq.schema index aaefce4c2..ca242c4c7 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -702,8 +702,8 @@ end}. %%-------------------------------------------------------------------- {mapping, "mqtt.broker.sys_interval", "emqttd.broker_sys_interval", [ - {default, 60}, - {datatype, integer} + {datatype, {duration, ms}}, + {default, "1m"} ]}. %%-------------------------------------------------------------------- @@ -735,8 +735,8 @@ end}. ]}. {mapping, "mqtt.bridge.ping_down_interval", "emqttd.bridge", [ - {default, 1}, - {datatype, integer} + {datatype, {duration, ms}}, + {default, "1s"} ]}. {translation, "emqttd.bridge", fun(Conf) -> From b98a320124f4053a47b16ce03ae993abdd4d8e6c Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 15:32:21 +0800 Subject: [PATCH 32/46] Improve documentation for all options --- etc/emq.conf | 442 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 303 insertions(+), 139 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index ef16ecc6b..4d37515aa 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -29,9 +29,10 @@ cluster.discovery = manual ## Default: on cluster.autoheal = on -## AutoClean down node after this duration. +## Autoclean down node. A down node will be removed from the cluster +## if this value > 0. ## -## Value: time duration with units +## Value: Duration ## -h: hour, e.g. '2h' for 2 hours ## -m: minute, e.g. '5m' for 5 minutes ## -s: second, e.g. '30s' for 30 seconds @@ -70,8 +71,6 @@ cluster.autoclean = 5m ## Multicast Ttl. ## ## Value: 0-255 -## -## Default: 255 ## cluster.mcast.ttl = 255 ## Multicast loop. @@ -101,7 +100,7 @@ cluster.autoclean = 5m ## cluster.etcd.server = http://127.0.0.1:2379 ## The prefix helps build nodes path in etcd. Each node in the cluster -## will create a path in etcd: v2/keys/{prefix}/{cluster.name}/{node.name} +## will create a path in etcd: v2/keys/// ## ## Value: String ## cluster.etcd.prefix = emqcl @@ -121,7 +120,7 @@ cluster.autoclean = 5m ## Value: String ## cluster.k8s.apiserver = http://10.110.111.204:8080 -## The service name helps build node name: {service_name}@{ip} +## The service name helps lookup EMQ nodes in the cluster. ## ## Value: String ## cluster.k8s.service_name = emq @@ -142,7 +141,9 @@ cluster.autoclean = 5m ## Node name. ## -## Value: {name}@{host} +## See: http://erlang.org/doc/reference_manual/distributed.html +## +## Value: @ ## ## Default: emq@127.0.0.1 node.name = emq@127.0.0.1 @@ -159,14 +160,13 @@ node.smp = auto ## Heartbeat monitoring of an Erlang runtime system. Comment the line to disable ## heartbeat, or set the value as 'on' -## or the line comment. ## ## Value: on ## ## vm.args: -heart ## node.heartbeat = on -## Enable Kernel Poll. +## Enable kernel poll. ## ## Value: on | off ## @@ -174,7 +174,8 @@ node.smp = auto node.kernel_poll = on ## Sets the number of threads in async thread pool. Valid range is 0-1024. -## More information at: http://erlang.org/doc/man/erl.html +## +## See: http://erlang.org/doc/man/erl.html ## ## Value: 0-1024 ## @@ -183,7 +184,8 @@ node.async_threads = 32 ## Sets the maximum number of simultaneously existing processes for this ## system if a Number is passed as value. -## More information at: http://erlang.org/doc/man/erl.html +## +## See: http://erlang.org/doc/man/erl.html ## ## Value: Number [1024-134217727] ## @@ -192,7 +194,8 @@ node.process_limit = 256000 ## Sets the maximum number of simultaneously existing ports for this system ## if a Number is passed as value. -## More information at: http://erlang.org/doc/man/erl.html +## +## See: http://erlang.org/doc/man/erl.html ## ## Value: Number [1024-134217727] ## @@ -200,15 +203,16 @@ node.process_limit = 256000 node.max_ports = 65536 ## Set the distribution buffer busy limit (dist_buf_busy_limit). -## More information at: http://erlang.org/doc/man/erl.html +## +## See: http://erlang.org/doc/man/erl.html ## ## Value: Number [1KB-2GB] ## ## vm.args: +zdbbl size -node.dist_buffer_size = 16MB +node.dist_buffer_size = 8MB -## Sets the maximum number of ETS tables. Note that mnesia and SSL -## will create temporary ETS tables. +## Sets the maximum number of ETS tables. Note that mnesia and SSL will +## create temporary ETS tables. ## ## Value: Number ## @@ -227,11 +231,11 @@ node.fullsweep_after = 1000 ## Value: Log file node.crash_dump = {{ platform_log_dir }}/crash.dump -## Specifies the net_kernel tick time. TickTime is specified in seconds. +## Sets the net_kernel tick time. TickTime is specified in seconds. ## Notice that all communicating nodes are to have the same TickTime ## value specified. ## -## More information at: http://www.erlang.org/doc/man/kernel_app.html#net_ticktime +## See: http://www.erlang.org/doc/man/kernel_app.html#net_ticktime ## ## Value: Number ## @@ -239,10 +243,10 @@ node.crash_dump = {{ platform_log_dir }}/crash.dump node.dist_net_ticktime = 60 ## Sets the port range for the listener socket of a distributed Erlang node. -## Note that if there is a firewall between clustered nodes, this port segment +## Note that if there are firewalls between clustered nodes, this port segment ## for nodes’ communication should be allowed. ## -## More information at: http://www.erlang.org/doc/man/kernel_app.html +## See: http://www.erlang.org/doc/man/kernel_app.html ## ## Value: Port [1024-65535] node.dist_listen_min = 6369 @@ -273,7 +277,7 @@ log.console = console ## Default: error log.console.level = error -## The file where console logs will be writed to, when 'log.console' is set to 'file'. +## The file where console logs will be writed to, when 'log.console' is set as 'file'. ## ## Value: File Name ## log.console.file = {{ platform_log_dir }}/console.log @@ -328,12 +332,12 @@ log.crash = on ## Value: File Name log.crash.file = {{ platform_log_dir }}/crash.log -## Enable Syslog. +## Enable syslog. ## ## Values: on | off log.syslog = on -## The severity level for syslog. +## Sets the severity level for syslog. ## ## Value: debug | info | notice | warning | error | critical | alert | emergency log.syslog.level = error @@ -343,7 +347,8 @@ log.syslog.level = error ##-------------------------------------------------------------------- ## Allow Anonymous Authentication. -## !!! Notice: Should disable the config for production deployment. +## +## Notice: Disable the option for production deployment. ## ## Value: true | false mqtt.allow_anonymous = true @@ -358,7 +363,7 @@ mqtt.acl_nomatch = allow ## Value: File Name mqtt.acl_file = {{ platform_etc_dir }}/acl.conf -## Cache ACL for PUBLISH Messages. +## Whether to cache ACL for publish messages. ## ## Value: true | false mqtt.cache_acl = true @@ -367,7 +372,7 @@ mqtt.cache_acl = true ## MQTT Protocol ##-------------------------------------------------------------------- -## Maximum MQTT clientId length allowed. +## Maximum length of MQTT clientId allowed. ## ## Value: Number [23-65535] mqtt.max_clientid_len = 1024 @@ -380,13 +385,13 @@ mqtt.max_clientid_len = 1024 mqtt.max_packet_size = 64KB ## Check if the websocket protocol header is valid. -## Turn off the config when developing WeChat App. +## Turn off the option when developing WeChat App. ## ## Value: on | off mqtt.websocket_protocol_header = on ## The backoff for MQTT keepalive timeout. -## The broker will kick a MQTT connection out until 'Keepalive * backoff * 2' timeout. +## EMQ will kick a MQTT connection out until 'Keepalive * backoff * 2' timeout. ## ## Value: Float > 0.5 mqtt.keepalive_backoff = 0.75 @@ -395,7 +400,7 @@ mqtt.keepalive_backoff = 0.75 ## MQTT Connection ##-------------------------------------------------------------------- -## Force GC the MQTT connection. Value 0 will disable the Force GC. +## Force GC the MQTT connections. Value 0 will disable the Force GC. ## ## Value: Number >= 0 mqtt.conn.force_gc_count = 100 @@ -409,8 +414,7 @@ mqtt.conn.force_gc_count = 100 ## Value: Duration mqtt.client.idle_timeout = 30s -## Maximum publish rate of MQTT messages per second. -## TODO: R2.4 release +## TODO: Maximum publish rate of MQTT messages per second. ## ## Value: Number ## mqtt.client.max_publish_rate = 5 @@ -439,7 +443,7 @@ mqtt.session.upgrade_qos = off ## Value: Number mqtt.session.max_inflight = 32 -## Retry interval for QoS1/2 message redelivering. +## Retry interval for QoS1/2 message delivering. ## ## Value: Duration mqtt.session.retry_interval = 20s @@ -470,7 +474,7 @@ mqtt.session.enable_stats = on ## Default: 2h, 2 hours mqtt.session.expiry_interval = 2h -## Ignore loop delivery of messages. +## Whether to ignore loop delivery of messages. ## ## Value: true | false ## @@ -481,12 +485,12 @@ mqtt.session.ignore_loop_deliver = false ## MQTT Message Queue ##-------------------------------------------------------------------- -## Message Queue Type. +## Message queue type. ## ## Value: simple | priority mqtt.mqueue.type = simple -## Topic Priority. Default is 0. +## Topic priority. Default is 0. ## ## Value: Number [0-255] ## @@ -508,7 +512,7 @@ mqtt.mqueue.low_watermark = 20% ## Value: Percent mqtt.mqueue.high_watermark = 60% -## Queue Qos0 messages? +## Whether to enqueue Qos0 messages. ## ## Value: false | true mqtt.mqueue.store_qos0 = true @@ -517,19 +521,19 @@ mqtt.mqueue.store_qos0 = true ## MQTT Broker and PubSub ##-------------------------------------------------------------------- -## System Interval of publishing $SYS Messages. +## System interval of publishing $SYS messages. ## ## Value: Duration ## ## Default: 1m, 1 minute mqtt.broker.sys_interval = 1m -## The PubSub pool size. Default value should be scheduler numbers. +## The PubSub pool size. Default value should be same as scheduler numbers. ## ## Value: Number > 1 mqtt.pubsub.pool_size = 8 -## TODO: Subscribe Asynchronously. +## TODO: Subscribe asynchronously. ## ## Value: true | false mqtt.pubsub.async = true @@ -609,15 +613,18 @@ listener.tcp.external.max_clients = 102400 ## listener.tcp.external.rate_limit = 100,10 ## The access control rules for the MQTT/TCP listener. -## More information at: https://github.com/emqtt/esockd#allowdeny +## +## See: https://github.com/emqtt/esockd#allowdeny ## ## Value: ACL Rule -## listener.tcp.external.access.1 = allow 192.168.0.0/24 -listener.tcp.external.access.2 = allow all +## +## Example: allow 192.168.0.0/24 +listener.tcp.external.access.1 = allow all -## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind -## HAProxy or Nginx. -## More information at: https://www.haproxy.com/blog/haproxy/proxy-protocol/ +## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed +## behind HAProxy or Nginx. +## +## See: https://www.haproxy.com/blog/haproxy/proxy-protocol/ ## ## Value: on | off ## listener.tcp.external.proxy_protocol = on @@ -635,8 +642,6 @@ listener.tcp.external.access.2 = allow all ## Value: cn ## listener.tcp.external.peer_cert_as_username = cn -## TCP socket options for the MQTT listener. - ## The TCP backlog defines the maximum length that the queue of pending ## connections can grow to. ## @@ -654,13 +659,15 @@ listener.tcp.external.send_timeout = 15s listener.tcp.external.send_timeout_close = on ## The TCP receive buffer(os kernel) for MQTT connections. -## More information at: http://erlang.org/doc/man/inet.html +## +## See: http://erlang.org/doc/man/inet.html ## ## Value: Bytes ## listener.tcp.external.recbuf = 4KB ## The TCP send buffer(os kernel) for MQTT connections. -## More information at: http://erlang.org/doc/man/inet.html +## +## See: http://erlang.org/doc/man/inet.html ## ## Value: Bytes ## listener.tcp.external.sndbuf = 4KB @@ -671,7 +678,8 @@ listener.tcp.external.send_timeout_close = on ## >= max(val(sndbuf),val(recbuf)) to avoid performance issues because ## of unnecessary copying. val(buffer) is automatically set to the above ## maximum when values sndbuf or recbuf are set. -## More information at: http://erlang.org/doc/man/inet.html +## +## See: http://erlang.org/doc/man/inet.html ## ## Value: Bytes ## listener.tcp.external.buffer = 4KB @@ -690,8 +698,8 @@ listener.tcp.external.nodelay = true ##-------------------------------------------------------------------- ## Internal TCP Listener for MQTT Protocol -## The IP address and port that the internal MQTT/TCP protocol listener will -## bind. +## The IP address and port that the internal MQTT/TCP protocol listener +## will bind. ## ## Value: IP:Port, Port ## @@ -713,61 +721,73 @@ listener.tcp.internal.max_clients = 102400 ## Value: String ## listener.tcp.internal.zone = internal -## Mountpoint of the MQTT/TCP Listener. All the topics will -## be prefixed with the mount point if this option is enabled. +## Mountpoint of the MQTT/TCP Listener. +## +## See: listener.tcp..mountpoint ## ## Value: String -## listener.tcp.external.mountpoint = internal/ +## listener.tcp.internal.mountpoint = internal/ ## Rate limit for the internal MQTT/TCP connections. -## Format is 'burst,rate'. +## +## See: listener.tcp..rate_limit ## ## Value: burst,rate -## Unit: KB/sec ## listener.tcp.internal.rate_limit = 1000,100 -## The TCP backlog defines the maximum length that the queue of -## pending connections can grow to. +## The TCP backlog of internal MQTT/TCP Listener. +## +## See: listener.tcp..backlog ## ## Value: Number >= 0 listener.tcp.internal.backlog = 512 ## The TCP send timeout for internal MQTT connections. ## +## See: listener.tcp..send_timeout +## ## Value: Duration listener.tcp.internal.send_timeout = 5s ## Close the MQTT/TCP connection if send timeout. ## +## See: listener.tcp..send_timeout_close +## ## Value: on | off listener.tcp.external.send_timeout_close = on -## The TCP receive buffer(os kernel) for MQTT connections. -## More information at: http://erlang.org/doc/man/inet.html +## The TCP receive buffer(os kernel) for internal MQTT connections. +## +## See: listener.tcp..recbuf ## ## Value: Bytes listener.tcp.internal.recbuf = 16KB -## The TCP send buffer(os kernel) for MQTT connections. -## More information at: http://erlang.org/doc/man/inet.html +## The TCP send buffer(os kernel) for internal MQTT connections. +## +## See: http://erlang.org/doc/man/inet.html ## ## Value: Bytes listener.tcp.internal.sndbuf = 16KB ## The size of the user-level software buffer used by the driver. -## See: listener.tcp.external.buffer +## +## See: listener.tcp..buffer ## ## Value: Bytes listener.tcp.internal.buffer = 16KB ## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled. ## +## See: listener.tcp..tune_buffer +## ## Value: on | off listener.tcp.internal.tune_buffer = on -## The TCP_NODELAY flag for MQTT connections. -## See: listener.tcp.external.nodelay -# +## The TCP_NODELAY flag for internal MQTT connections. +## +## See: listener.tcp..nodelay +## ## Value: true | false listener.tcp.internal.nodelay = false @@ -797,43 +817,43 @@ listener.ssl.external.max_clients = 1024 ## Value: String ## listener.ssl.external.zone = external -## Mountpoint of the MQTT/SSL Listener. All the topics of this -## listener will be prefixed with the mount point if this option -## is enabled. +## Mountpoint of the MQTT/SSL Listener. ## ## Value: String ## listener.ssl.external.mountpoint = inbound/ -## Rate limit for the external MQTT/SSL connections. -## Format is 'burst,rate'. -## -## Value: burst,rate -## Unit: KB/sec -## listener.ssl.external.rate_limit = 100,10 - -## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind -## HAProxy or Nginx. -## More information at: https://www.haproxy.com/blog/haproxy/proxy-protocol/ -## -## Value: on | off -## listener.ssl.external.proxy_protocol = on - -## Sets the timeout for proxy protocol. EMQ will close the TCP connection -## if no proxy protocol packet recevied within the timeout. -## -## Value: Duration -## listener.ssl.external.proxy_protocol_timeout = 3s - ## The access control rules for the MQTT/SSL listener. -## More information at: https://github.com/emqtt/esockd#allowdeny +## +## See: listener.tcp..access ## ## Value: ACL Rule listener.ssl.external.access.1 = allow all -## TLS versions only to protect from POODLE attack. -## See http://erlang.org/doc/man/ssl.html +## Rate limit for the external MQTT/SSL connections. ## -## Value: String +## Value: burst,rate +## listener.ssl.external.rate_limit = 100,10 + +## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind +## HAProxy or Nginx. +## +## See: listener.tcp..proxy_protocol +## +## Value: on | off +## listener.ssl.external.proxy_protocol = on + +## Sets the timeout for proxy protocol. +## +## See: listener.tcp..proxy_protocol_timeout +## +## Value: Duration +## listener.ssl.external.proxy_protocol_timeout = 3s + +## TLS versions only to protect from POODLE attack. +## +## See: http://erlang.org/doc/man/ssl.html +## +## Value: String, seperated by ',' ## listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 ## TLS Handshake timeout. @@ -842,17 +862,20 @@ listener.ssl.external.access.1 = allow all listener.ssl.external.handshake_timeout = 15s ## Path to the file containing the user's private PEM-encoded key. -## More information at: http://erlang.org/doc/man/ssl.html +## +## See: http://erlang.org/doc/man/ssl.html ## ## Value: File listener.ssl.external.keyfile = {{ platform_etc_dir }}/certs/key.pem ## Path to a file containing the user certificate. ## +## See: http://erlang.org/doc/man/ssl.html +## ## Value: File listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem -## Path to a file containing PEM-encoded CA certificates. The CA certificates +## Path to the file containing PEM-encoded CA certificates. The CA certificates ## are used during server authentication and when building the client certificate chain. ## ## Value: File @@ -891,14 +914,17 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## Value: true | false ## listener.ssl.external.fail_if_no_peer_cert = true -## This is the single most important configuration option of an Erlang SSL application. -## Ciphers (and their ordering) define the way the client and server encrypt information -## over the wire, from the initial Diffie-Helman key exchange, the session key encryption -## algorithm and the message digest algorithm. Selecting a good cipher suite is critical -## for the application’s data security, confidentiality and performance. +## This is the single most important configuration option of an Erlang SSL +## application. Ciphers (and their ordering) define the way the client and +## server encrypt information over the wire, from the initial Diffie-Helman +## key exchange, the session key encryption ## algorithm and the message +## digest algorithm. Selecting a good cipher suite is critical for the +## application’s data security, confidentiality and performance. +## ## The cipher list above offers: ## -## A good balance between compatibility with older browsers. It can get stricter for Machine-To-Machine scenarios. +## A good balance between compatibility with older browsers. +## It can get stricter for Machine-To-Machine scenarios. ## Perfect Forward Secrecy. ## No old/insecure encryption and HMAC algorithms ## @@ -907,8 +933,8 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## Value: Ciphers ## listener.ssl.external.ciphers = 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 -## SSL parameter renegotiation is a feature that allows a client and -## a server to renegotiate the parameters of the SSL connection on the fly. +## SSL parameter renegotiation is a feature that allows a client and a server +## to renegotiate the parameters of the SSL connection on the fly. ## RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation, ## you drop support for the insecure renegotiation, prone to MitM attacks. ## @@ -918,7 +944,8 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## A performance optimization setting, it allows clients to reuse ## pre-existing sessions, instead of initializing new ones. ## Read more about it here. -## More information at: http://erlang.org/doc/man/ssl.html +## +## See: http://erlang.org/doc/man/ssl.html ## ## Value: on | off ## listener.ssl.external.reuse_sessions = on @@ -938,38 +965,57 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## listener.ssl.external.peer_cert_as_username = cn ## TCP backlog for the SSL connection. -## See 'listener.tcp.external.backlog' +## +## See listener.tcp..backlog ## ## Value: Number >= 0 ## listener.ssl.external.backlog = 1024 ## The TCP send timeout for the SSL connection. -## See 'listener.tcp.external.send_timeout' +## +## See listener.tcp..send_timeout ## ## Value: Duration ## listener.ssl.external.send_timeout = 15s -## See 'listener.tcp.external.send_timeout_close' +## Close the SSL connection if send timeout. +## +## See: listener.tcp..send_timeout_close ## ## Value: on | off ## listener.ssl.external.send_timeout_close = on -## See 'listener.tcp.external.recbuf' +## The TCP receive buffer(os kernel) for the SSL connections. +## +## See: listener.tcp..recbuf ## ## Value: Bytes ## listener.ssl.external.recbuf = 4KB -## See 'listener.tcp.external.sndbuf' +## The TCP send buffer(os kernel) for internal MQTT connections. +## +## See: listener.tcp..sndbuf ## ## Value: Bytes ## listener.ssl.external.sndbuf = 4KB -## See 'listener.tcp.external.buffer' +## The size of the user-level software buffer used by the driver. +## +## See: listener.tcp..buffer ## ## Value: Bytes ## listener.ssl.external.buffer = 4KB -## See 'listener.tcp.external.nodelay' +## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled. +## +## See: listener.tcp..tune_buffer +## +## Value: on | off +## listener.ssl.external.tune_buffer = on + +## The TCP_NODELAY flag for SSL connections. +## +## See: listener.tcp..nodelay ## ## Value: true | false ## listener.ssl.external.nodelay = true @@ -993,21 +1039,23 @@ listener.ws.external.acceptors = 4 ## Maximum number of concurrent MQTT/Websocket connections. ## ## Value: Number -listener.ws.external.max_clients = 64 +listener.ws.external.max_clients = 102400 ## TODO: Zone of the external MQTT/Websocket listener belonged to. ## ## Value: String ## listener.ws.external.zone = external -## Mountpoint of the MQTT/Websocket Listener. All the topics of -## this listener will be prefixed with the mount point if this -## option is enabled. +## Mountpoint of the MQTT/Websocket Listener. +## +## See: listener.tcp..mountpoint ## ## Value: String ## listener.ws.external.mountpoint = external/ -## The access control rules for the MQTT/Websocket listener. +## The access control for the MQTT/Websocket listener. +## +## See: listener.tcp..access ## ## Value: ACL Rule listener.ws.external.access.1 = allow all @@ -1015,43 +1063,70 @@ listener.ws.external.access.1 = allow all ## Enable the Proxy Protocol V1/2 if the EMQ cluster is deployed behind ## HAProxy or Nginx. ## +## See: listener.tcp..proxy_protocol +## ## Value: on | off ## listener.ws.external.proxy_protocol = on -## See 'listener.tcp.external.proxy_protocol_timeout' +## Sets the timeout for proxy protocol. +## +## See: listener.tcp..proxy_protocol_timeout ## ## Value: Duration ## listener.ws.external.proxy_protocol_timeout = 3s -## TCP Options +## The TCP backlog of external MQTT/Websocket Listener. +## +## See: listener.tcp..backlog +## +## Value: Number >= 0 listener.ws.external.backlog = 1024 -## See 'listener.tcp.external.send_timeout' +## The TCP send timeout for external MQTT/Websocket connections. +## +## See: listener.tcp..send_timeout ## ## Value: Duration listener.ws.external.send_timeout = 15s -## See 'listener.tcp.external.send_timeout_close' +## Close the MQTT/Websocket connection if send timeout. +## +## See: listener.tcp..send_timeout_close ## ## Value: on | off listener.ws.external.send_timeout_close = on -## See 'listener.tcp.external.recbuf' +## The TCP receive buffer(os kernel) for external MQTT/Websocket connections. +## +## See: listener.tcp..recbuf ## ## Value: Bytes ## listener.ws.external.recbuf = 4KB -## See 'listener.tcp.external.sndbuf' +## The TCP send buffer(os kernel) for external MQTT/Websocket connections. +## +## See 'listener.tcp..sndbuf' ## ## Value: Bytes ## listener.ws.external.sndbuf = 4KB -## See 'listener.tcp.external.buffer' +## The size of the user-level software buffer used by the driver. +## +## See: listener.tcp..buffer ## ## Value: Bytes ## listener.ws.external.buffer = 4KB -## See 'listener.tcp.external.nodelay' +## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled. +## +## See: listener.tcp..tune_buffer +## +## Value: on | off +listener.ws.external.tune_buffer = on + +## The TCP_NODELAY flag for external MQTT/Websocket connections. +## +## See: listener.tcp..nodelay ## ## Value: true | false listener.ws.external.nodelay = true @@ -1082,64 +1157,149 @@ listener.wss.external.max_clients = 64 ## Value: String ## listener.wss.external.zone = external -## See 'listener.ssl.external.mountpoint' +## Mountpoint of the MQTT/Websocket/SSL Listener. +## +## See 'listener.tcp..mountpoint' ## ## Value: String ## listener.wss.external.mountpoint = inbound/ -## See 'listener.ssl.external.acess.1' +## The access control rules for the MQTT/Websocket/SSL listener. +## +## See: listener.tcp..access. ## ## Value: ACL Rule listener.wss.external.access.1 = allow all -## See 'listener.ssl.external.proxy_protocol' +## Enable the Proxy Protocol V1/2 support. +## +## See: listener.tcp..proxy_protocol ## ## Value: on | off ## listener.wss.external.proxy_protocol = on -## See 'listener.ssl.external.proxy_protocol_timeout' +## Sets the timeout for proxy protocol. +## +## See: listener.tcp..proxy_protocol_timeout ## ## Value: Duration ## listener.wss.external.proxy_protocol_timeout = 3s -## SSL Options. Same to 'listener.ssl.*' +## TLS Handshake timeout. +## +## See: listener.ssl..handshake_timeout +## +## Value: Duration listener.wss.external.handshake_timeout = 15s +## Path to the file containing the user's private PEM-encoded key. +## +## See: listener.ssl..keyfile +## +## Value: File listener.wss.external.keyfile = {{ platform_etc_dir }}/certs/key.pem +## Path to a file containing the user certificate. +## +## See: listener.ssl..certfile +## +## Value: File listener.wss.external.certfile = {{ platform_etc_dir }}/certs/cert.pem +## Path to the file containing PEM-encoded CA certificates. +## +## See: listener.ssl..cacert +## +## Value: File ## listener.wss.external.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem +## See: listener.ssl..dhfile +## +## Value: File ## listener.ssl.external.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem +## See: listener.ssl..vefify +## +## Value: vefify_peer | verify_none ## listener.wss.external.verify = verify_peer +## See: listener.ssl..fail_if_no_peer_cert +## +## Value: false | true ## listener.wss.external.fail_if_no_peer_cert = true +## See: listener.ssl..ciphers +## +## Value: Ciphers ## listener.wss.external.ciphers = +## See: listener.ssl..secure_renegotiate +## +## Value: on | off ## listener.wss.external.secure_renegotiate = off +## See: listener.ssl..reuse_sessions +## +## Value: on | off ## listener.wss.external.reuse_sessions = on +## See: listener.ssl..honor_cipher_order +## +## Value: on | off ## listener.wss.external.honor_cipher_order = on +## See: listener.ssl..peer_cert_as_username +## +## Value: cn | dn ## listener.wss.external.peer_cert_as_username = cn -## TCP Options. Same to 'listener.tcp.*' +## TCP backlog for the Websocket/SSL connection. +## +## See 'listener.tcp..backlog' +## +## Value: Number >= 0 listener.wss.external.backlog = 1024 +## The TCP send timeout for the Websocket/SSL connection. +## +## See 'listener.tcp..send_timeout' +## +## Value: Duration listener.wss.external.send_timeout = 15s +## Close the Websocket/SSL connection if send timeout. +## +## See: listener.tcp..send_timeout_close +## +## Value: on | off listener.wss.external.send_timeout_close = on +## The TCP receive buffer(os kernel) for the Websocket/SSL connections. +## +## See: listener.tcp..recbuf +## +## Value: Bytes ## listener.wss.external.recbuf = 4KB +## The TCP send buffer(os kernel) for the Websocket/SSL connections. +## +## See: listener.tcp..sndbuf +## +## Value: Bytes ## listener.wss.external.sndbuf = 4KB +## The size of the user-level software buffer used by the driver. +## +## See: listener.tcp..buffer +## +## Value: Bytes ## listener.wss.external.buffer = 4KB +## The TCP_NODELAY flag for Websocket/SSL connections. +## +## See: listener.tcp..nodelay +## +## Value: true | false ## listener.wss.external.nodelay = true ##-------------------------------------------------------------------- @@ -1163,18 +1323,18 @@ listener.api.mgmt.acceptors = 4 listener.api.mgmt.max_clients = 64 ## The access control rules for the listener. -## More information at: https://github.com/emqtt/esockd#allowdeny +## +## See: https://github.com/emqtt/esockd#allowdeny ## ## Value: ACL Rule listener.api.mgmt.access.1 = allow all -## The TCP backlog defines the maximum length that the queue of pending -## connections can grow to. +## The TCP backlog for HTTP API. ## ## Value: Number >= 0 listener.api.mgmt.backlog = 512 -## The TCP send timeout. +## The TCP send timeout for HTTP API. ## ## Value: Duration listener.api.mgmt.send_timeout = 15s @@ -1196,13 +1356,15 @@ listener.api.mgmt.send_timeout_close = on sysmon.long_gc = false ## Enable Long Schedule(ms) monitoring. -## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## See: http://erlang.org/doc/man/erlang.html#system_monitor-2 ## ## Value: Number sysmon.long_schedule = 240 ## Enable Large Heap monitoring. -## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## See: http://erlang.org/doc/man/erlang.html#system_monitor-2 ## ## Value: bytes ## @@ -1210,13 +1372,15 @@ sysmon.long_schedule = 240 sysmon.large_heap = 8MB ## Enable Busy Port monitoring. -## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## See: http://erlang.org/doc/man/erlang.html#system_monitor-2 ## ## Value: true | false sysmon.busy_port = false ## Enable Busy Dist Port monitoring. -## More information at: http://erlang.org/doc/man/erlang.html#system_monitor-2 +## +## See: http://erlang.org/doc/man/erlang.html#system_monitor-2 ## ## Value: true | false sysmon.busy_dist_port = true From 3a39706d8402135b23470210262230b778e9d5ac Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 16:05:44 +0800 Subject: [PATCH 33/46] Add more options for 'listener.wss.' --- priv/emq.schema | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/priv/emq.schema b/priv/emq.schema index ca242c4c7..11c45cecb 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -1007,6 +1007,10 @@ end}. {datatype, string} ]}. +{mapping, "listener.ws.$name.mountpoint", "emqttd.listeners", [ + {datatype, string} +]}. + {mapping, "listener.ws.$name.access.$id", "emqttd.listeners", [ {datatype, string} ]}. @@ -1140,6 +1144,14 @@ end}. hidden ]}. +{mapping, "listener.wss.$name.tls_versions", "emqttd.listeners", [ + {datatype, string} +]}. + +{mapping, "listener.wss.$name.ciphers", "emqttd.listeners", [ + {datatype, string} +]}. + {mapping, "listener.wss.$name.handshake_timeout", "emqttd.listeners", [ {default, "15s"}, {datatype, {duration, ms}} @@ -1165,6 +1177,23 @@ end}. {datatype, {enum, [true, false]}} ]}. +{mapping, "listener.wss.$name.secure_renegotiate", "emqttd.listeners", [ + {datatype, flag} +]}. + +{mapping, "listener.wss.$name.reuse_sessions", "emqttd.listeners", [ + {default, on}, + {datatype, flag} +]}. + +{mapping, "listener.wss.$name.honor_cipher_order", "emqttd.listeners", [ + {datatype, flag} +]}. + +{mapping, "listener.wss.$name.peer_cert_as_username", "emqttd.listeners", [ + {datatype, {enum, [cn, dn]}} +]}. + {translation, "emqttd.listeners", fun(Conf) -> Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end, From 86fc80b9830ebae27d56ca7dabadf655e03aa9af Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 16:09:10 +0800 Subject: [PATCH 34/46] Change the type of 'mqtt.broker.sys_interval' to ms duration --- src/emqttd_broker.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emqttd_broker.erl b/src/emqttd_broker.erl index 0161720f2..9e78207ce 100644 --- a/src/emqttd_broker.erl +++ b/src/emqttd_broker.erl @@ -105,9 +105,9 @@ datetime() -> io_lib:format( "~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w", [Y, M, D, H, MM, S])). -%% @doc Start a tick timer +%% @doc Start a tick timer. start_tick(Msg) -> - start_tick(timer:seconds(emqttd:env(broker_sys_interval, 60)), Msg). + start_tick(emqttd:env(broker_sys_interval, 60000), Msg). start_tick(0, _Msg) -> undefined; From fdc55de5099b11b4f6cbd5519abe808c2cda9f58 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 16:09:45 +0800 Subject: [PATCH 35/46] Change the type of 'mqtt.bridge.ping_down_interval' to ms duration --- src/emqttd_bridge.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emqttd_bridge.erl b/src/emqttd_bridge.erl index 49b5a95d0..6c20290bd 100644 --- a/src/emqttd_bridge.erl +++ b/src/emqttd_bridge.erl @@ -92,7 +92,7 @@ parse_opts([{topic_prefix, Prefix} | Opts], State) -> parse_opts([{max_queue_len, Len} | Opts], State) -> parse_opts(Opts, State#state{max_queue_len = Len}); parse_opts([{ping_down_interval, Interval} | Opts], State) -> - parse_opts(Opts, State#state{ping_down_interval = Interval*1000}); + parse_opts(Opts, State#state{ping_down_interval = Interval}); parse_opts([_Opt | Opts], State) -> parse_opts(Opts, State). From a779c9f9cb743b82f5127f211153e1cd7db5d8d9 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Thu, 4 Jan 2018 20:25:26 +0800 Subject: [PATCH 36/46] Add 'listener.wss.external.tls_versions' option --- etc/emq.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/emq.conf b/etc/emq.conf index 4d37515aa..b8c21dc40 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1185,6 +1185,13 @@ listener.wss.external.access.1 = allow all ## Value: Duration ## listener.wss.external.proxy_protocol_timeout = 3s +## TLS versions only to protect from POODLE attack. +## +## See: listener.ssl..tls_versions +## +## Value: String, seperated by ',' +## listener.wss.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1 + ## TLS Handshake timeout. ## ## See: listener.ssl..handshake_timeout From 4e7a12a838ec44b8d507d28d7e5a6a3a62a55599 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Sat, 6 Jan 2018 15:46:43 +0800 Subject: [PATCH 37/46] Fix #1430 - update the link to emqx-lwm2m project --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 83fe86177..96ed87f7c 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Plugin | Descrip [emq_sn](https://github.com/emqtt/emq_sn) | MQTT-SN Protocol Plugin [emq_coap](https://github.com/emqtt/emq_coap) | CoAP Protocol Plugin [emq_stomp](https://github.com/emqtt/emq_stomp) | Stomp Protocol Plugin -[emq_lwm2m](https://github.com/emqtt/emq-lwm2m) | LWM2M Prototol Plugin +[emq_lwm2m](https://github.com/emqx/emqx-lwm2m) | LWM2M Prototol Plugin [emq_recon](https://github.com/emqtt/emq_recon) | Recon Plugin [emq_reloader](https://github.com/emqtt/emq_reloader) | Reloader Plugin [emq_sockjs](https://github.com/emqtt/emq_sockjs) | SockJS(Stomp) Plugin @@ -109,9 +109,7 @@ Plugin | Descrip * Issues: https://github.com/emqtt/emqttd/issues * QQ Group: 12222225 -## Partners - -[QingCloud](https://qingcloud.com) is the world’s first IaaS provider that can deliver any number of IT resources in seconds and adopts a second-based billing system. QingCloud is committed to providing a reliable, secure, on-demand and real-time IT resource platform with excellent performance, which includes all components of a complete IT infrastructure system: computing, storage, networking and security. +## Test Servers The **q.emqtt.com** hosts a public Four-Node *EMQ* cluster on [QingCloud](https://qingcloud.com): From 6ad7b46885a3fc9c7a997087e762aa25b8f3eadb Mon Sep 17 00:00:00 2001 From: HuangDan Date: Mon, 8 Jan 2018 13:39:52 +0800 Subject: [PATCH 38/46] Fix failed test --- test/emqttd_config_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/emqttd_config_SUITE.erl b/test/emqttd_config_SUITE.erl index 04c957b75..744f7402e 100644 --- a/test/emqttd_config_SUITE.erl +++ b/test/emqttd_config_SUITE.erl @@ -115,9 +115,9 @@ run_connection_cmd(_Config) -> ?assertEqual(1000, E). run_broker_config(_Config) -> - emqttd_cli_config:run(["config", "set", "mqtt.broker.sys_interval=10", "--app=emqttd"]), + emqttd_cli_config:run(["config", "set", "mqtt.broker.sys_interval=6000ms", "--app=emqttd"]), {ok, E} = application:get_env(emqttd, broker_sys_interval), - ?assertEqual(10, E). + ?assertEqual(6000, E). env_value("client", {Key, Type}) -> case string:split(Key, "=") of From 56195670c61fa9035404e381296c342d9144e536 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Fri, 12 Jan 2018 10:45:36 +0800 Subject: [PATCH 39/46] Misc fix --- src/emqttd_session.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emqttd_session.erl b/src/emqttd_session.erl index aa1a027a4..841a645a3 100644 --- a/src/emqttd_session.erl +++ b/src/emqttd_session.erl @@ -286,8 +286,8 @@ init([CleanSess, {ClientId, Username}, ClientPid]) -> {ok, QEnv} = emqttd:env(mqueue), MaxInflight = get_value(max_inflight, Env, 0), EnableStats = get_value(enable_stats, Env, false), - IgnoreLoopDeliver = get_value(ignore_loop_deliver, Env, false), ForceGcCount = emqttd_gc:conn_max_gc_count(), + IgnoreLoopDeliver = get_value(ignore_loop_deliver, Env, false), MQueue = ?MQueue:new(ClientId, QEnv, emqttd_alarm:alarm_fun()), State = #state{clean_sess = CleanSess, binding = binding(ClientPid), From a1cbdc51228ab9d7933932ccae8d847cfaf6ac4b Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Fri, 12 Jan 2018 10:46:35 +0800 Subject: [PATCH 40/46] Update emq.conf and emq.schema --- etc/emq.conf | 8 ++++---- priv/emq.schema | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index b8c21dc40..ef05b70e2 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -1105,7 +1105,7 @@ listener.ws.external.send_timeout_close = on ## The TCP send buffer(os kernel) for external MQTT/Websocket connections. ## -## See 'listener.tcp..sndbuf' +## See: listener.tcp..sndbuf ## ## Value: Bytes ## listener.ws.external.sndbuf = 4KB @@ -1159,7 +1159,7 @@ listener.wss.external.max_clients = 64 ## Mountpoint of the MQTT/Websocket/SSL Listener. ## -## See 'listener.tcp..mountpoint' +## See: listener.tcp..mountpoint ## ## Value: String ## listener.wss.external.mountpoint = inbound/ @@ -1262,14 +1262,14 @@ listener.wss.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## TCP backlog for the Websocket/SSL connection. ## -## See 'listener.tcp..backlog' +## See listener.tcp..backlog ## ## Value: Number >= 0 listener.wss.external.backlog = 1024 ## The TCP send timeout for the Websocket/SSL connection. ## -## See 'listener.tcp..send_timeout' +## See: listener.tcp..send_timeout ## ## Value: Duration listener.wss.external.send_timeout = 15s diff --git a/priv/emq.schema b/priv/emq.schema index 11c45cecb..a70a90f90 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -400,7 +400,7 @@ end}. {translation, "lager.handlers", fun(Conf) -> - ErrorHandler = case cuttlefish:conf_get("log.error.file", Conf) of + ErrorHandler = case cuttlefish:conf_get("log.error.file", Conf, undefined) of undefined -> []; ErrorFilename -> [{lager_file_backend, [{file, ErrorFilename}, {level, error}, @@ -442,7 +442,6 @@ end}. cuttlefish:conf_get("log.syslog.facility", Conf), cuttlefish:conf_get("log.syslog.level", Conf)]}] end, - ConsoleHandlers ++ ErrorHandler ++ InfoHandler ++ SyslogHandler end }. From a3e97f798b65e095bb6582f82551a74fd5c0a38d Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 16 Jan 2018 08:57:46 +0800 Subject: [PATCH 41/46] Update Copyright to 2018 --- include/emqttd.hrl | 4 ++-- include/emqttd_cli.hrl | 2 +- include/emqttd_internal.hrl | 2 +- include/emqttd_protocol.hrl | 2 +- include/emqttd_trie.hrl | 2 +- src/emqttd.erl | 2 +- src/emqttd_access_control.erl | 2 +- src/emqttd_access_rule.erl | 2 +- src/emqttd_acl_internal.erl | 2 +- src/emqttd_acl_mod.erl | 2 +- src/emqttd_alarm.erl | 2 +- src/emqttd_app.erl | 2 +- src/emqttd_auth_mod.erl | 2 +- src/emqttd_base62.erl | 2 +- src/emqttd_boot.erl | 2 +- src/emqttd_bridge.erl | 2 +- src/emqttd_bridge_sup.erl | 2 +- src/emqttd_bridge_sup_sup.erl | 2 +- src/emqttd_broker.erl | 2 +- src/emqttd_cli.erl | 2 +- src/emqttd_cli_config.erl | 2 +- src/emqttd_client.erl | 2 +- src/emqttd_cm.erl | 2 +- src/emqttd_cm_sup.erl | 2 +- src/emqttd_config.erl | 2 +- src/emqttd_ctl.erl | 2 +- src/emqttd_gc.erl | 2 +- src/emqttd_gen_mod.erl | 2 +- src/emqttd_guid.erl | 2 +- src/emqttd_hooks.erl | 2 +- src/emqttd_http.erl | 2 +- src/emqttd_inflight.erl | 2 +- src/emqttd_keepalive.erl | 2 +- src/emqttd_message.erl | 2 +- src/emqttd_metrics.erl | 2 +- src/emqttd_mgmt.erl | 2 +- src/emqttd_misc.erl | 2 +- src/emqttd_mod_sup.erl | 2 +- src/emqttd_mqueue.erl | 2 +- src/emqttd_net.erl | 2 +- src/emqttd_packet.erl | 2 +- src/emqttd_parser.erl | 2 +- src/emqttd_plugins.erl | 2 +- src/emqttd_pmon.erl | 2 +- src/emqttd_pool_sup.erl | 2 +- src/emqttd_pooler.erl | 2 +- src/emqttd_protocol.erl | 2 +- src/emqttd_pubsub.erl | 2 +- src/emqttd_pubsub_sup.erl | 2 +- src/emqttd_rest_api.erl | 2 +- src/emqttd_router.erl | 2 +- src/emqttd_serializer.erl | 2 +- src/emqttd_server.erl | 2 +- src/emqttd_session.erl | 2 +- src/emqttd_session_sup.erl | 2 +- src/emqttd_sm.erl | 2 +- src/emqttd_sm_helper.erl | 2 +- src/emqttd_sm_sup.erl | 2 +- src/emqttd_stats.erl | 2 +- src/emqttd_sup.erl | 2 +- src/emqttd_sysmon.erl | 2 +- src/emqttd_sysmon_sup.erl | 2 +- src/emqttd_time.erl | 2 +- src/emqttd_topic.erl | 2 +- src/emqttd_trace.erl | 2 +- src/emqttd_trace_sup.erl | 2 +- src/emqttd_trie.erl | 2 +- src/emqttd_vm.erl | 2 +- src/emqttd_ws.erl | 2 +- src/emqttd_ws_client.erl | 2 +- src/emqttd_ws_client_sup.erl | 2 +- src/lager_emqtt_backend.erl | 2 +- test/emqttd_SUITE.erl | 2 +- test/emqttd_access_SUITE.erl | 2 +- test/emqttd_acl_test_mod.erl | 2 +- test/emqttd_auth_anonymous_test_mod.erl | 2 +- test/emqttd_auth_dashboard.erl | 2 +- test/emqttd_cli_SUITE.erl | 2 +- test/emqttd_config_SUITE.erl | 2 +- test/emqttd_inflight_SUITE.erl | 2 +- test/emqttd_lib_SUITE.erl | 2 +- test/emqttd_mod_SUITE.erl | 2 +- test/emqttd_mqueue_SUITE.erl | 2 +- test/emqttd_net_SUITE.erl | 2 +- test/emqttd_protocol_SUITE.erl | 2 +- test/emqttd_router_SUITE.erl | 2 +- test/emqttd_topic_SUITE.erl | 2 +- test/emqttd_trie_SUITE.erl | 2 +- test/emqttd_vm_SUITE.erl | 2 +- 89 files changed, 90 insertions(+), 90 deletions(-) diff --git a/include/emqttd.hrl b/include/emqttd.hrl index 508712512..975b50dd4 100644 --- a/include/emqttd.hrl +++ b/include/emqttd.hrl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ %% Banner %%-------------------------------------------------------------------- --define(COPYRIGHT, "Copyright (c) 2013-2017 EMQ Enterprise, Inc."). +-define(COPYRIGHT, "Copyright (c) 2013-2018 EMQ Enterprise, Inc."). -define(LICENSE_MESSAGE, "Licensed under the Apache License, Version 2.0"). diff --git a/include/emqttd_cli.hrl b/include/emqttd_cli.hrl index bda88d801..b99038481 100644 --- a/include/emqttd_cli.hrl +++ b/include/emqttd_cli.hrl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/include/emqttd_internal.hrl b/include/emqttd_internal.hrl index 343be68e4..c2ae503de 100644 --- a/include/emqttd_internal.hrl +++ b/include/emqttd_internal.hrl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/include/emqttd_protocol.hrl b/include/emqttd_protocol.hrl index a6d6c06e6..8a0ad4478 100644 --- a/include/emqttd_protocol.hrl +++ b/include/emqttd_protocol.hrl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/include/emqttd_trie.hrl b/include/emqttd_trie.hrl index eb4e1390d..ffd2acebc 100644 --- a/include/emqttd_trie.hrl +++ b/include/emqttd_trie.hrl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd.erl b/src/emqttd.erl index 65739952f..ecea2ca18 100644 --- a/src/emqttd.erl +++ b/src/emqttd.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_access_control.erl b/src/emqttd_access_control.erl index 601fd263f..0b74e2dc2 100644 --- a/src/emqttd_access_control.erl +++ b/src/emqttd_access_control.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_access_rule.erl b/src/emqttd_access_rule.erl index 73718fd3a..f0bad6816 100644 --- a/src/emqttd_access_rule.erl +++ b/src/emqttd_access_rule.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_acl_internal.erl b/src/emqttd_acl_internal.erl index 5305985c4..9304b9208 100644 --- a/src/emqttd_acl_internal.erl +++ b/src/emqttd_acl_internal.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_acl_mod.erl b/src/emqttd_acl_mod.erl index 4ed07b369..66e5f098b 100644 --- a/src/emqttd_acl_mod.erl +++ b/src/emqttd_acl_mod.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_alarm.erl b/src/emqttd_alarm.erl index 1467797c7..d271cb425 100644 --- a/src/emqttd_alarm.erl +++ b/src/emqttd_alarm.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_app.erl b/src/emqttd_app.erl index 1e99cb951..f14229715 100644 --- a/src/emqttd_app.erl +++ b/src/emqttd_app.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_auth_mod.erl b/src/emqttd_auth_mod.erl index d413446ff..a33631b65 100644 --- a/src/emqttd_auth_mod.erl +++ b/src/emqttd_auth_mod.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_base62.erl b/src/emqttd_base62.erl index 481488fb9..707981e32 100644 --- a/src/emqttd_base62.erl +++ b/src/emqttd_base62.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_boot.erl b/src/emqttd_boot.erl index d7a6d311e..694b5248a 100644 --- a/src/emqttd_boot.erl +++ b/src/emqttd_boot.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_bridge.erl b/src/emqttd_bridge.erl index 6c20290bd..8349eeec1 100644 --- a/src/emqttd_bridge.erl +++ b/src/emqttd_bridge.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_bridge_sup.erl b/src/emqttd_bridge_sup.erl index 75138332f..29b68c199 100644 --- a/src/emqttd_bridge_sup.erl +++ b/src/emqttd_bridge_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_bridge_sup_sup.erl b/src/emqttd_bridge_sup_sup.erl index 11679aba8..fe5c33428 100644 --- a/src/emqttd_bridge_sup_sup.erl +++ b/src/emqttd_bridge_sup_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_broker.erl b/src/emqttd_broker.erl index 9e78207ce..798c94a6a 100644 --- a/src/emqttd_broker.erl +++ b/src/emqttd_broker.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_cli.erl b/src/emqttd_cli.erl index 280c050ee..49e2500bb 100644 --- a/src/emqttd_cli.erl +++ b/src/emqttd_cli.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_cli_config.erl b/src/emqttd_cli_config.erl index 1ce0de49c..3c69c8cbc 100644 --- a/src/emqttd_cli_config.erl +++ b/src/emqttd_cli_config.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_client.erl b/src/emqttd_client.erl index 5ca450bf5..f479d2253 100644 --- a/src/emqttd_client.erl +++ b/src/emqttd_client.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_cm.erl b/src/emqttd_cm.erl index 4edc155df..bcaf353ed 100644 --- a/src/emqttd_cm.erl +++ b/src/emqttd_cm.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_cm_sup.erl b/src/emqttd_cm_sup.erl index fc01ea649..ccaea00fb 100644 --- a/src/emqttd_cm_sup.erl +++ b/src/emqttd_cm_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_config.erl b/src/emqttd_config.erl index deaaa77d1..04d94b260 100644 --- a/src/emqttd_config.erl +++ b/src/emqttd_config.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_ctl.erl b/src/emqttd_ctl.erl index 77769e3c8..a32a40172 100644 --- a/src/emqttd_ctl.erl +++ b/src/emqttd_ctl.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_gc.erl b/src/emqttd_gc.erl index 75545a77f..6484a195d 100644 --- a/src/emqttd_gc.erl +++ b/src/emqttd_gc.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_gen_mod.erl b/src/emqttd_gen_mod.erl index f8d690024..012b610da 100644 --- a/src/emqttd_gen_mod.erl +++ b/src/emqttd_gen_mod.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_guid.erl b/src/emqttd_guid.erl index 24199fa01..805a128b6 100644 --- a/src/emqttd_guid.erl +++ b/src/emqttd_guid.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_hooks.erl b/src/emqttd_hooks.erl index 693a67ff7..4fc84f9e8 100644 --- a/src/emqttd_hooks.erl +++ b/src/emqttd_hooks.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_http.erl b/src/emqttd_http.erl index a41025294..2b484038b 100644 --- a/src/emqttd_http.erl +++ b/src/emqttd_http.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_inflight.erl b/src/emqttd_inflight.erl index bb9af390b..be7517197 100644 --- a/src/emqttd_inflight.erl +++ b/src/emqttd_inflight.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_keepalive.erl b/src/emqttd_keepalive.erl index a0458038a..abc6dbc50 100644 --- a/src/emqttd_keepalive.erl +++ b/src/emqttd_keepalive.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_message.erl b/src/emqttd_message.erl index 4c3bea0d8..86918e47a 100644 --- a/src/emqttd_message.erl +++ b/src/emqttd_message.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_metrics.erl b/src/emqttd_metrics.erl index 17e6e96d4..37d897b67 100644 --- a/src/emqttd_metrics.erl +++ b/src/emqttd_metrics.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_mgmt.erl b/src/emqttd_mgmt.erl index 1a608968e..2052d68fc 100644 --- a/src/emqttd_mgmt.erl +++ b/src/emqttd_mgmt.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_misc.erl b/src/emqttd_misc.erl index e60d27d4f..2224879ca 100644 --- a/src/emqttd_misc.erl +++ b/src/emqttd_misc.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_mod_sup.erl b/src/emqttd_mod_sup.erl index 749b84a42..b8335e6b3 100644 --- a/src/emqttd_mod_sup.erl +++ b/src/emqttd_mod_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_mqueue.erl b/src/emqttd_mqueue.erl index 08e620a37..92fda72f1 100644 --- a/src/emqttd_mqueue.erl +++ b/src/emqttd_mqueue.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_net.erl b/src/emqttd_net.erl index 1f246a315..9da9cd287 100644 --- a/src/emqttd_net.erl +++ b/src/emqttd_net.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_packet.erl b/src/emqttd_packet.erl index 6349e58b1..f269f3dbe 100644 --- a/src/emqttd_packet.erl +++ b/src/emqttd_packet.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_parser.erl b/src/emqttd_parser.erl index 91df07d77..e9277a7c6 100644 --- a/src/emqttd_parser.erl +++ b/src/emqttd_parser.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_plugins.erl b/src/emqttd_plugins.erl index 81ff61a4d..4491e26df 100644 --- a/src/emqttd_plugins.erl +++ b/src/emqttd_plugins.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_pmon.erl b/src/emqttd_pmon.erl index ebe691ad4..00cb9a4c3 100644 --- a/src/emqttd_pmon.erl +++ b/src/emqttd_pmon.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_pool_sup.erl b/src/emqttd_pool_sup.erl index 87654bcff..d5f408cd2 100644 --- a/src/emqttd_pool_sup.erl +++ b/src/emqttd_pool_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_pooler.erl b/src/emqttd_pooler.erl index a74e01fec..fdde12a66 100644 --- a/src/emqttd_pooler.erl +++ b/src/emqttd_pooler.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index d021c9e1f..c72f7172c 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_pubsub.erl b/src/emqttd_pubsub.erl index 994ef6230..17f5455ff 100644 --- a/src/emqttd_pubsub.erl +++ b/src/emqttd_pubsub.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_pubsub_sup.erl b/src/emqttd_pubsub_sup.erl index 09d08d110..6e18aa031 100644 --- a/src/emqttd_pubsub_sup.erl +++ b/src/emqttd_pubsub_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_rest_api.erl b/src/emqttd_rest_api.erl index 0eb6adc11..ecc8410cd 100644 --- a/src/emqttd_rest_api.erl +++ b/src/emqttd_rest_api.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_router.erl b/src/emqttd_router.erl index fa1a0c70c..f667f8ea0 100644 --- a/src/emqttd_router.erl +++ b/src/emqttd_router.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_serializer.erl b/src/emqttd_serializer.erl index 079cfbb3c..1b81a45be 100644 --- a/src/emqttd_serializer.erl +++ b/src/emqttd_serializer.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_server.erl b/src/emqttd_server.erl index 4e05c00aa..38e7be311 100644 --- a/src/emqttd_server.erl +++ b/src/emqttd_server.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_session.erl b/src/emqttd_session.erl index 841a645a3..dfba46b3e 100644 --- a/src/emqttd_session.erl +++ b/src/emqttd_session.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_session_sup.erl b/src/emqttd_session_sup.erl index bd9b34f02..506383834 100644 --- a/src/emqttd_session_sup.erl +++ b/src/emqttd_session_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sm.erl b/src/emqttd_sm.erl index a46d56fa6..e2e332041 100644 --- a/src/emqttd_sm.erl +++ b/src/emqttd_sm.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sm_helper.erl b/src/emqttd_sm_helper.erl index 0721339fd..7a1875be1 100644 --- a/src/emqttd_sm_helper.erl +++ b/src/emqttd_sm_helper.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sm_sup.erl b/src/emqttd_sm_sup.erl index 1c2e7f31a..f26716e0d 100644 --- a/src/emqttd_sm_sup.erl +++ b/src/emqttd_sm_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_stats.erl b/src/emqttd_stats.erl index 6d84395e2..4471a2814 100644 --- a/src/emqttd_stats.erl +++ b/src/emqttd_stats.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sup.erl b/src/emqttd_sup.erl index e38d20d65..0d0bf496c 100644 --- a/src/emqttd_sup.erl +++ b/src/emqttd_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sysmon.erl b/src/emqttd_sysmon.erl index c94c1df54..8a9489c9e 100644 --- a/src/emqttd_sysmon.erl +++ b/src/emqttd_sysmon.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_sysmon_sup.erl b/src/emqttd_sysmon_sup.erl index 99e7a628d..884112a00 100644 --- a/src/emqttd_sysmon_sup.erl +++ b/src/emqttd_sysmon_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_time.erl b/src/emqttd_time.erl index 7e5940438..77459195e 100644 --- a/src/emqttd_time.erl +++ b/src/emqttd_time.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_topic.erl b/src/emqttd_topic.erl index 91cd0ff08..6623c730f 100644 --- a/src/emqttd_topic.erl +++ b/src/emqttd_topic.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_trace.erl b/src/emqttd_trace.erl index 05734c2d2..b87359416 100644 --- a/src/emqttd_trace.erl +++ b/src/emqttd_trace.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_trace_sup.erl b/src/emqttd_trace_sup.erl index 728e6818e..35264e017 100644 --- a/src/emqttd_trace_sup.erl +++ b/src/emqttd_trace_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_trie.erl b/src/emqttd_trie.erl index 0bb6ec63e..2dae6974a 100644 --- a/src/emqttd_trie.erl +++ b/src/emqttd_trie.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_vm.erl b/src/emqttd_vm.erl index 16fae60ae..368463d35 100644 --- a/src/emqttd_vm.erl +++ b/src/emqttd_vm.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_ws.erl b/src/emqttd_ws.erl index 798c4d69b..e2375e4a6 100644 --- a/src/emqttd_ws.erl +++ b/src/emqttd_ws.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_ws_client.erl b/src/emqttd_ws_client.erl index 206f461bb..0462e3220 100644 --- a/src/emqttd_ws_client.erl +++ b/src/emqttd_ws_client.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/emqttd_ws_client_sup.erl b/src/emqttd_ws_client_sup.erl index 21f683eaa..48f3b1193 100644 --- a/src/emqttd_ws_client_sup.erl +++ b/src/emqttd_ws_client_sup.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/lager_emqtt_backend.erl b/src/lager_emqtt_backend.erl index 69c1aece4..1ceb9785e 100644 --- a/src/lager_emqtt_backend.erl +++ b/src/lager_emqtt_backend.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_SUITE.erl b/test/emqttd_SUITE.erl index c5794e5b0..360905859 100644 --- a/test/emqttd_SUITE.erl +++ b/test/emqttd_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_access_SUITE.erl b/test/emqttd_access_SUITE.erl index 762ae6f40..c3529d935 100644 --- a/test/emqttd_access_SUITE.erl +++ b/test/emqttd_access_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_acl_test_mod.erl b/test/emqttd_acl_test_mod.erl index 08f1f9c94..9ed34c263 100644 --- a/test/emqttd_acl_test_mod.erl +++ b/test/emqttd_acl_test_mod.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_auth_anonymous_test_mod.erl b/test/emqttd_auth_anonymous_test_mod.erl index be6a14bf8..0f01be47f 100644 --- a/test/emqttd_auth_anonymous_test_mod.erl +++ b/test/emqttd_auth_anonymous_test_mod.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_auth_dashboard.erl b/test/emqttd_auth_dashboard.erl index 49f54c377..97ed17ea4 100644 --- a/test/emqttd_auth_dashboard.erl +++ b/test/emqttd_auth_dashboard.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_cli_SUITE.erl b/test/emqttd_cli_SUITE.erl index 273518b7f..024432d95 100644 --- a/test/emqttd_cli_SUITE.erl +++ b/test/emqttd_cli_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_config_SUITE.erl b/test/emqttd_config_SUITE.erl index 744f7402e..8b227b1b2 100644 --- a/test/emqttd_config_SUITE.erl +++ b/test/emqttd_config_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_inflight_SUITE.erl b/test/emqttd_inflight_SUITE.erl index de5391f1a..d3800fc72 100644 --- a/test/emqttd_inflight_SUITE.erl +++ b/test/emqttd_inflight_SUITE.erl @@ -1,5 +1,5 @@ %% -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% -module(emqttd_inflight_SUITE). diff --git a/test/emqttd_lib_SUITE.erl b/test/emqttd_lib_SUITE.erl index a808fbcc8..dac72e210 100644 --- a/test/emqttd_lib_SUITE.erl +++ b/test/emqttd_lib_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_mod_SUITE.erl b/test/emqttd_mod_SUITE.erl index 1fcf455d0..9935b7424 100644 --- a/test/emqttd_mod_SUITE.erl +++ b/test/emqttd_mod_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_mqueue_SUITE.erl b/test/emqttd_mqueue_SUITE.erl index 93ccc9833..f709f1478 100644 --- a/test/emqttd_mqueue_SUITE.erl +++ b/test/emqttd_mqueue_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_net_SUITE.erl b/test/emqttd_net_SUITE.erl index 78abb50c9..c6bb10c14 100644 --- a/test/emqttd_net_SUITE.erl +++ b/test/emqttd_net_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_protocol_SUITE.erl b/test/emqttd_protocol_SUITE.erl index 21428f0c7..3401860e6 100644 --- a/test/emqttd_protocol_SUITE.erl +++ b/test/emqttd_protocol_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_router_SUITE.erl b/test/emqttd_router_SUITE.erl index 415550ec3..b305d699d 100644 --- a/test/emqttd_router_SUITE.erl +++ b/test/emqttd_router_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_topic_SUITE.erl b/test/emqttd_topic_SUITE.erl index 9ec7736bd..984d0b299 100644 --- a/test/emqttd_topic_SUITE.erl +++ b/test/emqttd_topic_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_trie_SUITE.erl b/test/emqttd_trie_SUITE.erl index a81a132f5..629531934 100644 --- a/test/emqttd_trie_SUITE.erl +++ b/test/emqttd_trie_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/test/emqttd_vm_SUITE.erl b/test/emqttd_vm_SUITE.erl index ef0ac2946..49252c2ae 100644 --- a/test/emqttd_vm_SUITE.erl +++ b/test/emqttd_vm_SUITE.erl @@ -1,5 +1,5 @@ %%-------------------------------------------------------------------- -%% Copyright (c) 2013-2017 EMQ Enterprise, Inc. (http://emqtt.io) +%% Copyright (c) 2013-2018 EMQ Enterprise, Inc. (http://emqtt.io) %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. From 701c632e074505eef76f2d10d7656ae27be992f0 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 23 Jan 2018 11:09:42 +0800 Subject: [PATCH 42/46] Fix issue #1461 - keep the retain flag for new subscription --- src/emqttd_protocol.erl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/emqttd_protocol.erl b/src/emqttd_protocol.erl index d021c9e1f..eaa81e092 100644 --- a/src/emqttd_protocol.erl +++ b/src/emqttd_protocol.erl @@ -563,8 +563,11 @@ sp(false) -> 0. %% The retained flag should be propagated for bridge. %%-------------------------------------------------------------------- -clean_retain(false, Msg = #mqtt_message{retain = true}) -> - Msg#mqtt_message{retain = false}; +clean_retain(false, Msg = #mqtt_message{retain = true, headers = Headers}) -> + case lists:member(retained, Headers) of + true -> Msg; + false -> Msg#mqtt_message{retain = false} + end; clean_retain(_IsBridge, Msg) -> Msg. From b9dcccd7f76d7538bcb71ce96063a1dbe96701d1 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 23 Jan 2018 15:20:35 +0800 Subject: [PATCH 43/46] Version 2.3.4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a7bb63edc..804123d2d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PROJECT = emqttd PROJECT_DESCRIPTION = Erlang MQTT Broker -PROJECT_VERSION = 2.3.3 +PROJECT_VERSION = 2.3.4 DEPS = goldrush gproc lager esockd ekka mochiweb pbkdf2 lager_syslog bcrypt clique jsx From 87ae76b6b4464ee591e453c8d2b685cec1771adc Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 23 Jan 2018 15:22:05 +0800 Subject: [PATCH 44/46] Fix issue #1460 - Add node.proto_dist option to support inet6_dist --- etc/emq.conf | 9 +++++++++ priv/emq.schema | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/etc/emq.conf b/etc/emq.conf index ef05b70e2..a5cc7584a 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -231,6 +231,15 @@ node.fullsweep_after = 1000 ## Value: Log file node.crash_dump = {{ platform_log_dir }}/crash.dump +## Specify the erlang distributed protocol. +## +## Value: Enum +## - inet_tcp: the default; handles TCP streams with IPv4 addressing. +## - inet6_tcp: handles TCP with IPv6 addressing. +## +## vm.args: -proto_dist inet_tcp +## node.proto_dist = inet_tcp + ## Sets the net_kernel tick time. TickTime is specified in seconds. ## Notice that all communicating nodes are to have the same TickTime ## value specified. diff --git a/priv/emq.schema b/priv/emq.schema index a70a90f90..954f1bdea 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -168,6 +168,11 @@ end}. {default, "emq@127.0.0.1"} ]}. +%% @doc The erlang distributed protocol +{mapping, "node.proto_dist", "vm_args.-proto_dist", [ + %%{default, "inet_tcp"} +]}. + %% @doc Secret cookie for distributed erlang node {mapping, "node.cookie", "vm_args.-setcookie", [ {default, "emqsecretcookie"} From 94e1229abb162f51c2ed30188ca0c911a8be774c Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Tue, 23 Jan 2018 16:32:53 +0800 Subject: [PATCH 45/46] Uncomment the 'node.proto_dist' to support docker env --- etc/emq.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/emq.conf b/etc/emq.conf index a5cc7584a..681dc9b54 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -238,7 +238,7 @@ node.crash_dump = {{ platform_log_dir }}/crash.dump ## - inet6_tcp: handles TCP with IPv6 addressing. ## ## vm.args: -proto_dist inet_tcp -## node.proto_dist = inet_tcp +node.proto_dist = inet_tcp ## Sets the net_kernel tick time. TickTime is specified in seconds. ## Notice that all communicating nodes are to have the same TickTime From f70bf23440a7d3dbdaa1489d66a1f3312342b9fc Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Wed, 24 Jan 2018 09:48:06 +0800 Subject: [PATCH 46/46] Add 'listener...reuseaddr' option --- etc/emq.conf | 71 +++++++++++++++++++++++++++++++++---------------- priv/emq.schema | 28 ++++++++++++++++++- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/etc/emq.conf b/etc/emq.conf index 681dc9b54..1042d880b 100644 --- a/etc/emq.conf +++ b/etc/emq.conf @@ -704,6 +704,11 @@ listener.tcp.external.tune_buffer = on ## Value: true | false listener.tcp.external.nodelay = true +## The SO_REUSEADDR flag for TCP listener. +## +## Value: true | false +listener.tcp.external.reuseaddr = true + ##-------------------------------------------------------------------- ## Internal TCP Listener for MQTT Protocol @@ -800,6 +805,11 @@ listener.tcp.internal.tune_buffer = on ## Value: true | false listener.tcp.internal.nodelay = false +## The SO_REUSEADDR flag for MQTT/TCP Listener. +## +## Value: true | false +listener.tcp.internal.reuseaddr = true + ##-------------------------------------------------------------------- ## MQTT/SSL - External SSL Listener for MQTT Protocol @@ -1029,10 +1039,15 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## Value: true | false ## listener.ssl.external.nodelay = true +## The SO_REUSEADDR flag for MQTT/SSL Listener. +## +## Value: true | false +listener.ssl.external.reuseaddr = true + ##-------------------------------------------------------------------- ## External WebSocket Listener for MQTT Protocol -## listener.ws. is the IP address and port that the MQTT/Websocket +## listener.ws. is the IP address and port that the MQTT/WebSocket ## listener will bind. ## ## Value: IP:Port | Port @@ -1040,29 +1055,29 @@ listener.ssl.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## Examples: 8083, 127.0.0.1:8083, ::1:8083 listener.ws.external = 8083 -## The acceptor pool for external MQTT/Websocket listener. +## The acceptor pool for external MQTT/WebSocket listener. ## ## Value: Number listener.ws.external.acceptors = 4 -## Maximum number of concurrent MQTT/Websocket connections. +## Maximum number of concurrent MQTT/WebSocket connections. ## ## Value: Number listener.ws.external.max_clients = 102400 -## TODO: Zone of the external MQTT/Websocket listener belonged to. +## TODO: Zone of the external MQTT/WebSocket listener belonged to. ## ## Value: String ## listener.ws.external.zone = external -## Mountpoint of the MQTT/Websocket Listener. +## Mountpoint of the MQTT/WebSocket Listener. ## ## See: listener.tcp..mountpoint ## ## Value: String ## listener.ws.external.mountpoint = external/ -## The access control for the MQTT/Websocket listener. +## The access control for the MQTT/WebSocket listener. ## ## See: listener.tcp..access ## @@ -1084,35 +1099,35 @@ listener.ws.external.access.1 = allow all ## Value: Duration ## listener.ws.external.proxy_protocol_timeout = 3s -## The TCP backlog of external MQTT/Websocket Listener. +## The TCP backlog of external MQTT/WebSocket Listener. ## ## See: listener.tcp..backlog ## ## Value: Number >= 0 listener.ws.external.backlog = 1024 -## The TCP send timeout for external MQTT/Websocket connections. +## The TCP send timeout for external MQTT/WebSocket connections. ## ## See: listener.tcp..send_timeout ## ## Value: Duration listener.ws.external.send_timeout = 15s -## Close the MQTT/Websocket connection if send timeout. +## Close the MQTT/WebSocket connection if send timeout. ## ## See: listener.tcp..send_timeout_close ## ## Value: on | off listener.ws.external.send_timeout_close = on -## The TCP receive buffer(os kernel) for external MQTT/Websocket connections. +## The TCP receive buffer(os kernel) for external MQTT/WebSocket connections. ## ## See: listener.tcp..recbuf ## ## Value: Bytes ## listener.ws.external.recbuf = 4KB -## The TCP send buffer(os kernel) for external MQTT/Websocket connections. +## The TCP send buffer(os kernel) for external MQTT/WebSocket connections. ## ## See: listener.tcp..sndbuf ## @@ -1133,17 +1148,22 @@ listener.ws.external.send_timeout_close = on ## Value: on | off listener.ws.external.tune_buffer = on -## The TCP_NODELAY flag for external MQTT/Websocket connections. +## The TCP_NODELAY flag for external MQTT/WebSocket connections. ## ## See: listener.tcp..nodelay ## ## Value: true | false listener.ws.external.nodelay = true +## The SO_REUSEADDR flag for MQTT/WebSocket Listener. +## +## Value: true | false +listener.ws.external.reuseaddr = true + ##-------------------------------------------------------------------- ## External WebSocket/SSL listener for MQTT Protocol -## listener.wss. is the IP address and port that the MQTT/Websocket/SSL +## listener.wss. is the IP address and port that the MQTT/WebSocket/SSL ## listener will bind. ## ## Value: IP:Port | Port @@ -1151,7 +1171,7 @@ listener.ws.external.nodelay = true ## Examples: 8084, 127.0.0.1:8084, ::1:8084 listener.wss.external = 8084 -## The acceptor pool for external MQTT/Websocket/SSL listener. +## The acceptor pool for external MQTT/WebSocket/SSL listener. ## ## Value: Number listener.wss.external.acceptors = 4 @@ -1161,19 +1181,19 @@ listener.wss.external.acceptors = 4 ## Value: Number listener.wss.external.max_clients = 64 -## TODO: Zone of the external MQTT/Websocket/SSL listener belonged to. +## TODO: Zone of the external MQTT/WebSocket/SSL listener belonged to. ## ## Value: String ## listener.wss.external.zone = external -## Mountpoint of the MQTT/Websocket/SSL Listener. +## Mountpoint of the MQTT/WebSocket/SSL Listener. ## ## See: listener.tcp..mountpoint ## ## Value: String ## listener.wss.external.mountpoint = inbound/ -## The access control rules for the MQTT/Websocket/SSL listener. +## The access control rules for the MQTT/WebSocket/SSL listener. ## ## See: listener.tcp..access. ## @@ -1269,35 +1289,35 @@ listener.wss.external.certfile = {{ platform_etc_dir }}/certs/cert.pem ## Value: cn | dn ## listener.wss.external.peer_cert_as_username = cn -## TCP backlog for the Websocket/SSL connection. +## TCP backlog for the WebSocket/SSL connection. ## ## See listener.tcp..backlog ## ## Value: Number >= 0 listener.wss.external.backlog = 1024 -## The TCP send timeout for the Websocket/SSL connection. +## The TCP send timeout for the WebSocket/SSL connection. ## ## See: listener.tcp..send_timeout ## ## Value: Duration listener.wss.external.send_timeout = 15s -## Close the Websocket/SSL connection if send timeout. +## Close the WebSocket/SSL connection if send timeout. ## ## See: listener.tcp..send_timeout_close ## ## Value: on | off listener.wss.external.send_timeout_close = on -## The TCP receive buffer(os kernel) for the Websocket/SSL connections. +## The TCP receive buffer(os kernel) for the WebSocket/SSL connections. ## ## See: listener.tcp..recbuf ## ## Value: Bytes ## listener.wss.external.recbuf = 4KB -## The TCP send buffer(os kernel) for the Websocket/SSL connections. +## The TCP send buffer(os kernel) for the WebSocket/SSL connections. ## ## See: listener.tcp..sndbuf ## @@ -1311,13 +1331,18 @@ listener.wss.external.send_timeout_close = on ## Value: Bytes ## listener.wss.external.buffer = 4KB -## The TCP_NODELAY flag for Websocket/SSL connections. +## The TCP_NODELAY flag for WebSocket/SSL connections. ## ## See: listener.tcp..nodelay ## ## Value: true | false ## listener.wss.external.nodelay = true +## The SO_REUSEADDR flag for WebSocket/SSL listener. +## +## Value: true | false +listener.wss.external.reuseaddr = true + ##-------------------------------------------------------------------- ## HTTP Management API Listener diff --git a/priv/emq.schema b/priv/emq.schema index 954f1bdea..b07055ead 100644 --- a/priv/emq.schema +++ b/priv/emq.schema @@ -850,6 +850,11 @@ end}. hidden ]}. +{mapping, "listener.tcp.$name.reuseaddr", "emqttd.listeners", [ + {datatype, {enum, [true, false]}}, + hidden +]}. + %%-------------------------------------------------------------------- %% SSL Listeners @@ -932,6 +937,11 @@ end}. hidden ]}. +{mapping, "listener.ssl.$name.reuseaddr", "emqttd.listeners", [ + {datatype, {enum, [true, false]}}, + hidden +]}. + {mapping, "listener.ssl.$name.tls_versions", "emqttd.listeners", [ {datatype, string} ]}. @@ -1067,6 +1077,11 @@ end}. hidden ]}. +{mapping, "listener.ws.$name.reuseaddr", "emqttd.listeners", [ + {datatype, {enum, [true, false]}}, + hidden +]}. + %%-------------------------------------------------------------------- %% MQTT/WebSocket/SSL Listeners @@ -1148,6 +1163,11 @@ end}. hidden ]}. +{mapping, "listener.wss.$name.reuseaddr", "emqttd.listeners", [ + {datatype, {enum, [true, false]}}, + hidden +]}. + {mapping, "listener.wss.$name.tls_versions", "emqttd.listeners", [ {datatype, string} ]}. @@ -1239,7 +1259,8 @@ end}. {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)}]) + {nodelay, cuttlefish:conf_get(Prefix ++ ".nodelay", Conf, true)}, + {reuseaddr, cuttlefish:conf_get(Prefix ++ ".reuseaddr", Conf, true)}]) end, SplitFun = fun(undefined) -> undefined; (S) -> string:tokens(S, ",") end, @@ -1378,6 +1399,11 @@ end}. hidden ]}. +{mapping, "listener.api.$name.reuseaddr", "emqttd.listeners", [ + {datatype, {enum, [true, false]}}, + hidden +]}. + {mapping, "listener.api.$name.handshake_timeout", "emqttd.listeners", [ {datatype, {duration, ms}} ]}.