Преглед изворни кода

Merge pull request #743 from emqtt/emq20

2.0-rc.3: bugfix
turtleDeng пре 9 година
родитељ
комит
6ddfb7f2cb

+ 15 - 13
etc/certs/cacert.pem

@@ -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-----

+ 16 - 13
etc/certs/cert.pem

@@ -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-----

+ 16 - 12
etc/certs/client-cert.pem

@@ -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-----

+ 25 - 7
etc/certs/client-key.pem

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

+ 25 - 13
etc/certs/key.pem

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

+ 2 - 33
etc/emq.conf

@@ -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
 

+ 11 - 0
include/emqttd.hrl

@@ -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
 %%--------------------------------------------------------------------

+ 4 - 81
priv/emq.schema

@@ -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
 %%--------------------------------------------------------------------

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
rebar.config


+ 1 - 29
src/emqttd_app.erl

@@ -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.

+ 2 - 1
src/emqttd_http.erl

@@ -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} ->

+ 0 - 75
src/emqttd_mod_presence.erl

@@ -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.
-

+ 0 - 202
src/emqttd_mod_retainer.erl

@@ -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).
-

+ 0 - 52
src/emqttd_mod_subscription.erl

@@ -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).
-

+ 1 - 1
src/emqttd_pubsub.erl

@@ -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;

+ 18 - 16
test/emqttd_SUITE_data/emqttd.conf

@@ -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
 

+ 11 - 5
test/emqttd_SUITE_data/emqttd.schema

@@ -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}.