Commit Graph

187 Commits

Author SHA1 Message Date
David Ansari 99337b84d3 Emit stats
'connection' field is not needed anymore because it was
previously the internal AMQP connection PID
2023-01-24 17:29:07 +00:00
David Ansari 218ee196c4 Make proxy_protocol tests green 2023-01-24 17:29:07 +00:00
David Ansari 77da78f478 Get most auth_SUITE tests green
Some tests which require clean_start=false
or QoS1 are skipped for now.

Differentiate between v3 and v4:
v4 allows for an error code in SUBACK frame.
2023-01-24 17:29:07 +00:00
David Ansari 73ad3bafe7 Revert maybe expression
rabbit_misc:pipeline looks better and doesn't require experimental
feature
2023-01-24 17:29:07 +00:00
David Ansari f4d1f68212 Move authn / authz into rabbitmq_mqtt 2023-01-24 17:29:07 +00:00
David Ansari eac0622f37 Consume with QoS0 via queue_type interface 2023-01-24 17:29:07 +00:00
David Ansari 24b0a6bcb2 Publish with QoS0 via queue_type interface 2023-01-24 17:29:07 +00:00
David Ansari 8710565b2a Use 1 instead of 22 Erlang processes per MQTT connection
* Create MQTT connections without proxying via AMQP
* Do authn / authz in rabbitmq_mqtt instead of rabbit_direct:connect/5
* Remove rabbit_heartbeat process and per connection supervisors

Current status:

Creating 10k MQTT connections with clean session succeeds:
./emqtt_bench conn -V 4 -C true -c 10000 -R 500
2023-01-24 17:29:07 +00:00
Alexey Lebedeff b6cd708a08 Fix all dialyzer warnings in rabbitmq_web_mqtt 2023-01-19 17:23:23 +01:00
Michael Klishin ec4f1dba7d
(c) year bump: 2022 => 2023 2023-01-01 23:17:36 -05:00
Luke Bakken 7fe159edef
Yolo-replace format strings
Replaces `~s` and `~p` with their unicode-friendly counterparts.

```
git ls-files *.erl | xargs sed -i.ORIG -e s/~s>/~ts/g -e s/~p>/~tp/g
```
2022-10-10 10:32:03 +04:00
David Ansari 49ed70900e Fix failing proxy_protocol test
Prior to this commit, test
```
make -C deps/rabbitmq_web_mqtt ct-proxy_protocol t=http_tests:proxy_protocol
```

was failing with reason
```
exception error: no function clause matching
                 rabbit_net:sockname({rabbit_proxy_socket,#Port<0.96>,
```
2022-08-25 20:00:49 +02:00
David Ansari 28db862d56 Avoid crash when client disconnects before server handles MQTT CONNECT
In case of a resource alarm, the server accepts incoming TCP
connections, but does not read from the socket.
When a client connects during a resource alarm, the MQTT CONNECT frame
is therefore not processed.

While the resource alarm is ongoing, the client might time out waiting
on a CONNACK MQTT packet.

When the resource alarm clears on the server, the MQTT CONNECT frame
gets processed.

Prior to this commit, this results in the following crash on the server:
```
** Reason for termination ==
** {{badmatch,{error,einval}},
    [{rabbit_mqtt_processor,process_login,4,
                            [{file,"rabbit_mqtt_processor.erl"},{line,585}]},
     {rabbit_mqtt_processor,process_request,3,
                            [{file,"rabbit_mqtt_processor.erl"},{line,143}]},
     {rabbit_mqtt_processor,process_frame,2,
                            [{file,"rabbit_mqtt_processor.erl"},{line,69}]},
     {rabbit_mqtt_reader,process_received_bytes,2,
                         [{file,"src/rabbit_mqtt_reader.erl"},{line,307}]},
```

After this commit, the server just logs:
```
[error] <0.887.0> MQTT protocol error on connection 127.0.0.1:55725 -> 127.0.0.1:1883: peername_not_known
```

In case the client already disconnected, we want the server to bail out
early, i.e. not authenticating and registering the client at all
since that can be expensive when many clients connected while the
resource alarm was ongoing.

To detect whether the client disconnected, we rely on inet:peername/1
which will return an error when the peer is not connected anymore.

Ideally we could use some better mechanism for detecting whether the
client disconnected.

The MQTT reader does receive a {tcp_closed, Socket} message once the
socket becomes active. However, we don't really want to read frames
ahead (i.e. ahead of the received CONNECT frame), one reason being that:
"Clients are allowed to send further Control Packets immediately
after sending a CONNECT Packet; Clients need not wait for a CONNACK Packet
to arrive from the Server."

Setting socket option `show_econnreset` does not help either because the client
closes the connection normally.

