Merge pull request #743 from emqtt/emq20

2.0-rc.3: bugfix
This commit is contained in:
turtleDeng 2016-10-31 20:44:46 +08:00 committed by GitHub
commit 6ddfb7f2cb
17 changed files with 148 additions and 554 deletions

View File

@ -1,15 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICZTCCAc4CCQCPzzI1ezeZPTANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJD
TjERMA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MREwDwYDVQQK
EwhlbXF0dC5pbzERMA8GA1UEAxMIZW1xdHQuaW8xHDAaBgkqhkiG9w0BCQEWDWhv
bmdAZW1xdHQuaW8wHhcNMTYxMDEzMDkwNzQ5WhcNMTYxMTEyMDkwNzQ5WjB3MQsw
CQYDVQQGEwJDTjERMA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91
MREwDwYDVQQKEwhlbXF0dC5pbzERMA8GA1UEAxMIZW1xdHQuaW8xHDAaBgkqhkiG
9w0BCQEWDWhvbmdAZW1xdHQuaW8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
AJ/6ACaLPXP6wpGOqc9+jFRFN6ufODqGB5SamCNmOKXpSm/U+KT87NPg4i4wn31s
167nb65lk3IbdvzPzTSCAP6DG5s0+qDgpEMHeKKEC4zaAwoIxCgVUjab51RbVFBs
AhzowxdRl6jQrGVgvXiLzz1+3b+1Xydu5J5Z2IeLm8NPAgMBAAEwDQYJKoZIhvcN
AQEFBQADgYEAkt/VWi4tUUEdOnDwnCZ4IheV9Sp+6T3XsRxje7PKDsvZQlmpvMP6
StfM+wkxty2dxVOU5Sx8CwXk5roKvULQY5rAyn9log6vEAI4Oyr4vnRN24JF7/Tr
xeP1cOv2LJlEuQm1JWe+VtNqfJ+f81CnfaJMAo17W5T/5UxI5n8ziKc=
MIICxjCCAa6gAwIBAgIJAPhU8tv3KMe/MA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
BAMMCE15VGVzdENBMB4XDTE2MTAzMTA3MTU0NVoXDTE3MTAzMTA3MTU0NVowEzER
MA8GA1UEAwwITXlUZXN0Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCtPcDnmjiVl7ScDhYvGaW+PUgfp7P5cM39mnrW6fkxhA0tgunWpWlYVKbcuh5y
4bTNYrOQpcFO3Zg62tva4XEL8O1huqTlGsAeysZ3vWE4/8NGN/3wZy0TKDvwiwOB
tbS3C5wcRQZohExL6yEL4XzDGk44x2mIs8/NzeG7Zycqybh9tsCJiHbLiTxnLa24
v5USOtlvWye0hA0yUUqc2k7tKVmIMT4A4ulMb2sDVRrSLjyFDTI0c8grlPLfKbG8
gpYLsHn9aAjqviyvmJdRLxwauqn+ghNWn1TyZwgAUxpoTtWeC0ilzEt18RP8vZjm
eCbEP4qQDDvSCdLrie5CezyxAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P
BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBJ/I/QJjU+mgkIaaHImFcIYFrfBirC
vDiWo2W+zRh7CbcSf+jsksI99d230ixSDY36CPLKZeZhELST7xWKEELKbPdNbtOO
EM10+XteLSXKVNGXfrEbW973eum3FGLobMA9OcH6+qDaf08pibe7kuv10aAgSs/I
0Qg5H/UTAKQJKO9hhOgERM/FettuF+WGJaaZZZb9Y2YYBNRf/GtM8KHCjpCX9+XD
kdeQGO8Hn10H9tOmggyfdIpsunBcs2/6/exCp8RPBWurN2GSW2RcnS5xVL0r+SVW
VOhSDy1JwnNPczpqkqE74qAbAah0dTJFcFWzeGLVk7Kp+2pissAiU3gg
-----END CERTIFICATE-----

View File

