Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "IPv6 connection unreliable from external PC" #485

Merged
merged 2 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,59 @@
"""
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,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
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)
joenpera marked this conversation as resolved.
Show resolved Hide resolved
comms_service_refresh.dns_service_refresh()
time.sleep(100)
# Wait for the service to be registered
comms_service_refresh.shutdown_service()
Loading