1
mirror of https://github.com/home-assistant/core synced 2024-09-06 10:29:55 +02:00

Prevent ping id allocation conflict with device_tracker (#48969)

* Prevent ping id allocation conflict with device_tracker

- Solves id conflict resulting unexpected home state

* Update homeassistant/components/ping/device_tracker.py

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
J. Nick Koston 2021-04-09 13:56:15 -10:00 committed by GitHub
parent 28ad5b5514
commit 9b0b2d9168
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 11 deletions

View File

@ -24,20 +24,22 @@ async def async_setup(hass, config):
@callback
def async_get_next_ping_id(hass):
def async_get_next_ping_id(hass, count=1):
"""Find the next id to use in the outbound ping.
When using multiping, we increment the id
by the number of ids that multiping
will use.
Must be called in async
"""
current_id = hass.data[DOMAIN][PING_ID]
if current_id == MAX_PING_ID:
next_id = DEFAULT_START_ID
else:
next_id = current_id + 1
hass.data[DOMAIN][PING_ID] = next_id
return next_id
allocated_id = hass.data[DOMAIN][PING_ID] + 1
if allocated_id > MAX_PING_ID:
allocated_id -= MAX_PING_ID - DEFAULT_START_ID
hass.data[DOMAIN][PING_ID] += count
if hass.data[DOMAIN][PING_ID] > MAX_PING_ID:
hass.data[DOMAIN][PING_ID] -= MAX_PING_ID - DEFAULT_START_ID
return allocated_id
def _can_use_icmp_lib_with_privilege() -> None | bool:

View File

@ -125,7 +125,7 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
count=PING_ATTEMPTS_COUNT,
timeout=ICMP_TIMEOUT,
privileged=privileged,
id=async_get_next_ping_id(hass),
id=async_get_next_ping_id(hass, len(ip_to_dev_id)),
)
)
_LOGGER.debug("Multiping responses: %s", responses)

View File

@ -0,0 +1,27 @@
"""Test ping id allocation."""
from homeassistant.components.ping import async_get_next_ping_id
from homeassistant.components.ping.const import (
DEFAULT_START_ID,
DOMAIN,
MAX_PING_ID,
PING_ID,
)
async def test_async_get_next_ping_id(hass):
"""Verify we allocate ping ids as expected."""
hass.data[DOMAIN] = {PING_ID: DEFAULT_START_ID}
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 1
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 2
assert async_get_next_ping_id(hass, 2) == DEFAULT_START_ID + 3
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 5
hass.data[DOMAIN][PING_ID] = MAX_PING_ID
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 1
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 2
hass.data[DOMAIN][PING_ID] = MAX_PING_ID
assert async_get_next_ping_id(hass, 2) == DEFAULT_START_ID + 1
assert async_get_next_ping_id(hass) == DEFAULT_START_ID + 3