'Negotiates a connection through a SOCKS4 server.'

def _negotiate_SOCKS4(self, dest_addr, dest_port):

    (proxy_type, addr, port, rdns, username, password) = self.proxy
    remote_resolve = False
    try:
        addr_bytes = socket.inet_aton(dest_addr)
    except socket.error:
        if rdns:
            addr_bytes = '\x00\x00\x00\x01'
            remote_resolve = True
        else:
            addr_bytes = socket.inet_aton(socket.gethostbyname(dest_addr))
    req = (struct.pack('>BBH', 4, 1, dest_port) + addr_bytes)
    if username:
        req += username
    req += '\x00'
    if remote_resolve:
        req += (dest_addr.encode() + '\x00')
    self.sendall(req)
    resp = self._recvall(8)
    if (resp[0:1] != '\x00'):
        raise GeneralProxyError('SOCKS4    proxy    server    sent    invalid    data')
    status = ord(resp[1:2])
    if (status != 90):
        error = SOCKS4_ERRORS.get(status, 'Unknown    error')
        raise SOCKS4Error('{:#04x}:    {}'.format(status, error))
    self.proxy_sockname = (socket.inet_ntoa(resp[4:]), struct.unpack('>H', resp[2:4])[0])
    if remote_resolve:
        self.proxy_peername = (socket.inet_ntoa(addr_bytes), dest_port)
    else:
        self.proxy_peername = (dest_addr, dest_port)
