#include "mgr/Registration.h"
#include "util.h"
#include "wordlist.h"
+#include "base/InstanceId.h"
#if HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
char name[NS_MAXDNAME + 1];
char orig[NS_MAXDNAME + 1];
size_t sz;
- unsigned short id;
+ unsigned short msg_id; /// random query ID sent to server; changes with every query sent
+ InstanceId<idns_query> xact_id; /// identifies our "transaction", stays constant when query is retried
+
int nsends;
int need_vc;
rfc1035_rr *answers;
} initial_AAAA;
};
+InstanceIdDefinitions(idns_query, "dns");
struct _nsvc {
int ns;
static EVH idnsCheckQueue;
static void idnsTickleQueue(void);
static void idnsRcodeCount(int, int);
+static unsigned short idnsQueryID(void);
static void
idnsAddNameserver(const char *buf)
for (n = lru_list.head; n; n = n->next) {
q = (idns_query *)n->data;
storeAppendPrintf(sentry, "%#06x %4d %5d %10.3f %9.3f\n",
- (int) q->id, (int) q->sz, q->nsends,
+ (int) q->msg_id, (int) q->sz, q->nsends,
tvSubDsec(q->start_t, current_time),
tvSubDsec(q->sent_t, current_time));
}
int x = -1, y = -1;
int ns;
+ q->start_t = current_time;
+ q->msg_id = idnsQueryID();
+ rfc1035SetQueryID(q->buf, q->msg_id);
+
do {
ns = q->nsends % nns;
for (n = lru_list.tail; n; n = n->prev) {
q = (idns_query*)n->data;
- if (q->id == id)
+ if (q->msg_id == id)
return q;
}
return;
}
- debugs(78, 3, "idnsGrokReply: ID 0x" << std::hex << message->id << ", " << std::dec << n << " answers");
+ debugs(78, 3, "idnsGrokReply: QID 0x" << std::hex << message->id << ", " << std::dec << n << " answers");
q = idnsFindQuery(message->id);
q->need_vc = 1;
q->nsends--;
idnsSendQuery(q);
- }
+ } else {
+ // Strange: A TCP DNS response with the truncation bit (TC) set.
+ // Return an error and cleanup; no point in trying TCP again.
+ debugs(78, 3, HERE << "TCP DNS response");
+ idnsCallback(q, NULL, 0, "Truncated TCP DNS response");
+ cbdataFree(q);
+ }
return;
}
*/
debugs(78, 3, "idnsGrokReply: Query result: SERV_FAIL");
rfc1035MessageDestroy(&message);
- q->start_t = current_time;
- q->id = idnsQueryID();
- rfc1035SetQueryID(q->buf, q->id);
idnsSendQuery(q);
return;
}
idnsDropMessage(message, q);
- q->start_t = current_time;
- q->id = idnsQueryID();
- rfc1035SetQueryID(q->buf, q->id);
if (Ip::EnableIpv6 && q->query.qtype == RFC1035_TYPE_AAAA) {
debugs(78, 3, "idnsGrokReply: Trying AAAA Query for " << q->name);
- q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query, Config.dns.packet_max);
+ q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), 0, &q->query, Config.dns.packet_max);
} else {
debugs(78, 3, "idnsGrokReply: Trying A Query for " << q->name);
// see EDNS notes at top of file why this sends 0
- q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query, 0);
+ q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), 0, &q->query, 0);
}
idnsCacheQuery(q);
idnsSendQuery(q);
// reset the query as an A query
q->nsends = 0;
- q->start_t = current_time;
- q->id = idnsQueryID();
- rfc1035SetQueryID(q->buf, q->id);
// see EDNS notes at top of file why this sends 0
- q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query, 0);
+ q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), 0, &q->query, 0);
q->need_A = false;
idnsCacheQuery(q);
idnsSendQuery(q);
continue;
}
- debugs(78, 3, "idnsCheckQueue: ID 0x" << std::hex << std::setfill('0') << std::setw(4) << q->id << "timeout" );
+ debugs(78, 3, "idnsCheckQueue: ID " << q->xact_id <<
+ " QID 0x" << std::hex << std::setfill('0') <<
+ std::setw(4) << q->msg_id << ": timeout" );
dlinkDelete(&q->lru, &lru_list);
if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) {
idnsSendQuery(q);
} else {
- debugs(78, 2, "idnsCheckQueue: ID " << std::hex << q->id <<
- ": giving up after " << std::dec << q->nsends << " tries and " <<
+ debugs(78, 2, "idnsCheckQueue: ID " << q->xact_id <<
+ " QID 0x" << std::hex << q->msg_id <<
+ " : giving up after " << std::dec << q->nsends << " tries and " <<
std::setw(5)<< std::setprecision(2) << tvSubDsec(q->start_t, current_time) << " seconds");
if (q->rcode != 0)
return 0;
q = cbdataAlloc(idns_query);
+ // idns_query is POD so no constructors are called after allocation
+ q->xact_id.change();
q->callback = callback;
return;
q = cbdataAlloc(idns_query);
-
- q->id = idnsQueryID();
+ // idns_query is POD so no constructors are called after allocation
+ q->xact_id.change();
for (i = 0; i < strlen(name); i++)
if (name[i] == '.')
}
if (Ip::EnableIpv6) {
- q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query, Config.dns.packet_max);
+ q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), 0, &q->query, Config.dns.packet_max);
q->need_A = true;
} else {
// see EDNS notes at top of file why this sends 0
- q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query, 0);
+ q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), 0, &q->query, 0);
q->need_A = false;
}
}
debugs(78, 3, "idnsALookup: buf is " << q->sz << " bytes for " << q->name <<
- ", id = 0x" << std::hex << q->id);
+ ", id = 0x" << std::hex << q->msg_id);
q->callback = callback;
q->callback_data = cbdataReference(data);
- q->start_t = current_time;
-
idnsCacheQuery(q);
idnsSendQuery(q);
q = cbdataAlloc(idns_query);
- q->id = idnsQueryID();
+ // idns_query is POD so no constructors are called after allocation
+ q->xact_id.change();
if (Ip::EnableIpv6 && addr.IsIPv6()) {
struct in6_addr addr6;
addr.GetInAddr(addr6);
- q->sz = rfc3596BuildPTRQuery6(addr6, q->buf, sizeof(q->buf), q->id, &q->query, Config.dns.packet_max);
+ q->sz = rfc3596BuildPTRQuery6(addr6, q->buf, sizeof(q->buf), 0, &q->query, Config.dns.packet_max);
} else {
struct in_addr addr4;
addr.GetInAddr(addr4);
// see EDNS notes at top of file why this sends 0
- q->sz = rfc3596BuildPTRQuery4(addr4, q->buf, sizeof(q->buf), q->id, &q->query, 0);
+ q->sz = rfc3596BuildPTRQuery4(addr4, q->buf, sizeof(q->buf), 0, &q->query, 0);
}
/* PTR does not do inbound A/AAAA */
}
debugs(78, 3, "idnsPTRLookup: buf is " << q->sz << " bytes for " << ip <<
- ", id = 0x" << std::hex << q->id);
+ ", id = 0x" << std::hex << q->msg_id);
q->callback = callback;
q->callback_data = cbdataReference(data);
- q->start_t = current_time;
-
idnsCacheQuery(q);
idnsSendQuery(q);