diff --git a/src/opengnsys/modules/server/OpenGnSys/__init__.py b/src/opengnsys/modules/server/OpenGnSys/__init__.py index 765bb5a..1203eb2 100644 --- a/src/opengnsys/modules/server/OpenGnSys/__init__.py +++ b/src/opengnsys/modules/server/OpenGnSys/__init__.py @@ -34,6 +34,7 @@ import base64 import os import random import shutil +import socket import string import sys import threading @@ -142,6 +143,36 @@ class OpenGnSysWorker(ServerWorker): logger.info('Connection to ogcore restored, re-registering') self._send_started() + def _best_interface(self, nets): + """ + Return the interface whose IP the OS routing table would use to reach + ogcore, by opening a no-op UDP socket (no packets sent) and reading + the local address assigned by the kernel. + + Returns None if the routing query itself fails (network not ready yet), + so the caller keeps retrying. Falls back to nets[0] only when the query + succeeds but no interface matches the routing IP (e.g. NAT or VPN). + """ + try: + host = urllib.parse.urlparse(self.REST.endpoint).hostname + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: + s.connect((host, 80)) + local_ip = s.getsockname()[0] + except Exception as e: + logger.debug('Routing query to ogcore failed (network not ready?): {}'.format(e)) + return None + + for iface in nets: + if iface.ip == local_ip: + logger.debug('Selected interface {} ({}) for ogcore at {}'.format( + iface.name, local_ip, host)) + return iface + + # Routing succeeded but no interface matched (NAT/VPN): best effort + logger.debug('No interface matched routing IP {}, falling back to {}'.format( + local_ip, nets[0].ip)) + return nets[0] + def _setup_network(self, ca_file, crt_file, key_file): """ Background thread: waits indefinitely for a network interface, then @@ -159,8 +190,8 @@ class OpenGnSysWorker(ServerWorker): try: nets = list(operations.getNetworkInfo()) if nets: - self.interface = nets[0] - if t > 0: + self.interface = self._best_interface(nets) + if self.interface and t > 0: logger.debug("Network interface found after {} seconds".format(t)) else: logger.error('No network interfaces found')