@ -1,15 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICZjCCAc+gAwIBAgIJAO89PfgaeHB2MA0GCSqGSIb3DQEBBQUAMHcxCzAJBgNV
BAYTAkNOMREwDwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ1pob3UxETAP
BgNVBAoTCGVtcXR0LmlvMREwDwYDVQQDEwhlbXF0dC5pbzEcMBoGCSqGSIb3DQEJ
ARYNaG9uZ0BlbXF0dC5pbzAeFw0xNjEwMTMwOTEzMTFaFw0xNjExMTIwOTEzMTFa
MEYxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhaaGVKaWFuZzERMA8GA1UEBwwISGFu
Z1pob3UxETAPBgNVBAsMCGVtcXR0LmlvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQDaOI1oasKjo0JGk5bMIxGInlxbvTuJZ8436u8HY4q8jZ+a4G12+UdTVHRF
d94/ClHWn8WvOvzbxvmSkhninlzdWm1rBLWis3Z2kStmhL77kITEfIImus9pjm5l
OgBxY4+Q7LSEsKYYH+ClYVaLlzO8PILEkBk6xxxq0X7AnCfDfQIDAQABoyswKTAJ
BgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3
DQEBBQUAA4GBAGS1yw1w9H7F4uOaK02mUCHZiV+EBB3gkBBqtAx7TXsmoGgT6ySA
7DwrbX6IH82bhZT4TjouhaPlUPE9pin88d/2kNbRrbZoZDMYGq02mVVRxfLzJqM2
GVlsxebsFFPbYhOaf9TuRR3v13ebga0FrXNke+IGLsYZSM2PZ+F4EvIA
MIIC9jCCAd6gAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhNeVRl
c3RDQTAeFw0xNjEwMzEwNzE1NDVaFw0xNzEwMzEwNzE1NDVaMDkxJjAkBgNVBAMT
HWRlbmdoYWlndWlkZU1hY0Jvb2stQWlyLmxvY2FsMQ8wDQYDVQQKEwZzZXJ2ZXIw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4Ena4vgWrzwUB0hGW1v0v
K986FhU5ZdYz5H5MGonfWwv89nR2DlftSDXEvKFyc2MT81GGm16VJv3mVpQJLuKA
xLBLY7a1zSrJdugXWy+mgJJTPW6KjTY4jPtfCl6x/yVr8YclVa8XO0JFzOme2LMV
Ylc/ixVEa66UpxRNrg5yWHS26KcB1lE3GLERoRBKF7nsyGqGY4X9TypBwglCVoqK
3dKVGwCvFur+oPnt/C5pwR6UmUV/Ppf1EaRD7Po+xcyJSeCvszG3FH4iHsDHnjLe
DR6lxouvMCb+aKJi9d0xowOjhbKoFMF179t4SVnptQeq+U6ui3cPKUjia7Zh1tZT
AgMBAAGjLzAtMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgUgMBMGA1UdJQQMMAoGCCsG
AQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQB2jlDPiZfP/whsvvFn43g37QMwX5ST
Z5OpmEFnFjAH3ec0PPqPrKYEu00q5wEC+8L6uVH8FHOFf11JLH4wl11/C/mvE92D
qZtGG8KCnG2+rk5OJPGX+28Z+OnCZlXOjQ8qd2x5KtIW50JuXJ3cbDRHtF/TVanm
Exu+TCBeToNwbcU2sfQnbljkUTj4idUFz0pq3uvw3dA4R1J2foungPAYXSWcVhtb
RYtG8epIvkAyyUE5nY3kC05AUml6gSZkrJiYM5I1IJTX1lQ7Pv2yxRBZUtTx33rP
ccnsW6tbHTDBG8UDHx4LKHErdWFgCJWI81EUEcTip9g2zCOGTWKnpz+z
-----END CERTIFICATE-----

View File

@ -1,14 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICITCCAYoCCQDvPT34GnhwdzANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJD
TjERMA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MREwDwYDVQQK
EwhlbXF0dC5pbzERMA8GA1UEAxMIZW1xdHQuaW8xHDAaBgkqhkiG9w0BCQEWDWhv
bmdAZW1xdHQuaW8wHhcNMTYxMDEzMDkxNTMxWhcNMTYxMTEyMDkxNTMxWjB3MQsw
CQYDVQQGEwJDTjERMA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91
MREwDwYDVQQKEwhlbXF0dC5pbzERMA8GA1UEAxMIZW1xdHQuaW8xHDAaBgkqhkiG
9w0BCQEWDWhvbmdAZW1xdHQuaW8wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAx1yF
I3YnvDPtHpGzJ+9ZGnnKkvMdaoyawT9rPvLsteeDkfknJcGCV5mKmjvH1xeeMIN1
Kql9nVPoe7BtzJ0XwQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAALulKuZuE6RhwIT
JBrUN7j4dbJe7Ttz+Q3qSQq6hNJoDf8hNrAHUDQzov9yU/KMMi9xE6+hu+ieuTo6
hKLBDAD4hDzb6+EU5HAcASDkAXWnQq/Keo73+VrmUwMQs93tTC/jGXpsj/gLMEWB
xcxXpgBPDGIR9L8Y2YMhEBLjm7Zv
MIIC9jCCAd6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhNeVRl
c3RDQTAeFw0xNjEwMzEwNzE1NDZaFw0xNzEwMzEwNzE1NDZaMDkxJjAkBgNVBAMT
HWRlbmdoYWlndWlkZU1hY0Jvb2stQWlyLmxvY2FsMQ8wDQYDVQQKEwZjbGllbnQw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmPMkieMtJO4PGIQG30uxI
SEoRJoF2w0ufFhZGYCEaqFlHaSoc6nTiCUmnxadDpjkNBs4R6RDfM9zPJ0QdgSFO
OJsWgQEHym/EQTcEx11+/2NDZWMJyZdpWZlU57SwHfWDwYa2XFX1bV+pAvhB8cli
wCkygTwp1cZcwQpb8TfZySy8r5mwrWq2nhCQPtYqMxjNjpR/UeeZzt+Uh3CEXQ8h
omjGinDXnnGwrYwBEP9G6fzTvyCWTyrsWC1Q37oAMzbkwFRoIBSAQWXBv9hgI08s
IBYvXnRGKWOJZGxAP4a4TvpFS+nqi+fFVn4ktUfcH3PoSMh7PKavrFT2hQaryLt1
AgMBAAGjLzAtMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsG
AQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAeimI8AQBFWiE9/Nf/0radux355mod
5vPLbKn6I6nzb/sS/Ug8SMoFnkhncwj+XOgTSliUyWcwOB11UDVJbUIkB/x+Qo3w
hvrATTdby2WdFNQvH4X7PmP8asDDN7ZxoLyRmuhjL4avJ3giwRcuQK4cB35b+Lb2
p1e7hW81RaV7OEc0o4/vJgPvv9N7wvUuipwJns6PrN7VDn99lT8zWrt2pQ06e2mk
jDuXulVpiUtLHJhTnABkCaKiHWCYAFfMjFeRb3gUXKqShzOyDSGWY91YMID/HE4r
sVLm2mD1zurue8EmYtQQ6uiJIW9SzvshMHG6EA5QWA1ytoalfePbvf+c
-----END CERTIFICATE-----

