Skip to content

Commit

Permalink
Fix "IPv6 connection unreliable from external PC"
Browse files Browse the repository at this point in the history
Avahi workaround

Jira-Id: SECO-7551

Signed-off-by: Mika Joenpera <[email protected]>
  • Loading branch information
joenpera committed Oct 23, 2024
1 parent 61d2773 commit 1507023
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# Mesh Shield config file #
###########################

# hostname of the device
hostname: nixos

# All the interfaces are black by default.
# Excluded interfaces or interfaces without macsec certificates are not added to lower CBMA.
# White interfaces are added to upper CBMA and are excluded automatically from lower CBMA.
Expand Down
35 changes: 35 additions & 0 deletions modules/sc-mesh-secure-deployment/src/nats/src/cbma_adaptation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from src.interface import Interface
from src import comms_config_store
from src.bat_ctrl_utils import BatCtrlUtils
from src.comms_service_refresh import CommsServiceRefresh

from controller import CBMAController
from models.certificates import CBMACertificates
Expand Down Expand Up @@ -85,6 +86,7 @@ def __init__(
if self.__config is not None:
self.__cbma_config = self.__config.read("CBMA")
self.__vlan_config = self.__config.read("VLAN")
self.__hostname = self.__config.read("hostname")

# Create VLAN interfaces if configured
self.__create_vlan_interfaces()
Expand All @@ -106,6 +108,9 @@ def __init__(
self.__red_interfaces.extend(red_interfaces)
self.__na_cbma_interfaces.extend(exclude_interfaces)

self.__service_refresh = CommsServiceRefresh(self.__hostname, logger)
self.__service_thread = None

def __validate_cbma_config(
self,
exclude_interfaces: List[str],
Expand Down Expand Up @@ -277,6 +282,24 @@ def __delete_vlan_interfaces(self) -> bool:
success = False
return success

def __set_hostname(self) -> None:
"""
Set hostname for device configured in ms_config.yaml.
"""
try:
subprocess.run(["hostname", self.__hostname], check=True)
except subprocess.CalledProcessError as e:
self.logger.error(f"Error setting hostname {self.__hostname}: {e}")

def __update_avahi_hostname(self) -> None:
"""
Update avahi hostname for device configured in ms_config.yaml.
"""
try:
subprocess.run(["avahi-set-host-name", self.__hostname], check=True)
except subprocess.CalledProcessError as e:
self.logger.error(f"Error updating avahi hostname {self.__hostname}: {e}")

def __get_interfaces(self) -> None:
interfaces = []
ip = IPRoute()
Expand Down Expand Up @@ -731,6 +754,10 @@ def setup_cbma(self) -> bool:
:return: True if both lower and upper CBMA was setup
successfully. Returns False otherwise.
"""
# hostname updates
self.__set_hostname()
self.__update_avahi_hostname()

self.__init_batman_and_bridge()

self.__update_cbma_interface_lists()
Expand Down Expand Up @@ -762,6 +789,10 @@ def setup_cbma(self) -> bool:
# Set batman hop penalty
self.__batman.set_hop_penalty()

# Start the service publisher thread
self.__service_thread = threading.Thread(target=self.__service_refresh.dns_service_refresh)
self.__service_thread.start()

return True

def __is_valid_ipv6_local(self, address: tuple[str, int]) -> bool:
Expand Down Expand Up @@ -1007,4 +1038,8 @@ def stop_cbma(self) -> bool:
self.__cleanup_cbma()
self.stop_radios()

self.__service_refresh.shutdown_service()
if self.__service_thread is not None:
self.__service_thread.join()

return lower_stopped and upper_stopped
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Refresher class for the comms service registration
"""
import logging
import threading
import time
import subprocess

class CommsServiceRefresh:
"""
Comms service publisher class
"""
DNS_SERVICE_EVENT_LOOP_TIMEOUT: int = 5

def __init__(self, __hostname, __logger: logging.Logger) -> None:

self.logger: logging.Logger = __logger.getChild("CommsServicePublisher")
self.logger.setLevel(logging.INFO)
self.__event: threading.Event = threading.Event()
self.__hostname: str = __hostname


def __refresh_hostname(self) -> None:
"""
Refresh the hostname with avahi-resolve-host-name
"""
try:
subprocess.run(["avahi-resolve-host-name", self.__hostname + ".local"], check=True)
except subprocess.CalledProcessError:
self.logger.exception("Error refreshing hostname")

def dns_service_refresh(self) -> None:
"""
Register and re-announce service periodically
"""
self.logger.info("Refresh start")
while not self.__event.is_set():
time.sleep(self.DNS_SERVICE_EVENT_LOOP_TIMEOUT)
self.__refresh_hostname()
self.logger.info("Refresh stopped")


def shutdown_service(self) -> None:
"""
Shutdown the service
"""
self.__event.set()

if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("CommsServiceRefresh")
comms_service_refresh = CommsServiceRefresh("mika-battlestation", logger)
comms_service_refresh.dns_service_refresh()
time.sleep(100)
# Wait for the service to be registered
comms_service_refresh.shutdown_service()

0 comments on commit 1507023

Please sign in to comment.