From 4b065245671f62d52292801ebf918a706e9e7f61 Mon Sep 17 00:00:00 2001 From: Jeff Mattson Date: Mon, 21 Oct 2024 20:41:08 -0400 Subject: [PATCH] add option for multicast_ttl value --- docs/configuration.md | 4 ++++ pytak/client_functions.py | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9a92049..ec093a8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -69,6 +69,10 @@ PyTAK has the following built-in configuration parameters: For systems with multiple IP network interfaces, specifies which IP interface to use for the multicast group. +* **`PYTAK_MULTICAST_TTL`** + * Default: `1` + + For clients that are more than one hop away from the TAK broadcast network, specifies the time-to-live (TTL) of multicast packets. This is helpful when the client is hosted in a virtual machine or container with an overlay network. ## CoT Event Attributes diff --git a/pytak/client_functions.py b/pytak/client_functions.py index c569a20..178bfee 100644 --- a/pytak/client_functions.py +++ b/pytak/client_functions.py @@ -108,7 +108,8 @@ async def protocol_factory( # NOQA pylint: disable=too-many-locals,too-many-bra ), 0, ) - reader, writer = await pytak.create_udp_client(cot_url, local_addr) + multicast_ttl = config.get("PYTAK_MULTICAST_TTL", 1) + reader, writer = await pytak.create_udp_client(cot_url, local_addr, multicast_ttl) # LOG elif "log" in scheme: @@ -130,7 +131,7 @@ async def protocol_factory( # NOQA pylint: disable=too-many-locals,too-many-bra async def create_udp_client( - url: ParseResult, local_addr=None + url: ParseResult, local_addr=None, multicast_ttl=1 ) -> Tuple[Union[DatagramClient, None], DatagramClient]: """Create an AsyncIO UDP network client for Unicast, Broadcast & Multicast. @@ -170,6 +171,11 @@ async def create_udp_client( if is_broadcast: writer.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + if is_multicast: + writer.socket.setsockopt( + socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, struct.pack("b", multicast_ttl) + ) + if is_write_only: return reader, writer @@ -207,11 +213,7 @@ async def create_udp_client( ) group = int(ipaddress.IPv4Address(host)) mreq = struct.pack("!LL", group, ip) - reader.socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - reader.socket.setsockopt( - socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, struct.pack("b", 1) - ) return reader, writer