IPv6 support.

This commit is contained in:
grossmj 2015-06-06 21:37:34 -06:00
parent 9f97b52f5f
commit 81e56e035b
6 changed files with 56 additions and 36 deletions

View File

@ -357,9 +357,13 @@ class BaseManager:
rhost = nio_settings["rhost"] rhost = nio_settings["rhost"]
rport = nio_settings["rport"] rport = nio_settings["rport"]
try: try:
# TODO: handle IPv6 info = socket.getaddrinfo(rhost, rport, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: if not info:
sock.connect((rhost, rport)) raise aiohttp.web.HTTPInternalServerError(text="getaddrinfo returns an empty list on {}:{}".format(rhost, rport))
for res in info:
af, socktype, proto, _, sa = res
with socket.socket(af, socktype, proto) as sock:
sock.connect(sa)
except OSError as e: except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e)) raise aiohttp.web.HTTPInternalServerError(text="Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(lport, rhost, rport) nio = NIOUDP(lport, rhost, rport)

View File

@ -331,10 +331,16 @@ class Dynamips(BaseManager):
server_host = server_config.get("host") server_host = server_config.get("host")
try: try:
info = socket.getaddrinfo(server_host, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
if not info:
raise DynamipsError("getaddrinfo returns an empty list on {}".format(server_host))
for res in info:
af, socktype, proto, _, sa = res
# let the OS find an unused port for the Dynamips hypervisor # let the OS find an unused port for the Dynamips hypervisor
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: with socket.socket(af, socktype, proto) as sock:
sock.bind((server_host, 0)) sock.bind(sa)
port = sock.getsockname()[1] port = sock.getsockname()[1]
break
except OSError as e: except OSError as e:
raise DynamipsError("Could not find free port for the Dynamips hypervisor: {}".format(e)) raise DynamipsError("Could not find free port for the Dynamips hypervisor: {}".format(e))
@ -375,9 +381,13 @@ class Dynamips(BaseManager):
rhost = nio_settings["rhost"] rhost = nio_settings["rhost"]
rport = nio_settings["rport"] rport = nio_settings["rport"]
try: try:
# TODO: handle IPv6 info = socket.getaddrinfo(rhost, rport, 0, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: if not info:
sock.connect((rhost, rport)) raise DynamipsError("getaddrinfo returns an empty list on {}:{}".format(rhost, rport))
for res in info:
af, socktype, proto, _, sa = res
with socket.socket(af, socktype, proto) as sock:
sock.connect(sa)
except OSError as e: except OSError as e:
raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e)) raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(node.hypervisor, lport, rhost, rport) nio = NIOUDP(node.hypervisor, lport, rhost, rport)

View File

@ -355,10 +355,16 @@ class TelnetServer(Console):
def __enter__(self): def __enter__(self):
# Open a socket and start listening # Open a socket and start listening
sock_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
info = socket.getaddrinfo(self.addr, self.port, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
if not info:
raise TelnetServerError("getaddrinfo returns an empty list on {}:{}".format(self.addr, self.port))
for res in info:
af, socktype, proto, _, sa = res
sock_fd = socket.socket(af, socktype, proto)
sock_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try: try:
sock_fd.bind((self.addr, self.port)) sock_fd.bind(sa)
except OSError: except OSError:
raise TelnetServerError("Cannot bind to {}:{}" raise TelnetServerError("Cannot bind to {}:{}"
.format(self.addr, self.port)) .format(self.addr, self.port))

View File

@ -151,15 +151,11 @@ class PortManager:
if port in ignore_ports: if port in ignore_ports:
continue continue
try: try:
if ":" in host: for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type, 0, socket.AI_PASSIVE):
# IPv6 address support af, socktype, proto, _, sa = res
with socket.socket(socket.AF_INET6, socket_type) as s: with socket.socket(af, socktype, proto) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port)) # the port is available if bind is a success s.bind(sa) # the port is available if bind is a success
else:
with socket.socket(socket.AF_INET, socket_type) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port)) # the port is available if bind is a success
return port return port
except OSError as e: except OSError as e:
last_exception = e last_exception = e

View File

@ -615,9 +615,14 @@ class QemuVM(BaseVM):
if self._manager.config.get_section_config("Qemu").getboolean("monitor", True): if self._manager.config.get_section_config("Qemu").getboolean("monitor", True):
try: try:
info = socket.getaddrinfo(self._monitor_host, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
if not info:
raise QemuError("getaddrinfo returns an empty list on {}".format(self._monitor_host))
for res in info:
af, socktype, proto, _, sa = res
# let the OS find an unused port for the Qemu monitor # let the OS find an unused port for the Qemu monitor
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: with socket.socket(af, socktype, proto) as sock:
sock.bind((self._monitor_host, 0)) sock.bind(sa)
self._monitor = sock.getsockname()[1] self._monitor = sock.getsockname()[1]
except OSError as e: except OSError as e:
raise QemuError("Could not find free port for the Qemu monitor: {}".format(e)) raise QemuError("Could not find free port for the Qemu monitor: {}".format(e))

View File

@ -60,14 +60,13 @@ class TelnetServer(threading.Thread):
# we must a thread for reading the pipe on Windows because it is a Named Pipe and it cannot be monitored by select() # we must a thread for reading the pipe on Windows because it is a Named Pipe and it cannot be monitored by select()
self._use_thread = True self._use_thread = True
if ":" in self._host: for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
# IPv6 address support af, socktype, proto, _, sa = res
self._server_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self._server_socket = socket.socket(af, socktype, proto)
else:
self._server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._server_socket.bind((self._host, self._port)) self._server_socket.bind(sa)
self._server_socket.listen(socket.SOMAXCONN) self._server_socket.listen(socket.SOMAXCONN)
break
log.info("Telnet server initialized, waiting for clients on {}:{}".format(self._host, self._port)) log.info("Telnet server initialized, waiting for clients on {}:{}".format(self._host, self._port))