Exemplo n.º 1
0
    def check_duplex_connection(self):
        logging.debug("Remote: checking duplex with '%s'" %
                      self.display_hostname)

        ret = self.stub.CheckDuplexConnection(
            warp_pb2.LookupName(id=self.local_ident,
                                readable_name=util.get_hostname()))

        return ret.response
Exemplo n.º 2
0
    def wait_for_duplex(self):
        logging.debug("Remote: waiting for duplex from '%s'" %
                      self.display_hostname)

        future = self.stub.WaitingForDuplex.future(
            warp_pb2.LookupName(id=self.local_ident,
                                readable_name=util.get_hostname()))

        return future
Exemplo n.º 3
0
    def update_remote_machine_avatar(self):
        logging.debug("Remote RPC: calling GetRemoteMachineAvatar on '%s'" %
                      self.display_hostname)
        iterator = self.stub.GetRemoteMachineAvatar(
            warp_pb2.LookupName(id=self.local_ident,
                                readable_name=util.get_hostname()))
        loader = None
        try:
            for info in iterator:
                if loader == None:
                    loader = util.CairoSurfaceLoader()
                loader.add_bytes(info.avatar_chunk)
        except grpc.RpcError as e:
            logging.debug(
                "Remote RPC: could not fetch remote avatar, using a generic one. (%s, %s)"
                % (e.code(), e.details()))

        self.get_avatar_surface(loader)
Exemplo n.º 4
0
    def update_remote_machine_info(self):
        logging.debug("Remote RPC: calling GetRemoteMachineInfo on '%s'" %
                      self.display_hostname)

        def get_info_finished(future):
            info = future.result()
            self.display_name = info.display_name
            self.user_name = info.user_name
            self.favorite = prefs.get_is_favorite(self.ident)

            valid = GLib.utf8_make_valid(self.display_name, -1)
            self.sort_key = GLib.utf8_collate_key(valid.lower(), -1)

            self.emit_machine_info_changed()
            self.set_remote_status(RemoteStatus.ONLINE)

        future = self.stub.GetRemoteMachineInfo.future(
            warp_pb2.LookupName(id=self.local_ident,
                                readable_name=util.get_hostname()))
        future.add_done_callback(get_info_finished)
Exemplo n.º 5
0
        def run_secure_loop():
            logging.debug(
                "Remote: Starting a new connection loop for %s (%s:%d)" %
                (self.display_hostname, self.ip_address, self.port))

            cert = auth.get_singleton().load_cert(self.hostname,
                                                  self.ip_address)
            creds = grpc.ssl_channel_credentials(cert)

            with grpc.secure_channel("%s:%d" % (self.ip_address, self.port),
                                     creds) as channel:
                future = grpc.channel_ready_future(channel)

                try:
                    future.result(timeout=4)
                    self.stub = warp_pb2_grpc.WarpStub(channel)
                except grpc.FutureTimeoutError:
                    self.set_remote_status(RemoteStatus.UNREACHABLE)
                    future.cancel()

                    if not self.ping_timer.is_set():
                        logging.debug(
                            "Remote: Unable to establish secure connection with %s (%s:%d). Trying again in %ds"
                            % (self.display_hostname, self.ip_address,
                               self.port, CHANNEL_RETRY_WAIT_TIME))
                        self.ping_timer.wait(CHANNEL_RETRY_WAIT_TIME)
                        return True  # run_secure_loop()

                    return False  # run_secure_loop()

                duplex_fail_counter = 0
                one_ping = False  # A successful duplex response lets us finish setting things up.

                while not self.ping_timer.is_set():

                    if self.busy:
                        logging.debug(
                            "Remote Ping: Skipping keepalive ping to %s (%s:%d) (busy)"
                            % (self.display_hostname, self.ip_address,
                               self.port))
                        self.busy = False
                    else:
                        try:
                            # t = GLib.get_monotonic_time()
                            logging.debug("Remote Ping: to   %s (%s:%d)" %
                                          (self.display_hostname,
                                           self.ip_address, self.port))
                            self.stub.Ping(warp_pb2.LookupName(
                                id=self.local_ident,
                                readable_name=util.get_hostname()),
                                           timeout=5)
                            # logging.debug("Latency: %s (%s)"
                            # % (util.precise_format_time_span(GLib.get_monotonic_time() - t), self.display_hostname))
                            if not one_ping:
                                self.set_remote_status(
                                    RemoteStatus.AWAITING_DUPLEX)
                                if self.check_duplex_connection():
                                    logging.debug(
                                        "Remote: Connected to %s (%s:%d)" %
                                        (self.display_hostname,
                                         self.ip_address, self.port))

                                    self.set_remote_status(RemoteStatus.ONLINE)

                                    self.rpc_call(
                                        self.update_remote_machine_info)
                                    self.rpc_call(
                                        self.update_remote_machine_avatar)
                                    one_ping = True
                                else:
                                    duplex_fail_counter += 1
                                    if duplex_fail_counter > DUPLEX_MAX_FAILURES:
                                        logging.debug(
                                            "Remote: CheckDuplexConnection to %s (%s:%d) failed too many times"
                                            % (self.display_hostname,
                                               self.ip_address, self.port))
                                        self.ping_timer.wait(
                                            CHANNEL_RETRY_WAIT_TIME)
                                        return True
                        except grpc.RpcError as e:
                            logging.debug(
                                "Remote: Ping failed, shutting down %s (%s:%d)"
                                % (self.display_hostname, self.ip_address,
                                   self.port))
                            break

                    self.ping_timer.wait(
                        CONNECTED_PING_TIME if self.status ==
                        RemoteStatus.ONLINE else DUPLEX_WAIT_PING_TIME)

                # This is reached by the RpcError break above.  If the remote is still discoverable, start
                # the secure loop over.  This could have happened as a result of a quick disco/reconnect,
                # And we don't notice until it has already come back. In this case, try a new connection.
                if self.has_zc_presence and not self.ping_timer.is_set():
                    return True  # run_secure_loop()

                # The ping timer has been triggered, this is an orderly shutdown.
                return False  # run_secure_loop()
Exemplo n.º 6
0
    def check_duplex_connection(self):
        ret = self.stub.CheckDuplexConnection(
            warp_pb2.LookupName(id=self.local_ident))

        return ret.response