From 8322cf4628ce4fa8fe9b23a5326855091f860ed6 Mon Sep 17 00:00:00 2001 From: Lucas Alvares Gomes Date: Wed, 30 Nov 2016 15:37:35 +0000 Subject: [PATCH] IpmiServer to allow using IP version 4 This patch is changing the IpmiServer and Session classes to figure out which IP version has been passed to it and create the correct socket. Change-Id: I802c4e2dbe140da40f3f3111aa84d692d4374bb1 --- pyghmi/ipmi/private/serversession.py | 8 +++++--- pyghmi/ipmi/private/session.py | 12 ++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pyghmi/ipmi/private/serversession.py b/pyghmi/ipmi/private/serversession.py index a567619..55632d6 100644 --- a/pyghmi/ipmi/private/serversession.py +++ b/pyghmi/ipmi/private/serversession.py @@ -23,6 +23,7 @@ import hmac import os import pyghmi.ipmi.private.constants as constants import pyghmi.ipmi.private.session as ipmisession +import socket import struct import uuid @@ -239,7 +240,7 @@ class IpmiServer(object): reasonable subset. :param port: The default port number to bind to. Defaults to the standard 623 - :param address: The IPv6 address to bind to. Defaults to '::' (all + :param address: The IP address to bind to. Defaults to '::' (all zeroes) """ self.revision = 0 @@ -265,8 +266,9 @@ class IpmiServer(object): authstatus, chancap, *oemdata) self.kg = None self.timeout = 60 - self.serversocket = ipmisession.Session._assignsocket( - (address, port, 0, 0)) + addrinfo = socket.getaddrinfo(address, port, 0, + socket.SOCK_DGRAM)[0] + self.serversocket = ipmisession.Session._assignsocket(addrinfo) ipmisession.Session.bmc_handlers[self.serversocket] = self def send_auth_cap(self, myaddr, mylun, clientaddr, clientlun, clientseq, diff --git a/pyghmi/ipmi/private/session.py b/pyghmi/ipmi/private/session.py index fd7a7d0..5c1d954 100644 --- a/pyghmi/ipmi/private/session.py +++ b/pyghmi/ipmi/private/session.py @@ -329,6 +329,7 @@ class Session(object): 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 @@ -340,7 +341,14 @@ class Session(object): cls.socketpool[sorted_candidates[0][0]] += 1 return sorted_candidates[0][0] # we need a new socket - if ipv6support: + if server: + # Regardless of whether ipv6 is supported or not, we + # must try to honor the address format of the given + # server, rather than trying to create an automatic one + tmpsocket = socket.socket(server[0], socket.SOCK_DGRAM) + if server[0] == socket.AF_INET6: + tmpsocket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) + elif 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 @@ -360,7 +368,7 @@ class Session(object): tmpsocket.bind(('', 0)) cls.socketpool[tmpsocket] = 1 else: - tmpsocket.bind(server) + tmpsocket.bind(server[4]) iosockets.append(tmpsocket) if myself is None: # we have confirmed kernel IPv6 support, but ::1 may still not