diff -r 93410e5e4ad8 tools/examples/xend-config.sxp --- a/tools/examples/xend-config.sxp Sat May 22 06:36:41 2010 +0100 +++ b/tools/examples/xend-config.sxp Mon May 24 16:49:10 2010 +0200 @@ -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 -r 93410e5e4ad8 tools/python/xen/web/tcp.py --- a/tools/python/xen/web/tcp.py Sat May 22 06:36:41 2010 +0100 +++ b/tools/python/xen/web/tcp.py Mon May 24 16:49:10 2010 +0200 @@ -21,6 +21,8 @@ import re 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.SocketListe 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.SocketListe 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):