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

thomas.neuman at nutanix.com thomas.neuman at nutanix.com
Tue Oct 13 23:38:55 UTC 2020


>From 66126413b47872b06a2acfc5d00219db2704c7c4 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.
---
 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