View File

@ -1,9 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1,15 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -169,37 +169,6 @@ mqtt.plugins.etc_dir = etc/plugins/
## File to store loaded plugin names.
mqtt.plugins.loaded_file = data/loaded_plugins
##-------------------------------------------------------------------
## MQTT Modules
##-------------------------------------------------------------------
## Enable retainer module
mqtt.module.retainer = on
## disc: disc_copies, ram: ram_copies
mqtt.module.retainer.storage_type = ram
## Max number of retained messages
mqtt.module.retainer.max_message_num = 100000
## Max Payload Size of retained message
mqtt.module.retainer.max_payload_size = 64KB
## Expired after seconds, never expired if 0
mqtt.module.retainer.expired_after = 0
## Enable presence module
## Publish presence messages when client connected or disconnected.
mqtt.module.presence = on
mqtt.module.presence.qos = 0
## Enable subscription module
## Subscribe topics automatically when client connected
mqtt.module.subscription = on
mqtt.module.subscription.topics = $client/%c=1,$user/%u=1
##--------------------------------------------------------------------
## MQTT Listeners
##--------------------------------------------------------------------
@ -237,10 +206,10 @@ mqtt.listener.ssl.max_clients = 512
## Configuring SSL Options
## See http://erlang.org/doc/man/ssl.html
mqtt.listener.ssl.handshake_timeout = 15
mqtt.listener.ssl.handshake_timeout = 2000
mqtt.listener.ssl.keyfile = etc/certs/key.pem
mqtt.listener.ssl.certfile = etc/certs/cert.pem
mqtt.listener.ssl.cacertfile = etc/certs/cacert.pem
## mqtt.listener.ssl.cacertfile = etc/certs/cacert.pem
## mqtt.listener.ssl.verify = verify_peer
## mqtt.listener.ssl.failed_if_no_peer_cert = true

View File

