diff --git a/confluent_server/confluent/forwarder.py b/confluent_server/confluent/forwarder.py new file mode 100644 index 00000000..decb2814 --- /dev/null +++ b/confluent_server/confluent/forwarder.py @@ -0,0 +1,78 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2017 Lenovo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#This handles port forwarding for web interfaces on management devices +#It will also hijack port 3900 and do best effort.. + +import eventlet +import eventlet.green.select as select +import eventlet.green.socket as socket +forwarders = {} +sockhandler = {} +vidtarget = None +vidforwarder = None + +def handle_connection(incoming, outgoing): + while True: + r, _, _ = select.select((incoming, outgoing), (), (), 60) + for mysock in r: + data = mysock.recv(32768) + if not data: + return + if mysock == incoming: + outgoing.sendall(data) + elif mysock == outgoing: + incoming.sendall(data) + + +def forward_port(sock, target): + while True: + conn, _ = sock.accept() + try: + client = socket.create_connection((target, 443)) + except Exception: + conn.close() + continue + eventlet.spawn_n(handle_connection, conn, client) + + +def forward_video(): + sock = eventlet.listen(('localhost', 3900, 0, 0), family=socket.AF_INET6) + while True: + conn, _ = sock.accept() + if vidtarget is None: + conn.close() + continue + try: + vidclient = socket.create_connection((vidtarget, 3900)) + except Exception: + conn.close() + continue + eventlet.spawn_n(handle_connection, conn, vidclient) + +def get_port(addr): + global vidtarget + global vidforwarder + if addr not in forwarders: + newsock = eventlet.listen(('localhost', 0, 0, 0), + family=socket.AF_INET6) + forwarders[addr] = newsock + sockhandler[newsock] = eventlet.spawn(forward_port, newsock, addr) + if not vidforwarder: + vidforwarder = eventlet.spawn(forward_video) + vidtarget = addr + return forwarders[addr].getsockname()[1] +