From 02d89ce5ddf35d87a3f98b3a34aafb71105f4304 Mon Sep 17 00:00:00 2001 From: Daniel Goldberg Date: Tue, 13 Feb 2018 16:24:13 +0200 Subject: [PATCH] Rewrite actual check for sockets to be cross platform and notify when we fail to open a socket for unknown reasons. --- chaos_monkey/network/tools.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/chaos_monkey/network/tools.py b/chaos_monkey/network/tools.py index 716be15a0..eac020dc0 100644 --- a/chaos_monkey/network/tools.py +++ b/chaos_monkey/network/tools.py @@ -113,25 +113,30 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False): err = sock.connect_ex((ip, port)) if err == 0: good_ports.append((port, sock)) + continue if err == 10035: # WSAEWOULDBLOCK is valid, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 good_ports.append((port, sock)) + continue + if err == 115: # EINPROGRESS 115 /* Operation now in progress */ + good_ports.append((port, sock)) + continue + LOG.warning("Failed to connect to port %s, error code is %d", port, err) if len(good_ports) != 0: time.sleep(timeout) - read_sockets, write_sockets, errored_sockets = \ - select.select( - [s[1] for s in good_ports], - [s[1] for s in good_ports], - [s[1] for s in good_ports], - 0) # no timeout because we've already slept - connected_ports_sockets = [x for x in good_ports if x[1] in write_sockets] + # this is possibly connected. meaning after timeout wait, we expect to see a connection up + # Possible valid errors codes if we chose to check for actually closed are + # ECONNREFUSED (111) or WSAECONNREFUSED (10061) or WSAETIMEDOUT(10060) + connected_ports_sockets = [s for s in good_ports if + s[1].getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) == 0] LOG.debug( "On host %s discovered the following ports %s" % (str(ip), ",".join([str(x[0]) for x in connected_ports_sockets]))) banners = [] if get_banner: - # read first X bytes - banners = [sock.recv(BANNER_READ) if sock in read_sockets else "" + readable_sockets, _, _ = select.select([s[1] for s in connected_ports_sockets], [], [], 0) + # read first BANNER_READ bytes + banners = [sock.recv(BANNER_READ) if sock in readable_sockets else "" for port, sock in connected_ports_sockets] pass # try to cleanup