Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Mike Perry
Tor
Commits
965a73dc
Commit
965a73dc
authored
21 years ago
by
Roger Dingledine
Browse files
Options
Downloads
Patches
Plain Diff
bugfix: we were caching transient dns failures
svn:r1266
parent
45a3f6b9
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/or/dns.c
+47
-23
47 additions, 23 deletions
src/or/dns.c
with
47 additions
and
23 deletions
src/or/dns.c
+
47
−
23
View file @
965a73dc
...
...
@@ -16,16 +16,13 @@
#define MIN_DNSWORKERS 3
#define MAX_IDLE_DNSWORKERS 10
#define DNS_RESOLVE_FAILED_TRANSIENT 1
#define DNS_RESOLVE_FAILED_PERMANENT 2
#define DNS_RESOLVE_SUCCEEDED 3
int
num_dnsworkers
=
0
;
int
num_dnsworkers_busy
=
0
;
static
void
purge_expired_resolves
(
uint32_t
now
);
static
int
assign_to_dnsworker
(
connection_t
*
exitconn
);
static
void
dns_found_answer
(
char
*
address
,
uint32_t
addr
);
int
dnsworker_main
(
void
*
data
);
static
int
spawn_dnsworker
(
void
);
static
void
spawn_enough_dnsworkers
(
void
);
struct
pending_connection_t
{
struct
connection_t
*
conn
;
struct
pending_connection_t
*
next
;
...
...
@@ -44,6 +41,14 @@ struct cached_resolve {
struct
cached_resolve
*
next
;
};
static
void
purge_expired_resolves
(
uint32_t
now
);
static
int
assign_to_dnsworker
(
connection_t
*
exitconn
);
static
void
dns_purge_resolve
(
struct
cached_resolve
*
resolve
);
static
void
dns_found_answer
(
char
*
address
,
uint32_t
addr
,
char
outcome
);
int
dnsworker_main
(
void
*
data
);
static
int
spawn_dnsworker
(
void
);
static
void
spawn_enough_dnsworkers
(
void
);
static
SPLAY_HEAD
(
cache_tree
,
cached_resolve
)
cache_root
;
static
int
compare_cached_resolves
(
struct
cached_resolve
*
a
,
...
...
@@ -238,7 +243,7 @@ void connection_dns_remove(connection_t *conn)
void
dns_cancel_pending_resolve
(
char
*
address
)
{
struct
pending_connection_t
*
pend
;
struct
cached_resolve
search
;
struct
cached_resolve
*
resolve
,
*
tmp
;
struct
cached_resolve
*
resolve
;
connection_t
*
pendconn
;
strncpy
(
search
.
address
,
address
,
MAX_ADDRESSLEN
);
...
...
@@ -266,6 +271,12 @@ void dns_cancel_pending_resolve(char *address) {
tor_free
(
pend
);
}
dns_purge_resolve
(
resolve
);
}
static
void
dns_purge_resolve
(
struct
cached_resolve
*
resolve
)
{
struct
cached_resolve
*
tmp
;
/* remove resolve from the linked list */
if
(
resolve
==
oldest_cached_resolve
)
{
oldest_cached_resolve
=
resolve
->
next
;
...
...
@@ -287,7 +298,7 @@ void dns_cancel_pending_resolve(char *address) {
tor_free
(
resolve
);
}
static
void
dns_found_answer
(
char
*
address
,
uint32_t
addr
)
{
static
void
dns_found_answer
(
char
*
address
,
uint32_t
addr
,
char
outcome
)
{
struct
pending_connection_t
*
pend
;
struct
cached_resolve
search
;
struct
cached_resolve
*
resolve
;
...
...
@@ -316,7 +327,7 @@ static void dns_found_answer(char *address, uint32_t addr) {
/* assert(resolve->state == CACHE_STATE_PENDING); */
resolve
->
addr
=
ntohl
(
addr
);
if
(
resolve
->
addr
)
if
(
outcome
==
DNS_RESOLVE_SUCCEEDED
)
resolve
->
state
=
CACHE_STATE_VALID
;
else
resolve
->
state
=
CACHE_STATE_FAILED
;
...
...
@@ -337,6 +348,10 @@ static void dns_found_answer(char *address, uint32_t addr) {
resolve
->
pending_connections
=
pend
->
next
;
tor_free
(
pend
);
}
if
(
outcome
==
DNS_RESOLVE_FAILED_TRANSIENT
)
{
/* remove from cache */
dns_purge_resolve
(
resolve
);
}
}
/******************************************************************/
...
...
@@ -348,6 +363,7 @@ int connection_dns_finished_flushing(connection_t *conn) {
}
int
connection_dns_process_inbuf
(
connection_t
*
conn
)
{
char
answer
[
5
];
uint32_t
addr
;
assert
(
conn
&&
conn
->
type
==
CONN_TYPE_DNSWORKER
);
...
...
@@ -364,16 +380,19 @@ int connection_dns_process_inbuf(connection_t *conn) {
}
assert
(
conn
->
state
==
DNSWORKER_STATE_BUSY
);
if
(
buf_datalen
(
conn
->
inbuf
)
<
4
)
/* entire answer available? */
if
(
buf_datalen
(
conn
->
inbuf
)
<
5
)
/* entire answer available? */
return
0
;
/* not yet */
assert
(
buf_datalen
(
conn
->
inbuf
)
==
4
);
assert
(
buf_datalen
(
conn
->
inbuf
)
==
5
);
connection_fetch_from_buf
((
char
*
)
&
addr
,
sizeof
(
addr
),
conn
);
connection_fetch_from_buf
(
answer
,
sizeof
(
answer
),
conn
);
addr
=
*
(
uint32_t
*
)(
answer
+
1
);
log_fn
(
LOG_DEBUG
,
"DNSWorker (fd %d) returned answer for '%s'"
,
conn
->
s
,
conn
->
address
);
dns_found_answer
(
conn
->
address
,
addr
);
assert
(
answer
[
0
]
>=
DNS_RESOLVE_FAILED_TRANSIENT
);
assert
(
answer
[
0
]
<=
DNS_RESOLVE_SUCCEEDED
);
dns_found_answer
(
conn
->
address
,
addr
,
answer
[
0
]);
tor_free
(
conn
->
address
);
conn
->
address
=
tor_strdup
(
"<idle>"
);
...
...
@@ -386,6 +405,7 @@ int connection_dns_process_inbuf(connection_t *conn) {
int
dnsworker_main
(
void
*
data
)
{
char
address
[
MAX_ADDRESSLEN
];
unsigned
char
address_len
;
char
answer
[
5
];
struct
hostent
*
rent
;
int
*
fdarray
=
data
;
int
fd
;
...
...
@@ -398,7 +418,6 @@ int dnsworker_main(void *data) {
for
(;;)
{
if
(
recv
(
fd
,
&
address_len
,
1
,
0
)
!=
1
)
{
// log_fn(LOG_INFO,"read length failed. Child exiting.");
log_fn
(
LOG_INFO
,
"dnsworker exiting because tor process died."
);
spawn_exit
();
}
...
...
@@ -412,19 +431,24 @@ int dnsworker_main(void *data) {
rent
=
gethostbyname
(
address
);
if
(
!
rent
)
{
log_fn
(
LOG_INFO
,
"Could not resolve dest addr %s. Returning nulls."
,
address
);
if
(
write_all
(
fd
,
"
\0\0\0\0
"
,
4
,
1
)
!=
4
)
{
log_fn
(
LOG_ERR
,
"writing nulls failed. Child exiting."
);
spawn_exit
();
if
(
h_errno
==
TRY_AGAIN
)
{
/* transient error -- don't cache it */
log_fn
(
LOG_INFO
,
"Could not resolve dest addr %s (transient)."
,
address
);
answer
[
0
]
=
DNS_RESOLVE_FAILED_TRANSIENT
;
}
else
{
/* permanent error, can be cached */
log_fn
(
LOG_INFO
,
"Could not resolve dest addr %s (permanent)."
,
address
);
answer
[
0
]
=
DNS_RESOLVE_FAILED_PERMANENT
;
}
memset
(
answer
+
1
,
0
,
4
);
}
else
{
assert
(
rent
->
h_length
==
4
);
/* break to remind us if we move away from ipv4 */
if
(
write_all
(
fd
,
rent
->
h_addr
,
4
,
1
)
!=
4
)
{
log_fn
(
LOG_INFO
,
"writing answer failed. Child exiting."
);
spawn_exit
();
}
answer
[
0
]
=
DNS_RESOLVE_SUCCEEDED
;
memcpy
(
answer
+
1
,
rent
->
h_addr
,
4
);
log_fn
(
LOG_INFO
,
"Resolved address '%s'."
,
address
);
}
if
(
write_all
(
fd
,
answer
,
5
,
1
)
!=
5
)
{
log_fn
(
LOG_ERR
,
"writing answer failed. Child exiting."
);
spawn_exit
();
}
}
return
0
;
/* windows wants this function to return an int */
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment