def run(self): debug("ProxyProcess.run() pid=%s, uid=%s, gid=%s", os.getpid(), os.getuid(), os.getgid()) #change uid and gid: if os.getgid() != self.gid: os.setgid(self.gid) if os.getuid() != self.uid: os.setuid(self.uid) debug("ProxyProcess.run() new uid=%s, gid=%s", os.getuid(), os.getgid()) if self.env_options: #TODO: whitelist env update? os.environ.update(self.env_options) log.info("new proxy started for client %s and server %s", self.client_conn, self.server_conn) if not USE_THREADING: signal.signal(signal.SIGTERM, self.signal_quit) signal.signal(signal.SIGINT, self.signal_quit) debug("registered signal handler %s", self.signal_quit) make_daemon_thread(self.server_message_queue, "server message queue").start() self.main_queue = Queue() #setup protocol wrappers: self.server_packets = Queue(PROXY_QUEUE_SIZE) self.client_packets = Queue(PROXY_QUEUE_SIZE) self.client_protocol = Protocol(self, self.client_conn, self.process_client_packet, self.get_client_packet) self.client_protocol.restore_state(self.client_state) self.server_protocol = Protocol(self, self.server_conn, self.process_server_packet, self.get_server_packet) #server connection tweaks: self.server_protocol.large_packets.append("draw") self.server_protocol.large_packets.append("keymap-changed") self.server_protocol.large_packets.append("server-settings") self.server_protocol.set_compression_level( self.session_options.get("compression_level", 0)) debug("starting network threads") self.server_protocol.start() self.client_protocol.start() #forward the hello packet: hello_packet = ("hello", self.filter_client_caps(self.caps)) self.queue_server_packet(hello_packet) try: try: self.run_queue() except KeyboardInterrupt, e: self.stop(str(e)) finally: debug("ProxyProcess.run() ending %s", os.getpid())
def make_protocol(self, socktype, conn, frominfo=""): netlog.info("New %s connection received%s", socktype, frominfo) protocol = Protocol(self, conn, self.process_packet) self._potential_protocols.append(protocol) protocol.large_packets.append("info-response") protocol.challenge_sent = False protocol.authenticator = None if socktype == "tcp": protocol.auth_class = self.tcp_auth_class protocol.encryption = self.tcp_encryption protocol.keyfile = self.tcp_encryption_keyfile elif socktype == "vsock": protocol.auth_class = self.vsock_auth_class protocol.encryption = None protocol.keyfile = None else: protocol.auth_class = self.auth_class protocol.encryption = self.encryption protocol.keyfile = self.encryption_keyfile protocol.socket_type = socktype protocol.invalid_header = self.invalid_header protocol.receive_aliases.update(self._aliases) authlog("socktype=%s, auth class=%s, encryption=%s, keyfile=%s", socktype, protocol.auth_class, protocol.encryption, protocol.keyfile) if protocol.encryption and ENCRYPT_FIRST_PACKET: password = self.get_encryption_key(None, protocol.keyfile) protocol.set_cipher_in(protocol.encryption, DEFAULT_IV, password, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING) protocol.start() self.timeout_add(SOCKET_TIMEOUT * 1000, self.verify_connection_accepted, protocol) return True
def make_protocol(self): #figure out where we read from and write to: if self.input_filename == "-": #disable stdin buffering: self._input = os.fdopen(sys.stdin.fileno(), 'rb', 0) setbinarymode(self._input.fileno()) else: self._input = open(self.input_filename, 'rb') if self.output_filename == "-": #disable stdout buffering: self._output = os.fdopen(sys.stdout.fileno(), 'wb', 0) setbinarymode(self._output.fileno()) else: self._output = open(self.output_filename, 'wb') #stdin and stdout wrapper: conn = TwoFileConnection(self._output, self._input, abort_test=None, target=self.name, socktype=self.name, close_cb=self.net_stop) conn.timeout = 0 protocol = Protocol(self, conn, self.process_packet, get_packet_cb=self.get_packet) setup_fastencoder_nocompression(protocol) protocol.large_packets = self.large_packets return protocol
def setup_connection(self, conn): log.debug("setup_connection(%s)", conn) self._protocol = Protocol(conn, self.process_packet, self.next_packet) self._protocol.large_packets.append("keymap-changed") self._protocol.large_packets.append("server-settings") self._protocol.set_compression_level(self.compression_level) self.have_more = self._protocol.source_has_more
def _new_connection(self, listener, *args): socktype = self.socket_types.get(listener, "") sock, address = listener.accept() if len(self._potential_protocols) >= self._max_connections: log.error("too many connections (%s), ignoring new one", len(self._potential_protocols)) sock.close() return True try: peername = sock.getpeername() except: peername = str(address) sockname = sock.getsockname() target = peername or sockname sock.settimeout(self._socket_timeout) log("new_connection(%s) sock=%s, sockname=%s, address=%s, peername=%s", args, sock, sockname, address, peername) sc = SocketConnection(sock, sockname, address, target, socktype) log.info("New connection received: %s", sc) protocol = Protocol(self, sc, self.process_packet) protocol.large_packets.append("info-response") protocol.authenticator = None protocol.invalid_header = self.invalid_header protocol.receive_aliases.update(self._aliases) self._potential_protocols.append(protocol) protocol.start() self.timeout_add(SOCKET_TIMEOUT * 1000, self.verify_connection_accepted, protocol) return True
def make_protocol(self): #figure out where we read from and write to: if self.input_filename == "-": #disable stdin buffering: self._input = os.fdopen(sys.stdin.fileno(), 'rb', 0) setbinarymode(self._input.fileno()) else: self._input = open(self.input_filename, 'rb') if self.output_filename == "-": #disable stdout buffering: self._output = os.fdopen(sys.stdout.fileno(), 'wb', 0) setbinarymode(self._output.fileno()) else: self._output = open(self.output_filename, 'wb') #stdin and stdout wrapper: conn = TwoFileConnection(self._output, self._input, abort_test=None, target=self.name, info=self.name, close_cb=self.net_stop) conn.timeout = 0 protocol = Protocol(gobject, conn, self.process_packet, get_packet_cb=self.get_packet) try: protocol.enable_encoder("rencode") except Exception as e: log.warn("failed to enable rencode: %s", e) protocol.enable_encoder("bencode") protocol.enable_compressor("none") protocol.large_packets = self.large_packets return protocol
def handle_new_connection(self, socktype, listener, _handle): socket_info = self.socket_info.get(listener) assert socktype, "cannot find socket type for %s" % listener socket_options = self.socket_options.get(listener, {}) assert socktype != "named-pipe" conn = accept_connection(socktype, listener, SOCKET_TIMEOUT, socket_options) if conn is None: return #limit number of concurrent network connections: if len(self._potential_protocols) >= MAX_CONCURRENT_CONNECTIONS: log.error("Error: too many connections (%i)", len(self._potential_protocols)) log.error(" ignoring new one: %s", conn.endpoint) conn.close() return sock = conn._socket socktype = conn.socktype peername = conn.endpoint sockname = sock.getsockname() target = peername or sockname log("handle_new_connection%s sockname=%s, target=%s", (conn, socket_info, socket_options), sockname, target) sock.settimeout(SOCKET_TIMEOUT) log_new_connection(conn, socket_info) socktype = socktype.lower() protocol = Protocol(self, conn, self.process_network_packet) #protocol.large_packets.append(b"info-response") protocol.socket_type = socktype self._potential_protocols.append(protocol) protocol.authenticators = () protocol.start()
def setup_connection(self, conn): netlog("setup_connection(%s) timeout=%s", conn, conn.timeout) self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet) self._protocol.large_packets.append("keymap-changed") self._protocol.large_packets.append("server-settings") self._protocol.large_packets.append("logging") self._protocol.large_packets.append("input-devices") self._protocol.set_compression_level(self.compression_level) self._protocol.receive_aliases.update(self._aliases) self._protocol.enable_default_encoder() self._protocol.enable_default_compressor() if self.encryption and ENCRYPT_FIRST_PACKET: key = self.get_encryption_key() self._protocol.set_cipher_out(self.encryption, DEFAULT_IV, key, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING) self.have_more = self._protocol.source_has_more if conn.timeout > 0: self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected) process = getattr(conn, "process", None) #ie: ssh is handled by anotherprocess if process: proc, name, command = process getChildReaper().add_process(proc, name, command, ignore=True, forget=False) netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
def setup_connection(self, conn): netlog("setup_connection(%s) timeout=%s, socktype=%s", conn, conn.timeout, conn.socktype) if conn.socktype=="udp": from xpra.net.udp_protocol import UDPClientProtocol self._protocol = UDPClientProtocol(self.get_scheduler(), conn, self.process_packet, self.next_packet) #use a random uuid: import random self._protocol.uuid = random.randint(0, 2**64-1) self.set_packet_handlers(self._packet_handlers, { "udp-control" : self._process_udp_control, }) else: self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet) for x in (b"keymap-changed", b"server-settings", b"logging", b"input-devices"): self._protocol.large_packets.append(x) self._protocol.set_compression_level(self.compression_level) self._protocol.receive_aliases.update(self._aliases) self._protocol.enable_default_encoder() self._protocol.enable_default_compressor() if self.encryption and ENCRYPT_FIRST_PACKET: key = self.get_encryption_key() self._protocol.set_cipher_out(self.encryption, DEFAULT_IV, key, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING) self.have_more = self._protocol.source_has_more if conn.timeout>0: self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected) process = getattr(conn, "process", None) #ie: ssh is handled by anotherprocess if process: proc, name, command = process if proc: getChildReaper().add_process(proc, name, command, ignore=True, forget=False) netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
def new_control_connection(self, sock, address): if len(self.potential_protocols) >= self.max_connections: log.error("too many connections (%s), ignoring new one", len(self.potential_protocols)) sock.close() return True try: peername = sock.getpeername() except OSError: peername = str(address) sockname = sock.getsockname() target = peername or sockname #sock.settimeout(0) log( "new_control_connection() sock=%s, sockname=%s, address=%s, peername=%s", sock, sockname, address, peername) sc = SocketConnection(sock, sockname, address, target, "unix-domain") log.info("New proxy instance control connection received:") log.info(" '%s'", sc) protocol = Protocol(self, sc, self.process_control_packet) protocol.large_packets.append(b"info-response") self.potential_protocols.append(protocol) protocol.enable_default_encoder() protocol.start() self.timeout_add(SOCKET_TIMEOUT * 1000, self.verify_connection_accepted, protocol) return True
def make_protocol(self, socktype, conn, listener): socktype = socktype.lower() protocol = Protocol(self, conn, self.process_network_packet) #protocol.large_packets.append(b"info-response") protocol.socket_type = socktype self._potential_protocols.append(protocol) protocol.authenticators = () protocol.start()
def make_protocol(self): #make a connection using the process stdin / stdout conn = TwoFileConnection(self.process.stdin, self.process.stdout, abort_test=self.abort_test, target=self.description, socktype=self.description, close_cb=self.subprocess_exit) conn.timeout = 0 protocol = Protocol(self, conn, self.process_packet, get_packet_cb=self.get_packet) setup_fastencoder_nocompression(protocol) protocol.large_packets = self.large_packets return protocol
def _new_connection(self, listener, *args): if self._closing: netlog.warn("ignoring new connection during shutdown") return False socktype = self.socket_types.get(listener) assert socktype, "cannot find socket type for %s" % listener sock, address = listener.accept() if len(self._potential_protocols) >= self._max_connections: netlog.error("too many connections (%s), ignoring new one", len(self._potential_protocols)) sock.close() return True try: peername = sock.getpeername() except: peername = str(address) sockname = sock.getsockname() target = peername or sockname sock.settimeout(self._socket_timeout) netlog( "new_connection(%s) sock=%s, timeout=%s, sockname=%s, address=%s, peername=%s", args, sock, self._socket_timeout, sockname, address, peername) sc = SocketConnection(sock, sockname, address, target, socktype) netlog("socket connection: %s", sc) frominfo = "" if peername: frominfo = " from %s" % pretty_socket(peername) elif socktype == "unix-domain": frominfo = " on %s" % sockname netlog.info("New %s connection received%s", socktype, frominfo) protocol = Protocol(self, sc, self.process_packet) self._potential_protocols.append(protocol) protocol.large_packets.append("info-response") protocol.challenge_sent = False protocol.authenticator = None if socktype == "tcp": protocol.auth_class = self.tcp_auth_class protocol.encryption = self.tcp_encryption protocol.keyfile = self.tcp_encryption_keyfile else: protocol.auth_class = self.auth_class protocol.encryption = self.encryption protocol.keyfile = self.encryption_keyfile protocol.socket_type = socktype protocol.invalid_header = self.invalid_header protocol.receive_aliases.update(self._aliases) authlog("socktype=%s, auth class=%s, encryption=%s, keyfile=%s", socktype, protocol.auth_class, protocol.encryption, protocol.keyfile) if protocol.encryption and ENCRYPT_FIRST_PACKET: password = self.get_encryption_key(None, protocol.keyfile) protocol.set_cipher_in(protocol.encryption, DEFAULT_IV, password, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING) protocol.start() self.timeout_add(SOCKET_TIMEOUT * 1000, self.verify_connection_accepted, protocol) return True
def loopback_protocol(process_packet_cb, get_packet_cb): conn = loopback_connection("fake", "fake") protocol = Protocol(GLib, conn, process_packet_cb, get_packet_cb=get_packet_cb) protocol.enable_encoder("rencode") protocol.enable_compressor("none") return protocol
def init(self, exit_cb, packets=[]): self.packets = packets sock = socket.socket(socket.AF_UNIX) sock.settimeout(5) sock.connect(TEST_SOCKFILE) sock.settimeout(None) sc = makeSocketConnection(sock, "test-client-socket") self.protocol = Protocol(sc, self.process_packet, None) self.protocol.start() if len(self.packets) > 0: gobject.timeout_add(1000, self.send_packet)
def new_connection(self, *args): log.info("new_connection(%s)", args) sock, address = self.listener.accept() log.info("new_connection(%s) sock=%s, address=%s", args, sock, address) sock.settimeout(None) sock.setblocking(1) sc = makeSocketConnection(sock, str(address) + "server") protocol = Protocol(sc, self.process_packet) protocol.salt = None protocol.set_compression_level(1) protocol.start() return True
def setup_connection(self, conn): log.debug("setup_connection(%s)", conn) self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet) self._protocol.large_packets.append("keymap-changed") self._protocol.large_packets.append("server-settings") self._protocol.set_compression_level(self.compression_level) self._protocol.receive_aliases.update(self._aliases) self._protocol.enable_default_encoder() self._protocol.enable_default_compressor() self.have_more = self._protocol.source_has_more if conn.timeout>0: self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected)
def make_protocol(self): #make a connection using the process stdin / stdout conn = TwoFileConnection(self.process.stdin, self.process.stdout, abort_test=self.abort_test, target=self.description, socktype=self.description, close_cb=self.subprocess_exit) conn.timeout = 0 protocol = Protocol(self, conn, self.process_packet, get_packet_cb=self.get_packet) if LOCAL_ALIASES: protocol.send_aliases = LOCAL_SEND_ALIASES protocol.receive_aliases = LOCAL_RECEIVE_ALIASES setup_fastencoder_nocompression(protocol) protocol.large_packets = self.large_packets return protocol
def _new_connection(self, listener, *args): socktype = self.socket_types.get(listener) assert socktype, "cannot find socket type for %s" % listener sock, address = listener.accept() if len(self._potential_protocols) >= self._max_connections: netlog.error("too many connections (%s), ignoring new one", len(self._potential_protocols)) sock.close() return True try: peername = sock.getpeername() except: peername = str(address) sockname = sock.getsockname() target = peername or sockname sock.settimeout(self._socket_timeout) netlog( "new_connection(%s) sock=%s, timeout=%s, sockname=%s, address=%s, peername=%s", args, sock, self._socket_timeout, sockname, address, peername) sc = SocketConnection(sock, sockname, address, target, socktype) netlog("socket connection: %s", sc) frominfo = "" if peername: frominfo = " from %s" % str(peername) netlog.info("New %s connection received%s", socktype, frominfo) protocol = Protocol(self, sc, self.process_packet) self._potential_protocols.append(protocol) protocol.large_packets.append("info-response") protocol.challenge_sent = False protocol.authenticator = None if socktype == "tcp": protocol.auth_class = self.tcp_auth_class else: protocol.auth_class = self.auth_class protocol.socket_type = socktype protocol.invalid_header = self.invalid_header protocol.receive_aliases.update(self._aliases) protocol.start() self.timeout_add(SOCKET_TIMEOUT * 1000, self.verify_connection_accepted, protocol) return True
def setup_connection(self, conn): netlog("setup_connection(%s) timeout=%s", conn, conn.timeout) self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet) self._protocol.large_packets.append("keymap-changed") self._protocol.large_packets.append("server-settings") self._protocol.large_packets.append("logging") self._protocol.set_compression_level(self.compression_level) self._protocol.receive_aliases.update(self._aliases) self._protocol.enable_default_encoder() self._protocol.enable_default_compressor() if self.encryption and ENCRYPT_FIRST_PACKET: key = self.get_encryption_key() self._protocol.set_cipher_out(self.encryption, DEFAULT_IV, key, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING) self.have_more = self._protocol.source_has_more if conn.timeout > 0: self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected) netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
def make_protocol(self): #make a connection using the process stdin / stdout conn = TwoFileConnection(self.process.stdin, self.process.stdout, abort_test=None, target=self.description, info=self.description, close_cb=self.subprocess_exit) conn.timeout = 0 protocol = Protocol(gobject, conn, self.process_packet, get_packet_cb=self.get_packet) #we assume the other end has the same encoders (which is reasonable): #TODO: fallback to bencoder try: protocol.enable_encoder("rencode") except Exception as e: log.warn("failed to enable rencode: %s", e) protocol.enable_encoder("bencode") #we assume this is local, so no compression: protocol.enable_compressor("none") protocol.large_packets = self.large_packets return protocol
def run(self): log("ProxyProcess.run() pid=%s, uid=%s, gid=%s", os.getpid(), os.getuid(), os.getgid()) #change uid and gid: if os.getgid() != self.gid: os.setgid(self.gid) if os.getuid() != self.uid: os.setuid(self.uid) log("ProxyProcess.run() new uid=%s, gid=%s", os.getuid(), os.getgid()) if self.env_options: #TODO: whitelist env update? os.environ.update(self.env_options) self.video_init() log.info("new proxy started for client %s and server %s", self.client_conn, self.server_conn) signal.signal(signal.SIGTERM, self.signal_quit) signal.signal(signal.SIGINT, self.signal_quit) log("registered signal handler %s", self.signal_quit) make_daemon_thread(self.server_message_queue, "server message queue").start() if self.create_control_socket(): self.control_socket_thread = make_daemon_thread( self.control_socket_loop, "control") self.control_socket_thread.start() self.main_queue = Queue() #setup protocol wrappers: self.server_packets = Queue(PROXY_QUEUE_SIZE) self.client_packets = Queue(PROXY_QUEUE_SIZE) self.client_protocol = Protocol(self, self.client_conn, self.process_client_packet, self.get_client_packet) self.client_protocol.restore_state(self.client_state) self.server_protocol = Protocol(self, self.server_conn, self.process_server_packet, self.get_server_packet) #server connection tweaks: self.server_protocol.large_packets.append("draw") self.server_protocol.large_packets.append("window-icon") self.server_protocol.large_packets.append("keymap-changed") self.server_protocol.large_packets.append("server-settings") self.server_protocol.set_compression_level( self.session_options.get("compression_level", 0)) self.server_protocol.enable_default_encoder() self.lost_windows = set() self.encode_queue = Queue() self.encode_thread = make_daemon_thread(self.encode_loop, "encode") self.encode_thread.start() log("starting network threads") self.server_protocol.start() self.client_protocol.start() #forward the hello packet: hello_packet = ("hello", self.filter_client_caps(self.caps)) self.queue_server_packet(hello_packet) self.timeout_add(VIDEO_TIMEOUT * 1000, self.timeout_video_encoders) try: try: self.run_queue() except KeyboardInterrupt as e: self.stop(str(e)) finally: log("ProxyProcess.run() ending %s", os.getpid())
def run(self): log("ProxyProcess.run() pid=%s, uid=%s, gid=%s", os.getpid(), getuid(), getgid()) setuidgid(self.uid, self.gid) if self.env_options: #TODO: whitelist env update? os.environ.update(self.env_options) self.video_init() log.info("new proxy instance started") log.info(" for client %s", self.client_conn) log.info(" and server %s", self.server_conn) signal.signal(signal.SIGTERM, self.signal_quit) signal.signal(signal.SIGINT, self.signal_quit) log("registered signal handler %s", self.signal_quit) start_thread(self.server_message_queue, "server message queue") if not self.create_control_socket(): #TODO: should send a message to the client return self.control_socket_thread = start_thread(self.control_socket_loop, "control") self.main_queue = Queue() #setup protocol wrappers: self.server_packets = Queue(PROXY_QUEUE_SIZE) self.client_packets = Queue(PROXY_QUEUE_SIZE) self.client_protocol = Protocol(self, self.client_conn, self.process_client_packet, self.get_client_packet) self.client_protocol.restore_state(self.client_state) self.server_protocol = Protocol(self, self.server_conn, self.process_server_packet, self.get_server_packet) #server connection tweaks: self.server_protocol.large_packets.append("input-devices") self.server_protocol.large_packets.append("draw") self.server_protocol.large_packets.append("window-icon") self.server_protocol.large_packets.append("keymap-changed") self.server_protocol.large_packets.append("server-settings") if self.caps.boolget("file-transfer"): self.client_protocol.large_packets.append("send-file") self.client_protocol.large_packets.append("send-file-chunk") self.server_protocol.large_packets.append("send-file") self.server_protocol.large_packets.append("send-file-chunk") self.server_protocol.set_compression_level(self.session_options.get("compression_level", 0)) self.server_protocol.enable_default_encoder() self.lost_windows = set() self.encode_queue = Queue() self.encode_thread = start_thread(self.encode_loop, "encode") log("starting network threads") self.server_protocol.start() self.client_protocol.start() self.send_hello() self.timeout_add(VIDEO_TIMEOUT*1000, self.timeout_video_encoders) try: self.run_queue() except KeyboardInterrupt as e: self.stop(str(e)) finally: log("ProxyProcess.run() ending %s", os.getpid())
def run(self): log("ProxyProcess.run() pid=%s, uid=%s, gid=%s", os.getpid(), getuid(), getgid()) self.setproctitle("Xpra Proxy Instance for %s" % self.server_conn) if POSIX and (os.getuid() != self.uid or os.getgid() != self.gid): #do we need a valid XDG_RUNTIME_DIR for the socket-dir? username = get_username_for_uid(self.uid) socket_dir = osexpand(self.socket_dir, username, self.uid, self.gid) if not os.path.exists(socket_dir): log( "the socket directory '%s' does not exist, checking for $XDG_RUNTIME_DIR path", socket_dir) for prefix in ("/run/user/", "/var/run/user/"): if socket_dir.startswith(prefix): from xpra.scripts.server import create_runtime_dir xrd = os.path.join(prefix, str(self.uid)) #ie: /run/user/99 log("creating XDG_RUNTIME_DIR=%s for uid=%i, gid=%i", xrd, self.uid, self.gid) create_runtime_dir(xrd, self.uid, self.gid) break #change uid or gid: setuidgid(self.uid, self.gid) if self.env_options: #TODO: whitelist env update? os.environ.update(self.env_options) self.video_init() log.info("new proxy instance started") log.info(" for client %s", self.client_conn) log.info(" and server %s", self.server_conn) signal.signal(signal.SIGTERM, self.signal_quit) signal.signal(signal.SIGINT, self.signal_quit) log("registered signal handler %s", self.signal_quit) start_thread(self.server_message_queue, "server message queue") if not self.create_control_socket(): #TODO: should send a message to the client return self.control_socket_thread = start_thread(self.control_socket_loop, "control") self.main_queue = Queue() #setup protocol wrappers: self.server_packets = Queue(PROXY_QUEUE_SIZE) self.client_packets = Queue(PROXY_QUEUE_SIZE) self.client_protocol = Protocol(self, self.client_conn, self.process_client_packet, self.get_client_packet) self.client_protocol.restore_state(self.client_state) self.server_protocol = Protocol(self, self.server_conn, self.process_server_packet, self.get_server_packet) #server connection tweaks: for x in (b"input-devices", b"draw", b"window-icon", b"keymap-changed", b"server-settings"): self.server_protocol.large_packets.append(x) if self.caps.boolget("file-transfer"): for x in (b"send-file", b"send-file-chunk"): self.server_protocol.large_packets.append(x) self.client_protocol.large_packets.append(x) self.server_protocol.set_compression_level( self.session_options.get("compression_level", 0)) self.server_protocol.enable_default_encoder() self.lost_windows = set() self.encode_queue = Queue() self.encode_thread = start_thread(self.encode_loop, "encode") log("starting network threads") self.server_protocol.start() self.client_protocol.start() self.send_hello() self.timeout_add(VIDEO_TIMEOUT * 1000, self.timeout_video_encoders) try: self.run_queue() except KeyboardInterrupt as e: self.stop(str(e)) finally: log("ProxyProcess.run() ending %s", os.getpid())