[ovs-dev] python: Use Unbound to resolve DNS names of OVSDB remotes

Thomas Neuman thomas.neuman at nutanix.com
Tue Oct 13 23:41:38 UTC 2020


 From 1bcd0b930a04df78fe5ca81ef6a17e11a1b867a1 Mon Sep 17 00:00:00 2001
From: Thomas Neuman <thomas.neuman at nutanix.com>
Date: Tue, 13 Oct 2020 16:09:54 -0700
Subject: [PATCH] python: Use Unbound to resolve DNS names of OVSDB remotes

If the Unbound library is present, allows for resolving remote OVSDB
instances in the Python client code. The Unbound context is created,
and the relevant configuration files in /etc/resolv.conf and
/etc/hosts read, when the Python library is first loaded. From that
point, attempts to open a connection to a given remote will use
that Unbound context for DNS resolution.

Signed-off-by: Thomas Neuman <thomas.neuman at nutanix.com>
---
  python/ovs/socket_util.py | 39 ++++++++++++++++++++++++++++++++-------
  1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py
index 8f9d318..c47aea0 100644
--- a/python/ovs/socket_util.py
+++ b/python/ovs/socket_util.py
@@ -33,6 +33,22 @@ if sys.platform == 'win32':
  vlog = ovs.vlog.Vlog("socket_util")
  
  
+try:
+    import unbound
+    ub_ctx = unbound.ub_ctx()
+    if sys.platform.startswith('linux'):
+        status = ub_ctx.resolvconf()
+        if status != 0:
+            vlog.warn("Failed to read /etc/resolv.conf: %s"
+                % unbound.ub_strerror(status))
+    status = ub_ctx.hosts()
+    if status != 0:
+        vlog.warn("Failed to read etc/hosts: %s"
+            % unbound.ub_strerror(status))
+except ImportError:
+    unbound = None
+
+
  def make_short_name(long_name):
      if long_name is None:
          return None
@@ -209,6 +225,20 @@ def is_valid_ipv4_address(address):
      return True
  
  
+def addr_parse_family(address):
+    if is_valid_ipv4_address(address):
+        return socket.AF_INET
+
+    if unbound:
+        status, result = ub_ctx.resolve(address)
+        if status == 0 and result.havedata:
+            addr = result.data.address_list[0]
+            if is_valid_ipv4_address(addr):
+                return socket.AF_INET
+
+    return socket.AF_INET6
+
+
  def inet_parse_active(target, default_port):
      address = target.split(":")
      if len(address) >= 2:
@@ -228,13 +258,8 @@ def inet_parse_active(target, default_port):
  def inet_open_active(style, target, default_port, dscp):
      address = inet_parse_active(target, default_port)
      try:
-        is_addr_inet = is_valid_ipv4_address(address[0])
-        if is_addr_inet:
-            sock = socket.socket(socket.AF_INET, style, 0)
-            family = socket.AF_INET
-        else:
-            sock = socket.socket(socket.AF_INET6, style, 0)
-            family = socket.AF_INET6
+        family = addr_parse_family(address[0])
+        sock = socket.socket(family, style, 0)
      except socket.error as e:
          return get_exception_errno(e), None
  
-- 
1.9.4





More information about the dev mailing list