From c532cdec72649c3e290d6ba3daee4e21227941fc Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 12 Sep 2022 16:35:36 -0400 Subject: [PATCH] Agent: Detect closed socket in SocketsPipe When a socket is closed, select.select() returns the socket in the read_list. A closed socket can be detected by attempting to read from it. If 0 data is read, then the socket is closed. See below for more details: > If a socket is in the output readable list, you can be as-close-to-certain-as-we-ever-get-in-this-business that a recv on that socket will return something. https://docs.python.org/3/howto/sockets.html#non-blocking-sockets https://stackoverflow.com/questions/17386487/python-detect-when-a-socket-disconnects-for-any-reason https://stackoverflow.com/questions/17705239/is-there-a-way-to-detect-that-tcp-socket-has-been-closed-by-the-remote-peer-wit --- monkey/infection_monkey/network/relay/sockets_pipe.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/network/relay/sockets_pipe.py b/monkey/infection_monkey/network/relay/sockets_pipe.py index ad1307a05..ca60a7c22 100644 --- a/monkey/infection_monkey/network/relay/sockets_pipe.py +++ b/monkey/infection_monkey/network/relay/sockets_pipe.py @@ -30,7 +30,9 @@ class SocketsPipe(Thread): def _pipe(self): sockets = [self.source, self.dest] - while True: + socket_closed = False + + while not socket_closed: read_list, _, except_list = select.select(sockets, [], sockets, self.timeout) if except_list: raise OSError("select() failed on sockets {except_list}") @@ -43,6 +45,9 @@ class SocketsPipe(Thread): data = r.recv(READ_BUFFER_SIZE) if data: other.sendall(data) + else: + socket_closed = True + break def run(self): try: