Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
BIND
Commits
61b103da
Commit
61b103da
authored
Nov 05, 1999
by
Bob Halley
Browse files
RTT support
parent
28ab8277
Changes
1
Hide whitespace changes
Inline
Side-by-side
lib/dns/resolver.c
View file @
61b103da
...
...
@@ -92,6 +92,8 @@ typedef struct query {
unsigned
int
magic
;
fetchctx_t
*
fctx
;
dns_dispatch_t
*
dispatch
;
dns_adbaddrinfo_t
*
addrinfo
;
isc_time_t
start
;
/* Locked by fctx lock. */
dns_messageid_t
id
;
dns_dispentry_t
*
dispentry
;
/* XXX name */
...
...
@@ -138,9 +140,10 @@ struct fetchctx {
dns_message_t
*
qmessage
;
dns_message_t
*
rmessage
;
ISC_LIST
(
resquery_t
)
queries
;
ISC_LIST
(
dns_adbfind_t
)
finds
;
dns_adbfind
list
_t
finds
;
dns_adbfind_t
*
find
;
unsigned
int
pending
;
unsigned
int
restarts
;
};
#define FCTX_MAGIC 0x46212121U
/* F!!! */
...
...
@@ -246,17 +249,42 @@ fctx_stoptimer(fetchctx_t *fctx) {
}
}
static
inline
void
fctx_cancelquery
(
resquery_t
**
queryp
,
dns_dispatchevent_t
**
deventp
)
{
fctx_cancelquery
(
resquery_t
**
queryp
,
dns_dispatchevent_t
**
deventp
,
isc_time_t
*
finish
)
{
fetchctx_t
*
fctx
;
resquery_t
*
query
;
unsigned
int
rtt
;
isc_time_t
now
;
unsigned
int
factor
;
query
=
*
queryp
;
fctx
=
query
->
fctx
;
FCTXTRACE
(
"cancelquery"
);
if
(
finish
!=
NULL
)
{
rtt
=
(
unsigned
int
)
isc_time_microdiff
(
finish
,
&
query
->
start
);
factor
=
0
;
}
else
{
/*
* We don't have an RTT for this query. Maybe the packet
* was lost, or maybe this server is very slow. We don't
* know. Increase the RTT.
*/
rtt
=
query
->
addrinfo
->
srtt
+
(
100000
*
fctx
->
restarts
);
if
(
rtt
>
10000000
)
rtt
=
10000000
;
/*
* We set 'factor' to 1, so that we will replace the current
* RTT.
*/
factor
=
1
;
}
dns_adb_adjustsrtt
(
fctx
->
res
->
view
->
adb
,
query
->
addrinfo
,
rtt
,
factor
);
dns_dispatch_removeresponse
(
query
->
dispatch
,
&
query
->
dispentry
,
deventp
);
ISC_LIST_UNLINK
(
fctx
->
queries
,
query
,
link
);
...
...
@@ -277,7 +305,7 @@ fctx_cancelqueries(fetchctx_t *fctx) {
query
!=
NULL
;
query
=
next_query
)
{
next_query
=
ISC_LIST_NEXT
(
query
,
link
);
fctx_cancelquery
(
&
query
,
NULL
);
fctx_cancelquery
(
&
query
,
NULL
,
NULL
);
}
}
...
...
@@ -285,6 +313,8 @@ static void
fctx_cleanupfinds
(
fetchctx_t
*
fctx
)
{
dns_adbfind_t
*
find
,
*
next_find
;
REQUIRE
(
ISC_LIST_EMPTY
(
fctx
->
queries
));
for
(
find
=
ISC_LIST_HEAD
(
fctx
->
finds
);
find
!=
NULL
;
find
=
next_find
)
{
...
...
@@ -298,8 +328,8 @@ fctx_cleanupfinds(fetchctx_t *fctx) {
static
inline
void
fctx_stopeverything
(
fetchctx_t
*
fctx
)
{
FCTXTRACE
(
"stopeverything"
);
fctx_cleanupfinds
(
fctx
);
fctx_cancelqueries
(
fctx
);
fctx_cleanupfinds
(
fctx
);
fctx_stoptimer
(
fctx
);
}
...
...
@@ -364,13 +394,13 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
(
void
)
task
;
if
(
sevent
->
result
!=
ISC_R_SUCCESS
)
fctx_cancelquery
(
&
query
,
NULL
);
fctx_cancelquery
(
&
query
,
NULL
,
NULL
);
isc_event_free
(
&
event
);
}
static
isc_result_t
fctx_sendquery
(
fetchctx_t
*
fctx
,
isc_sockaddr
_t
*
addr
ess
)
{
fctx_sendquery
(
fetchctx_t
*
fctx
,
dns_adbaddrinfo
_t
*
addr
info
)
{
resquery_t
*
query
;
isc_result_t
result
;
dns_rdataset_t
*
qrdataset
;
...
...
@@ -400,10 +430,20 @@ fctx_sendquery(fetchctx_t *fctx, isc_sockaddr_t *address) {
goto
cleanup_temps
;
query
=
isc_mem_get
(
res
->
mctx
,
sizeof
*
query
);
if
(
query
==
NULL
)
return
(
ISC_R_NOMEMORY
);
if
(
query
==
NULL
)
{
result
=
ISC_R_NOMEMORY
;
goto
cleanup_temps
;
}
isc_buffer_init
(
&
query
->
buffer
,
query
->
data
,
sizeof
query
->
data
,
ISC_BUFFERTYPE_BINARY
);
/*
* Note that the caller MUST guarantee that 'addrinfo' will remain
* valid until this query is canceled.
*/
query
->
addrinfo
=
addrinfo
;
result
=
isc_time_now
(
&
query
->
start
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
cleanup_query
;
/*
* If this is a TCP query, then we need to make a socket and
...
...
@@ -417,7 +457,7 @@ fctx_sendquery(fetchctx_t *fctx, isc_sockaddr_t *address) {
result
=
DNS_R_NOTIMPLEMENTED
;
goto
cleanup_query
;
}
else
{
switch
(
isc_sockaddr_pf
(
addr
ess
))
{
switch
(
isc_sockaddr_pf
(
addr
info
->
sockaddr
))
{
case
AF_INET
:
query
->
dispatch
=
res
->
dispatch4
;
break
;
...
...
@@ -443,7 +483,7 @@ fctx_sendquery(fetchctx_t *fctx, isc_sockaddr_t *address) {
*/
query
->
dispentry
=
NULL
;
result
=
dns_dispatch_addresponse
(
query
->
dispatch
,
addr
ess
,
addr
info
->
sockaddr
,
task
,
resquery_response
,
query
,
...
...
@@ -513,7 +553,7 @@ fctx_sendquery(fetchctx_t *fctx, isc_sockaddr_t *address) {
isc_buffer_used
(
&
query
->
buffer
,
&
r
);
result
=
isc_socket_sendto
(
dns_dispatch_getsocket
(
query
->
dispatch
),
&
r
,
task
,
resquery_senddone
,
query
,
addr
ess
);
query
,
addr
info
->
sockaddr
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
cleanup_message
;
...
...
@@ -612,6 +652,61 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
empty_bucket
(
res
);
}
static
void
sort_adbfind
(
dns_adbfind_t
*
find
)
{
dns_adbaddrinfo_t
*
best
,
*
curr
;
dns_adbaddrinfolist_t
sorted
;
/*
* Lame N^2 bubble sort.
*/
ISC_LIST_INIT
(
sorted
);
while
(
!
ISC_LIST_EMPTY
(
find
->
list
))
{
best
=
ISC_LIST_HEAD
(
find
->
list
);
curr
=
ISC_LIST_NEXT
(
best
,
publink
);
while
(
curr
!=
NULL
)
{
if
(
curr
->
srtt
<
best
->
srtt
)
best
=
curr
;
curr
=
ISC_LIST_NEXT
(
curr
,
publink
);
}
ISC_LIST_UNLINK
(
find
->
list
,
best
,
publink
);
ISC_LIST_APPEND
(
sorted
,
best
,
publink
);
}
find
->
list
=
sorted
;
}
static
void
sort_finds
(
fetchctx_t
*
fctx
)
{
dns_adbfind_t
*
best
,
*
curr
;
dns_adbfindlist_t
sorted
;
dns_adbaddrinfo_t
*
addrinfo
,
*
bestaddrinfo
;
/*
* Lame N^2 bubble sort.
*/
ISC_LIST_INIT
(
sorted
);
while
(
!
ISC_LIST_EMPTY
(
fctx
->
finds
))
{
best
=
ISC_LIST_HEAD
(
fctx
->
finds
);
bestaddrinfo
=
ISC_LIST_HEAD
(
best
->
list
);
INSIST
(
bestaddrinfo
!=
NULL
);
curr
=
ISC_LIST_NEXT
(
best
,
publink
);
while
(
curr
!=
NULL
)
{
addrinfo
=
ISC_LIST_HEAD
(
curr
->
list
);
INSIST
(
addrinfo
!=
NULL
);
if
(
addrinfo
->
srtt
<
bestaddrinfo
->
srtt
)
{
best
=
curr
;
bestaddrinfo
=
addrinfo
;
}
curr
=
ISC_LIST_NEXT
(
curr
,
publink
);
}
ISC_LIST_UNLINK
(
fctx
->
finds
,
best
,
publink
);
ISC_LIST_APPEND
(
sorted
,
best
,
publink
);
}
fctx
->
finds
=
sorted
;
}
static
isc_result_t
fctx_getaddresses
(
fetchctx_t
*
fctx
)
{
dns_rdata_t
rdata
;
...
...
@@ -625,6 +720,13 @@ fctx_getaddresses(fetchctx_t *fctx) {
FCTXTRACE
(
"getaddresses"
);
/*
* Don't pound on remote servers.
*/
fctx
->
restarts
++
;
if
(
fctx
->
restarts
>
10
)
return
(
DNS_R_SERVFAIL
);
res
=
fctx
->
res
;
options
=
DNS_ADBFIND_WANTEVENT
|
DNS_ADBFIND_EMPTYEVENT
;
if
(
res
->
dispatch4
!=
NULL
)
...
...
@@ -635,7 +737,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
if
(
result
!=
ISC_R_SUCCESS
)
return
(
result
);
fctx_cleanupfinds
(
fctx
);
INSIST
(
ISC_LIST_EMPTY
(
fctx
->
finds
)
);
result
=
dns_rdataset_first
(
&
fctx
->
nameservers
);
while
(
result
==
ISC_R_SUCCESS
)
{
...
...
@@ -647,7 +749,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
dns_name_init
(
&
name
,
NULL
);
dns_name_fromregion
(
&
name
,
&
r
);
/*
* XXXRTH If this name is the same as QNAME, remember
* XXXRTH If this name is the same as QNAME, remember
to
* skip it, and remember that we did so so we can
* use an ancestor QDOMAIN if we find no addresses.
*/
...
...
@@ -668,9 +770,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
* name.
*/
INSIST
((
find
->
options
&
DNS_ADBFIND_WANTEVENT
)
==
0
);
/*
* XXXRTH Sort.
*/
sort_adbfind
(
find
);
ISC_LIST_APPEND
(
fctx
->
finds
,
find
,
publink
);
}
else
{
/*
...
...
@@ -713,11 +813,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
* We've found some addresses. We might still be looking
* for more addresses.
*/
/*
* XXXRTH Sort.
*/
sort_finds
(
fctx
);
result
=
ISC_R_SUCCESS
;
}
...
...
@@ -732,7 +828,6 @@ static inline dns_adbaddrinfo_t *
fctx_nextaddress
(
fetchctx_t
*
fctx
)
{
dns_adbfind_t
*
find
;
dns_adbaddrinfo_t
*
addrinfo
;
int
count
=
0
;
/*
* Return the next untried address, if any.
...
...
@@ -755,8 +850,6 @@ fctx_nextaddress(fetchctx_t *fctx) {
*/
addrinfo
=
NULL
;
while
(
find
!=
fctx
->
find
)
{
count
++
;
INSIST
(
count
<
1000
);
for
(
addrinfo
=
ISC_LIST_HEAD
(
find
->
list
);
addrinfo
!=
NULL
;
addrinfo
=
ISC_LIST_NEXT
(
addrinfo
,
publink
))
{
...
...
@@ -774,6 +867,10 @@ fctx_nextaddress(fetchctx_t *fctx) {
fctx
->
find
=
find
;
/* XXX */
if
(
addrinfo
!=
NULL
)
printf
(
"RTT = %u
\n
"
,
addrinfo
->
srtt
);
return
(
addrinfo
);
}
...
...
@@ -796,6 +893,7 @@ fctx_try(fetchctx_t *fctx) {
* We have no more addresses. Start over.
*/
fctx_cancelqueries
(
fctx
);
fctx_cleanupfinds
(
fctx
);
result
=
fctx_getaddresses
(
fctx
);
if
(
result
==
DNS_R_WAIT
)
{
/*
...
...
@@ -826,7 +924,7 @@ fctx_try(fetchctx_t *fctx) {
* just send a single query.
*/
result
=
fctx_sendquery
(
fctx
,
addrinfo
->
sockaddr
);
result
=
fctx_sendquery
(
fctx
,
addrinfo
);
if
(
result
!=
ISC_R_SUCCESS
)
fctx_done
(
fctx
,
result
);
}
...
...
@@ -1083,6 +1181,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
ISC_LIST_INIT
(
fctx
->
finds
);
fctx
->
find
=
NULL
;
fctx
->
pending
=
0
;
fctx
->
restarts
=
0
;
fctx
->
attributes
=
0
;
fctx
->
qmessage
=
NULL
;
...
...
@@ -2265,6 +2364,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
dns_name_t
*
fname
;
dns_fixedname_t
foundname
;
isc_stdtime_t
now
;
isc_time_t
tnow
,
*
finish
;
REQUIRE
(
VALID_QUERY
(
query
));
fctx
=
query
->
fctx
;
...
...
@@ -2280,11 +2380,22 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
broken_server
=
ISC_FALSE
;
get_nameservers
=
ISC_FALSE
;
covers
=
0
;
finish
=
NULL
;
/*
* XXXRTH We should really get the current time just once. We
* need a routine to convert from an isc_time_t to an
* isc_stdtime_t.
*/
result
=
isc_time_now
(
&
tnow
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
done
;
finish
=
&
tnow
;
result
=
isc_stdtime_get
(
&
now
);
if
(
result
!=
ISC_R_SUCCESS
)
goto
done
;
message
=
fctx
->
rmessage
;
message
->
querytsig
=
query
->
tsig
;
message
->
tsigkey
=
query
->
tsigkey
;
...
...
@@ -2429,14 +2540,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
done:
/*
*
Give the event back to the dispatch
er.
*
Cancel the qu
er
y
.
*/
dns_dispatch_freeevent
(
query
->
dispatch
,
query
->
dispent
ry
,
&
devent
);
fctx_cancelquery
(
&
que
ry
,
&
devent
,
finish
);
/*
* XXXRTH Record round-trip statistics here. Note that 'result'
* MUST NOT be changed by this recording process.
*/
if
(
keep_trying
)
{
if
(
result
==
DNS_R_FORMERR
)
broken_server
=
ISC_TRUE
;
...
...
@@ -2496,6 +2603,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
fctx_done
(
fctx
,
DNS_R_SERVFAIL
);
return
;
}
fctx_cancelqueries
(
fctx
);
fctx_cleanupfinds
(
fctx
);
}
/*
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment