diff mbox series

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

Message ID 5f863a8f.49B7DC8/gVsdoIuP%thomas.neuman@nutanix.com
State New
Headers show
Series [ovs-dev] python: Use Unbound to resolve DNS names of OVSDB remotes | expand

Commit Message

Thomas Neuman Oct. 13, 2020, 11:38 p.m. UTC
From 66126413b47872b06a2acfc5d00219db2704c7c4 Mon Sep 17 00:00:00 2001
From: thomas-neuman <thomas.neuman@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(-)

Comments

Thomas Neuman Oct. 13, 2020, 11:41 p.m. UTC | #1
From 1bcd0b930a04df78fe5ca81ef6a17e11a1b867a1 Mon Sep 17 00:00:00 2001
From: Thomas Neuman <thomas.neuman@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@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
diff mbox series

Patch

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