Rewrite actual check for sockets to be cross platform

and notify when we fail to open a socket for unknown reasons.
This commit is contained in:
Daniel Goldberg 2018-02-13 16:24:13 +02:00
parent 41de1a86e0
commit 02d89ce5dd
1 changed files with 14 additions and 9 deletions

View File

@ -113,25 +113,30 @@ def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
err = sock.connect_ex((ip, port)) err = sock.connect_ex((ip, port))
if err == 0: if err == 0:
good_ports.append((port, sock)) 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 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)) 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: if len(good_ports) != 0:
time.sleep(timeout) time.sleep(timeout)
read_sockets, write_sockets, errored_sockets = \ # this is possibly connected. meaning after timeout wait, we expect to see a connection up
select.select( # Possible valid errors codes if we chose to check for actually closed are
[s[1] for s in good_ports], # ECONNREFUSED (111) or WSAECONNREFUSED (10061) or WSAETIMEDOUT(10060)
[s[1] for s in good_ports], connected_ports_sockets = [s for s in good_ports if
[s[1] for s in good_ports], s[1].getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) == 0]
0) # no timeout because we've already slept
connected_ports_sockets = [x for x in good_ports if x[1] in write_sockets]
LOG.debug( LOG.debug(
"On host %s discovered the following ports %s" % "On host %s discovered the following ports %s" %
(str(ip), ",".join([str(x[0]) for x in connected_ports_sockets]))) (str(ip), ",".join([str(x[0]) for x in connected_ports_sockets])))
banners = [] banners = []
if get_banner: if get_banner:
# read first X bytes readable_sockets, _, _ = select.select([s[1] for s in connected_ports_sockets], [], [], 0)
banners = [sock.recv(BANNER_READ) if sock in read_sockets else "" # read first BANNER_READ bytes
banners = [sock.recv(BANNER_READ) if sock in readable_sockets else ""
for port, sock in connected_ports_sockets] for port, sock in connected_ports_sockets]
pass pass
# try to cleanup # try to cleanup