Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Hostnames are ambiguously resolved on Dual Stack IPv4/6 Networks #35

Open
andydoubleyou opened this Issue · 2 comments

3 participants

@andydoubleyou

Steps to reproduce:
Network like Splunk's, with support for both IPv4 and IPv6.
Two machines configured for both protocols.
One running Splunk.
One running Splunk Python SDK.

When hostname is provided, Splunk Python SDK will attempt to connect using IPv6 if the machine being reached has a AAAA record. Unfortunately, Splunkd does not come configured automatically to listen on IPv6. So the service attempts to connect and times out. We should have a default of using IPv4 to connect, with a suite of configurable options akin to Splunk's own "connectUsingIpVersion" directive.

http://docs.splunk.com/Documentation/Splunk/latest/Admin/ConfigureSplunkforIPv6#Configure_Splunk_to_listen_on_an_IPv6_network

http://docs.python.org/library/socket.html

This is a common issue with any utility using php, perl, python... pretty much any language that utilizes the getHostByHostname family of underlying routines. Sadly, this is not elegantly configurable as IPv6 support for python's socket is a compile time option. Best work around is to use socket directly to resolve the hostname at connect time (do not cache this data) and use the appropriate returned IP address(es) for the connect option desired.

@andydoubleyou

This is a short workaround I wrote to force IPv4 by using a call that hasn't been updated for IPv6 (from SplunkRest.py as used by QA):

def __init__(self, uri_base, username='admin', password='changeme', timeout=60, debug_level=0):
    """Constructor of the SplunkRest object."""
    if socket.has_ipv6:
        # resolving hostname using method that only works with ipv4 to avoid problems on dual stack test hosts
        o = urlparse.urlsplit(str(uri_base))
        self.uri_base = "%s://%s:%s%s" % (o[0], socket.gethostbyname(o.hostname), str(o.port), o[2])
    else:
        self.uri_base = uri_base #https://localhost:8089 for example
    self.username = username
    self.password = password

What happens here is we exploit this behavior (from http://docs.python.org/library/socket.html ):

socket.gethostbyname(hostname)
Translate a host name to IPv4 address format. The IPv4 address is returned as a string, such as '100.50.200.5'. If the host name is an IPv4 address itself it is returned unchanged. See gethostbyname_ex() for a more complete interface. gethostbyname() does not support IPv6 name resolution, and getaddrinfo() should be used instead for IPv4/v6 dual stack support.

@itay
Owner

@andydoubleyou Thanks for the issue and the workaround. Apologies for not responding sooner! We'll look into this and see if we can integrate it somehow.

@shakeelmohamed shakeelmohamed self-assigned this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.