Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
David Goulet
Tor
Commits
aa63a84f
Commit
aa63a84f
authored
Feb 13, 2006
by
Roger Dingledine
Browse files
the things we do for our windows users.
i hope they appreciate it. svn:r6004
parent
d113b75d
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
src/or/directory.c
View file @
aa63a84f
This diff is collapsed.
Click to expand it.
src/or/dirserv.c
View file @
aa63a84f
...
...
@@ -147,7 +147,7 @@ dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
{
char
fp
[
FINGERPRINT_LEN
+
1
];
if
(
crypto_pk_get_fingerprint
(
pk
,
fp
,
0
)
<
0
)
{
err
(
LD_BUG
,
"Error computing fingerprint"
);
log_
err
(
LD_BUG
,
"Error computing fingerprint"
);
return
-
1
;
}
if
(
!
fingerprint_list
)
...
...
@@ -173,13 +173,13 @@ dirserv_parse_fingerprint_file(const char *fname)
cf
=
read_file_to_str
(
fname
,
0
);
if
(
!
cf
)
{
warn
(
LD_FS
,
"Cannot open fingerprint file %s"
,
fname
);
log_
warn
(
LD_FS
,
"Cannot open fingerprint file %s"
,
fname
);
return
-
1
;
}
result
=
config_get_lines
(
cf
,
&
front
);
tor_free
(
cf
);
if
(
result
<
0
)
{
warn
(
LD_CONFIG
,
"Error reading from fingerprint file"
);
log_
warn
(
LD_CONFIG
,
"Error reading from fingerprint file"
);
return
-
1
;
}
...
...
@@ -188,35 +188,39 @@ dirserv_parse_fingerprint_file(const char *fname)
for
(
list
=
front
;
list
;
list
=
list
->
next
)
{
nickname
=
list
->
key
;
fingerprint
=
list
->
value
;
if
(
strlen
(
nickname
)
>
MAX_NICKNAME_LEN
)
{
notice
(
LD_CONFIG
,
"Nickname '%s' too long in fingerprint file. Skipping."
,
nickname
);
log_notice
(
LD_CONFIG
,
"Nickname '%s' too long in fingerprint file. Skipping."
,
nickname
);
continue
;
}
if
(
!
is_legal_nickname
(
nickname
)
&&
strcasecmp
(
nickname
,
"!reject"
)
&&
strcasecmp
(
nickname
,
"!invalid"
))
{
notice
(
LD_CONFIG
,
"Invalid nickname '%s' in fingerprint file. Skipping."
,
nickname
);
log_notice
(
LD_CONFIG
,
"Invalid nickname '%s' in fingerprint file. Skipping."
,
nickname
);
continue
;
}
if
(
strlen
(
fingerprint
)
!=
FINGERPRINT_LEN
||
!
crypto_pk_check_fingerprint_syntax
(
fingerprint
))
{
notice
(
LD_CONFIG
,
"Invalid fingerprint (nickname '%s', fingerprint %s). Skipping."
,
nickname
,
fingerprint
);
log_notice
(
LD_CONFIG
,
"Invalid fingerprint (nickname '%s', "
"fingerprint %s). Skipping."
,
nickname
,
fingerprint
);
continue
;
}
if
(
0
==
strcasecmp
(
nickname
,
DEFAULT_CLIENT_NICKNAME
))
{
/* If you approved an OR called "client", then clients who use
* the default nickname could all be rejected. That's no good. */
notice
(
LD_CONFIG
,
"Authorizing a nickname '%s' would break many clients; skipping."
,
DEFAULT_CLIENT_NICKNAME
);
log_notice
(
LD_CONFIG
,
"Authorizing a nickname '%s' would break "
"many clients; skipping."
,
DEFAULT_CLIENT_NICKNAME
);
continue
;
}
if
(
add_fingerprint_to_dir
(
nickname
,
fingerprint
,
fingerprint_list_new
)
!=
0
)
notice
(
LD_CONFIG
,
"Duplicate nickname '%s'."
,
nickname
);
log_
notice
(
LD_CONFIG
,
"Duplicate nickname '%s'."
,
nickname
);
}
config_free_lines
(
front
);
...
...
@@ -239,7 +243,7 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg)
char
fingerprint
[
FINGERPRINT_LEN
+
1
];
if
(
crypto_pk_get_fingerprint
(
router
->
identity_pkey
,
fingerprint
,
0
))
{
warn
(
LD_BUG
,
"Error computing fingerprint"
);
log_
warn
(
LD_BUG
,
"Error computing fingerprint"
);
return
-
1
;
}
...
...
@@ -288,8 +292,8 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
fingerprint_list
=
smartlist_create
();
if
(
should_log
)
debug
(
LD_DIRSERV
,
"%d fingerprints known."
,
smartlist_len
(
fingerprint_list
));
log_
debug
(
LD_DIRSERV
,
"%d fingerprints known."
,
smartlist_len
(
fingerprint_list
));
SMARTLIST_FOREACH
(
fingerprint_list
,
fingerprint_entry_t
*
,
ent
,
{
if
(
!
strcasecmp
(
fp
,
ent
->
fingerprint
))
...
...
@@ -318,20 +322,20 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
if
(
rej
==
ADDR_POLICY_PROBABLY_REJECTED
||
rej
==
ADDR_POLICY_REJECTED
)
{
if
(
should_log
)
info
(
LD_DIRSERV
,
"Rejecting '%s' because of address '%s'"
,
nickname
,
address
);
log_
info
(
LD_DIRSERV
,
"Rejecting '%s' because of address '%s'"
,
nickname
,
address
);
if
(
msg
)
*
msg
=
"Authdir is rejecting routers in this range."
;
return
FP_REJECT
;
}
if
(
inv
==
ADDR_POLICY_PROBABLY_REJECTED
||
inv
==
ADDR_POLICY_REJECTED
)
{
if
(
should_log
)
info
(
LD_DIRSERV
,
"Not marking '%s' valid because of address '%s'"
,
nickname
,
address
);
log_
info
(
LD_DIRSERV
,
"Not marking '%s' valid because of address '%s'"
,
nickname
,
address
);
return
FP_INVALID
;
}
if
(
should_log
)
debug
(
LD_DIRSERV
,
"No fingerprint found for '%s'"
,
nickname
);
log_
debug
(
LD_DIRSERV
,
"No fingerprint found for '%s'"
,
nickname
);
if
(
!
platform
||
tor_version_as_new_as
(
platform
,
"0.1.0.2-rc"
))
return
reject_unlisted
?
FP_REJECT
:
FP_VALID
;
else
...
...
@@ -339,16 +343,16 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
}
if
(
0
==
strcasecmp
(
nn_ent
->
fingerprint
,
fp
))
{
if
(
should_log
)
debug
(
LD_DIRSERV
,
"Good fingerprint for '%s'"
,
nickname
);
log_
debug
(
LD_DIRSERV
,
"Good fingerprint for '%s'"
,
nickname
);
return
FP_NAMED
;
/* Right fingerprint. */
}
else
{
if
(
should_log
)
warn
(
LD_DIRSERV
,
"Mismatched fingerprint for '%s': expected '%s' got '%s'. "
"ContactInfo '%s', platform '%s'.)"
,
nickname
,
nn_ent
->
fingerprint
,
fp
,
contact
?
contact
:
""
,
platform
?
platform
:
""
);
log_
warn
(
LD_DIRSERV
,
"Mismatched fingerprint for '%s': expected '%s' got '%s'. "
"ContactInfo '%s', platform '%s'.)"
,
nickname
,
nn_ent
->
fingerprint
,
fp
,
contact
?
contact
:
""
,
platform
?
platform
:
""
);
if
(
msg
)
*
msg
=
"Rejected: There is already a verified server with this nickname "
"and a different fingerprint."
;
...
...
@@ -406,14 +410,14 @@ dirserv_router_has_valid_address(routerinfo_t *ri)
if
(
get_options
()
->
DirAllowPrivateAddresses
)
return
0
;
/* whatever it is, we're fine with it */
if
(
!
tor_inet_aton
(
ri
->
address
,
&
iaddr
))
{
info
(
LD_DIRSERV
,
"Router '%s' published non-IP address '%s'. Refusing."
,
ri
->
nickname
,
ri
->
address
);
log_
info
(
LD_DIRSERV
,
"Router '%s' published non-IP address '%s'. Refusing."
,
ri
->
nickname
,
ri
->
address
);
return
-
1
;
}
if
(
is_internal_IP
(
ntohl
(
iaddr
.
s_addr
),
0
))
{
info
(
LD_DIRSERV
,
"Router '%s' published internal IP address '%s'. Refusing."
,
ri
->
nickname
,
ri
->
address
);
log_
info
(
LD_DIRSERV
,
"Router '%s' published internal IP address '%s'. Refusing."
,
ri
->
nickname
,
ri
->
address
);
return
-
1
;
/* it's a private IP, we should reject it */
}
return
0
;
...
...
@@ -514,7 +518,7 @@ dirserv_add_descriptor(const char *desc, const char **msg)
/* Check: is the descriptor syntactically valid? */
ri
=
router_parse_entry_from_string
(
desc
,
NULL
);
if
(
!
ri
)
{
warn
(
LD_DIRSERV
,
"Couldn't parse uploaded server descriptor"
);
log_
warn
(
LD_DIRSERV
,
"Couldn't parse uploaded server descriptor"
);
*
msg
=
"Rejected: Couldn't parse server descriptor."
;
return
-
2
;
}
...
...
@@ -526,9 +530,9 @@ dirserv_add_descriptor(const char *desc, const char **msg)
if
(
ri_old
&&
ri_old
->
cache_info
.
published_on
<
ri
->
cache_info
.
published_on
&&
router_differences_are_cosmetic
(
ri_old
,
ri
)
&&
!
router_is_me
(
ri
))
{
info
(
LD_DIRSERV
,
"Not replacing descriptor from '%s'; differences are cosmetic."
,
ri
->
nickname
);
log_
info
(
LD_DIRSERV
,
"Not replacing descriptor from '%s'; differences are cosmetic."
,
ri
->
nickname
);
*
msg
=
"Not replacing router descriptor; no information has changed since "
"the last one with this identity."
;
routerinfo_free
(
ri
);
...
...
@@ -572,22 +576,22 @@ directory_remove_invalid(void)
router_status_t
r
=
dirserv_router_get_status
(
ent
,
&
msg
);
switch
(
r
)
{
case
FP_REJECT
:
info
(
LD_DIRSERV
,
"Router '%s' is now rejected: %s"
,
ent
->
nickname
,
msg
?
msg
:
""
);
log_
info
(
LD_DIRSERV
,
"Router '%s' is now rejected: %s"
,
ent
->
nickname
,
msg
?
msg
:
""
);
routerlist_remove
(
rl
,
ent
,
i
--
,
0
);
changed
=
1
;
break
;
case
FP_NAMED
:
if
(
!
ent
->
is_verified
||
!
ent
->
is_named
)
{
info
(
LD_DIRSERV
,
"Router '%s' is now verified and named."
,
ent
->
nickname
);
log_
info
(
LD_DIRSERV
,
"Router '%s' is now verified and named."
,
ent
->
nickname
);
ent
->
is_verified
=
ent
->
is_named
=
1
;
changed
=
1
;
}
break
;
case
FP_VALID
:
if
(
!
ent
->
is_verified
||
ent
->
is_named
)
{
info
(
LD_DIRSERV
,
"Router '%s' is now verified."
,
ent
->
nickname
);
log_
info
(
LD_DIRSERV
,
"Router '%s' is now verified."
,
ent
->
nickname
);
ent
->
is_verified
=
1
;
ent
->
is_named
=
0
;
changed
=
1
;
...
...
@@ -595,8 +599,8 @@ directory_remove_invalid(void)
break
;
case
FP_INVALID
:
if
(
ent
->
is_verified
||
ent
->
is_named
)
{
info
(
LD_DIRSERV
,
"Router '%s' is no longer verified."
,
ent
->
nickname
);
log_
info
(
LD_DIRSERV
,
"Router '%s' is no longer verified."
,
ent
->
nickname
);
ent
->
is_verified
=
ent
->
is_named
=
0
;
changed
=
1
;
}
...
...
@@ -812,7 +816,7 @@ dirserv_dump_directory_to_string(char **dir_out,
if
(
crypto_pk_write_public_key_to_string
(
private_key
,
&
identity_pkey
,
&
identity_pkey_len
)
<
0
)
{
warn
(
LD_BUG
,
"write identity_pkey to string failed!"
);
log_
warn
(
LD_BUG
,
"write identity_pkey to string failed!"
);
return
-
1
;
}
...
...
@@ -870,7 +874,7 @@ dirserv_dump_directory_to_string(char **dir_out,
goto
truncated
;
if
(
router_get_dir_hash
(
buf
,
digest
))
{
warn
(
LD_BUG
,
"couldn't compute digest"
);
log_
warn
(
LD_BUG
,
"couldn't compute digest"
);
tor_free
(
buf
);
return
-
1
;
}
...
...
@@ -882,7 +886,7 @@ dirserv_dump_directory_to_string(char **dir_out,
*
dir_out
=
buf
;
return
0
;
truncated:
warn
(
LD_BUG
,
"tried to exceed string length."
);
log_
warn
(
LD_BUG
,
"tried to exceed string length."
);
tor_free
(
buf
);
return
-
1
;
}
...
...
@@ -910,21 +914,21 @@ set_cached_dir(cached_dir_t *d, char *directory, time_t when)
{
time_t
now
=
time
(
NULL
);
if
(
when
<=
d
->
published
)
{
info
(
LD_DIRSERV
,
"Ignoring old directory; not caching."
);
log_
info
(
LD_DIRSERV
,
"Ignoring old directory; not caching."
);
tor_free
(
directory
);
}
else
if
(
when
>=
now
+
ROUTER_MAX_AGE
)
{
info
(
LD_DIRSERV
,
"Ignoring future directory; not caching."
);
log_
info
(
LD_DIRSERV
,
"Ignoring future directory; not caching."
);
tor_free
(
directory
);
}
else
{
/* if (when>d->published && when<now+ROUTER_MAX_AGE) */
debug
(
LD_DIRSERV
,
"Caching directory."
);
log_
debug
(
LD_DIRSERV
,
"Caching directory."
);
tor_free
(
d
->
dir
);
d
->
dir
=
directory
;
d
->
dir_len
=
strlen
(
directory
);
tor_free
(
d
->
dir_z
);
if
(
tor_gzip_compress
(
&
(
d
->
dir_z
),
&
(
d
->
dir_z_len
),
d
->
dir
,
d
->
dir_len
,
ZLIB_METHOD
))
{
warn
(
LD_BUG
,
"Error compressing cached directory"
);
log_
warn
(
LD_BUG
,
"Error compressing cached directory"
);
}
d
->
published
=
when
;
}
...
...
@@ -1043,11 +1047,11 @@ dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
if
(
regenerate
!=
NULL
)
{
if
(
dirty
&&
dirty
+
DIR_REGEN_SLACK_TIME
<
time
(
NULL
))
{
if
(
regenerate
())
{
err
(
LD_BUG
,
"Couldn't generate %s?"
,
name
);
log_
err
(
LD_BUG
,
"Couldn't generate %s?"
,
name
);
exit
(
1
);
}
}
else
{
info
(
LD_DIRSERV
,
"The %s is still clean; reusing."
,
name
);
log_
info
(
LD_DIRSERV
,
"The %s is still clean; reusing."
,
name
);
}
}
return
auth_src
?
auth_src
:
cache_src
;
...
...
@@ -1111,15 +1115,15 @@ dirserv_regenerate_directory(void)
if
(
dirserv_dump_directory_to_string
(
&
new_directory
,
get_identity_key
()))
{
warn
(
LD_BUG
,
"Error creating directory."
);
log_
warn
(
LD_BUG
,
"Error creating directory."
);
tor_free
(
new_directory
);
return
-
1
;
}
set_cached_dir
(
&
the_directory
,
new_directory
,
time
(
NULL
));
info
(
LD_DIRSERV
,
"New directory (size %d) has been built."
,
(
int
)
the_directory
.
dir_len
);
debug
(
LD_DIRSERV
,
"New directory (size %d):
\n
%s"
,
(
int
)
the_directory
.
dir_len
,
the_directory
.
dir
);
log_
info
(
LD_DIRSERV
,
"New directory (size %d) has been built."
,
(
int
)
the_directory
.
dir_len
);
log_
debug
(
LD_DIRSERV
,
"New directory (size %d):
\n
%s"
,
(
int
)
the_directory
.
dir_len
,
the_directory
.
dir
);
the_directory_is_dirty
=
0
;
...
...
@@ -1152,7 +1156,7 @@ generate_runningrouters(void)
}
if
(
crypto_pk_write_public_key_to_string
(
private_key
,
&
identity_pkey
,
&
identity_pkey_len
)
<
0
)
{
warn
(
LD_BUG
,
"write identity_pkey to string failed!"
);
log_
warn
(
LD_BUG
,
"write identity_pkey to string failed!"
);
goto
err
;
}
format_iso_time
(
published
,
time
(
NULL
));
...
...
@@ -1170,7 +1174,7 @@ generate_runningrouters(void)
tor_free
(
router_status
);
tor_free
(
identity_pkey
);
if
(
router_get_runningrouters_hash
(
s
,
digest
))
{
warn
(
LD_BUG
,
"couldn't compute digest"
);
log_
warn
(
LD_BUG
,
"couldn't compute digest"
);
goto
err
;
}
if
(
router_append_dirobj_signature
(
s
,
len
,
digest
,
private_key
)
<
0
)
...
...
@@ -1286,7 +1290,7 @@ dirserv_compute_stable_uptime(routerlist_t *rl)
stable_uptime
=
*
(
long
*
)
smartlist_get
(
uptimes
,
smartlist_len
(
uptimes
)
/
2
);
info
(
LD_DIRSERV
,
"Uptime cutoff is %ld seconds."
,
stable_uptime
);
log_
info
(
LD_DIRSERV
,
"Uptime cutoff is %ld seconds."
,
stable_uptime
);
SMARTLIST_FOREACH
(
uptimes
,
long
*
,
up
,
tor_free
(
up
));
smartlist_free
(
uptimes
);
...
...
@@ -1328,7 +1332,7 @@ generate_v2_networkstatus(void)
const
char
*
contact
;
if
(
resolve_my_address
(
options
,
&
addr
,
&
hostname
)
<
0
)
{
warn
(
LD_NET
,
"Couldn't resolve my hostname"
);
log_
warn
(
LD_NET
,
"Couldn't resolve my hostname"
);
goto
done
;
}
in
.
s_addr
=
htonl
(
addr
);
...
...
@@ -1341,12 +1345,12 @@ generate_v2_networkstatus(void)
if
(
crypto_pk_write_public_key_to_string
(
private_key
,
&
identity_pkey
,
&
identity_pkey_len
)
<
0
)
{
warn
(
LD_BUG
,
"Writing public key to string failed."
);
log_
warn
(
LD_BUG
,
"Writing public key to string failed."
);
goto
done
;
}
if
(
crypto_pk_get_fingerprint
(
private_key
,
fingerprint
,
0
)
<
0
)
{
err
(
LD_BUG
,
"Error computing fingerprint"
);
log_
err
(
LD_BUG
,
"Error computing fingerprint"
);
goto
done
;
}
...
...
@@ -1436,7 +1440,7 @@ generate_v2_networkstatus(void)
f_running
?
" Running"
:
""
,
f_valid
?
" Valid"
:
""
,
f_v2_dir
?
" V2Dir"
:
""
)
<
0
)
{
warn
(
LD_BUG
,
"Unable to print router status."
);
log_
warn
(
LD_BUG
,
"Unable to print router status."
);
goto
done
;
}
outp
+=
strlen
(
outp
);
...
...
@@ -1445,17 +1449,17 @@ generate_v2_networkstatus(void)
if
(
tor_snprintf
(
outp
,
endp
-
outp
,
"directory-signature %s
\n
"
,
get_options
()
->
Nickname
)
<
0
)
{
warn
(
LD_BUG
,
"Unable to write signature line."
);
log_
warn
(
LD_BUG
,
"Unable to write signature line."
);
goto
done
;
}
if
(
router_get_networkstatus_v2_hash
(
status
,
digest
)
<
0
)
{
warn
(
LD_BUG
,
"Unable to hash network status"
);
log_
warn
(
LD_BUG
,
"Unable to hash network status"
);
goto
done
;
}
if
(
router_append_dirobj_signature
(
outp
,
endp
-
outp
,
digest
,
private_key
)
<
0
)
{
warn
(
LD_BUG
,
"Unable to sign router status."
);
log_
warn
(
LD_BUG
,
"Unable to sign router status."
);
goto
done
;
}
...
...
@@ -1503,7 +1507,8 @@ dirserv_get_networkstatus_v2(smartlist_t *result,
if
(
d
)
smartlist_add
(
result
,
d
);
else
warn
(
LD_BUG
,
"Unable to generate an authoritative network status."
);
log_warn
(
LD_BUG
,
"Unable to generate an authoritative network status."
);
}
}
else
if
(
!
strcmp
(
key
,
"all"
))
{
digestmap_iter_t
*
iter
;
...
...
@@ -1518,8 +1523,8 @@ dirserv_get_networkstatus_v2(smartlist_t *result,
iter
=
digestmap_iter_next
(
cached_v2_networkstatus
,
iter
);
}
if
(
smartlist_len
(
result
)
==
0
)
warn
(
LD_DIRSERV
,
"Client requested 'all' network status objects; we have none."
);
log_
warn
(
LD_DIRSERV
,
"Client requested 'all' network status objects; we have none."
);
}
else
if
(
!
strcmpstart
(
key
,
"fp/"
))
{
smartlist_t
*
digests
=
smartlist_create
();
dir_split_resource_into_fingerprints
(
key
+
3
,
digests
,
NULL
,
1
);
...
...
@@ -1534,8 +1539,8 @@ dirserv_get_networkstatus_v2(smartlist_t *result,
}
else
{
char
hexbuf
[
HEX_DIGEST_LEN
+
1
];
base16_encode
(
hexbuf
,
sizeof
(
hexbuf
),
cp
,
DIGEST_LEN
);
info
(
LD_DIRSERV
,
"Don't know about any network status with "
"fingerprint '%s'"
,
hexbuf
);
log_
info
(
LD_DIRSERV
,
"Don't know about any network status with "
"fingerprint '%s'"
,
hexbuf
);
}
tor_free
(
cp
);
});
...
...
@@ -1651,15 +1656,17 @@ dirserv_orconn_tls_done(const char *address,
if
(
!
ri
->
is_verified
)
{
/* We have a router at the same address! */
if
(
strcasecmp
(
ri
->
nickname
,
nickname_rcvd
))
{
notice
(
LD_DIRSERV
,
"Dropping descriptor: nickname '%s' does not match "
"nickname '%s' in cert from %s:%d"
,
ri
->
nickname
,
nickname_rcvd
,
address
,
or_port
);
log_notice
(
LD_DIRSERV
,
"Dropping descriptor: nickname '%s' does not match "
"nickname '%s' in cert from %s:%d"
,
ri
->
nickname
,
nickname_rcvd
,
address
,
or_port
);
drop
=
1
;
}
else
if
(
memcmp
(
ri
->
cache_info
.
identity_digest
,
digest_rcvd
,
DIGEST_LEN
))
{
notice
(
LD_DIRSERV
,
"Dropping descriptor: identity key does not match "
"key in cert from %s:%d"
,
address
,
or_port
);
log_notice
(
LD_DIRSERV
,
"Dropping descriptor: identity key does not match "
"key in cert from %s:%d"
,
address
,
or_port
);
drop
=
1
;
}
}
...
...
@@ -1667,7 +1674,8 @@ dirserv_orconn_tls_done(const char *address,
routerlist_remove
(
rl
,
ri
,
i
--
,
0
);
directory_set_dirty
();
}
else
{
/* correct nickname and digest. mark this router reachable! */
info
(
LD_DIRSERV
,
"Found router %s to be reachable. Yay."
,
ri
->
nickname
);
log_info
(
LD_DIRSERV
,
"Found router %s to be reachable. Yay."
,
ri
->
nickname
);
ri
->
last_reachable
=
time
(
NULL
);
ri
->
num_unreachable_notifications
=
0
;
}
...
...
src/or/dns.c
View file @
aa63a84f
...
...
@@ -160,15 +160,18 @@ purge_expired_resolves(uint32_t now)
*/
while
(
oldest_cached_resolve
&&
(
oldest_cached_resolve
->
expire
<
now
))
{
resolve
=
oldest_cached_resolve
;
debug
(
LD_EXIT
,
"Forgetting old cached resolve (address %s, expires %lu)"
,
safe_str
(
resolve
->
address
),
(
unsigned
long
)
resolve
->
expire
);
log_debug
(
LD_EXIT
,
"Forgetting old cached resolve (address %s, expires %lu)"
,
safe_str
(
resolve
->
address
),
(
unsigned
long
)
resolve
->
expire
);
if
(
resolve
->
state
==
CACHE_STATE_PENDING
)
{
debug
(
LD_EXIT
,
"Bug: Expiring a dns resolve ('%s') that's still pending."
" Forgot to cull it?"
,
safe_str
(
resolve
->
address
));
log_debug
(
LD_EXIT
,
"Bug: Expiring a dns resolve ('%s') that's still pending."
" Forgot to cull it?"
,
safe_str
(
resolve
->
address
));
tor_fragile_assert
();
}
if
(
resolve
->
pending_connections
)
{
debug
(
LD_EXIT
,
"Closing pending connections on expiring DNS resolve!"
);
log_debug
(
LD_EXIT
,
"Closing pending connections on expiring DNS resolve!"
);
tor_fragile_assert
();
while
(
resolve
->
pending_connections
)
{
pend
=
resolve
->
pending_connections
;
...
...
@@ -296,21 +299,21 @@ dns_resolve(connection_t *exitconn)
pending_connection
->
conn
=
exitconn
;
pending_connection
->
next
=
resolve
->
pending_connections
;
resolve
->
pending_connections
=
pending_connection
;
debug
(
LD_EXIT
,
"Connection (fd %d) waiting for pending DNS "
"resolve of '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
log_
debug
(
LD_EXIT
,
"Connection (fd %d) waiting for pending DNS "
"resolve of '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
exitconn
->
state
=
EXIT_CONN_STATE_RESOLVING
;
return
0
;
case
CACHE_STATE_VALID
:
exitconn
->
addr
=
resolve
->
addr
;
debug
(
LD_EXIT
,
"Connection (fd %d) found cached answer for '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
log_
debug
(
LD_EXIT
,
"Connection (fd %d) found cached answer for '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
if
(
exitconn
->
purpose
==
EXIT_PURPOSE_RESOLVE
)
send_resolved_cell
(
exitconn
,
RESOLVED_TYPE_IPV4
);
return
1
;
case
CACHE_STATE_FAILED
:
debug
(
LD_EXIT
,
"Connection (fd %d) found cached error for '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
log_
debug
(
LD_EXIT
,
"Connection (fd %d) found cached error for '%s'"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
));
if
(
exitconn
->
purpose
==
EXIT_PURPOSE_RESOLVE
)
send_resolved_cell
(
exitconn
,
RESOLVED_TYPE_ERROR
);
circ
=
circuit_get_by_edge_conn
(
exitconn
);
...
...
@@ -359,16 +362,16 @@ assign_to_dnsworker(connection_t *exitconn)
DNSWORKER_STATE_IDLE
);
if
(
!
dnsconn
)
{
warn
(
LD_EXIT
,
"no idle dns workers. Failing."
);
log_
warn
(
LD_EXIT
,
"no idle dns workers. Failing."
);
if
(
exitconn
->
purpose
==
EXIT_PURPOSE_RESOLVE
)
send_resolved_cell
(
exitconn
,
RESOLVED_TYPE_ERROR_TRANSIENT
);
goto
err
;
}
debug
(
LD_EXIT
,
"Connection (fd %d) needs to resolve '%s'; assigning "
"to DNSWorker (fd %d)"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
),
dnsconn
->
s
);
log_
debug
(
LD_EXIT
,
"Connection (fd %d) needs to resolve '%s'; assigning "
"to DNSWorker (fd %d)"
,
exitconn
->
s
,
safe_str
(
exitconn
->
address
),
dnsconn
->
s
);
tor_free
(
dnsconn
->
address
);
dnsconn
->
address
=
tor_strdup
(
exitconn
->
address
);
...
...
@@ -402,8 +405,8 @@ connection_dns_remove(connection_t *conn)
resolve
=
HT_FIND
(
cache_map
,
&
cache_root
,
&
search
);
if
(
!
resolve
)
{
/* XXXX RD This *is* a bug, right? -NM */
notice
(
LD_BUG
,
"Address '%s' is not pending. Dropping."
,
safe_str
(
conn
->
address
));
log_
notice
(
LD_BUG
,
"Address '%s' is not pending. Dropping."
,
safe_str
(
conn
->
address
));
return
;
}
...
...
@@ -415,9 +418,9 @@ connection_dns_remove(connection_t *conn)
if
(
pend
->
conn
==
conn
)
{
resolve
->
pending_connections
=
pend
->
next
;
tor_free
(
pend
);
debug
(
LD_EXIT
,
"First connection (fd %d) no longer waiting
for resolve
"
"
of '%s'"
,
conn
->
s
,
safe_str
(
conn
->
address
));
log_
debug
(
LD_EXIT
,
"First connection (fd %d) no longer waiting "
"for resolve
of '%s'"
,
conn
->
s
,
safe_str
(
conn
->
address
));
return
;
}
else
{
for
(
;
pend
->
next
;
pend
=
pend
->
next
)
{
...
...
@@ -425,9 +428,9 @@ connection_dns_remove(connection_t *conn)
victim
=
pend
->
next
;
pend
->
next
=
victim
->
next
;
tor_free
(
victim
);
debug
(
LD_EXIT
,
"Connection (fd %d) no longer waiting for resolve "
"
of '%s'"
,
conn
->
s
,
safe_str
(
conn
->
address
));
log_
debug
(
LD_EXIT
,
"Connection (fd %d) no longer waiting for resolve
of '%s'"
,
conn
->
s
,
safe_str
(
conn
->
address
));
return
;
/* more are pending */
}
}
...
...
@@ -489,22 +492,25 @@ dns_cancel_pending_resolve(char *address)
resolve
=
HT_FIND
(
cache_map
,
&
cache_root
,
&
search
);
if
(
!
resolve
)
{
/* XXXX RD This *is* a bug, right? -NM */
notice
(
LD_BUG
,
"Address '%s' is not pending. Dropping."
,
safe_str
(
address
));
log_notice
(
LD_BUG
,
"Address '%s' is not pending. Dropping."
,
safe_str
(
address
));
return
;
}
if
(
!
resolve
->
pending_connections
)
{
/* XXX this should never trigger, but sometimes it does */
warn
(
LD_BUG
,
"Bug: Address '%s' is pending but has no pending connections!"
,
safe_str
(
address
));
log_warn
(
LD_BUG
,
"Bug: Address '%s' is pending but has no pending connections!"
,
safe_str
(
address
));
tor_fragile_assert
();
return
;
}
tor_assert
(
resolve
->
pending_connections
);
/* mark all pending connections to fail */
debug
(
LD_EXIT
,
"Failing all connections waiting on DNS resolve of '%s'"
,
safe_str
(
address
));
log_debug
(
LD_EXIT
,
"Failing all connections waiting on DNS resolve of '%s'"
,
safe_str
(
address
));
while
(
resolve
->
pending_connections
)
{
pend
=
resolve
->
pending_connections
;
pend
->
conn
->
state
=
EXIT_CONN_STATE_RESOLVEFAILED
;
...
...
@@ -575,8 +581,8 @@ dns_found_answer(char *address, uint32_t addr, char outcome)
resolve
=
HT_FIND
(
cache_map
,
&
cache_root
,
&
search
);
if
(
!
resolve
)
{
info
(
LD_EXIT
,
"Resolved unasked address '%s'; caching anyway."
,
safe_str
(
address
));
log_
info
(
LD_EXIT
,
"Resolved unasked address '%s'; caching anyway."
,
safe_str
(
address
));
resolve
=
tor_malloc_zero
(
sizeof
(
cached_resolve_t
));
resolve
->
state
=
(
outcome
==
DNS_RESOLVE_SUCCEEDED
)
?
CACHE_STATE_VALID
:
CACHE_STATE_FAILED
;
...
...
@@ -589,8 +595,8 @@ dns_found_answer(char *address, uint32_t addr, char outcome)
if
(
resolve
->
state
!=
CACHE_STATE_PENDING
)
{
/* XXXX Maybe update addr? or check addr for consistency? Or let
* VALID replace FAILED? */
notice
(
LD_EXIT
,
"Resolved '%s' which was already resolved; ignoring"
,
safe_str
(
address
));
log_
notice
(
LD_EXIT
,
"Resolved '%s' which was already resolved; ignoring"
,
safe_str
(
address
));
tor_assert
(
resolve
->
pending_connections
==
NULL
);
return
;
}
...
...
@@ -681,7 +687,7 @@ connection_dns_finished_flushing(connection_t *conn)
int
connection_dns_reached_eof
(
connection_t
*
conn
)
{
warn
(
LD_EXIT
,
"Read eof. Worker died unexpectedly."
);
log_
warn
(
LD_EXIT
,
"Read eof. Worker died unexpectedly."
);
if
(
conn
->
state
==
DNSWORKER_STATE_BUSY
)
{
/* don't cancel the resolve here -- it would be cancelled in
* connection_about_to_close_connection(), since conn is still
...
...
@@ -707,9 +713,10 @@ connection_dns_process_inbuf(connection_t *conn)
tor_assert
(
conn
->
type
==
CONN_TYPE_DNSWORKER
);
if
(
conn
->
state
!=
DNSWORKER_STATE_BUSY
&&
buf_datalen
(
conn
->
inbuf
))
{
warn
(
LD_BUG
,
"Bug: read data (%d bytes) from an idle dns worker (fd %d, "
"address '%s'). Please report."
,
(
int
)
buf_datalen
(
conn
->
inbuf
),
conn
->
s
,
safe_str
(
conn
->
address
));
log_warn
(
LD_BUG
,
"Bug: read data (%d bytes) from an idle dns worker (fd %d, "
"address '%s'). Please report."
,
(
int
)
buf_datalen
(
conn
->
inbuf
),
conn
->
s
,
safe_str
(
conn
->
address
));