'__negotiatesocks5(self,destaddr,destport)
Negotiates a connection through a SOCKS5 server.'

def __negotiatesocks5(self, destaddr, destport):

    if ((self.__proxy[4] != None) and (self.__proxy[5] != None)):
        self.sendall('\x05\x02\x00\x02')
    else:
        self.sendall('\x05\x01\x00')
    chosenauth = self.__recvall(2)
    if (chosenauth[0] != '\x05'):
        self.close()
        raise GeneralProxyError((1, _generalerrors[1]))
    if (chosenauth[1] == '\x00'):
        pass
    elif (chosenauth[1] == '\x02'):
        self.sendall((((('\x01' + chr(len(self.__proxy[4]))) + self.__proxy[4]) + chr(len(self.__proxy[5]))) + self.__proxy[5]))
        authstat = self.__recvall(2)
        if (authstat[0] != '\x01'):
            self.close()
            raise GeneralProxyError((1, _generalerrors[1]))
        if (authstat[1] != '\x00'):
            self.close()
            raise Socks5AuthError((3, _socks5autherrors[3]))
    else:
        self.close()
        if (chosenauth[1] == '\xff'):
            raise Socks5AuthError((2, _socks5autherrors[2]))
        else:
            raise GeneralProxyError((1, _generalerrors[1]))
    req = '\x05\x01\x00'
    try:
        ipaddr = socket.inet_aton(destaddr)
        req = ((req + '\x01') + ipaddr)
    except socket.error:
        if (self.__proxy[3] == True):
            ipaddr = None
            req = (((req + '\x03') + chr(len(destaddr))) + destaddr)
        else:
            ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
            req = ((req + '\x01') + ipaddr)
    req = (req + self.__decode(struct.pack('>H', destport)))
    self.sendall(req)
    resp = self.__recvall(4)
    if (resp[0] != '\x05'):
        self.close()
        raise GeneralProxyError((1, _generalerrors[1]))
    elif (resp[1] != '\x00'):
        self.close()
        if (ord(resp[1]) <= 8):
            raise Socks5Error((ord(resp[1]), _socks5errors[ord(resp[1])]))
        else:
            raise Socks5Error((9, _socks5errors[9]))
    elif (resp[3] == '\x01'):
        boundaddr = self.__recvall(4)
    elif (resp[3] == '\x03'):
        resp = (resp + self.recv(1))
        boundaddr = self.__recvall(ord(resp[4]))
    else:
        self.close()
        raise GeneralProxyError((1, _generalerrors[1]))
    boundport = struct.unpack('>H', bytes(self.__recvall(2), 'utf8'))[0]
    self.__proxysockname = (boundaddr, boundport)
    if (ipaddr != None):
        self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
    else:
        self.__proxypeername = (destaddr, destport)
