Skip to content

Commit

Permalink
Update udp.rst
Browse files Browse the repository at this point in the history
  • Loading branch information
nagyrobi authored Jun 7, 2024
1 parent 27b592a commit 9f1d6ca
Showing 1 changed file with 23 additions and 19 deletions.
42 changes: 23 additions & 19 deletions components/udp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ UDP Component
:image: udp.svg
:keywords: UDP

The purpose of this component is to allow ESPHome nodes to directly communicate with each over a network (WiFi or Ethernet)
without relying on Home Assistant. It permits the state of sensors and binary sensors to be broadcast via UDP packets
The purpose of this component is to allow ESPHome nodes to directly communicate with each over an IP network
without relying on Home Assistant. It permits the state of sensors and binary sensors to be broadcasted via UDP packets
to other nodes on the same LAN, or to specific IP addresses (which may be in a remote, but reachable, network.)

Nodes may be *providers* which broadcast sensor data, or *consumers* which receive sensor data from one or more
Expand All @@ -19,7 +19,7 @@ providers. A node may be both a provider and a consumer. Optional security is pr
- a rolling code
- a challenge-response (ping-pong) key

Wherever a provider name is required, this should be the name configured in the ``esphome:`` block.
Wherever a provider name is required, this should be the node name configured in the ``esphome:`` block.

.. code-block:: yaml
Expand Down Expand Up @@ -47,22 +47,20 @@ Wherever a provider name is required, this should be the name configured in the
provider: unencrypted-device
id: other_binary_sensor_id # also used as remote_id
Configuration variables:
------------------------

- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
- **update_interval** (*Optional*, :ref:`config-time`): Interval between full broadcasts. Defaults to 15s.
- **port** (*Optional*, int): The UDP port number to use. Defaults to 18511.
- **port** (*Optional*, int): The destination UDP port number to use. Defaults to 18511.
- **addresses** (*Optional*, list of IPv4 addresses): One or more IP addresses to broadcast data to. Defaults to ``255.255.255.255``
which is the local network broadcast address.
- **sensors** (*Optional*, list): A list of sensor IDs to be broadcast.
- **binary_sensors** (*Optional*, list): A list of binary sensor IDs to be broadcast.
- **sensors** (*Optional*, list): A list of sensor IDs to be broadcasted.
- **binary_sensors** (*Optional*, list): A list of binary sensor IDs to be broadcasted.
- **encryption** (*Optional*, string): The encryption key to use when broadcasting. Default is no encryption. This may be
any string, and will be hashed to form a 256 bit key.
- **rolling_code_enable** (*Optional*, boolean): Enables a rolling code to be included in all broadcasts. Requires ``encryption`` to be set. Defaults to false
- **ping_pong_enable** (*Optional*, boolean): When set, requires encrypted providers to include a nonce generated by this device in broadcasts. Defaults to false.
- **rolling_code_enable** (*Optional*, boolean): Enables a rolling code to be included in all broadcasts. Requires ``encryption`` to be set. Defaults to ``false``.
- **ping_pong_enable** (*Optional*, boolean): When set, requires encrypted providers to include a *nonce* generated by this device in broadcasts. Defaults to ``false``.
- **providers** (*Optional*, list): A list of provider device names and optionally their secret encryption keys.

- **name** (**Required**, string): The device name of the provider.
Expand All @@ -72,7 +70,7 @@ Reliability
-----------

UDP, like any other network protocol, does not provide a guarantee that data will be delivered, but unlike TCP it does not
provide any indication whether data has been successfully delivered or not. When any of the configured sensors changes state,
even provide any indication whether data has been successfully delivered or not. When any of the configured sensors changes state,
the component will broadcast that sensor's state, but since this may not be received by a consumer, the UDP component
also broadcasts *all* sensor data on a timed schedule, set by ``update_interval``. Even this does not guarantee
delivery, but in practice unless the network has failed, updates will eventually be received, albeit possibly after
Expand All @@ -87,25 +85,32 @@ by providing an encryption key, which is shared between the provider and consume

The encryption used is `XXTEA <https://en.wikipedia.org/wiki/XXTEA>`_ which is fast and compact. Although XXTEA is known
to be susceptible to a chosen-plaintext attack, such an attack is not possible with this application, and it otherwise
has no published weaknesses. The implementation used here has been modified slightly to use a 256 bit key.
has no published weaknesses [#f1]_. The implementation used here has been modified slightly to use a 256 bit key.

Encryption ensures that data cannot be read in transit and protects against spoofing of data, but does not protect
Encryption alone ensures that data cannot be read in transit and protects against spoofing of data, but does not protect
against replay attacks (where a threat actor records a transmission and replays it later, e.g. to repeat an action.)

A rolling code can be enabled which mitigates replay attacks - each transmission contains a 64 bit value which is
guaranteed to monotonically increase, so the consumer will reject any data received which contains a rolling code
already seen. The rolling code also ensures that the data in every packet is different, which makes brute-force
attacks on the encryption much more difficult. This is enabled in the provider configuration and adds minor overhead.

For further protection a ``ping-pong`` (or challenge-response) facility is available, which is enabled in the
consumer configuration. The consumer periodically generates a 32 bit random number (aka a ``nonce`` or Number used Once)
For further protection a ``ping-pong`` (or challenge-response) facility is available, which can be enabled in the
consumer configuration. The consumer periodically generates a 32 bit random number (a *nonce* aka "Number used Once")
and broadcasts it. Any provider receiving this nonce will include it in any future encrypted broadcasts. The consumer
expects to see its most recently transmitted nonce in any packets it receives, and will reject any that do not
contain it.

Use of the ping-pong feature will add to network traffic and the size of the transmitted packets (a single packet may
include up to 4 nonces from different devices) but provides a high level of protection against replay attacks. It does
require a 2-way network connection.
require a 2-way network connection, and it only works on local networks because the consumer can only *broadcast* it to
all the providers.

.. note::

The rolling code's top 32 bits is incremented and written to flash *once* at reboot on the provider node.
It's also incremented and written to flash when the counting, lower 32 bits overflows, which can only happen after
a very long time. The consumer side does not store the received rolling codes in flash.

Configuration examples
----------------------
Expand All @@ -116,7 +121,6 @@ the other to follow suit. In each case a template binary_sensor is used to mirro
.. code-block:: yaml
# Device 1
esphome:
name: device-1
Expand Down Expand Up @@ -145,7 +149,6 @@ the other to follow suit. In each case a template binary_sensor is used to mirro
# Device 2
esphome:
name: device-2
Expand All @@ -172,7 +175,6 @@ the other to follow suit. In each case a template binary_sensor is used to mirro
on_release:
switch.turn_off: relay2
The following example shows a device using encryption to read a sensor and two binary sensors from two different
devices, one with encryption and ping-pong and one without. It also rebroadcasts one of those binary sensors with its own
encryption and a rolling code to a remote host.
Expand Down Expand Up @@ -205,6 +207,8 @@ encryption and a rolling code to a remote host.
provider: st7735s
id: wifi_signal_sensor
.. [#f1] As until 2024.06.
See Also
--------

Expand Down

0 comments on commit 9f1d6ca

Please sign in to comment.