Esempio n. 1
0
    def wait_for_connection(self, timeout=None):
        """
        Wait until we've established a connection with the server.

        :param float timeout: how long to wait, in seconds
        """
        if timeout is not None:
            wait_time = timeout / 10.0
        else:
            wait_time = None
        with self.__connect_wait_condition:
            while self.running and not self.is_connected() and not self.connection_error:
                self.__connect_wait_condition.wait(wait_time)
        if not self.running or not self.is_connected():
            raise exception.ConnectFailedException()
Esempio n. 2
0
    def attempt_connection(self):
        """
        Try connecting to the (host, port) tuples specified at construction time.
        """
        self.connection_error = False
        sleep_exp = 1
        connect_count = 0

        while self.running and self.socket is None and connect_count < self.__reconnect_attempts_max:
            for host_and_port in self.__hosts_and_ports:
                try:
                    log.info("Attempting connection to websocket %s", host_and_port)
                    self.socket = websocket.WebSocket()
                    proto, host, port, path = host_and_port[3], host_and_port[0], host_and_port[1], host_and_port[2]
                    if port:
                        ws_uri = '{}://{}:{}/{}'.format(proto, host, port, path)
                    else:
                        ws_uri = '{}://{}/{}'.format(proto, host, path)

                    self.socket.connect(ws_uri,
                                        timeout=self.__timeout)

                    self.current_host_and_port = host_and_port
                    log.info("Established connection to %s", ws_uri)
                    break
                except WebSocketException:
                    self.socket = None
                    connect_count += 1
                    log.warning("Could not connect to host %s, port %s", host_and_port[0], host_and_port[1], exc_info=1)

            if self.socket is None:
                sleep_duration = (min(self.__reconnect_sleep_max,
                                      ((self.__reconnect_sleep_initial / (1.0 + self.__reconnect_sleep_increase))
                                       * math.pow(1.0 + self.__reconnect_sleep_increase, sleep_exp)))
                                  * (1.0 + random.random() * self.__reconnect_sleep_jitter))
                sleep_end = monotonic() + sleep_duration
                log.debug("Sleeping for %.1f seconds before attempting reconnect", sleep_duration)
                while self.running and monotonic() < sleep_end:
                    time.sleep(0.2)

                if sleep_duration < self.__reconnect_sleep_max:
                    sleep_exp += 1

        if not self.socket:
            raise exception.ConnectFailedException()
Esempio n. 3
0
    def attempt_connection(self):
        """
        Try connecting to the (host, port) tuples specified at construction time.
        """
        self.connection_error = False
        sleep_exp = 1
        connect_count = 0

        while self.running and self.socket is None and connect_count < self.__reconnect_attempts_max:
            for host_and_port in self.__host_and_ports:
                try:
                    log.info("Attempting connection to host %s, port %s",
                             host_and_port[0], host_and_port[1])
                    self.socket = get_socket(host_and_port[0],
                                             host_and_port[1], self.__timeout)
                    self.__enable_keepalive()
                    need_ssl = self.__need_ssl(host_and_port)

                    if need_ssl:  # wrap socket
                        ssl_params = self.get_ssl(host_and_port)
                        if ssl_params['ca_certs']:
                            cert_validation = ssl.CERT_REQUIRED
                        else:
                            cert_validation = ssl.CERT_NONE
                        try:
                            tls_context = ssl.create_default_context(
                                cafile=ssl_params['ca_certs'])
                        except AttributeError:
                            tls_context = None
                        if tls_context:
                            # Wrap the socket for TLS
                            certfile = ssl_params['cert_file']
                            keyfile = ssl_params['key_file']
                            password = ssl_params.get('password')
                            if certfile and not keyfile:
                                keyfile = certfile
                            if certfile:
                                tls_context.load_cert_chain(
                                    certfile, keyfile, password)
                            if cert_validation is None or cert_validation == ssl.CERT_NONE:
                                tls_context.check_hostname = False
                            tls_context.verify_mode = cert_validation
                            self.socket = tls_context.wrap_socket(
                                self.socket, server_hostname=host_and_port[0])
                        else:
                            # Old-style wrap_socket where we don't have a modern SSLContext (so no SNI)
                            self.socket = ssl.wrap_socket(
                                self.socket,
                                keyfile=ssl_params['key_file'],
                                certfile=ssl_params['cert_file'],
                                cert_reqs=cert_validation,
                                ca_certs=ssl_params['ca_certs'],
                                ssl_version=ssl_params['ssl_version'])

                    self.socket.settimeout(self.__timeout)

                    if self.blocking is not None:
                        self.socket.setblocking(self.blocking)

                    #
                    # Validate server cert
                    #
                    if need_ssl and ssl_params['cert_validator']:
                        cert = self.socket.getpeercert()
                        (ok, errmsg) = ssl_params['cert_validator'](
                            cert, host_and_port[0])
                        if not ok:
                            raise SSLError(
                                "Server certificate validation failed: %s",
                                errmsg)

                    self.current_host_and_port = host_and_port
                    log.info("Established connection to host %s, port %s",
                             host_and_port[0], host_and_port[1])
                    break
                except socket.error:
                    self.socket = None
                    connect_count += 1
                    log.warning("Could not connect to host %s, port %s",
                                host_and_port[0],
                                host_and_port[1],
                                exc_info=1)

            if self.socket is None:
                sleep_duration = (min(self.__reconnect_sleep_max, (
                    (self.__reconnect_sleep_initial /
                     (1.0 + self.__reconnect_sleep_increase)) *
                    math.pow(1.0 + self.__reconnect_sleep_increase, sleep_exp)
                )) * (1.0 + random.random() * self.__reconnect_sleep_jitter))
                sleep_end = monotonic() + sleep_duration
                log.debug(
                    "Sleeping for %.1f seconds before attempting reconnect",
                    sleep_duration)
                while self.running and monotonic() < sleep_end:
                    time.sleep(0.2)

                if sleep_duration < self.__reconnect_sleep_max:
                    sleep_exp += 1

        if not self.socket:
            raise exception.ConnectFailedException()
Esempio n. 4
0
    def attempt_connection(self):
        """
        Try connecting to the (host, port) tuples specified at construction time.
        """
        self.connection_error = False
        sleep_exp = 1
        connect_count = 0

        while self.running and self.socket is None and connect_count < self.__reconnect_attempts_max:
            for host_and_port in self.__host_and_ports:
                try:
                    log.info("Attempting connection to host %s, port %s",
                             host_and_port[0], host_and_port[1])
                    self.socket = get_socket(host_and_port[0],
                                             host_and_port[1], self.__timeout)
                    self.__enable_keepalive()
                    need_ssl = self.__need_ssl(host_and_port)

                    if need_ssl:  # wrap socket
                        ssl_params = self.get_ssl(host_and_port)
                        if ssl_params['ca_certs']:
                            cert_validation = ssl.CERT_REQUIRED
                        else:
                            cert_validation = ssl.CERT_NONE
                        self.socket = ssl.wrap_socket(
                            self.socket,
                            keyfile=ssl_params['key_file'],
                            certfile=ssl_params['cert_file'],
                            cert_reqs=cert_validation,
                            ca_certs=ssl_params['ca_certs'],
                            ssl_version=ssl_params['ssl_version'])

                    self.socket.settimeout(self.__timeout)

                    if self.blocking is not None:
                        self.socket.setblocking(self.blocking)

                    #
                    # Validate server cert
                    #
                    if need_ssl and ssl_params['cert_validator']:
                        cert = self.socket.getpeercert()
                        (ok, errmsg) = ssl_params['cert_validator'](
                            cert, host_and_port[0])
                        if not ok:
                            raise SSLError(
                                "Server certificate validation failed: %s",
                                errmsg)

                    self.current_host_and_port = host_and_port
                    log.info("Established connection to host %s, port %s",
                             host_and_port[0], host_and_port[1])
                    break
                except socket.error:
                    self.socket = None
                    connect_count += 1
                    log.info("Could not connect to host %s, port %s",
                             host_and_port[0],
                             host_and_port[1],
                             exc_info=1)

            if self.socket is None:
                sleep_duration = (min(self.__reconnect_sleep_max, (
                    (self.__reconnect_sleep_initial /
                     (1.0 + self.__reconnect_sleep_increase)) *
                    math.pow(1.0 + self.__reconnect_sleep_increase, sleep_exp)
                )) * (1.0 + random.random() * self.__reconnect_sleep_jitter))
                sleep_end = monotonic() + sleep_duration
                log.debug(
                    "Sleeping for %.1f seconds before attempting reconnect",
                    sleep_duration)
                while self.running and monotonic() < sleep_end:
                    time.sleep(0.2)

                if sleep_duration < self.__reconnect_sleep_max:
                    sleep_exp += 1

        if not self.socket:
            raise exception.ConnectFailedException()