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
Mike Perry
Tor
Commits
6fbdf635
Commit
6fbdf635
authored
Jul 31, 2009
by
Mike Perry
Browse files
Implement measured bw parsing + unit tests.
parent
9da7b223
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/or/config.c
View file @
6fbdf635
...
...
@@ -337,6 +337,7 @@ static config_var_t _option_vars[] = {
V
(
V3AuthDistDelay
,
INTERVAL
,
"5 minutes"
),
V
(
V3AuthNIntervalsValid
,
UINT
,
"3"
),
V
(
V3AuthUseLegacyKey
,
BOOL
,
"0"
),
V
(
V3BandwidthsFile
,
FILENAME
,
NULL
),
VAR
(
"VersioningAuthoritativeDirectory"
,
BOOL
,
VersioningAuthoritativeDir
,
"0"
),
V
(
VirtualAddrNetwork
,
STRING
,
"127.192.0.0/10"
),
V
(
WarnPlaintextPorts
,
CSV
,
"23,109,110,143"
),
...
...
src/or/dirserv.c
View file @
6fbdf635
...
...
@@ -63,6 +63,9 @@ static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
time_t
publish_cutoff
);
static
int
dirserv_add_extrainfo
(
extrainfo_t
*
ei
,
const
char
**
msg
);
/************** Measured Bandwidth parsing code ******/
#define MAX_MEASUREMENT_AGE (3*24*60*60)
/* 3 days */
/************** Fingerprint handling code ************/
#define FP_NAMED 1
/**< Listed in fingerprint file. */
...
...
@@ -1854,16 +1857,18 @@ version_from_platform(const char *platform)
* which has at least <b>buf_len</b> free characters. Do NUL-termination.
* Use the same format as in network-status documents. If <b>version</b> is
* non-NULL, add a "v" line for the platform. Return 0 on success, -1 on
* failure. If <b>first_line_only</b> is true, don't include any flags
* or version line.
* failure.
*
* The format argument has three possible values:
* NS_V2 - Output an entry suitable for a V2 NS opinion document
* NS_V3_CONSENSUS - Output the first portion of a V3 NS consensus entry
* NS_V3_VOTE - Output a complete V3 NS vote
* NS_CONTROL_PORT - Output a NS docunent for the control port
*/
int
routerstatus_format_entry
(
char
*
buf
,
size_t
buf_len
,
routerstatus_t
*
rs
,
const
char
*
version
,
int
first_line_only
,
int
v2_format
)
/* XXX: first_line_only and v2_format should probably be be both
* replaced by a single purpose parameter.
*/
routerstatus_format_type_t
format
)
{
int
r
;
struct
in_addr
in
;
...
...
@@ -1894,7 +1899,12 @@ routerstatus_format_entry(char *buf, size_t buf_len,
log_warn
(
LD_BUG
,
"Not enough space in buffer."
);
return
-
1
;
}
if
(
first_line_only
)
/* TODO: Maybe we want to pass in what we need to build the rest of
* this here, instead of in the caller. Then we could use the
* networkstatus_type_t values, with an additional control port value
* added -MP */
if
(
format
==
NS_V3_CONSENSUS
)
return
0
;
cp
=
buf
+
strlen
(
buf
);
...
...
@@ -1931,62 +1941,81 @@ routerstatus_format_entry(char *buf, size_t buf_len,
cp
+=
strlen
(
cp
);
}
if
(
!
v2_
format
)
{
if
(
format
!=
NS_V2
)
{
routerinfo_t
*
desc
=
router_get_by_digest
(
rs
->
identity_digest
);
/* Blow up more or less nicely if we didn't get anything or not the
* thing we expected.
*/
if
(
!
desc
)
{
char
id
[
HEX_DIGEST_LEN
+
1
];
char
dd
[
HEX_DIGEST_LEN
+
1
];
base16_encode
(
id
,
sizeof
(
id
),
rs
->
identity_digest
,
DIGEST_LEN
);
base16_encode
(
dd
,
sizeof
(
dd
),
rs
->
descriptor_digest
,
DIGEST_LEN
);
log_warn
(
LD_BUG
,
"Cannot get any descriptor for %s "
"(wanted descriptor %s)."
,
id
,
dd
);
return
-
1
;
};
if
(
memcmp
(
desc
->
cache_info
.
signed_descriptor_digest
,
rs
->
descriptor_digest
,
DIGEST_LEN
))
{
char
rl_d
[
HEX_DIGEST_LEN
+
1
];
char
rs_d
[
HEX_DIGEST_LEN
+
1
];
char
id
[
HEX_DIGEST_LEN
+
1
];
base16_encode
(
rl_d
,
sizeof
(
rl_d
),
desc
->
cache_info
.
signed_descriptor_digest
,
DIGEST_LEN
);
base16_encode
(
rs_d
,
sizeof
(
rs_d
),
rs
->
descriptor_digest
,
DIGEST_LEN
);
base16_encode
(
id
,
sizeof
(
id
),
rs
->
identity_digest
,
DIGEST_LEN
);
log_err
(
LD_BUG
,
"descriptor digest in routerlist does not match "
"the one in routerstatus: %s vs %s "
"(router %s)
\n
"
,
rl_d
,
rs_d
,
id
);
tor_assert
(
!
memcmp
(
desc
->
cache_info
.
signed_descriptor_digest
,
rs
->
descriptor_digest
,
DIGEST_LEN
));
};
if
(
format
!=
NS_CONTROL_PORT
)
{
/* Blow up more or less nicely if we didn't get anything or not the
* thing we expected.
*/
if
(
!
desc
)
{
char
id
[
HEX_DIGEST_LEN
+
1
];
char
dd
[
HEX_DIGEST_LEN
+
1
];
base16_encode
(
id
,
sizeof
(
id
),
rs
->
identity_digest
,
DIGEST_LEN
);
base16_encode
(
dd
,
sizeof
(
dd
),
rs
->
descriptor_digest
,
DIGEST_LEN
);
log_warn
(
LD_BUG
,
"Cannot get any descriptor for %s "
"(wanted descriptor %s)."
,
id
,
dd
);
return
-
1
;
};
/* This assert can fire for the control port, because
* it can request NS documents before all descriptors
* have been fetched. */
if
(
memcmp
(
desc
->
cache_info
.
signed_descriptor_digest
,
rs
->
descriptor_digest
,
DIGEST_LEN
))
{
char
rl_d
[
HEX_DIGEST_LEN
+
1
];
char
rs_d
[
HEX_DIGEST_LEN
+
1
];
char
id
[
HEX_DIGEST_LEN
+
1
];
base16_encode
(
rl_d
,
sizeof
(
rl_d
),
desc
->
cache_info
.
signed_descriptor_digest
,
DIGEST_LEN
);
base16_encode
(
rs_d
,
sizeof
(
rs_d
),
rs
->
descriptor_digest
,
DIGEST_LEN
);
base16_encode
(
id
,
sizeof
(
id
),
rs
->
identity_digest
,
DIGEST_LEN
);
log_err
(
LD_BUG
,
"descriptor digest in routerlist does not match "
"the one in routerstatus: %s vs %s "
"(router %s)
\n
"
,
rl_d
,
rs_d
,
id
);
tor_assert
(
!
memcmp
(
desc
->
cache_info
.
signed_descriptor_digest
,
rs
->
descriptor_digest
,
DIGEST_LEN
));
};
}
r
=
tor_snprintf
(
cp
,
buf_len
-
(
cp
-
buf
),
"w Bandwidth=%d
\n
"
,
router_get_advertised_bandwidth_capped
(
desc
)
/
1024
);
if
(
r
<
0
)
{
log_warn
(
LD_BUG
,
"Not enough space in buffer."
);
return
-
1
;
}
cp
+=
strlen
(
cp
);
if
(
format
==
NS_V3_VOTE
&&
rs
->
has_measured_bw
)
{
*--
cp
=
'\0'
;
/* Kill "\n" */
r
=
tor_snprintf
(
cp
,
buf_len
-
(
cp
-
buf
),
" Measured=%d
\n
"
,
rs
->
measured_bw
);
if
(
r
<
0
)
{
log_warn
(
LD_BUG
,
"Not enough space in buffer for weight line."
);
return
-
1
;
}
cp
+=
strlen
(
cp
);
}
summary
=
policy_summarize
(
desc
->
exit_policy
);
r
=
tor_snprintf
(
cp
,
buf_len
-
(
cp
-
buf
),
"p %s
\n
"
,
summary
);
if
(
r
<
0
)
{
log_warn
(
LD_BUG
,
"Not enough space in buffer."
);
if
(
desc
)
{
summary
=
policy_summarize
(
desc
->
exit_policy
);
r
=
tor_snprintf
(
cp
,
buf_len
-
(
cp
-
buf
),
"p %s
\n
"
,
summary
);
if
(
r
<
0
)
{
log_warn
(
LD_BUG
,
"Not enough space in buffer."
);
tor_free
(
summary
);
return
-
1
;
}
cp
+=
strlen
(
cp
);
tor_free
(
summary
);
return
-
1
;
}
cp
+=
strlen
(
cp
);
tor_free
(
summary
);
}
return
0
;
...
...
@@ -2189,6 +2218,194 @@ router_clear_status_flags(routerinfo_t *router)
router
->
is_bad_exit
=
router
->
is_bad_directory
=
0
;
}
#ifndef HAVE_STRTOK_R
/*
* XXX-MP: If a system lacks strtok_r and we use a non-reentrant strtok,
* we may introduce odd bugs if we call a codepath that also uses strtok
* and resets its internal state. Do we want to abandon use of strtok
* entirely for this reason? Roger mentioned smartlist_split and
* eat_whitespace() as alternatives.
*/
static
char
*
strtok_r
(
char
*
s
,
const
char
*
delim
,
char
**
state
)
{
(
void
)
state
;
return
strtok
(
s
,
delim
);
}
#endif
/**
* Helper function to parse out a line in the measured bandwidth file
* into a measured_bw_line_t output structure. Returns -1 on failure
* or 0 on success.
*/
int
measured_bw_line_parse
(
measured_bw_line_t
*
out
,
const
char
*
orig_line
)
{
char
*
line
=
tor_strdup
(
orig_line
);
char
*
cp
=
line
;
int
got_bw
=
0
;
int
got_node_id
=
0
;
char
*
strtok_state
;
/* lame sauce d'jour */
cp
=
strtok_r
(
cp
,
"
\t
"
,
&
strtok_state
);
if
(
!
cp
)
{
log_warn
(
LD_DIRSERV
,
"Invalid line in bandwidth file: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
if
(
orig_line
[
strlen
(
orig_line
)
-
1
]
!=
'\n'
)
{
log_warn
(
LD_DIRSERV
,
"Incomplete line in bandwidth file: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
do
{
if
(
strncasecmp
(
cp
,
"bw="
,
strlen
(
"bw="
))
==
0
)
{
char
*
endptr
;
if
(
got_bw
)
{
log_warn
(
LD_DIRSERV
,
"Double bw= in bandwidth file line: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
cp
+=
strlen
(
"bw="
);
errno
=
0
;
out
->
bw
=
strtol
(
cp
,
&
endptr
,
0
);
if
(
errno
||
endptr
==
cp
||
(
*
endptr
&&
!
TOR_ISSPACE
(
*
endptr
))
||
out
->
bw
<
0
)
{
log_warn
(
LD_DIRSERV
,
"Invalid bandwidth in bandwidth file line: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
got_bw
=
1
;
}
else
if
(
strncasecmp
(
cp
,
"node_id=$"
,
strlen
(
"node_id=$"
))
==
0
)
{
if
(
got_node_id
)
{
log_warn
(
LD_DIRSERV
,
"Double node_id= in bandwidth file line: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
cp
+=
strlen
(
"node_id=$"
);
if
(
strlen
(
cp
)
!=
HEX_DIGEST_LEN
||
base16_decode
(
out
->
node_id
,
DIGEST_LEN
,
cp
,
HEX_DIGEST_LEN
))
{
log_warn
(
LD_DIRSERV
,
"Invalid node_id in bandwidth file line: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
strncpy
(
out
->
node_hex
,
cp
,
sizeof
(
out
->
node_hex
));
got_node_id
=
1
;
}
}
while
((
cp
=
strtok_r
(
NULL
,
"
\t
"
,
&
strtok_state
)));
if
(
got_bw
&&
got_node_id
)
{
tor_free
(
line
);
return
0
;
}
else
{
log_warn
(
LD_DIRSERV
,
"Incomplete line in bandwidth file: %s"
,
escaped
(
orig_line
));
tor_free
(
line
);
return
-
1
;
}
}
/**
* Helper function to apply a parsed measurement line to a list
* of bandwidth statuses. Returns true if a line is found,
* false otherwise.
*/
int
measured_bw_line_apply
(
measured_bw_line_t
*
parsed_line
,
smartlist_t
*
routerstatuses
)
{
routerstatus_t
*
rs
=
NULL
;
if
(
!
routerstatuses
)
return
0
;
rs
=
smartlist_bsearch
(
routerstatuses
,
parsed_line
->
node_id
,
compare_digest_to_routerstatus_entry
);
if
(
rs
)
{
rs
->
has_measured_bw
=
1
;
rs
->
measured_bw
=
parsed_line
->
bw
;
}
else
{
log_info
(
LD_DIRSERV
,
"Node ID %s not found in routerstatus list"
,
parsed_line
->
node_hex
);
}
return
rs
!=
NULL
;
}
/**
* Read the measured bandwidth file and apply it to the list of
* routerstatuses. Returns -1 on error, 0 otherwise.
*/
int
dirserv_read_measured_bandwidths
(
const
char
*
from_file
,
smartlist_t
*
routerstatuses
)
{
char
line
[
256
];
FILE
*
fp
=
fopen
(
from_file
,
"r"
);
int
applied_lines
=
0
;
time_t
file_time
;
int
ok
;
if
(
fp
==
NULL
)
{
log_warn
(
LD_CONFIG
,
"Can't open bandwidth file at configured location: %s"
,
from_file
);
return
-
1
;
}
fgets
(
line
,
sizeof
(
line
),
fp
);
if
(
line
[
strlen
(
line
)
-
1
]
!=
'\n'
)
{
log_warn
(
LD_DIRSERV
,
"Long or truncated time in bandwidth file: %s"
,
escaped
(
line
));
fclose
(
fp
);
return
-
1
;
}
line
[
strlen
(
line
)
-
1
]
=
'\0'
;
file_time
=
tor_parse_ulong
(
line
,
10
,
0
,
ULONG_MAX
,
&
ok
,
NULL
);
if
(
!
ok
)
{
log_warn
(
LD_DIRSERV
,
"Non-integer time in bandwidth file: %s"
,
escaped
(
line
));
fclose
(
fp
);
return
-
1
;
}
if
((
time
(
NULL
)
-
file_time
)
>
MAX_MEASUREMENT_AGE
)
{
log_warn
(
LD_DIRSERV
,
"Bandwidth measurement file stale. Age: %u"
,
(
unsigned
)(
time
(
NULL
)
-
file_time
));
fclose
(
fp
);
return
-
1
;
}
if
(
routerstatuses
)
smartlist_sort
(
routerstatuses
,
compare_routerstatus_entries
);
while
(
!
feof
(
fp
))
{
measured_bw_line_t
parsed_line
;
fgets
(
line
,
sizeof
(
line
),
fp
);
if
(
measured_bw_line_parse
(
&
parsed_line
,
line
)
!=
-
1
)
{
if
(
measured_bw_line_apply
(
&
parsed_line
,
routerstatuses
)
>
0
)
applied_lines
++
;
}
}
fclose
(
fp
);
log_notice
(
LD_DIRSERV
,
"Bandwidth measurement file successfully read. "
"Applied %d measurements."
,
applied_lines
);
return
0
;
}
/** Return a new networkstatus_t* containing our current opinion. (For v3
* authorities) */
networkstatus_t
*
...
...
@@ -2288,9 +2505,15 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
smartlist_add
(
routerstatuses
,
vrs
);
}
});
smartlist_free
(
routers
);
digestmap_free
(
omit_as_sybil
,
NULL
);
if
(
options
->
V3BandwidthsFile
)
{
dirserv_read_measured_bandwidths
(
options
->
V3BandwidthsFile
,
routerstatuses
);
}
v3_out
=
tor_malloc_zero
(
sizeof
(
networkstatus_t
));
v3_out
->
type
=
NS_TYPE_VOTE
;
...
...
@@ -2494,7 +2717,7 @@ generate_v2_networkstatus_opinion(void)
if
(
digestmap_get
(
omit_as_sybil
,
ri
->
cache_info
.
identity_digest
))
clear_status_flags_on_sybil
(
&
rs
);
if
(
routerstatus_format_entry
(
outp
,
endp
-
outp
,
&
rs
,
version
,
0
,
1
))
{
if
(
routerstatus_format_entry
(
outp
,
endp
-
outp
,
&
rs
,
version
,
NS_V2
))
{
log_warn
(
LD_BUG
,
"Unable to print router status."
);
tor_free
(
version
);
goto
done
;
...
...
src/or/dirvote.c
View file @
6fbdf635
...
...
@@ -103,6 +103,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
tor_snprintf
(
status
,
len
,
"network-status-version 3
\n
"
"vote-status %s
\n
"
/* TODO-160: add 6 when ready */
"consensus-methods 1 2 3 4 5
\n
"
"published %s
\n
"
"valid-after %s
\n
"
...
...
@@ -142,7 +143,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
SMARTLIST_FOREACH
(
v3_ns
->
routerstatus_list
,
vote_routerstatus_t
*
,
vrs
,
{
if
(
routerstatus_format_entry
(
outp
,
endp
-
outp
,
&
vrs
->
status
,
vrs
->
version
,
0
,
0
)
<
0
)
{
vrs
->
version
,
NS_V3_VOTE
)
<
0
)
{
log_warn
(
LD_BUG
,
"Unable to print router status."
);
goto
err
;
}
...
...
@@ -701,7 +702,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_t
*
versions
=
smartlist_create
();
smartlist_t
*
exitsummaries
=
smartlist_create
();
uint32_t
*
bandwidths
=
tor_malloc
(
sizeof
(
uint32_t
)
*
smartlist_len
(
votes
));
uint32_t
*
measured_bws
=
tor_malloc
(
sizeof
(
uint32_t
)
*
smartlist_len
(
votes
));
int
num_bandwidths
;
int
num_mbws
;
int
*
n_voter_flags
;
/* n_voter_flags[j] is the number of flags that
* votes[j] knows about. */
...
...
@@ -835,6 +839,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_clear
(
chosen_flags
);
smartlist_clear
(
versions
);
num_bandwidths
=
0
;
num_mbws
=
0
;
/* Okay, go through all the entries for this digest. */
SMARTLIST_FOREACH_BEGIN
(
votes
,
networkstatus_t
*
,
v
)
{
...
...
@@ -868,6 +873,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* count bandwidths */
if
(
rs
->
status
.
has_measured_bw
)
measured_bws
[
num_mbws
++
]
=
rs
->
status
.
measured_bw
;
if
(
rs
->
status
.
has_bandwidth
)
bandwidths
[
num_bandwidths
++
]
=
rs
->
status
.
bandwidth
;
}
SMARTLIST_FOREACH_END
(
v
);
...
...
@@ -945,7 +953,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* Pick a bandwidth */
if
(
consensus_method
>=
5
&&
num_bandwidths
>
0
)
{
if
(
consensus_method
>=
6
&&
num_mbws
>
2
)
{
rs_out
.
has_bandwidth
=
1
;
rs_out
.
bandwidth
=
median_uint32
(
measured_bws
,
num_mbws
);
}
else
if
(
consensus_method
>=
5
&&
num_bandwidths
>
0
)
{
rs_out
.
has_bandwidth
=
1
;
rs_out
.
bandwidth
=
median_uint32
(
bandwidths
,
num_bandwidths
);
}
...
...
@@ -1036,7 +1047,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
/* Okay!! Now we can write the descriptor... */
/* First line goes into "buf". */
routerstatus_format_entry
(
buf
,
sizeof
(
buf
),
&
rs_out
,
NULL
,
1
,
0
);
routerstatus_format_entry
(
buf
,
sizeof
(
buf
),
&
rs_out
,
NULL
,
NS_V3_CONSENSUS
);
smartlist_add
(
chunks
,
tor_strdup
(
buf
));
/* Second line is all flags. The "\n" is missing. */
smartlist_add
(
chunks
,
...
...
@@ -1055,8 +1067,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
log_warn
(
LD_BUG
,
"Not enough space in buffer for weight line."
);
*
buf
=
'\0'
;
}
smartlist_add
(
chunks
,
tor_strdup
(
buf
));
};
/* Now the exitpolicy summary line. */
if
(
rs_out
.
has_exitsummary
)
{
char
buf
[
MAX_POLICY_LINE_LEN
+
1
];
...
...
src/or/networkstatus.c
View file @
6fbdf635
...
...
@@ -780,8 +780,8 @@ networkstatus_v2_list_clean(time_t now)
/** Helper for bsearching a list of routerstatus_t pointers: compare a
* digest in the key to the identity digest of a routerstatus_t. */
static
int
_
compare_digest_to_routerstatus_entry
(
const
void
*
_key
,
const
void
**
_member
)
int
compare_digest_to_routerstatus_entry
(
const
void
*
_key
,
const
void
**
_member
)
{
const
char
*
key
=
_key
;
const
routerstatus_t
*
rs
=
*
_member
;
...
...
@@ -794,7 +794,7 @@ routerstatus_t *
networkstatus_v2_find_entry
(
networkstatus_v2_t
*
ns
,
const
char
*
digest
)
{
return
smartlist_bsearch
(
ns
->
entries
,
digest
,
_
compare_digest_to_routerstatus_entry
);
compare_digest_to_routerstatus_entry
);
}
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
...
...
@@ -803,7 +803,7 @@ routerstatus_t *
networkstatus_vote_find_entry
(
networkstatus_t
*
ns
,
const
char
*
digest
)
{
return
smartlist_bsearch
(
ns
->
routerstatus_list
,
digest
,
_
compare_digest_to_routerstatus_entry
);
compare_digest_to_routerstatus_entry
);
}
/*XXXX make this static once functions are moved into this file. */
...
...
@@ -815,7 +815,7 @@ networkstatus_vote_find_entry_idx(networkstatus_t *ns,
const
char
*
digest
,
int
*
found_out
)
{
return
smartlist_bsearch_idx
(
ns
->
routerstatus_list
,
digest
,
_
compare_digest_to_routerstatus_entry
,
compare_digest_to_routerstatus_entry
,
found_out
);
}
...
...
@@ -868,7 +868,7 @@ router_get_consensus_status_by_id(const char *digest)
if
(
!
current_consensus
)
return
NULL
;
return
smartlist_bsearch
(
current_consensus
->
routerstatus_list
,
digest
,
_
compare_digest_to_routerstatus_entry
);
compare_digest_to_routerstatus_entry
);
}
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
...
...
@@ -1827,7 +1827,7 @@ char *
networkstatus_getinfo_helper_single
(
routerstatus_t
*
rs
)
{
char
buf
[
RS_ENTRY_LEN
+
1
];
routerstatus_format_entry
(
buf
,
sizeof
(
buf
),
rs
,
NULL
,
0
,
1
);
routerstatus_format_entry
(
buf
,
sizeof
(
buf
),
rs
,
NULL
,
NS_CONTROL_PORT
);
return
tor_strdup
(
buf
);
}
...
...
src/or/or.h
View file @
6fbdf635
...
...
@@ -1509,6 +1509,9 @@ typedef struct routerstatus_t {
unsigned
int
has_bandwidth
:
1
;
/**< The vote/consensus had bw info */
unsigned
int
has_exitsummary
:
1
;
/**< The vote/consensus had exit summaries */
unsigned
int
has_measured_bw
:
1
;
/**< The vote/consensus had a measured bw */
uint32_t
measured_bw
;
/**< Measured bandwidth (capacity) of the router */
uint32_t
bandwidth
;
/**< Bandwidth (capacity) of the router as reported in
* the vote/consensus, in kilobytes/sec. */
...
...
@@ -2539,6 +2542,9 @@ typedef struct {
* migration purposes? */
int
V3AuthUseLegacyKey
;
/** Location of bandwidth measurement file */
char
*
V3BandwidthsFile
;
/** The length of time that we think an initial consensus should be fresh.
* Only altered on testing networks. */
int
TestingV3AuthInitialVotingInterval
;
...
...
@@ -3437,8 +3443,8 @@ download_status_mark_impossible(download_status_t *dl)
* Running Stable Unnamed V2Dir Valid\n". */
#define MAX_FLAG_LINE_LEN 96
/** Length of "w" line for weighting. Currently at most
* "w Bandwidth=<uint32t>\n" */
#define MAX_WEIGHT_LINE_LEN (1
3+10
)
* "w Bandwidth=<uint32t>
Measured=<uint32t>
\n" */
#define MAX_WEIGHT_LINE_LEN (1
2+10+10+10+1
)
/** Maximum length of an exit policy summary line. */
#define MAX_POLICY_LINE_LEN (3+MAX_EXITPOLICY_SUMMARY_LEN)
/** Amount of space to allocate for each entry: r, s, and v lines. */
...
...
@@ -3521,13 +3527,34 @@ int dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff);
int
dirserv_have_any_serverdesc
(
smartlist_t
*
fps
,
int
spool_src
);
size_t
dirserv_estimate_data_size
(
smartlist_t
*
fps
,
int
is_serverdescs
,
int
compressed
);
typedef
enum
{
NS_V2
,
NS_V3_CONSENSUS
,
NS_V3_VOTE
,
NS_CONTROL_PORT
}
routerstatus_format_type_t
;
int
routerstatus_format_entry
(
char
*
buf
,
size_t
buf_len
,
routerstatus_t
*
rs
,
const
char
*
platform
,
int
first_line_only
,
int
v2_
format
);
routerstatus_format_type_t
format
);
void
dirserv_free_all
(
void
);
void
cached_dir_decref
(
cached_dir_t
*
d
);
cached_dir_t
*
new_cached_dir
(
char
*
s
,
time_t
published
);
#ifdef DIRSERV_PRIVATE
typedef
struct
measured_bw_line_t
{
char
node_id
[
DIGEST_LEN
];
char
node_hex
[
MAX_HEX_NICKNAME_LEN
+
1
];
long
int
bw
;
}
measured_bw_line_t
;
int
measured_bw_line_parse
(
measured_bw_line_t
*
out
,
const
char
*
line
);
int
measured_bw_line_apply
(
measured_bw_line_t
*
parsed_line
,
smartlist_t
*
routerstatuses
);
#endif
int
dirserv_read_measured_bandwidths
(
const
char
*
from_file
,
smartlist_t
*
routerstatuses
);
/********************************* dirvote.c ************************/
/** Lowest allowable value for VoteSeconds. */
...
...
@@ -3841,6 +3868,8 @@ int router_set_networkstatus_v2(const char *s, time_t arrived_at,
v2_networkstatus_source_t
source
,
smartlist_t
*
requested_fingerprints
);
void
networkstatus_v2_list_clean
(
time_t
now
);
int
compare_digest_to_routerstatus_entry
(
const
void
*
_key
,
const
void
**
_member
);
routerstatus_t
*
networkstatus_v2_find_entry
(
networkstatus_v2_t
*
ns
,
const
char
*
digest
);
routerstatus_t
*
networkstatus_vote_find_entry
(
networkstatus_t
*
ns
,
...
...
@@ -4705,6 +4734,7 @@ void sort_version_list(smartlist_t *lst, int remove_duplicates);
void
assert_addr_policy_ok
(
smartlist_t
*
t
);
void
dump_distinct_digest_count
(
int
severity
);
int
compare_routerstatus_entries
(
const
void
**
_a
,
const
void
**
_b
);
networkstatus_v2_t
*
networkstatus_v2_parse_from_string
(
const
char
*
s
);
networkstatus_t
*
networkstatus_parse_vote_from_string
(
const
char
*
s
,
const
char
**
eos_out
,
...
...
src/or/routerparse.c
View file @
6fbdf635
...
...
@@ -1924,6 +1924,16 @@ routerstatus_parse_entry_from_string(memarea_t *area,
goto
err
;
}
rs
->
has_bandwidth
=
1
;
}
else
if
(
!
strcmpstart
(
tok
->
args
[
i
],
"Measured="
))
{
int
ok
;
rs
->
measured_bw
=
tor_parse_ulong
(
strchr
(
tok
->
args
[
i
],
'='
)
+
1
,
10
,
0
,
UINT32_MAX
,
&
ok
,
NULL
);
if
(
!
ok
)
{
log_warn
(
LD_DIR
,
"Invalid Measured Bandwidth %s"
,