Skip to content

Commit

Permalink
Improve forwarder context manager
Browse files Browse the repository at this point in the history
Mapping has been added to define the sender and receiver for each event.
Additionally we continue with other events to combat the case where a
sender has sent data and also hung up unexpectedly.
  • Loading branch information
Stealthii committed Apr 12, 2022
1 parent 64f6771 commit ccbabd3
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions fabric/context_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,26 +458,27 @@ def _forwarder(chan, sock):
"""
Bidirectionally forward data between a socket and a Paramiko channel.
"""
mapping = {
sock.fileno(): (sock, chan),
chan.fileno(): (chan, sock),
}
poller = select.poll()
poller.register(sock, select.POLLIN)
poller.register(chan, select.POLLIN)
for fd in mapping:
poller.register(fd, select.POLLIN)
active = True
while active:
events = poller.poll()
for fd, flag in events:
if flag & select.POLLIN:
if fd is sock.fileno():
data = sock.recv(1024)
if len(data) == 0:
active = False
break
chan.send(data)
if fd is chan.fileno():
data = chan.recv(1024)
if len(data) == 0:
active = False
break
sock.send(data)
sender, receiver = mapping[fd]
data = sender.recv(1024)
if data:
receiver.send(data)
else:
active = False
# Handle unexpected hangups
if flag & select.POLLHUP:
active = False
chan.close()
sock.close()

Expand Down

0 comments on commit ccbabd3

Please sign in to comment.