mirror of
https://opendev.org/x/pyghmi
synced 2025-01-14 19:57:47 +00:00
Add support for IPv4-only environments
IPv4-only environments may come in two forms. It may not even have kernel support for AF_INET6, detect and tolerate this by fallback to AF_INET. Secondly, it may have AF_INET6 support, but not have any IPv6 addresses, including ::1, so fall back to IPv4 localhost in that scenario. Change-Id: I9e2f992afa9f6e71d1210701ac53080d8e788028
This commit is contained in:
parent
8a7a909b2e
commit
6360d54351
@ -47,6 +47,8 @@ iothread = None # the thread in which all IO will be performed
|
||||
iothreadready = False # whether io thread is yet ready to work
|
||||
iothreadwaiters = [] # threads waiting for iothreadready
|
||||
ioqueue = collections.deque([])
|
||||
myself = None
|
||||
ipv6support = None
|
||||
selectdeadline = 0
|
||||
running = True
|
||||
iosockets = [] # set of iosockets that will be shared amongst Session objects
|
||||
@ -60,7 +62,8 @@ def define_worker():
|
||||
def join(self):
|
||||
Session._cleanup()
|
||||
self.running = False
|
||||
iosockets[0].sendto('\x01', ('::1', iosockets[0].getsockname()[1]))
|
||||
iosockets[0].sendto(
|
||||
'\x01', (myself, iosockets[0].getsockname()[1]))
|
||||
super(_IOWorker, self).join()
|
||||
|
||||
def run(self):
|
||||
@ -136,7 +139,7 @@ def _io_wait(timeout, myaddr=None, evq=None):
|
||||
# it piggy back on the select() in the io thread, which is a truly
|
||||
# lazy wait even with eventlet involvement
|
||||
if deadline < selectdeadline:
|
||||
iosockets[0].sendto('\x01', ('::1', iosockets[0].getsockname()[1]))
|
||||
iosockets[0].sendto('\x01', (myself, iosockets[0].getsockname()[1]))
|
||||
evt.wait()
|
||||
|
||||
|
||||
@ -314,6 +317,8 @@ class Session(object):
|
||||
global iothread
|
||||
global iothreadready
|
||||
global iosockets
|
||||
global ipv6support
|
||||
global myself
|
||||
# seek for the least used socket. As sessions close, they may free
|
||||
# up slots in seemingly 'full' sockets. This scheme allows those
|
||||
# slots to be recycled
|
||||
@ -325,9 +330,20 @@ class Session(object):
|
||||
cls.socketpool[sorted_candidates[0][0]] += 1
|
||||
return sorted_candidates[0][0]
|
||||
# we need a new socket
|
||||
tmpsocket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) # INET6
|
||||
# can do IPv4 if you are nice to it
|
||||
tmpsocket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
if ipv6support:
|
||||
tmpsocket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
tmpsocket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
elif ipv6support is None: # we need to determine ipv6 support now
|
||||
try:
|
||||
tmpsocket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
tmpsocket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||
ipv6support = True
|
||||
except socket.error:
|
||||
ipv6support = False
|
||||
myself = '127.0.0.1'
|
||||
tmpsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
else:
|
||||
tmpsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
if server is None:
|
||||
# Rather than wait until send() to bind, bind now so that we have
|
||||
# a port number allocated no matter what
|
||||
@ -336,6 +352,16 @@ class Session(object):
|
||||
else:
|
||||
tmpsocket.bind(server)
|
||||
iosockets.append(tmpsocket)
|
||||
if myself is None:
|
||||
# we have confirmed kernel IPv6 support, but ::1 may still not
|
||||
# be there
|
||||
try:
|
||||
iosockets[0].sendto(
|
||||
'\x01', ('::1', iosockets[0].getsockname()[1]))
|
||||
myself = '::1'
|
||||
except socket.error:
|
||||
# AF_INET6, but no '::1', try the AF_INET6 version of 127
|
||||
myself = '::ffff:127.0.0.1'
|
||||
if iothread is None:
|
||||
initevt = threading.Event()
|
||||
iothreadwaiters.append(initevt)
|
||||
@ -366,7 +392,8 @@ class Session(object):
|
||||
trueself = None
|
||||
for res in socket.getaddrinfo(bmc, port, 0, socket.SOCK_DGRAM):
|
||||
sockaddr = res[4]
|
||||
if res[0] == socket.AF_INET: # convert the sockaddr to AF_INET6
|
||||
if ipv6support and res[0] == socket.AF_INET:
|
||||
# convert the sockaddr to AF_INET6
|
||||
newhost = '::ffff:' + sockaddr[0]
|
||||
sockaddr = (newhost, sockaddr[1], 0, 0)
|
||||
if sockaddr in cls.bmc_handlers:
|
||||
@ -1570,8 +1597,8 @@ class Session(object):
|
||||
0,
|
||||
socket.SOCK_DGRAM):
|
||||
sockaddr = res[4]
|
||||
if res[0] == socket.AF_INET: # convert the sockaddr
|
||||
# to AF_INET6
|
||||
if ipv6support and res[0] == socket.AF_INET:
|
||||
# convert the sockaddr to AF_INET6
|
||||
newhost = '::ffff:' + sockaddr[0]
|
||||
sockaddr = (newhost, sockaddr[1], 0, 0)
|
||||
self.allsockaddrs.append(sockaddr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user