Exemplo n.º 1
0
    def wrap(self):
        ip, port = utils.get_ip_port(self.ip_str)
        if isinstance(ip, str):
            ip = utils.to_bytes(ip)

        ip_port = (utils.to_str(ip), port)

        if sys.version_info[0] == 3:
            try:
                self._sock.connect((ip, port))
            except Exception as e:
                raise socket.error('conn %s fail, sni:%s, e:%r' %
                                   (self.ip_str, self.sni, e))

            self._connection = self._context.wrap_socket(
                self._sock,
                server_hostname=self.sni,
                do_handshake_on_connect=False)
        else:
            self._connection = OpenSSL.SSL.Connection(self._context,
                                                      self._sock)
            self._connection.set_connect_state()
            if self.sni:
                try:
                    self._connection.set_tlsext_host_name(self.sni)
                except:
                    pass
            self._connection.connect(ip_port)
Exemplo n.º 2
0
    def wrap(self):
        ip, port = utils.get_ip_port(self.ip_str)
        if isinstance(ip, str):
            ip = utils.to_bytes(ip)

        try:
            self._sock.connect((ip, port))
        except Exception as e:
            raise socket.error('conn %s fail, sni:%s, e:%r' %
                               (self.ip_str, self.sni, e))

        self._connection = self._context.wrap_socket(
            self._sock,
            server_hostname=self.sni,
            do_handshake_on_connect=False)
Exemplo n.º 3
0
    def connect_ssl(self, ip_str, sni=None, close_cb=None):
        if sni:
            host = sni
        else:
            sni, host = self.host_manager.get_sni_host(ip_str)

        host = str(host)
        if isinstance(sni, str):
            sni = bytes(sni, encoding='ascii')

        if self.debug:
            self.logger.debug("sni:%s", sni)

        ip, port = utils.get_ip_port(ip_str)
        if isinstance(ip, str):
            ip = bytes(ip, encoding='ascii')

        ip_port = (utils.to_str(ip), port)

        if int(self.config.PROXY_ENABLE):
            sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
        else:
            sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
        # resize socket recv buffer ->64 above to improve browser releated application performance
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.config.connect_receive_buffer)
        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
        sock.settimeout(self.timeout)

        time_begin = time.time()
        try:
            sock.connect(ip_port)
        except Exception as e:
            raise socket.error('conn fail, sni:%s, top:%s e:%r' % (sni, host, e))

        ssl_sock = openssl_wrap.SSLConnection(self.openssl_context.context, sock,
                                              ip_str=ip_str,
                                              server_hostname=sni,
                                              on_close=close_cb)

        ssl_sock.sni = utils.to_str(sni)

        time_connected = time.time()

        try:
            ssl_sock.do_handshake()
        except Exception as e:
            raise socket.error('tls handshake fail, sni:%s, top:%s e:%r' % (sni, host, e))

        if self.connect_force_http1:
            ssl_sock.h2 = False
        elif self.connect_force_http2:
            ssl_sock.h2 = True
        else:
            try:
                if ssl_sock.selected_alpn_protocol() == "h2" or ssl_sock.selected_npn_protocol() == "h2":
                    ssl_sock.h2 = True
                else:
                    ssl_sock.h2 = False
            except Exception as e:
                self.logger.exception("alpn:%r", e)
                ssl_sock.h2 = False

        time_handshaked = time.time()

        # self.check_cert(ssl_sock)

        connect_time = int((time_connected - time_begin) * 1000)
        handshake_time = int((time_handshaked - time_begin) * 1000)
        ssl_sock.fd = sock.fileno()
        ssl_sock.create_time = time_begin
        ssl_sock.connect_time = connect_time
        ssl_sock.handshake_time = handshake_time
        ssl_sock.last_use_time = time_handshaked
        ssl_sock.host = host
        ssl_sock.received_size = 0

        return ssl_sock
Exemplo n.º 4
0
    def connect_ssl(self, ip_str, sni="", close_cb=None):
        info = self.host_manager.get_info(ip_str)
        sni = str(info["sni"])
        host = sni
        ip, port = utils.get_ip_port(ip_str)

        if int(self.config.PROXY_ENABLE):
            sock = socks.socksocket(socket.AF_INET if ':' not in
                                    ip else socket.AF_INET6)
        else:
            sock = socket.socket(socket.AF_INET if ':' not in
                                 ip else socket.AF_INET6)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                        struct.pack('ii', 1, 0))
        # resize socket recv buffer ->64 above to improve browser releated application performance
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF,
                        self.config.connect_receive_buffer)
        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
        sock.settimeout(self.timeout)

        if info["client_ca"]:
            self.openssl_context.context.use_certificate_file(
                info["client_ca_fn"])
            self.openssl_context.context.use_privatekey_file(
                info["client_key_fn"])
            #self.openssl_context.context.load_cert_chain(certfile=info["client_ca"], keyfile=info["client_key"])

        ssl_sock = front_base.openssl_wrap.SSLConnection(
            self.openssl_context.context, sock, ip_str, on_close=close_cb)
        ssl_sock.set_connect_state()

        if sni:
            if self.debug:
                self.logger.debug("sni:%s", sni)

            try:
                ssl_sock.set_tlsext_host_name(sni)
            except:
                pass

        time_begin = time.time()
        ip_port = (ip, port)

        try:
            ssl_sock.connect(ip_port)
            time_connected = time.time()
            ssl_sock.do_handshake()
        except Exception as e:
            raise socket.error('conn fail, sni:%s, top:%s e:%r' %
                               (sni, host, e))

        if self.connect_force_http1:
            ssl_sock.h2 = False
        elif self.connect_force_http2:
            ssl_sock.h2 = True
        else:
            try:
                h2 = ssl_sock.get_alpn_proto_negotiated()
                if h2 == "h2":
                    ssl_sock.h2 = True
                else:
                    ssl_sock.h2 = False
            except Exception as e:
                # xlog.exception("alpn:%r", e)
                if hasattr(ssl_sock._connection,
                           "protos") and ssl_sock._connection.protos == "h2":
                    ssl_sock.h2 = True
                else:
                    ssl_sock.h2 = False

        time_handshaked = time.time()

        ssl_sock.sni = sni
        self.check_cert(ssl_sock)

        connect_time = int((time_connected - time_begin) * 1000)
        handshake_time = int((time_handshaked - time_begin) * 1000)
        # sometimes, we want to use raw tcp socket directly(select/epoll), so setattr it to ssl socket.
        ssl_sock.ip_str = ip_str
        ssl_sock._sock = sock
        ssl_sock.fd = sock.fileno()
        ssl_sock.create_time = time_begin
        ssl_sock.connect_time = connect_time
        ssl_sock.handshake_time = handshake_time
        ssl_sock.last_use_time = time_handshaked
        ssl_sock.host = host
        ssl_sock.received_size = 0

        return ssl_sock