diff options
-rw-r--r-- | tools/examples/xend-config.sxp | 2 | ||||
-rw-r--r-- | tools/python/xen/web/tcp.py | 94 |
2 files changed, 96 insertions, 0 deletions
diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 6c056d4e05..7ab7eb8f38 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -110,6 +110,8 @@ # Address xend should listen on for relocation-socket connections, if # xend-relocation-server is set. # Meaning and default as for xend-address above. +# Also, interface name is allowed (e.g. eth0) there to get the +# relocation address to be bound on. #(xend-relocation-address '') # The hosts allowed to talk to the relocation port. If this is empty (the diff --git a/tools/python/xen/web/tcp.py b/tools/python/xen/web/tcp.py index c4436d506e..222737514a 100644 --- a/tools/python/xen/web/tcp.py +++ b/tools/python/xen/web/tcp.py @@ -21,6 +21,8 @@ import errno import re import socket import time +import fcntl # For get_interface_addr +import struct # For get_interface_addr import connection @@ -35,6 +37,49 @@ class TCPListener(connection.SocketListener): self.hosts_allow = hosts_allow connection.SocketListener.__init__(self, protocol_class) + def isValidHex(self, word): + # If we have empty word we treat it as valid + if len(word) == 0: + return True + try: + int(word, 16) + return True + except ValueError: + return False + + def isValidIP(self, ipaddr): + # Check for IPv4 address + numValid = 0 + tmp = ipaddr.split('.') + for byte in tmp: + if byte.isdigit(): + numValid += 1 + + if numValid == len(tmp): + return True + + # Check for IPv6 address + numValid = 0 + tmp = ipaddr.split(':') + for word in tmp: + if self.isValidHex(word): + numValid += 1 + + return numValid == len(tmp) + + def getIfAddr(self, ifname): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + x = socket.inet_ntoa(fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack('256s', ifname[:15]) + )[20:24]) + s.close() + except Exception, e: + x = ifname + + return x def createSocket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -46,6 +91,9 @@ class TCPListener(connection.SocketListener): timeout = time.time() + 30 while True: try: + if not self.isValidIP(self.interface): + self.interface = self.getIfAddr(self.interface) + log.debug("Listening on %s:%s" % (self.interface, self.port)) sock.bind((self.interface, self.port)) return sock except socket.error, (_errno, strerrno): @@ -78,6 +126,49 @@ class SSLTCPListener(TCPListener): TCPListener.__init__(self, protocol_class, port, interface, hosts_allow) + def isValidHex(self, word): + # If we have empty word we treat it as valid + if len(word) == 0: + return True + try: + int(word, 16) + return True + except ValueError: + return False + + def isValidIP(self, ipaddr): + # Check for IPv4 address + numValid = 0 + tmp = ipaddr.split('.') + for byte in tmp: + if byte.isdigit(): + numValid += 1 + + if numValid == len(tmp): + return True + + # Check for IPv6 address + numValid = 0 + tmp = ipaddr.split(':') + for word in tmp: + if self.isValidHex(word): + numValid += 1 + + return numValid == len(tmp) + + def getIfAddr(self, ifname): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + x = socket.inet_ntoa(fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack('256s', ifname[:15]) + )[20:24]) + s.close() + except Exception, e: + x = ifname + + return x def createSocket(self): from OpenSSL import SSL @@ -97,6 +188,9 @@ class SSLTCPListener(TCPListener): timeout = time.time() + 30 while True: try: + if not self.isValidIP(self.interface): + self.interface = self.getIfAddr(self.interface) + log.debug("Listening on %s:%s" % (self.interface, self.port)) sock.bind((self.interface, self.port)) return sock except socket.error, (_errno, strerrno): |