Connects to the specified destination through a proxy.
        Uses the same API as socket's connect().
        To select the proxy server, use set_proxy().

        dest_pair - 2-tuple of (IP/hostname, port).

def connect(self, dest_pair):
        """
        Connects to the specified destination through a proxy.
        Uses the same API as socket's connect().
        To select the proxy server, use set_proxy().

        dest_pair - 2-tuple of (IP/hostname, port).
        """
        if len(dest_pair) != 2 or dest_pair[0].startswith("["):
            # Probably IPv6, not supported -- raise an error, and hope
            # Happy Eyeballs (RFC6555) makes sure at least the IPv4
            # connection works...
            raise socket.error("PySocks doesn't support IPv6: %s" % str(dest_pair))

        dest_addr, dest_port = dest_pair

        if self.type == socket.SOCK_DGRAM:
            if not self._proxyconn:
                self.bind(("", 0))
            dest_addr = socket.gethostbyname(dest_addr)

            # If the host address is INADDR_ANY or similar, reset the peer
            # address so that packets are received from any peer
            if dest_addr == "0.0.0.0" and not dest_port:
                self.proxy_peername = None
            else:
                self.proxy_peername = (dest_addr, dest_port)
            return

        proxy_type, proxy_addr, proxy_port, rdns, username, password = self.proxy

        # Do a minimal input check first
        if (not isinstance(dest_pair, (list, tuple))
                or len(dest_pair) != 2
                or not dest_addr
                or not isinstance(dest_port, int)):
            raise GeneralProxyError("Invalid destination-connection (host, port) pair")


        # We set the timeout here so that we don't hang in connection or during
        # negotiation.
        super(socksocket, self).settimeout(self._timeout)

        if proxy_type is None:
            # Treat like regular socket object
            self.proxy_peername = dest_pair
            super(socksocket, self).settimeout(self._timeout)
            super(socksocket, self).connect((dest_addr, dest_port))
            return

        proxy_addr = self._proxy_addr()

        try:
            # Initial connection to proxy server.
            super(socksocket, self).connect(proxy_addr)

        except socket.error as error:
            # Error while connecting to proxy
            self.close()
            proxy_addr, proxy_port = proxy_addr
            proxy_server = "{0}:{1}".format(proxy_addr, proxy_port)
            printable_type = PRINTABLE_PROXY_TYPES[proxy_type]

            msg = "Error connecting to {0} proxy {1}".format(printable_type,
                                                           proxy_server)
            log.debug("%s due to: %s", msg, error)
            raise ProxyConnectionError(msg, error)

        else:
            # Connected to proxy server, now negotiate
            try:
                # Calls negotiate_{SOCKS4, SOCKS5, HTTP}
                negotiate = self._proxy_negotiators[proxy_type]
                negotiate(self, dest_addr, dest_port)
            except socket.error as error:
                # Wrap socket errors
                self.close()
                raise GeneralProxyError("Socket error", error)
            except ProxyError:
                # Protocol error while negotiating with proxy
                self.close()
                raise