Skip to content

Commit 72c6e22

Browse files
authored
Merge pull request #485 from tiiuae/fix_avahi
Fix "IPv6 connection unreliable from external PC"
2 parents e9ad4c4 + 9e81465 commit 72c6e22

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

modules/sc-mesh-secure-deployment/src/nats/conf/default_ms_config.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Mesh Shield config file #
33
###########################
44

5+
# hostname of the device
6+
hostname: nixos
7+
58
# All the interfaces are black by default.
69
# Excluded interfaces or interfaces without macsec certificates are not added to lower CBMA.
710
# White interfaces are added to upper CBMA and are excluded automatically from lower CBMA.

modules/sc-mesh-secure-deployment/src/nats/src/cbma_adaptation.py

+35
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from src.interface import Interface
2323
from src import comms_config_store
2424
from src.bat_ctrl_utils import BatCtrlUtils
25+
from src.comms_service_refresh import CommsServiceRefresh
2526

2627
from controller import CBMAController
2728
from models.certificates import CBMACertificates
@@ -85,6 +86,7 @@ def __init__(
8586
if self.__config is not None:
8687
self.__cbma_config = self.__config.read("CBMA")
8788
self.__vlan_config = self.__config.read("VLAN")
89+
self.__hostname = self.__config.read("hostname")
8890

8991
# Create VLAN interfaces if configured
9092
self.__create_vlan_interfaces()
@@ -106,6 +108,9 @@ def __init__(
106108
self.__red_interfaces.extend(red_interfaces)
107109
self.__na_cbma_interfaces.extend(exclude_interfaces)
108110

111+
self.__service_refresh = CommsServiceRefresh(self.__hostname, logger)
112+
self.__service_thread = None
113+
109114
def __validate_cbma_config(
110115
self,
111116
exclude_interfaces: List[str],
@@ -280,6 +285,24 @@ def __delete_vlan_interfaces(self) -> bool:
280285
success = False
281286
return success
282287

288+
def __set_hostname(self) -> None:
289+
"""
290+
Set hostname for device configured in ms_config.yaml.
291+
"""
292+
try:
293+
subprocess.run(["hostname", self.__hostname], check=True)
294+
except subprocess.CalledProcessError as e:
295+
self.logger.error(f"Error setting hostname {self.__hostname}: {e}")
296+
297+
def __update_avahi_hostname(self) -> None:
298+
"""
299+
Update avahi hostname for device configured in ms_config.yaml.
300+
"""
301+
try:
302+
subprocess.run(["avahi-set-host-name", self.__hostname], check=True)
303+
except subprocess.CalledProcessError as e:
304+
self.logger.error(f"Error updating avahi hostname {self.__hostname}: {e}")
305+
283306
def __get_interfaces(self) -> None:
284307
interfaces = []
285308
ip = IPRoute()
@@ -809,6 +832,10 @@ def setup_cbma(self) -> bool:
809832
:return: True if both lower and upper CBMA was setup
810833
successfully. Returns False otherwise.
811834
"""
835+
# hostname updates
836+
self.__set_hostname()
837+
self.__update_avahi_hostname()
838+
812839
self.__init_batman_and_bridge()
813840

814841
self.__update_cbma_interface_lists()
@@ -841,6 +868,10 @@ def setup_cbma(self) -> bool:
841868
# Set batman hop penalty
842869
self.__batman.set_hop_penalty()
843870

871+
# Start the service publisher thread
872+
self.__service_thread = threading.Thread(target=self.__service_refresh.dns_service_refresh)
873+
self.__service_thread.start()
874+
844875
return True
845876

846877
def __is_valid_ipv6_local(self, address: tuple[str, int]) -> bool:
@@ -1090,4 +1121,8 @@ def stop_cbma(self) -> bool:
10901121
self.__cleanup_cbma()
10911122
self.stop_radios()
10921123

1124+
self.__service_refresh.shutdown_service()
1125+
if self.__service_thread is not None:
1126+
self.__service_thread.join()
1127+
10931128
return lower_stopped and upper_stopped
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""
2+
Refresher class for the comms service registration
3+
"""
4+
import logging
5+
import threading
6+
import time
7+
import subprocess
8+
9+
class CommsServiceRefresh:
10+
"""
11+
Comms service publisher class
12+
"""
13+
DNS_SERVICE_EVENT_LOOP_TIMEOUT: int = 5
14+
15+
def __init__(self, __hostname, __logger: logging.Logger) -> None:
16+
17+
self.logger: logging.Logger = __logger.getChild("CommsServicePublisher")
18+
self.logger.setLevel(logging.INFO)
19+
self.__event: threading.Event = threading.Event()
20+
self.__hostname: str = __hostname
21+
22+
23+
def __refresh_hostname(self) -> None:
24+
"""
25+
Refresh the hostname with avahi-resolve-host-name
26+
"""
27+
try:
28+
subprocess.run(["avahi-resolve-host-name", self.__hostname + ".local"],
29+
check=True,
30+
stdout=subprocess.PIPE,
31+
stderr=subprocess.PIPE)
32+
except subprocess.CalledProcessError:
33+
self.logger.exception("Error refreshing hostname")
34+
35+
def dns_service_refresh(self) -> None:
36+
"""
37+
Register and re-announce service periodically
38+
"""
39+
self.logger.info("Refresh start")
40+
while not self.__event.is_set():
41+
time.sleep(self.DNS_SERVICE_EVENT_LOOP_TIMEOUT)
42+
self.__refresh_hostname()
43+
self.logger.info("Refresh stopped")
44+
45+
46+
def shutdown_service(self) -> None:
47+
"""
48+
Shutdown the service
49+
"""
50+
self.__event.set()

0 commit comments

Comments
 (0)