Co-authored-by: Péter Gömöri @gomoripeti
2022-08-25 18:42:37 +02:00
David Ansari 20677395cd Check queue and exchange existence with ets:member/2
This reduces memory usage and improves code readability.
2022-05-10 10:16:40 +00:00
Michael Klishin 0ae3f19698
mqtt.queue_type => mqtt.durable_queue_type 2022-03-31 19:48:00 +04:00
Gabriele Santomaggio 2c49748c70
Add quorum queues support for MQTT
Enable the quorum queue for MQTT only if CleanSession is False.
QQs don't support auto-delete flag so in case Clean session is True
the queue will be a classic queue.

Add another group test non_parallel_tests_quorum.
For Mixed test the quorum_queue feature flag must be enabled.

Add log message
2022-03-30 08:49:17 -07:00
Michael Klishin c38a3d697d
Bump (c) year 2022-03-21 01:21:56 +04:00
Alexey Lebedeff e0723d5e66 Prevent crash logs when mqtt user is missing permissions
Fixes #2941

This adds proper exception handlers in the right places. And tests
ensure that it indeed provides nice neat logs without large
stacktraces for every amqp operation.

Unnecessary checking for subscribe permissions on topic was dropped,
as `queue.bind` does exactly the same check. Topic permissions tests
were also added, and they indeed confirm that there was no change in
behaviour.

Ideally the same explicit topic permission check should be dropped for
publishing, but it's more complicated - so for now there only a
detailed comment in the source code explaining it.

A few other things were also optimized away:
- Using amqp client to test for queue existence
- Creating queues/starting consumptions too eagerly, even if not yet
  requested by client
2021-11-12 18:03:05 +01:00
Michal Kuratczyk 41922b96cf
Change a log line from INFO to DEBUG
This line is printed on every new MQTT connection which leads to very chatty logs when there is a lot of connections. Given that the way MQTT uses vhosts is generally static (once set up, always the same for all connections), I think this can be a debug message instead.
2021-07-12 16:50:25 +02:00
Michael Klishin 97ff62d3b2
Drop trailing newlines from logged messages where possible
Lager strips trailing newline characters but OTP logger with the default
formatter adds a newline at the end. To avoid unintentional multi-line log
messages we have to revisit most messages logged.

Some log entries are intentionally multiline, others
are printed to stdout directly: newlines are required there
for sensible formatting.
2021-03-11 15:17:37 +01:00
Michael Klishin 52479099ec
Bump (c) year 2021-01-22 09:00:14 +03:00
dcorbacho d80e8e1bec Add protocol to auth attempt metrics 2020-09-23 11:16:13 +01:00
dcorbacho b138241b52 Add auth attempt metrics 2020-08-28 13:19:05 +01:00
dcorbacho 119eb99e8d Switch to Mozilla Public License 2.0 (MPL 2.0) 2020-07-13 17:39:36 +01:00
Jean-Sébastien Pédron dcc5f7b553 Update copyright (year 2020) 2020-03-10 16:39:48 +01:00
Michael Klishin e6a8d93bb5 Inject a delay before joining client ID tracking cluster
We have considered multiple options in preventing a split cluster
scenario when N nodes a started in parallel and are initially unaware of
each other. They all are fairly involved and run various risks, e.g.
of losing consistency for cluster members that need to rejoin a newly
discovered set of members.

A simple delay to see if there may be any peers seems to be a straightfoward
solution that would make a practical difference.

In the future consistent client ID tracking should be a feature the user
can opt out of because it tilts MQTT plugin potentially to far towards
C on the consistency/availability range.

Pair: @kjnilsson
2020-02-24 17:58:03 +03:00
Michael Klishin 377752d003 Ignore client ID tracker timeouts on connection closure
There isn't much to do about those at this stage in the connection
lifecycle anyway.
2020-02-21 21:42:39 +03:00
kjnilsson eadf5f7094 Make interactions with Ra async
To avoid blocking when registering or unregistering a client id. This is
ok as informing the current connection holder of the client id is
already async. This should be more scalable and provide much better MQTT
connection setup latency.
2020-02-10 17:28:18 +00:00
Michael Klishin 2927f473ce (c) bump 2019-12-29 05:50:32 +03:00
Grigory Starinkin a337839983 limit topic permission cache size 2019-11-07 14:40:10 +00:00
Grigory Starinkin 8c29181b7b cache topic permission access
performance optimisation
2019-11-07 14:39:43 +00:00
Michael Klishin 35a99a24a2 Downgrade QoS 2 to QoS 1 when sending Last Will
Closes #214.
2019-11-05 16:54:20 +00:00
Luke Bakken d0c0ec33ff Use new translation funs in library 2019-09-04 08:07:33 -07:00
Michael Klishin 5c7fe2cc7b Use more diverse return values from process_request for CONNECT
A drive-by change discovered with @kjnilsson while pairing
on #200.
2019-07-29 16:59:19 +03:00
Michael Klishin 1434eb991b Switch rabbit_mqtt_collector:list/0 to use a leader query
While at it, improve error handling around client ID
collector unavailability.
2019-06-04 13:40:26 +03:00
Spring Operator 852c61ea99 URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# HTTP URLs that Could Not Be Fixed
These URLs were unable to be fixed. Please review them to see if they can be manually resolved.