@ -55,6 +55,17 @@
-type(mqtt_topic() :: #mqtt_topic{}).
%%--------------------------------------------------------------------
%% MQTT Subscription
%%--------------------------------------------------------------------
-record(mqtt_subscription, {
subid :: binary() | atom(),
topic :: binary(),
qos :: 0 | 1 | 2
}).
-type(mqtt_subscription() :: #mqtt_subscription{}).
%%--------------------------------------------------------------------
%% MQTT Client
%%--------------------------------------------------------------------

View File

@ -533,7 +533,7 @@ end}.
]}.
{mapping, "mqtt.listener.ssl.verify", "emqttd.listeners", [
{datatype, string}
{datatype, atom}
]}.
{mapping, "mqtt.listener.ssl.failed_if_no_peer_cert", "emqttd.listeners", [
@ -589,7 +589,7 @@ end}.
]}.
{mapping, "mqtt.listener.https.verify", "emqttd.listeners", [
{datatype, string}
{datatype, atom}
]}.
{mapping, "mqtt.listener.https.failed_if_no_peer_cert", "emqttd.listeners", [
@ -615,8 +615,8 @@ end}.
{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
{certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
{cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)},
{verify, cuttlefish:conf_get(Prefix ++ ".verify_peer", Conf, undefined)},
{failed_if_no_peer_cert, cuttlefish:conf_get(Prefix ++ "failed_if_no_peer_cert", Conf, undefined)}])
{verify, cuttlefish:conf_get(Prefix ++ ".verify", Conf, undefined)},
{failed_if_no_peer_cert, cuttlefish:conf_get(Prefix ++ ".failed_if_no_peer_cert", Conf, undefined)}])
end,
Listeners = fun(Name) when is_atom(Name) ->
@ -636,83 +636,6 @@ end}.
lists:append([Listeners(tcp), Listeners(ssl), Listeners(http), Listeners(https)])
end}.
%%--------------------------------------------------------------------
%% MQTT Modules
%%--------------------------------------------------------------------
{mapping, "mqtt.module.retainer", "emqttd.modules", [
{default, on},
{datatype, flag}
]}.
{mapping, "mqtt.module.retainer.storage_type", "emqttd.modules", [
{default, ram},
{datatype, {enum, [disc, ram]}}
]}.
{mapping, "mqtt.module.retainer.max_message_num", "emqttd.modules", [
{default, 100000},
{datatype, integer}
]}.
{mapping, "mqtt.module.retainer.max_payload_size", "emqttd.modules", [
{default, "64KB"},
{datatype, bytesize}
]}.
{mapping, "mqtt.module.retainer.expired_after", "emqttd.modules", [
{default, 0},
{datatype, integer}
]}.
{mapping, "mqtt.module.presence", "emqttd.modules", [
{default, on},
{datatype, flag}
]}.
{mapping, "mqtt.module.presence.qos", "emqttd.modules", [
{default, 0},
{datatype, integer},
{validators, ["range:0-2"]}
]}.
{mapping, "mqtt.module.subscription", "emqttd.modules", [
{default, off},
{datatype, flag}
]}.
{mapping, "mqtt.module.subscription.topics", "emqttd.modules", [
{default, undefined},
{datatype, string}
]}.
{translation, "emqttd.modules", fun(Conf) ->
WithMod = fun(Name, OptsF) ->
Key = "mqtt.module." ++ atom_to_list(Name),
case cuttlefish:conf_get(Key, Conf, false) of
true -> [{Name, OptsF(Key)}];
false -> []
end
end,
RetainOpts = fun(Prefix) ->
[{storage_type, cuttlefish:conf_get(Prefix ++ ".storage_type", Conf, ram)},
{max_message_num, cuttlefish:conf_get(Prefix ++ ".max_message_num", Conf, undefined)},
{max_payload_size, cuttlefish:conf_get(Prefix ++ ".max_payload_size", Conf, undefined)},
{expired_after, cuttlefish:conf_get(Prefix ++ ".expired_after", Conf, 0)}]
end,
PresOpts = fun(Prefix) ->
[{qos, cuttlefish:conf_get(Prefix ++ ".qos", Conf, 0)}]
end,
ParseFun = fun(undefined) -> [];
(Topics) -> [begin
[Topic, Qos] = string:tokens(S, "="),
{list_to_binary(Topic), list_to_integer(Qos)}
end || S <- string:tokens(Topics, ",")]
end,
SubOpts = fun(Prefix) -> ParseFun(cuttlefish:conf_get(Prefix ++ ".topics", Conf)) end,
lists:append([WithMod(retainer, RetainOpts), WithMod(presence, PresOpts), WithMod(subscription, SubOpts)])
end}.
%%--------------------------------------------------------------------
%% System Monitor
%%--------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
{deps, [
{gproc,".*",{git,"https://github.com/uwiger/gproc",""}},{lager,".*",{git,"https://github.com/basho/lager","master"}},{gen_logger,".*",{git,"https://github.com/emqtt/gen_logger",""}},{esockd,".*",{git,"https://github.com/emqtt/esockd","emq20"}},{mochiweb,".*",{git,"https://github.com/emqtt/mochiweb",""}},{getopt,".*",{git,"https://github.com/jcomellas/getopt","v0.8.2"}},{pbkdf2,".*",{git,"https://github.com/basho/erlang-pbkdf2","2.0.0"}},{clique,".*",{git,"https://github.com/basho/clique",""}},{time_compat,".*",{git,"https://github.com/lasp-lang/time_compat",""}},{rand_compat,".*",{git,"https://github.com/lasp-lang/rand_compat",""}}
{gproc,".*",{git,"https://github.com/uwiger/gproc",""}},{lager,".*",{git,"https://github.com/basho/lager","master"}},{gen_logger,".*",{git,"https://github.com/emqtt/gen_logger",""}},{esockd,".*",{git,"https://github.com/emqtt/esockd","emq20"}},{mochiweb,".*",{git,"https://github.com/emqtt/mochiweb",""}}
]}.
{erl_opts, [{parse_transform,lager_transform}]}.

View File

