'Build a L{dns.Query} for the given parameters and dispatch it via UDP.
If this query is already outstanding, it will not be re-issued.
Instead, when the outstanding query receives a response, that response
will be re-used for this query as well.
@type name: C{str}
@type type: C{int}
@type cls: C{int}
@return: A L{Deferred} which fires with a three-tuple giving the
answer, authority, and additional sections of the response or with
a L{Failure} if the response code is anything other than C{dns.OK}.'

def _lookup(self, name, cls, type, timeout):

    key = (name, type, cls)
    waiting = self._waiting.get(key)
    if (waiting is None):
        self._waiting[key] = []
        d = self.queryUDP([dns.Query(name, type, cls)], timeout)
        def cbResult(result):
            for d in self._waiting.pop(key):
                d.callback(result)
            return result
        d.addCallback(self.filterAnswers)
        d.addBoth(cbResult)
    else:
        d = defer.Deferred()
        waiting.append(d)
    return d