* http://blog.listincomprehension.com/search/label/procket (200) with 1 occurrences could not be migrated:
   ([https](https://blog.listincomprehension.com/search/label/procket) result ClosedChannelException).
* http://dozzie.jarowit.net/trac/wiki/TOML (200) with 1 occurrences could not be migrated:
   ([https](https://dozzie.jarowit.net/trac/wiki/TOML) result SSLHandshakeException).
* http://dozzie.jarowit.net/trac/wiki/subproc (200) with 1 occurrences could not be migrated:
   ([https](https://dozzie.jarowit.net/trac/wiki/subproc) result SSLHandshakeException).
* http://e2project.org (200) with 1 occurrences could not be migrated:
   ([https](https://e2project.org) result AnnotatedConnectException).
* http://nitrogenproject.com/ (200) with 2 occurrences could not be migrated:
   ([https](https://nitrogenproject.com/) result ConnectTimeoutException).
* http://proper.softlab.ntua.gr (200) with 1 occurrences could not be migrated:
   ([https](https://proper.softlab.ntua.gr) result SSLHandshakeException).
* http://yaws.hyber.org (200) with 1 occurrences could not be migrated:
   ([https](https://yaws.hyber.org) result AnnotatedConnectException).
* http://choven.ca (503) with 1 occurrences could not be migrated:
   ([https](https://choven.ca) result ConnectTimeoutException).

# Fixed URLs

## Fixed But Review Recommended
These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended.

* http://fixprotocol.org/ (301) with 1 occurrences migrated to:
  https://fixtrading.org ([https](https://fixprotocol.org/) result SSLHandshakeException).
* http://erldb.org (UnknownHostException) with 1 occurrences migrated to:
  https://erldb.org ([https](https://erldb.org) result UnknownHostException).

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* http://cloudi.org/ with 27 occurrences migrated to:
  https://cloudi.org/ ([https](https://cloudi.org/) result 200).
* http://erlware.org/ with 1 occurrences migrated to:
  https://erlware.org/ ([https](https://erlware.org/) result 200).
* http://inaka.github.io/cowboy-trails/ with 1 occurrences migrated to:
  https://inaka.github.io/cowboy-trails/ ([https](https://inaka.github.io/cowboy-trails/) result 200).
* http://ninenines.eu with 6 occurrences migrated to:
  https://ninenines.eu ([https](https://ninenines.eu) result 200).
* http://www.actordb.com/ with 2 occurrences migrated to:
  https://www.actordb.com/ ([https](https://www.actordb.com/) result 200).
* http://www.cs.kent.ac.uk/projects/wrangler/Home.html with 1 occurrences migrated to:
  https://www.cs.kent.ac.uk/projects/wrangler/Home.html ([https](https://www.cs.kent.ac.uk/projects/wrangler/Home.html) result 200).
* http://www.rabbitmq.com/mpl.html with 1 occurrences migrated to:
  https://www.rabbitmq.com/mpl.html ([https](https://www.rabbitmq.com/mpl.html) result 200).
* http://www.rabbitmq.com/mqtt.html with 1 occurrences migrated to:
  https://www.rabbitmq.com/mqtt.html ([https](https://www.rabbitmq.com/mqtt.html) result 200).
* http://www.rebar3.org with 1 occurrences migrated to:
  https://www.rebar3.org ([https](https://www.rebar3.org) result 200).
* http://contributor-covenant.org with 1 occurrences migrated to:
  https://contributor-covenant.org ([https](https://contributor-covenant.org) result 301).
* http://contributor-covenant.org/version/1/3/0/ with 1 occurrences migrated to:
  https://contributor-covenant.org/version/1/3/0/ ([https](https://contributor-covenant.org/version/1/3/0/) result 301).
* http://inaka.github.com/apns4erl with 1 occurrences migrated to:
  https://inaka.github.com/apns4erl ([https](https://inaka.github.com/apns4erl) result 301).
* http://inaka.github.com/edis/ with 1 occurrences migrated to:
  https://inaka.github.com/edis/ ([https](https://inaka.github.com/edis/) result 301).
* http://lasp-lang.org/ with 1 occurrences migrated to:
  https://lasp-lang.org/ ([https](https://lasp-lang.org/) result 301).
* http://saleyn.github.com/erlexec with 1 occurrences migrated to:
  https://saleyn.github.com/erlexec ([https](https://saleyn.github.com/erlexec) result 301).
* http://www.mozilla.org/MPL/ with 27 occurrences migrated to:
  https://www.mozilla.org/MPL/ ([https](https://www.mozilla.org/MPL/) result 301).
* http://www.rabbitmq.com/man/rabbitmq-plugins.1.man.html with 1 occurrences migrated to:
  https://www.rabbitmq.com/man/rabbitmq-plugins.1.man.html ([https](https://www.rabbitmq.com/man/rabbitmq-plugins.1.man.html) result 301).
* http://zhongwencool.github.io/observer_cli with 1 occurrences migrated to:
  https://zhongwencool.github.io/observer_cli ([https](https://zhongwencool.github.io/observer_cli) result 301).
2019-03-20 03:18:59 -05:00
Michael Klishin 0d747b18df Wording 2019-02-08 01:58:27 +03:00
Luke Bakken 2f205cc21a Handle duplicate CONNECT frame
Fixes #179

Uses undefined MQTT return code 255 to mean "duplicate auth attempt"

Treat duplicate CONNECT / login like a real connect
2019-02-07 12:49:24 -08:00
Michael Klishin 530cf87095 Handle socket write failures and log them
...instead of letting connection proceesses terminate and
the runtime to log scary looking crash reports.

STOMP has been doing this without logging for a while:

 * https://github.com/rabbitmq/rabbitmq-stomp/blame/v3.7.x/src/rabbit_stomp_reader.erl#L344
 * https://github.com/rabbitmq/rabbitmq-stomp/blob/v3.7.x/src/rabbit_stomp_processor.erl#L1167

Note that otherwise connection error handling is not affected
by this change.

While at it, added more debug logging.

Per discussion with @lukebakken.

References rabbitmq/rabbitmq-server#1862.
2019-02-05 02:49:36 +03:00
Ryan Sandbach 563e6529c0 Use translation for retained messages. 2019-02-01 00:20:27 -05:00
Arnaud Cogoluègnes ec65574e1f Add client ID to connection metadata
[#153246723]

Fixes #152
2019-01-22 10:30:25 +01:00
Loïc Hoguin 7e09b85426 Allow giving the peer address directly for initial_state
Changes initial_state/4 to initial_state/5 to add the peer
address that needs to be provided by Web MQTT. This function
was only used locally and by Web MQTT.
2018-12-04 14:50:32 +01:00
Diana Corbacho 4d4f490bc3 Session flag must be calculated before declaring the queue
[#159921198]
2018-08-21 12:05:29 +01:00
Michael Klishin 1c3c2af838 Support maps as well as proplists when fetching global runtime params
Part of rabbitmq/rabbitmq-management#528.
2018-01-03 03:29:24 +08:00
Michael Klishin 2ebff17ddc Merge branch 'stable'
Conflicts:
	src/rabbit_mqtt_processor.erl
2017-11-09 14:23:46 +03:00
Luke Bakken 717730b275 Ensure maximum message id value is used when saving to process state
Fixes #132
2017-11-08 17:31:09 -08:00
Jean-Sébastien Pédron 94640f9707 rabbit_mqtt_process: Close channels after send_will()
This gives a greater chance to the Last Will message to be delivered
because it will implicitely block `rabbit_mqtt_reader` while the
server-side AMQP channel processes the message.

Without this, `rabbit_mqtt_reader` asks the Last Will message to be
sent asynchronously and immediately closes the AMQP connection. The
server-side AMQP channel might thus try to query an already closed
connection.

Fixes #146.
[#150162950]

(cherry picked from commit a2eb8c1be8c52d476ee9ea0ff08ef381a2ca326c)
2017-08-11 14:40:44 +02:00
Jean-Sébastien Pédron ccde25c2a9 rabbit_mqtt_process: Close channels after send_will()
This gives a greater chance to the Last Will message to be delivered
because it will implicitely block `rabbit_mqtt_reader` while the
server-side AMQP channel processes the message.

Without this, `rabbit_mqtt_reader` asks the Last Will message to be
sent asynchronously and immediately closes the AMQP connection. The
server-side AMQP channel might thus try to query an already closed
connection.

Fixes #146.
[#150162950]
2017-08-11 12:29:34 +02:00
Daniil Fedotov e683048145 Use lager sink API for logs.
Lager sink parse-transform allows us to use a fake module name
to select sinks.
It's more convenient that to use a helper function for every module.

[#149634975]
2017-08-07 14:43:00 +01:00
Jean-Sébastien Pédron ab46563c45 Merge branch 'stable' 2017-07-31 10:17:08 +02:00