@ -23,7 +23,7 @@
%% Application callbacks
-export([start/2, stop/1]).
-export([start_listener/1, stop_listener/1, is_mod_enabled/1]).
-export([start_listener/1, stop_listener/1]).
%% MQTT SockOpts
-define(MQTT_SOCKOPTS, [binary, {packet, raw}, {reuseaddr, true},
@ -47,7 +47,6 @@ start(_StartType, _StartArgs) ->
start_servers(Sup),
emqttd_cli:load(),
register_acl_mod(),
load_all_mods(),
emqttd_plugins:init(),
emqttd_plugins:load(),
start_listeners(),
@ -151,26 +150,6 @@ register_acl_mod() ->
undefined -> ok
end.
%%--------------------------------------------------------------------
%% Load Modules
%%--------------------------------------------------------------------
%% @doc Load all modules
load_all_mods() ->
lists:foreach(fun load_mod/1, emqttd:env(modules, [])).
load_mod({Name, Opts}) ->
Mod = list_to_atom("emqttd_mod_" ++ atom_to_list(Name)),
case catch Mod:load(Opts) of
ok -> lager:info("Load module ~s successfully", [Name]);
{error, Error} -> lager:error("Load module ~s error: ~p", [Name, Error]);
{'EXIT', Reason} -> lager:error("Load module ~s error: ~p", [Name, Reason])
end.
%% @doc Is module enabled?
-spec(is_mod_enabled(Name :: atom()) -> boolean()).
is_mod_enabled(Name) -> lists:keyfind(Name, 1, emqttd:env(modules, [])).
%%--------------------------------------------------------------------
%% Start Listeners
%%--------------------------------------------------------------------
@ -231,11 +210,4 @@ merge_sockopts_test_() ->
Opts = [{acceptors, 16}, {max_clients, 512}],
?_assert(merge_sockopts(Opts) == [{sockopts, ?MQTT_SOCKOPTS} | Opts]).
load_all_mods_test_() ->
?_assert(load_all_mods() == ok).
is_mod_enabled_test_() ->
?_assert(is_mod_enabled(presence) == {module, presence, [{qos, 0}]}),
?_assert(is_mod_enabled(test) == false).
-endif.

View File

@ -133,7 +133,8 @@ authorized(Req) ->
false;
"Basic " ++ BasicAuth ->
{Username, Password} = user_passwd(BasicAuth),
case emqttd_access_control:auth(#mqtt_client{username = Username}, Password) of
{ok, Peer} = Req:get(peername),
case emqttd_access_control:auth(#mqtt_client{username = Username, peername = Peer}, Password) of
ok ->
true;
{error, Reason} ->

View File

@ -1,75 +0,0 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2012-2016 Feng Lee <feng@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.
%%--------------------------------------------------------------------
-module(emqttd_mod_presence).
-behaviour(emqttd_gen_mod).
-include("emqttd.hrl").
-export([load/1, unload/1]).
-export([on_client_connected/3, on_client_disconnected/3]).
load(Opts) ->
emqttd:hook('client.connected', fun ?MODULE:on_client_connected/3, [Opts]),
emqttd:hook('client.disconnected', fun ?MODULE:on_client_disconnected/3, [Opts]).
on_client_connected(ConnAck, Client = #mqtt_client{client_id = ClientId,
username = Username,
peername = {IpAddr, _},
clean_sess = CleanSess,
proto_ver = ProtoVer}, Opts) ->
Json = mochijson2:encode([{clientid, ClientId},
{username, Username},
{ipaddress, list_to_binary(emqttd_net:ntoa(IpAddr))},
{session, sess(CleanSess)},
{protocol, ProtoVer},
{connack, ConnAck},
{ts, emqttd_time:now_to_secs()}]),
Msg = message(qos(Opts), topic(connected, ClientId), Json),
emqttd:publish(emqttd_message:set_flag(sys, Msg)),
{ok, Client}.
on_client_disconnected(Reason, #mqtt_client{client_id = ClientId}, Opts) ->
Json = mochijson2:encode([{clientid, ClientId},
{reason, reason(Reason)},
{ts, emqttd_time:now_to_secs()}]),
Msg = message(qos(Opts), topic(disconnected, ClientId), Json),
emqttd:publish(emqttd_message:set_flag(sys, Msg)),
ok.
unload(_Opts) ->
emqttd:unhook('client.connected', fun ?MODULE:on_client_connected/3),
emqttd:unhook('client.disconnected', fun ?MODULE:on_client_disconnected/3).
sess(false) -> true;
sess(true) -> false.
qos(Opts) -> proplists:get_value(qos, Opts, 0).
message(Qos, Topic, Json) ->
emqttd_message:make(presence, Qos, Topic, iolist_to_binary(Json)).
topic(connected, ClientId) ->
emqttd_topic:systop(list_to_binary(["clients/", ClientId, "/connected"]));
topic(disconnected, ClientId) ->
emqttd_topic:systop(list_to_binary(["clients/", ClientId, "/disconnected"])).
reason(Reason) when is_atom(Reason) -> Reason;
reason({Error, _}) when is_atom(Error) -> Error;
reason(_) -> internal_error.

View File

@ -1,202 +0,0 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2012-2016 Feng Lee <feng@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.
%%--------------------------------------------------------------------
-module(emqttd_mod_retainer).
-behaviour(gen_server).
-behaviour(emqttd_gen_mod).
-include("emqttd.hrl").
-include("emqttd_internal.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
%% gen_mod Callbacks
-export([load/1, unload/1]).
%% Hook Callbacks
-export([on_session_subscribed/4, on_message_publish/2]).
%% API Function Exports
-export([start_link/1]).
%% gen_server Function Exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(mqtt_retained, {topic, msg}).
-record(state, {stats_fun, expired_after, stats_timer, expire_timer}).
%%--------------------------------------------------------------------
%% Load/Unload
%%--------------------------------------------------------------------
load(Env) ->
emqttd_mod_sup:start_child(spec(Env)),
emqttd:hook('session.subscribed', fun ?MODULE:on_session_subscribed/4, [Env]),
emqttd:hook('message.publish', fun ?MODULE:on_message_publish/2, [Env]).
on_session_subscribed(_ClientId, _Username, {Topic, _Opts}, _Env) ->
SessPid = self(),
Msgs = case emqttd_topic:wildcard(Topic) of
false -> read_messages(Topic);
true -> match_messages(Topic)
end,
lists:foreach(fun(Msg) -> SessPid ! {dispatch, Topic, Msg} end, lists:reverse(Msgs)).
on_message_publish(Msg = #mqtt_message{retain = false}, _Env) ->
{ok, Msg};
%% RETAIN flag set to 1 and payload containing zero bytes
on_message_publish(Msg = #mqtt_message{retain = true, topic = Topic, payload = <<>>}, _Env) ->
mnesia:dirty_delete(mqtt_retained, Topic),
{stop, Msg};
on_message_publish(Msg = #mqtt_message{topic = Topic, retain = true, payload = Payload}, Env) ->
case {is_table_full(Env), is_too_big(size(Payload), Env)} of
{false, false} ->
mnesia:dirty_write(#mqtt_retained{topic = Topic, msg = Msg}),
emqttd_metrics:set('messages/retained', retained_count());
{true, _}->
lager:error("Cannot retain message(topic=~s) for table is full!", [Topic]);
{_, true}->
lager:error("Cannot retain message(topic=~s, payload_size=~p)"
" for payload is too big!", [Topic, size(Payload)])
end,
{ok, Msg#mqtt_message{retain = false}}.
is_table_full(Env) ->
Limit = proplists:get_value(max_message_num, Env, 0),
Limit > 0 andalso (retained_count() > Limit).
is_too_big(Size, Env) ->
Limit = proplists:get_value(max_payload_size, Env, 0),
Limit > 0 andalso (Size > Limit).
unload(_Env) ->
emqttd:unhook('session.subscribed', fun ?MODULE:on_session_subscribed/4),
emqttd:unhook('message.publish', fun ?MODULE:on_message_publish/2),
emqttd_mod_sup:stop_child(?MODULE).
spec(Env) ->
{?MODULE, {?MODULE, start_link, [Env]}, permanent, 5000, worker, [?MODULE]}.
%%--------------------------------------------------------------------
%% API
%%--------------------------------------------------------------------
%% @doc Start the retainer
-spec(start_link(Env :: list()) -> {ok, pid()} | ignore | {error, any()}).
start_link(Env) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [Env], []).
%%--------------------------------------------------------------------
%% gen_server Callbacks
%%--------------------------------------------------------------------
init([Env]) ->
Copy = case proplists:get_value(storage_type, Env, disc) of
disc -> disc_copies;
ram -> ram_copies
end,
ok = emqttd_mnesia:create_table(mqtt_retained, [
{type, ordered_set},
{Copy, [node()]},
{record_name, mqtt_retained},
{attributes, record_info(fields, mqtt_retained)},
{storage_properties, [{ets, [compressed]},
{dets, [{auto_save, 1000}]}]}]),
ok = emqttd_mnesia:copy_table(mqtt_retained),
StatsFun = emqttd_stats:statsfun('retained/count', 'retained/max'),
{ok, StatsTimer} = timer:send_interval(timer:seconds(1), stats),
State = #state{stats_fun = StatsFun, stats_timer = StatsTimer},
{ok, init_expire_timer(proplists:get_value(expired_after, Env, 0), State)}.
init_expire_timer(0, State) ->
State;
init_expire_timer(undefined, State) ->
State;
init_expire_timer(Secs, State) ->
{ok, Timer} = timer:send_interval(timer:seconds(Secs), expire),
State#state{expired_after = Secs, expire_timer = Timer}.
handle_call(Req, _From, State) ->
?UNEXPECTED_REQ(Req, State).
handle_cast(Msg, State) ->
?UNEXPECTED_MSG(Msg, State).
handle_info(stats, State = #state{stats_fun = StatsFun}) ->
StatsFun(retained_count()),
{noreply, State, hibernate};
handle_info(expire, State = #state{expired_after = Never})
when Never =:= 0 orelse Never =:= undefined ->
{noreply, State, hibernate};
handle_info(expire, State = #state{expired_after = ExpiredAfter}) ->
expire_messages(emqttd_time:now_to_secs() - ExpiredAfter),
{noreply, State, hibernate};
handle_info(Info, State) ->
?UNEXPECTED_INFO(Info, State).
terminate(_Reason, _State = #state{stats_timer = TRef1, expire_timer = TRef2}) ->
timer:cancel(TRef1),
timer:cancel(TRef2).
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%--------------------------------------------------------------------
%% Internal Functions
%%--------------------------------------------------------------------
-spec(read_messages(binary()) -> [mqtt_message()]).
read_messages(Topic) ->
[Msg || #mqtt_retained{msg = Msg} <- mnesia:dirty_read(mqtt_retained, Topic)].
-spec(match_messages(binary()) -> [mqtt_message()]).
match_messages(Filter) ->
%% TODO: optimize later...
Fun = fun(#mqtt_retained{topic = Name, msg = Msg}, Acc) ->
case emqttd_topic:match(Name, Filter) of
true -> [Msg|Acc];
false -> Acc
end
end,
mnesia:async_dirty(fun mnesia:foldl/3, [Fun, [], mqtt_retained]).
-spec(expire_messages(pos_integer()) -> any()).
expire_messages(Time) when is_integer(Time) ->
mnesia:transaction(
fun() ->
Match = ets:fun2ms(
fun(#mqtt_retained{topic = Topic, msg = #mqtt_message{timestamp = Ts}})
when Time > Ts -> Topic
end),
Topics = mnesia:select(mqtt_retained, Match, write),
lists:foreach(fun(<<"$SYS/", _/binary>>) -> ok; %% ignore $SYS/# messages
(Topic) -> mnesia:delete({mqtt_retained, Topic})
end, Topics)
end).
-spec(retained_count() -> non_neg_integer()).
retained_count() -> mnesia:table_info(mqtt_retained, size).

View File

@ -1,52 +0,0 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2012-2016 Feng Lee <feng@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.
%%--------------------------------------------------------------------
-module(emqttd_mod_subscription).
-behaviour(emqttd_gen_mod).
-include("emqttd.hrl").
-include("emqttd_protocol.hrl").
-export([load/1, on_client_connected/3, unload/1]).
load(Opts) ->
Topics = [{iolist_to_binary(Topic), QoS} || {Topic, QoS} <- Opts, ?IS_QOS(QoS)],
emqttd:hook('client.connected', fun ?MODULE:on_client_connected/3, [Topics]).
on_client_connected(?CONNACK_ACCEPT, Client = #mqtt_client{client_id = ClientId,
client_pid = ClientPid,
username = Username}, Topics) ->
Replace = fun(Topic) -> rep(<<"%u">>, Username, rep(<<"%c">>, ClientId, Topic)) end,
TopicTable = [{Replace(Topic), Qos} || {Topic, Qos} <- Topics],
emqttd_client:subscribe(ClientPid, TopicTable),
{ok, Client};
on_client_connected(_ConnAck, _Client, _State) ->
ok.
unload(_Opts) ->
emqttd:unhook('client.connected', fun ?MODULE:on_client_connected/3).
rep(<<"%c">>, ClientId, Topic) ->
emqttd_topic:feed_var(<<"%c">>, ClientId, Topic);
rep(<<"%u">>, undefined, Topic) ->
Topic;
rep(<<"%u">>, Username, Topic) ->
emqttd_topic:feed_var(<<"%u">>, Username, Topic).

View File

@ -228,7 +228,7 @@ del_subscriber_(Share, Topic, Subscriber) ->
del_local_subscriber_(Share, Topic, Subscriber) ->
ets:delete_object(mqtt_subscriber, {{local, Topic}, shared(Share, Subscriber)}),
(not ets:member(subscriber, {local, Topic})) andalso emqttd_router:del_local_route(Topic).
(not ets:member(mqtt_subscriber, {local, Topic})) andalso emqttd_router:del_local_route(Topic).
shared(undefined, Subscriber) ->
Subscriber;

View File

@ -80,6 +80,9 @@ mqtt.client_idle_timeout = 30
## Allow Anonymous authentication
mqtt.allow_anonymous = true
## Default ACL File
mqtt.acl_file = etc/acl.conf
##--------------------------------------------------------------------
## MQTT Session
##--------------------------------------------------------------------
@ -161,10 +164,10 @@ mqtt.bridge.ping_down_interval = 1
##-------------------------------------------------------------------
## Dir of plugins' config
##mqtt.plugins.etc_dir = etc/plugins/
mqtt.plugins.etc_dir = etc/plugins/
## File to store loaded plugin names.
##mqtt.plugins.loaded_file = data/loaded_plugins
mqtt.plugins.loaded_file = data/loaded_plugins
##-------------------------------------------------------------------
## MQTT Modules
@ -186,8 +189,7 @@ mqtt.module.retainer.max_payload_size = 64KB
mqtt.module.retainer.expired_after = 0
## Enable presence module
## Client presence management module. Publish presence messages when
## client connected or disconnected.
## Publish presence messages when client connected or disconnected.
mqtt.module.presence = on
mqtt.module.presence.qos = 0
@ -235,26 +237,26 @@ mqtt.listener.ssl.max_clients = 512
## Configuring SSL Options
## See http://erlang.org/doc/man/ssl.html
mqtt.listener.ssl.handshake_timeout = 15 #seconds
mqtt.listener.ssl.keyfile = etc/ssl/key.pem
mqtt.listener.ssl.certfile = etc/ssl/cert.pem
mqtt.listener.ssl.cacertfile = etc/ssl/cacert.pem
mqtt.listener.ssl.handshake_timeout = 15
mqtt.listener.ssl.keyfile = etc/certs/key.pem
mqtt.listener.ssl.certfile = etc/certs/cert.pem
## mqtt.listener.ssl.cacertfile = etc/certs/cacert.pem
## mqtt.listener.ssl.verify = verify_peer
## mqtt.listener.ssl.failed_if_no_peer_cert = true
## HTTP Listener
## HTTP and WebSocket Listener
mqtt.listener.http = 8083
mqtt.listener.http.acceptors = 4
mqtt.listener.http.max_clients = 64
## HTTP(SSL) Listener
mqtt.listener.https = 8084
mqtt.listener.https.acceptors = 4
mqtt.listener.https.max_clients = 64
mqtt.listener.https.handshake_timeout = 10 #seconds
mqtt.listener.https.certfile = etc/ssl/cert.pem
mqtt.listener.https.keyfile = etc/ssl/key.pem
mqtt.listener.https.cacertfile = etc/ssl/cacert.pem
## mqtt.listener.https = 8084
## mqtt.listener.https.acceptors = 4
## mqtt.listener.https.max_clients = 64
## mqtt.listener.https.handshake_timeout = 10
## mqtt.listener.https.certfile = etc/certs/cert.pem
## mqtt.listener.https.keyfile = etc/certs/key.pem
## mqtt.listener.https.cacertfile = etc/certs/cacert.pem
## mqtt.listener.https.verify = verify_peer
## mqtt.listener.https.failed_if_no_peer_cert = true

View File

@ -261,6 +261,12 @@ end}.
hidden
]}.
%% @doc Default ACL File
{mapping, "mqtt.acl_file", "emqttd.acl_file", [
{datatype, string},
hidden
]}.
%%--------------------------------------------------------------------
%% MQTT Session
%%--------------------------------------------------------------------
@ -527,7 +533,7 @@ end}.
]}.
{mapping, "mqtt.listener.ssl.verify", "emqttd.listeners", [
{datatype, string}
{datatype, atom}
]}.
{mapping, "mqtt.listener.ssl.failed_if_no_peer_cert", "emqttd.listeners", [
@ -583,7 +589,7 @@ end}.
]}.
{mapping, "mqtt.listener.https.verify", "emqttd.listeners", [
{datatype, string}
{datatype, atom}
]}.
{mapping, "mqtt.listener.https.failed_if_no_peer_cert", "emqttd.listeners", [
@ -609,8 +615,8 @@ end}.
{keyfile, cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
{certfile, cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
{cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)},
{verify, cuttlefish:conf_get(Prefix ++ ".verify_peer", Conf, undefined)},
{failed_if_no_peer_cert, cuttlefish:conf_get(Prefix ++ "failed_if_no_peer_cert", Conf, undefined)}])
{verify, cuttlefish:conf_get(Prefix ++ ".verify", Conf, undefined)},
{failed_if_no_peer_cert, cuttlefish:conf_get(Prefix ++ ".failed_if_no_peer_cert", Conf, undefined)}])
end,
Listeners = fun(Name) when is_atom(Name) ->
@ -703,7 +709,7 @@ end}.
{list_to_binary(Topic), list_to_integer(Qos)}
end || S <- string:tokens(Topics, ",")]
end,
SubOpts = fun(Prefix) -> [{topics, ParseFun(cuttlefish:conf_get(Prefix ++ ".topics", Conf))}] end,
SubOpts = fun(Prefix) -> ParseFun(cuttlefish:conf_get(Prefix ++ ".topics", Conf)) end,
lists:append([WithMod(retainer, RetainOpts), WithMod(presence, PresOpts), WithMod(subscription, SubOpts)])
end}.