To fix issue#2303(https://github.com/emqx/emqx/issues/2303)
It will report the following error, when a connection sends a TCP frame contained many of MQTT packet and followed a split MQTT packet.
* Improve emqx_hooks and credentials
1. Modify the return modes of emqx hooks.
Change the return value of hook functions to:
- ok: stop the hook chain and return ok
- {error, Reason}: stop the hook chain and return error
- continue: continue the hook chain
And the return value of emqx_hooks:run/2 is changed to:
- ok
- {error, Reason}
And the return value of emqx_hooks:run/3:
- {ok, Acc}
- {error, Reason, Acc}
2. Treat password as a member of credentials.
Password should be wrapped in the `credentials` data-structure, as the
username/password pair together consists of an authentication method.
There can be some methods using some other credential data (e.g.
a JWT token), and these credential data should also be wrapped in the
the `credentials` data-structure.
An event `client.authenticate` is triggered when an user logs in:
```erlang
emqx_hooks:run('client.authenticate', [], Credentials)
```
A `default callback` that deny/allow any user (according to the
`allow_anonymous` config) should be appended to the end of the
callback chain.
The `credentails` is passed through all of the callbacks, and
can be changed over in this process.
* Refactor emqx hooks return mode
* Remove password from PState
* Delete response_topic_prefix
The Response-Infomation in CONNACK was misinterpreated, it should
not be a broker's global config, instead, it should be per-client
or even per-session prefix/suffix mechanism
* Delete request-response code from emqx_client
* Add request-response test code
* meck as default dependency --- temp workaround for dep-vsn-check
Prior to this change, if a emqx_client:publish/? caller sends in
QoS=1/2 messages too fast, emqx_client may return
`{error, inflight_full}` which could put put the caller to an
awkward situation: there seem to be no ohter option except for
putting self to a sleep-n-retry infinite loop.
In this change, a new gen_statm state 'inflight_full' is introduced
as a sub-state of 'connected'. When emqx_client is in 'inflight_full'
state, it postpone all publish calls (for QoS=1/2) until inflight
window size shrinks.
bridge.$name.transport was added before we decided to derive
transport portocol based on the 'address' config.
i.e. when it's a remote erlang node, use gen_rpc
otherwise (must be IP or hostnmae), we should estabilish mqtt connection
In this commit, msg_handler option is added to emqx_client.
so the caller can provide callbacks to handle puback, publish,
as well as disconnected events instead of always delivered
as message like Owner ! {publish, Msg} to the owner process.
This is to make it ready to implement emqx_portal_connect on
top of emqx_client.
* Replace case catch.. with try ... catch
Prior to this change, case catch ... would cost a lot of performance
because it would retrieve the whole stacktrace. However, try...catch
will not retrieve the whole stacktrace. So try...catch syntax is better.
* Fix the Exit in testcases
* Fix Exit in emqx_mod_sup_SUITE
* Update testcases for log_tracer
* Fix Exit in emqx_protocol_SUITE
* Add will_acl_check
* Fix more Exits
1. Add do_add_route/1 do_add_route/2, do_delete_route/1,
do_delete_route/2 APIs in emqx_router module
2. Improve the code of emqx_trie module
3. Update the emqx_broker module to call the new APIs of emqx_router
1. Add do_add_route/1 do_add_route/2, do_delete_route/1,
do_delete_route/2 APIs in emqx_router module
2. Improve the code of emqx_trie module
3. Update the emqx_broker module to call the new APIs of emqx_router
* Add acking mechamism for shared dispatch
For QoS0 messages, no acking
For QoS1/2 messages, 'ACK' at any of events below:
- ACK when QoS is downgraded to 0
- Message is sent to connection process
'NACK' at any of events below:
- Message queue is full and the receiving session starts to drop old messages
- The receiving session crash
Upon 'NACK', messages are dispatched to the 'next' subscriber in the group,
depending on the shared subscription dispatch strategy.
* Fix issue#1874
Prior to this change, if user use one client connect emqx with mqtt
v3.1.1, the client subscribe the topic and publish message to this
topic, it would receive this message itself published, this commit
provide a configure option to let user ignore the message itself published.
This change fix issue 1874.
* Small Fix
* Fix bug
* Better design
* Fix compile warning and improve coverage
* Better design to solve the performance issue
* Fix typo
* Fix typo
* Delete spaces in end of lines.
* Do not use anonymous function
* Better performance
Formatting variables and then passing them into the logger functions leads
to performance issues. i.e.
```erlang
logger:debug("RECV ~s", [emqx_packet:format(Packet)])
```
Above message will only be printed when the current log level set to
`debug`, but the function emqx_packet:format/1 will always be evaluated no
matter what the current log level is.
OTP 21 provides a special meta-data named `report_cb`, which can be used
for lazy evaluation. The fun is only evaluated if the primary/handler log level
check passes, and is therefore recommended if it is expensive to generate
the message.
Prior to this change, emqx_client:start_link does 2 works in one call:
- init an erlang process for emqx_client
- send MQTT CONNECT to remote broker
But this solution have some drawbacks:
- the return value of `start_link` compiles the return values of the 2
works: {ok, Pid, MqttResult}. It is inconsistent with the return value
of `gen_statem:start_link`, may causes confusions.
- the return mode of the 2 works are different:
`start_link` should always return {ok, Pid} or {error, Reason}, but
connecting to mqtt may throw out exceptions as it handles the
socket. But the caller couldn't have thought of the exception, he would
pattern match on the result of `emqx_client:start_link`, but it crashed!
- If the init work succeed but the connection failed, the caller couldn't
get a Pid from the return value, but indeed it was created inside the
emqx_client. This hides the fact that the Pid was created, and when the
Pid dies, the caller would receive an message from a Pid it doesn' know about.
This change divived these 2 work into 2 APIs:
- `start_link/1` is to build and verify the options, and returns {ok,Pid}
(on success) or {error, Reason} (on failure).
- `connect/1` is to send MQTT CONNECT, and returns {ok, MQTTResult::properties()} or
{error, MQTTReason}. MQTT reason codes will contains in the `MQTTReason`.
Prior to this change, there are ok, {binary, _Data}. {datagram, _Peer,
_Dara} case clauses, and the {binary, _Data} and {datagram, _Peer,
_Data} are unnecessary cases
This change delete these two cases and add ok in the end of funtion in
send_fun of emqx_ws_connection.
Fixed bugs:
- Priority queue lack of a `len + 1` logic in `in/2`
Changed behaviors:
- Topics not found in priority table (from config) will be treated with default priority,
instead of hasing topic name to a priority number.
- Default priority is now configurable (it was always lower than all configured priorities)
- The dropped message due to reaching `max_len` is now returned from `in/2`,
so the queue owner (`in/2` caller) can perform autopsy on it