Most basic DNS primitive that looks up a domain, waits for a
        second response, then returns all of the results

        :param domain: the domain to lookup
        :param nameserver: the nameserver to use
        :param log_prefix:
        :return:

        Note: if you want to lookup multiple domains you *should not* use
        this function, you should use lookup_domains because this does
        blocking IO to wait for the second response

def lookup_domain(self, domain, nameserver=None, log_prefix=''):
        """Most basic DNS primitive that looks up a domain, waits for a
        second response, then returns all of the results

        :param domain: the domain to lookup
        :param nameserver: the nameserver to use
        :param log_prefix:
        :return:

        Note: if you want to lookup multiple domains you *should not* use
        this function, you should use lookup_domains because this does
        blocking IO to wait for the second response

        """
        if domain not in self.results:
            self.results[domain] = []
        # get the resolver to use
        if nameserver is None:
            logging.debug("Nameserver not specified, using %s" % self.nameservers[0])
            nameserver = self.nameservers[0]
        results = {'domain': domain, 'nameserver': nameserver}
        # construct the socket to use
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(self.timeout)
        # set port number and increment index:
        interrupt = False
        with self.port_lock:
            counter = 1
            while True:
                if counter > 100:
                    logging.warning("Stop trying to get an available port")
                    interrupt = True
                    break
                try:
                    sock.bind(('', self.port))
                    break
                except socket.error:
                    logging.debug("Port {} already in use, try next one".format(self.port))
                    self.port += 1
                    counter += 1
            self.port += 1

        if interrupt:
            sock.close()
            results['error'] = 'Failed to run DNS test'
            self.results[domain].append(results)
            return results

        logging.debug("%sQuerying DNS enteries for "
                      "%s (nameserver: %s)." % (log_prefix, domain, nameserver))

        # construct and send the request
        request = dns.message.make_query(domain,
                                         dns.rdatatype.from_text(self.rtype))
        results['request'] = b64encode(request.to_wire())
        sock.sendto(request.to_wire(), (nameserver, 53))

        # read the first response from the socket
        try:
            response = sock.recvfrom(4096)[0]
            results['response1'] = b64encode(response)
            resp = dns.message.from_wire(response)
            results['response1-ips'] = parse_out_ips(resp)

            # first domain name in response should be the same with query
            # domain name
            for entry in resp.answer:
                if domain.lower() != entry.name.to_text().lower()[:-1]:
                    logging.debug("%sWrong domain name %s for %s!"
                                  % (log_prefix, entry.name.to_text().lower()[:-1], domain))
                    results['response1-domain'] = entry.name.to_text().lower()[:-1]
                break
        except socket.timeout:
            # if we didn't get anything, then set the results to nothing
            logging.debug("%sQuerying DNS enteries for "
                          "%s (nameserver: %s) timed out!" % (log_prefix, domain, nameserver))
            sock.close()
            results['response1'] = None
            self.results[domain].append(results)
            return results

        # if we have made it this far, then wait for the next response
        try:
            response2 = sock.recvfrom(4096)[0]
            results['response2'] = b64encode(response2)
            resp2 = dns.message.from_wire(response2)
            results['response2-ips'] = parse_out_ips(resp2)

            # first domain name in response should be the same with query
            # domain name
            for entry in resp2.answer:
                if domain.lower != entry.name.to_text().lower()[:-1]:
                    logging.debug("%sWrong domain name %s for %s!"
                                  % (log_prefix, entry.name.to_text().lower()[:-1], domain))
                    results['response2-domain'] = entry.name.to_text().lower()[:-1]
                break
        except socket.timeout:
            # no second response
            results['response2'] = None

        sock.close()
        self.results[domain].append(results)
        return results