artiq_devtool: forward multiple connections.

In particular this is useful for running concurrent arqctl_corelog
and anything else using the management channel, such as
artiq_coreboot.
This commit is contained in:
whitequark 2017-08-23 09:33:07 +00:00
parent 32aac9c70d
commit 3823193060

View File

@ -112,27 +112,10 @@ def main():
elif action == "connect":
transport = client.get_transport()
def forwarder(port):
listener = socket.socket()
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(('localhost', port))
listener.listen(1)
while True:
local_stream, peer_addr = listener.accept()
logger.info("Accepting %s:%s and opening SSH channel to %s:%s",
*peer_addr, args.device, port)
if client.get_transport() is None:
logger.error("Trying to open a channel before the transport is ready!")
continue
def forwarder(local_stream, remote_stream):
try:
remote_stream = \
transport.open_channel('direct-tcpip', (args.device, port), peer_addr)
except Exception as e:
logger.exception("Cannot open channel on port %s", port)
continue
while True:
try:
r, _, _ = select.select([local_stream, remote_stream], [], [])
if local_stream in r:
data = local_stream.recv(65535)
@ -144,15 +127,38 @@ def main():
if data == b"":
break
local_stream.sendall(data)
except Exception as e:
logger.exception("Forward error on port %s", port)
break
except Exception as err:
logger.error("Cannot forward on port %s: %s", port, repr(err))
local_stream.close()
remote_stream.close()
def listener(port):
listener = socket.socket()
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(('localhost', port))
listener.listen(8)
while True:
local_stream, peer_addr = listener.accept()
logger.info("Accepting %s:%s and opening SSH channel to %s:%s",
*peer_addr, args.device, port)
if client.get_transport() is None:
logger.error("Trying to open a channel before the transport is ready!")
continue
try:
remote_stream = \
transport.open_channel('direct-tcpip', (args.device, port), peer_addr)
except Exception:
logger.exception("Cannot open channel on port %s", port)
continue
thread = threading.Thread(target=forwarder, args=(local_stream, remote_stream),
name="forward-{}".format(port), daemon=True)
thread.start()
for port in (1380, 1381, 1382, 1383):
thread = threading.Thread(target=forwarder, args=(port,),
name="port-{}".format(port), daemon=True)
thread = threading.Thread(target=listener, args=(port,),
name="listen-{}".format(port), daemon=True)
thread.start()
logger.info("Connecting to device")