QDnsLookup/Unix large replies: manually handle VC [3/3]
The current code was inefficient when replies exceeded the initial buffer size because the res_nsend() function switched to VC to get the full reply, but that wouldn't fit our buffer before we enlarged it. This commit tells res_nsend() to only use UDP or only use TCP, avoiding the two unnecessary transactions in the lookup. Since we don't get that second TCP reply now that would tell us the size of the reply, we must allocate the largest possible buffer for a DNS reply. Change-Id: I3e3bfef633af4130a03afffd175e73d2e9fa9bf1 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
df07d98243
commit
5ecdce0c35
@ -179,10 +179,25 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
|
||||
return responseLength;
|
||||
};
|
||||
|
||||
// strictly use UDP, we'll deal with truncated replies ourselves
|
||||
state.options |= RES_IGNTC;
|
||||
int responseLength = attemptToSend();
|
||||
if (responseLength > buffer.size()) {
|
||||
// increase our buffer size
|
||||
buffer.resize(responseLength);
|
||||
if (responseLength < 0)
|
||||
return;
|
||||
|
||||
// check if we need to use the virtual circuit (TCP)
|
||||
auto header = reinterpret_cast<HEADER *>(buffer.data());
|
||||
if (header->rcode == NOERROR && header->tc) {
|
||||
// yes, increase our buffer size
|
||||
buffer.resize(std::numeric_limits<quint16>::max());
|
||||
header = reinterpret_cast<HEADER *>(buffer.data());
|
||||
|
||||
// remove the EDNS record in the query
|
||||
reinterpret_cast<HEADER *>(qbuffer.data())->arcount = 0;
|
||||
queryLength -= sizeof(Edns0Record);
|
||||
|
||||
// send using the virtual circuit
|
||||
state.options |= RES_USEVC;
|
||||
responseLength = attemptToSend();
|
||||
if (Q_UNLIKELY(responseLength > buffer.size())) {
|
||||
// Ok, we give up.
|
||||
@ -198,7 +213,6 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
|
||||
return reply->makeInvalidReplyError();
|
||||
|
||||
// Parse the reply.
|
||||
auto header = reinterpret_cast<HEADER *>(buffer.data());
|
||||
if (header->rcode)
|
||||
return reply->makeDnsRcodeError(header->rcode);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user