This fixes up the DNS timeout management.
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [email protected]\
# 19a08w1tobnxdhy0
# target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/
# testament_sha1: 12df0be1bcabe9d4ae82e03f1d6e58035baac06c
# timestamp: 2012-03-05 10:44:36 +0100
# source_branch: http://www.squid-cache.org/bzr/squid3/trunk/
# base_revision_id: [email protected]\
# d3ba1y2dk0sobhwa
#
# Begin patch
=== modified file 'src/dns_internal.cc'
--- src/dns_internal.cc 2012-03-02 17:33:04 +0000
+++ src/dns_internal.cc 2012-03-04 22:24:58 +0000
@@ -149,6 +149,7 @@
unsigned short do_searchpath;
rfc1035_message *message;
int ancount;
+ const char *error;
};
InstanceIdDefinitions(idns_query, "dns");
@@ -232,7 +233,7 @@
static void idnsParseWIN32Registry(void);
static void idnsParseWIN32SearchList(const char *);
#endif
-static void idnsCacheQuery(idns_query * q);
+static void idnsStartQuery(idns_query * q, IDNSCB * callback, void *data);
static void idnsSendQuery(idns_query * q);
static IOCB idnsReadVCHeader;
static void idnsDoSendQueryVC(nsvc *vc);
@@ -906,8 +907,6 @@
int x = -1, y = -1;
int ns;
- q->start_t = current_time;
-
do {
ns = q->nsends % nns;
@@ -923,7 +922,7 @@
q->nsends++;
- q->queue_t = q->sent_t = current_time;
+ q->sent_t = current_time;
if (y < 0 && nameservers[ns].S.IsIPv6())
debugs(50, 1, "idnsSendQuery: FD " << DnsSocketB << ": sendto: " << xstrerror());
@@ -999,13 +998,70 @@
}
static void
-idnsCallback(idns_query *q, rfc1035_rr *answers, int n, const char *error)
+idnsCallback(idns_query *q, const char *error)
{
IDNSCB *callback;
void *cbdata;
+ if (error)
+ q->error = error;
+
+ if (q->master)
+ q = q->master;
+
+ idns_query *q2;
+ // If any of our subqueries are still pending then wait for them to complete before continuing
+ for ( q2 = q; q2; q2 = q2->slave) {
+ if (q2->pending) {
+ return;
+ }
+ }
+
+ /* Merge results */
+ rfc1035_message *message = q->message;
+ q->message = NULL;
+ int n = q->ancount;
+ error = q->error;
+
+ while ( (q2 = q->slave) ) {
+ debugs(78, 6, HERE << "Merging DNS results " << q->name << " A has " << n << " RR, AAAA has " << q2->ancount << " RR");
+ q->slave = q2->slave;
+ if ( !q2->error ) {
+ if (n > 0) {
+ // two sets of RR need merging
+ rfc1035_rr *result = (rfc1035_rr*) xmalloc( sizeof(rfc1035_rr)*(n + q2->ancount) );
+ if (Config.dns.v4_first) {
+ memcpy(result, message->answer, (sizeof(rfc1035_rr)*n) );
+ memcpy(result+n, q2->message->answer, (sizeof(rfc1035_rr)*q2->ancount) );
+ } else {
+ memcpy(result, q2->message->answer, (sizeof(rfc1035_rr)*q2->ancount) );
+ memcpy(result+q2->ancount, message->answer, (sizeof(rfc1035_rr)*n) );
+ }
+ n += q2->ancount;
+ // HACK WARNING, the answer rr:s have been copied in-place to
+ // result, do not free them here
+ safe_free(message->answer);
+ safe_free(q2->message->answer);
+ message->answer = result;
+ message->ancount += q2->message->ancount;
+ } else {
+ // first response empty or failed, just use the second
+ rfc1035MessageDestroy(&message);
+ message = q2->message;
+ q2->message = NULL;
+ n = q2->ancount;
+ error = NULL;
+ }
+ }
+ rfc1035MessageDestroy(&q2->message);
+ cbdataFree(q2);
+ }
+
+ debugs(78, 6, HERE << "Sending " << n << " (" << (error ? error : "OK") << ") DNS results to caller.");
+
callback = q->callback;
q->callback = NULL;
+ const rfc1035_rr *answers = message ? message->answer : NULL;
if (cbdataReferenceValidDone(q->callback_data, &cbdata))
callback(cbdata, answers, n, error);
@@ -1026,6 +1082,9 @@
hash_remove_link(idns_lookup_hash, &q->hash);
q->hash.key = NULL;
}
+
+ rfc1035MessageDestroy(&message);
+ cbdataFree(q);
}
static void
@@ -1097,8 +1156,7 @@
// 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);
+ idnsCallback(q, "Truncated TCP DNS response");
}
return;
@@ -1122,6 +1180,7 @@
return;
}
+ // Do searchpath processing on the master A query only, ignoring any AAAA query
if (q->rcode == 3 && !q->master && q->do_searchpath && q->attempt < MAX_ATTEMPT) {
assert(NULL == message->answer);
strcpy(q->name, q->orig);
@@ -1139,7 +1198,7 @@
rfc1035MessageDestroy(&message);
- // cleanup stale AAAA query
+ // cleanup slave AAAA query
while (idns_query *slave = q->slave) {
dlinkDelete(&slave->lru, &lru_list);
q->slave = slave->slave;
@@ -1154,11 +1213,12 @@
q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->query_id, &q->query, 0);
if (q->sz < 0) {
/* problem with query data -- query not sent */
- idnsCallback(static_cast<idns_query *>(q->callback_data), NULL, 0, "Internal error");
- cbdataFree(q);
+ idnsCallback(q, "Internal error");
return;
}
+ q->nsends = 0;
+
idnsSendQuery(q);
if (Ip::EnableIpv6)
idnsSendSlaveAAAAQuery(q);
@@ -1169,57 +1229,11 @@
q->message = message;
q->ancount = n;
- if (q->master)
- q = q->master;
-
- idns_query *q2;
- // If any of our subqueries are still pending then wait for them to complete before continuing
- for ( q2 = q; q2; q2 = q2->slave) {
- if (q2->pending) {
- return;
- }
- }
-
- /* Merge results */
- message = q->message;
- n = q->ancount;
-
- while ( (q2 = q->slave) ) {
- debugs(78, 6, HERE << "Merging DNS results " << q->name << " A has " << n << " RR, AAAA has " << q2->ancount << " RR");
- q->slave = q2->slave;
- if ( q2->ancount >= 0 ) {
- if (n > 0 ) {
- // two sets of RR need merging
- rfc1035_rr *result = (rfc1035_rr*) xmalloc( sizeof(rfc1035_rr)*(n + q2->ancount) );
- if (Config.dns.v4_first) {
- memcpy(result, message->answer, (sizeof(rfc1035_rr)*n) );
- memcpy(result+n, q2->message->answer, (sizeof(rfc1035_rr)*q2->ancount) );
- } else {
- memcpy(result, q2->message->answer, (sizeof(rfc1035_rr)*q2->ancount) );
- memcpy(result+q2->ancount, message->answer, (sizeof(rfc1035_rr)*n) );
- }
- n += q2->ancount;
- safe_free(message->answer);
- message->answer = result;
- message->ancount += q2->message->ancount;
- safe_free(q2->message->answer);
- q2->message->answer = NULL;
- } else if (n < 0 || q2->ancount > 0) {
- // first set empty / failed
- rfc1035MessageDestroy(&message);
- message = q->message = q2->message;
- q2->message = NULL;
- n = q2->ancount;
- }
- }
- rfc1035MessageDestroy(&q2->message);
- cbdataFree(q2);
- }
-
- debugs(78, 6, HERE << "Sending " << n << " DNS results to caller.");
- idnsCallback(q, message->answer, n, rfc1035ErrorMessage(n));
- rfc1035MessageDestroy(&message);
- cbdataFree(q);
+ if (n >= 0)
+ idnsCallback(q, NULL);
+ else
+ idnsCallback(q, rfc1035ErrorMessage(q->rcode));
+
}
static void
@@ -1328,7 +1342,7 @@
if ((time_msec_t)tvSubMsec(q->queue_t, current_time) < Config.Timeout.idns_retransmit )
break;
- /* Query timer expired? */
+ /* Query timer still running? */
if ((time_msec_t)tvSubMsec(q->sent_t, current_time) < (Config.Timeout.idns_retransmit * 1 << ((q->nsends - 1) / nns))) {
dlinkDelete(&q->lru, &lru_list);
q->queue_t = current_time;
@@ -1341,6 +1355,7 @@
std::setw(4) << q->query_id << ": timeout" );
dlinkDelete(&q->lru, &lru_list);
+ q->pending = 0;
if ((time_msec_t)tvSubMsec(q->start_t, current_time) < Config.Timeout.idns_query) {
idnsSendQuery(q);
@@ -1351,11 +1366,9 @@
std::setw(5)<< std::setprecision(2) << tvSubDsec(q->start_t, current_time) << " seconds");
if (q->rcode != 0)
- idnsCallback(q, NULL, -q->rcode, rfc1035ErrorMessage(q->rcode));
+ idnsCallback(q, rfc1035ErrorMessage(q->rcode));
else
- idnsCallback(q, NULL, -16, "Timeout");
-
- cbdataFree(q);
+ idnsCallback(q, "Timeout");
}
}
@@ -1606,10 +1619,16 @@
}
static void
-idnsCacheQuery(idns_query *q)
+idnsStartQuery(idns_query *q, IDNSCB * callback, void *data)
{
+ q->start_t = current_time;
+ q->callback = callback;
+ q->callback_data = cbdataReference(data);
+
q->hash.key = q->orig;
hash_join(idns_lookup_hash, &q->hash);
+
+ idnsSendQuery(q);
}
static void
@@ -1621,6 +1640,7 @@
q->master = master;
q->query_id = idnsQueryID();
q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), q->query_id, &q->query, Config.dns.packet_max);
+ q->start_t = master->start_t;
q->slave = master->slave;
debugs(78, 3, HERE << "buf is " << q->sz << " bytes for " << q->name <<
@@ -1681,11 +1701,7 @@
debugs(78, 3, "idnsALookup: buf is " << q->sz << " bytes for " << q->name <<
", id = 0x" << std::hex << q->query_id);
- q->callback = callback;
- q->callback_data = cbdataReference(data);
-
- idnsCacheQuery(q);
- idnsSendQuery(q);
+ idnsStartQuery(q, callback, data);
if (Ip::EnableIpv6)
idnsSendSlaveAAAAQuery(q);
@@ -1733,11 +1749,7 @@
debugs(78, 3, "idnsPTRLookup: buf is " << q->sz << " bytes for " << ip <<
", id = 0x" << std::hex << q->query_id);
- q->callback = callback;
- q->callback_data = cbdataReference(data);
-
- idnsCacheQuery(q);
- idnsSendQuery(q);
+ idnsStartQuery(q, callback, data);
}
#if SQUID_SNMP
=== modified file 'src/fqdncache.cc'
--- src/fqdncache.cc 2012-01-20 18:55:04 +0000
+++ src/fqdncache.cc 2012-03-04 22:24:58 +0000
@@ -134,7 +134,7 @@
static int fqdncacheParse(fqdncache_entry *, const char *buf);
#else
static IDNSCB fqdncacheHandleReply;
-static int fqdncacheParse(fqdncache_entry *, rfc1035_rr *, int, const char *error_message);
+static int fqdncacheParse(fqdncache_entry *, const rfc1035_rr *, int, const char *error_message);
#endif
static void fqdncacheRelease(fqdncache_entry *);
static fqdncache_entry *fqdncacheCreateEntry(const char *name);
@@ -417,7 +417,7 @@
#else
static int
-fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *error_message)
+fqdncacheParse(fqdncache_entry *f, const rfc1035_rr * answers, int nr, const char *error_message)
{
int k;
int ttl = 0;
@@ -496,7 +496,7 @@
#if USE_DNSHELPER
fqdncacheHandleReply(void *data, char *reply)
#else
-fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message)
+fqdncacheHandleReply(void *data, const rfc1035_rr * answers, int na, const char *error_message)
#endif
{
fqdncache_entry *f;
=== modified file 'src/ipcache.cc'
--- src/ipcache.cc 2012-01-20 18:55:04 +0000
+++ src/ipcache.cc 2012-03-04 22:24:58 +0000
@@ -144,7 +144,7 @@
#if USE_DNSHELPER
static int ipcacheParse(ipcache_entry *, const char *buf);
#else
-static int ipcacheParse(ipcache_entry *, rfc1035_rr *, int, const char *error);
+static int ipcacheParse(ipcache_entry *, const rfc1035_rr *, int, const char *error);
#endif
static ipcache_entry *ipcache_get(const char *);
static void ipcacheLockEntry(ipcache_entry *);
@@ -458,7 +458,7 @@
#else
static int
-ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_message)
+ipcacheParse(ipcache_entry *i, const rfc1035_rr * answers, int nr, const char *error_message)
{
int k;
int j = 0;
@@ -592,7 +592,7 @@
#if USE_DNSHELPER
ipcacheHandleReply(void *data, char *reply)
#else
-ipcacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message)
+ipcacheHandleReply(void *data, const rfc1035_rr * answers, int na, const char *error_message)
#endif
{
ipcache_entry *i;
=== modified file 'src/typedefs.h'
--- src/typedefs.h 2012-01-20 18:55:04 +0000
+++ src/typedefs.h 2012-03-04 22:24:58 +0000
@@ -137,7 +137,7 @@
typedef int HLPSAVAIL(void *);
typedef void HLPSONEQ(void *);
typedef void HLPCMDOPTS(int *argc, char **argv);
-typedef void IDNSCB(void *, rfc1035_rr *, int, const char *);
+typedef void IDNSCB(void *, const rfc1035_rr *, int, const char *);
/* MD5 cache keys */
typedef unsigned char cache_key;
# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWSJkvQoABzd/gERUQABxf///
/+/+gL////pgDH957M14PbeqtemQO2Al7u+XvRWvL3vLve91KvRhQ3bwkomU2qemhlTNkap6Mp5T
xTbUeonqMDUNGCaGQGglFMKbFGAmQp6CfqmmmRjKaPUANBoAAA0mjCRPVAZA00A0AAGgAAAAAkQi
TQNKemknlPJp6KBnqamEYjTQHlBkAaAkkmijyMoeptE0DRo0AAeo9R6jQAAAAkSE0AjJT0xNBJ5N
E9BTZT0hownlDagyA9J3hU3jAF2B+hKDi+XQufLs6+7hpcv/Dg64RRt0nBLG5B+3Vv36TYY4FEQd
kSPLCLB3LTqe21D/7X2TMlE2bgrS6TycUmFmdmvGUXOPasyGtL0TgHS77qxAELMAAoDlCziRdUtI
lqDRxXeZzmyCgg1Inc74K1g/1bAchCSWCQg7/HoqoD0PxcHZ+Xy58PRKrzaxfrvDptaGH1HfHlgh
fq0iYMCZm1H5n+9iPYHODSTbY2NgGvpvB+qEc2+AMc3H0u0h0U3Ug3ve+9rVMQN9LLvqvFmN6GVB
DZLI4BoIxwMyjWFZ3WaI7VROShjN4nITOeOK6mlU8MGyz2mW7KOX0nGiuTpwzP9/bcp3zz/WGuoh
upHN87LeXW891FUOcnDgm3M5OBLm8VRP1Z6R4UZGjSQ4jsVtCAyi6YyAOVEVjxhOuwdx/h+E7gjI
ssvYHN36ee+tc4vdGIlEos+8aa4La8zx6CKV5Q+L4uK31Kab4BhZprChd/YzzNS0VHLeaa/lr0vn
GsWkK1GmQCuu+fRNX+et2Q0SAV0oOeLooYLogMhvTU2NpZlK96jVihFRdxts18FeG0lvWV8euKa8
wthodKDo7tpxXLyz46d/1goFbYCaEOz3JrW967xGhjJM0yuEEVQMZMjY5DWhMhuYUanhQwsZRvKq
4maTl4oPaQQycEtrBiujZSxT/HtiuMVIDzDSvlCBQMY0YF6mGw4+8mg5VcZiZS7dUl47PgDU4WmC
zOkdc5qAxFKwT+HNeOCS9Af8GbzzLn1o2RAwIIaGJtptDFNDbE7aRUSq7jIGUpwhCXZtp6FQU0Qg
lwA5JtJwovb9x+EfhC70Zm/LAJfsQyRz9nHjFwg5sBtIhqGpacwTdEvClATgzmZ63mwYkYprEm+A
r0AGhFaeFqrHUQku4VK2DqK4ib7itwK6ypWQag+gGF2hKhEBYgKPOIBX1FsAzk0lkboDomtML3sQ
hh9DLR2DCg1ancJDCVtC+tuF/b5JLBZix9LDIYGo00YELNTiGtw0Q8CZbKGMaC71FQeO1loXVBBY
29oCtqRuGZeu5xG4sQf8mcAUrYadO2MtmeFM1F9los7t+FZmkFGFyJppgDSCxJ1gye0nADmLiVBT
BW1fAVYxI1sBX0oRYVkX4BgX2sdBcSSWRju4mRUsKm0NDmmma4556364RZWkorxsWCWtzST3Omww
qKQ8WbwZyqaGxKa2DMUIcjyFZA8iJmpiryZQuyk67KYJUM5+UkjQZRNpmrC4kC7Mb5xebcUK0oaD
guE1vJkGwumWGxYVR87CR5DnGDhh3BP8WxzVxtjoLLYLUMsSZLCRqaTZVkMJCYueCxLKg1mBeYcA
rk0chZCMDIyOU15HML95ZUtyOUZO3I9Y5ZAUK1cBOZApp7LTrvK2l1pbE9otfJxN5meo4KMcC+Nk
RwyorDM3E698zqGWFlS8tjqIPeb+Z0ZczgKZgYm81Fv2xF8tsGG52zRpUsBTnaMORidgmS1uwL7S
SyIIWWbKEzGWzMrBuLC8sBRdtui2wsLqE78hQSMi8kQZmhaMsAuJl0jI/QuxnuxIJiJsSyLi4xOn
pzPQtptL2sNGZqEYCjz0hGaVnvmyi+uFJok+TW+sE3rwuhv4qspG4qEdWHyXOALtWd7QTA7WRDQH
3NtGO7S2sRwZRD77ZsBkNDfL5keHwTaC+EOX0gCp75mgB57F/EJpgMPzfz/JUXQDTb+XWof28lZV
bCHapFF1DrpqKz92lGX/CJOZF6P5oR/kPfkJJTT+gHiPjnoBuJ2VJ00j3JZkKwMJKDs6MGoTz3Dx
MN6eoHimlt4kSFn2Ukrh1NI+xouMYDhBVFRGIlJSlMVqk4DEHkgb48LK6KSIjlSCxvMhVzEU44oS
AtpWooXBVJfSZLDmEIvmfkto6xE9YzZJixdsBLKQfBM7gXyhoSuVoC7kz6UjZbUN3Aq1oWH3facT
rO8ZzGft8poVO87lkJPMg4uL40H3STd+2agEZVGr0eQIhSlKEP2zcQTOs5m4g0NToOPNM4pwxpj7
eCG5d58f6T+KDGzaaGpuOfBlnG8RckHFkmhSJGELpazaE2VEfQFtLZ0OwhUFRtPZBCfVLMZ1/Hgt
S4VRMgbSQ3zz890aqFjJykwX5JQf2ApMSHhuJgdYHLQF0fBwFvsr1IDbKPP8Oxh8G/TRx6orN1CR
Y51utXC9lDCxIxhmOQgSugwDu5jScDwHgNpzuvpMyh+s3Ge1+7e1NEi9egua6JrcLcMJkBJLMcxc
D3F8ml4zCTc2afLPI3wghcdNl7cnkZMlOOstLQnZU1nVctKQ6XgA+Cg1SbSnIDANSDUKjPsMnOIE
+GtZGNOfzteft0tD3b/xjh7J+yHE4Fki0LkK8qCYUwwkMtB3OnoWeAW54AUM6Bo0tXC14ZE2cNe4
SIRnPeVI0EkqJ+0PcEiM3S/ecQYrOJkJe8jEuvTikdxPU9YpiEgHBaug9XRzP5kzvCJ1EiGdTk7G
nSQa5X7cUm4gTD3AGbHHHyrxAqUgMlzmV9qZR05koUKpIkrPDYNx7b2mNM2LqVk05ffXBks0eGVq
APtXumC8MEdLFUM0tN3vxHjU7pmzTBIlagYJhDlodJqiGOKucuQtLtyIbb1igV4EmytLYZCrFcTr
jwBzlQlrJ4BYvzSjKAT1ouRQlKM7BjDOObVehgHetrOtUUB12gXHibOzO4aA+oXhty+tuqqGewaP
X/0J+agrei49XjOaN9nUVEd+SA6vhx4nbvzsOdEZWz6M0qJLWeFyJ1nsqtw0FxWQZyR6zrA6sKpF
vaO9KYpg5W+0AiglSOfVdRTjxAOVwXoAuxBFTNiCQlaUuShNOGDAjztWlQwTs15AUG9dPA6WPT6P
NU0wXhx848zU2I8UpTowC2DaVYiD93xvptKJBnKxFOyBXggS1JdnKAVzKIWjRcKMs4jPn2Iq5lEs
JzmcjRp06RcWAC0iwPVBkwsz5iVYi/e2uPZsHWO4PPwRwxhQyPnKiXLPRVDJomBssdcHu8fkm7TZ
dnSB4oPKD3Lu8h0B1sGA4lptuYN0hDpDghh1DCHKbEscAw5ykBYc30HzHjhWlgMYGJlmQxpb+XTI
OlqTOG/jEgJWi0WQbHvQBKGvZpIOrwEFYRuBHfNTSWN1qtQvkMRvDvGlBRn2XWyUA1NpNRRt5Y22
TyyirM/cWhLkp+YumOSQRuOtAHd6/JY4IvDVR25S0d1GO1IgK94K1Cwpq+c+9VkeleoIEBlrEbGB
ESvXaugLjRLigLFIaFKdySby1UbtRGkuRsgU0FrlfNSuITbJJKImdBfMJ8XaaBMPsAcJkki/4AxS
wspKYcIDQC6kIM4V5UxKJWFbJI/gCsSno1AI3wGlo83BIwYtXyOxMopys2Fu5hrb2AeYtQ1TZXoV
F1YBD5363NqwJ4/3Y5Bld47QoJRWVdSMEgww8O8FxKCUxkDmRX1bcTAFiq2INRE3ZEQ6Jo6w2hBi
C8q8D4iTu6oowL0txEKLSoCw6Dbzqv/F3JFOFCQImS9CgA==