-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ticket3723 02 #194
Ticket3723 02 #194
Conversation
* add bwlist_headers argument to dirserv_read_measured_bandwidth in order to store all the headers found when parsing the file * add bwlist_headers to networkstatus_t in order to store the the headers found by the previous function * include the bandwidth headers as string in vote documents * add test to check that dirserv_read_measured_bandwidth generates the bwlist_headers
when there are not bw file headers lines.
to avoid interpreting as headers extra lines that are not key_values
bandwidth-file
and add bw file terminator constant
If bandwidth file terminator is found, set end of headers flag and do not store the line. If it is not, parse a relay line and check whether it is a header line.
also add tests for bw_file_headers. Headers are all that is found before a correct relay line or the terminator. Tests include: * a empty bandwidth file * a bandwidth file with only timestamp * a bandwidth file with v1.0.0 headers * a bandwidth file with v1.0.0 headers and relay lines * a bandwidth file with v1.1.0 headers and v1.0.0 relay lines * a bandwidth file with v1.0.0 headers, malformed relay lines and relay lines * a bandwidth file with v1.0.0 headers, malformed relay lines, relay lines and malformed relay lines * a bandwidth file with v1.1.0 headers without terminator * a bandwidth file with v1.1.0 headers with terminator * a bandwidth file with v1.1.0 headers without terminator and relay lines * a bandwidth file with v1.1.0 headers with terminator and relay lines * a bandwidth file with v1.1.0 headers without terminator, bad relay lines and relay lines * a bandwidth file with v1.1.0 headers with terminator, bad relay lines and relay lines
and complete v1.0.0 bandwidth file
FIXME: this seems to leak memory
FIXME: depends on smartlist_truncate
FIXME: leaks memory
Right now there is also this problem with last fixup:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see my comments on the new code.
|
||
/** Terminatore that separates bandwidth file headers from bandwidth file | ||
* relay lines */ | ||
#define BW_FILE_TERMINATOR "=====\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename to BW_FILE_HEADERS_TERMINATOR to avoid confusion.
* then assume this line is a header and add it to bw_file_headers */ | ||
else if (bw_file_headers && | ||
(line_is_after_headers == 0) && | ||
string_is_key_value(LOG_DEBUG, line) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
string_is_key_value returns true for relay bandwidth lines, because it allows spaces:
Line 19 in be40ad5
string_is_key_value(int severity, const char *string) |
Please also check that there are no spaces in the line.
for (i=0; i < diff; i++) { | ||
log_debug(LD_DIRSERV, "sl->list[size] %s\n", (char *)sl->list[size]); | ||
log_debug(LD_DIRSERV, "sl len %d\n", smartlist_len(sl)); | ||
smartlist_del(sl, size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use smartlist_del_keeporder() to avoid reordering the bandwidth headers.
Use smartlist_del_keeporder(sl, i) to delete the correct item.
Use tor_free(smartlist_get(sl, i)) to free the item before deleting it.
Also, you should probably delete from the end of the smartlist, rather than the start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think we can delete this entire commit.
See my comments on the next commit.
src/or/dirauth/dirvote.c
Outdated
if (smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN) | ||
/* FIXME */ | ||
smartlist_truncate(v3_ns->bw_file_headers, MAX_BW_FILE_HEADERS_LEN); | ||
} else | ||
bw_file_headers = tor_strdup(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If any block in a group of if/else blocks has braces, please put braces around every block.
src/or/dirauth/dirvote.c
Outdated
NULL); | ||
if (smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN) | ||
/* FIXME */ | ||
smartlist_truncate(v3_ns->bw_file_headers, MAX_BW_FILE_HEADERS_LEN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already limit the number of headers in earlier code.
So you can just log a BUG() warning here, and vote an empty string:
if (BUG(smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN)) {
bw_file_headers = tor_strdup("");
}
You should do this check before joining the string together, to avoid a memory leak, and to avoid allocating large amounts of memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so then i would do 2 checks?, 1 with the smartlist and 1 with the string?.
The code then would be:
if (BUG(smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN)) {
bw_file_headers = tor_strdup("");
}
bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ", 0,
NULL);
if (BUG(strlen(bw_file_headers) > MAX_VOTE_LINE_LEN)) {
tor_free(bw_file_headers);
bw_file_headers = tor_strdup("");
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost, but you can't overwrite bw_file_headers with valid data after an error:
if (BUG(smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN)) {
bw_file_headers = tor_strdup("");
} else {
bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ", 0,
NULL);
if (BUG(strlen(bw_file_headers) > MAX_VOTE_LINE_LEN)) {
tor_free(bw_file_headers);
bw_file_headers = tor_strdup("");
}
}
Here's another alternative that might make the code simpler:
char *bw_file_headers = NULL;
…
if (! BUG(smartlist_len(v3_ns->bw_file_headers) > MAX_BW_FILE_HEADERS_LEN)) {
bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ", 0,
NULL);
if (BUG(strlen(bw_file_headers) > MAX_VOTE_LINE_LEN)) {
/* Free and set to NULL, so the vote header line is empty */
tor_free(bw_file_headers);
}
}
…
bw_file_headers ? bw_file_headers : "");
Then the final tor_free(bw_file_headers) works because free(NULL) does nothing.
src/or/dirauth/dirvote.c
Outdated
@@ -267,10 +267,13 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, | |||
else | |||
params = tor_strdup(""); | |||
tor_assert(cert); | |||
if (v3_ns->bw_file_headers) | |||
if (v3_ns->bw_file_headers) { | |||
bw_file_headers = smartlist_join_strings(v3_ns->bw_file_headers, " ", 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please limit the length of the bw_file_headers string, not just the number of headers:
#126 (comment)
(Limiting the number of headers to 50 header is not enough to limit the vote line to 1024 bytes, because each header can be 512 bytes long.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could log a BUG() warning and use the empty string if the string is too long.
(It's very unlikely that the string will be too long.)
Remember to free the string before replacing it with "".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Limiting the number of headers to 50 header is not enough to limit the vote line to 1024 bytes, because each header can be 512 bytes long.)
Is there already a constant limiting the size of the vote line?, i don't find something like that, maybe i should add it?.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be:
/** Maximum size of a line in a vote. */
MAX_VOTE_LINE_LEN 1024
In dirvote.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are similar line length constants in diserv.h:
https://github.com/torproject/tor/blob/master/src/or/dirserv.h#L29
So I think this new constant should go in dirserv.h, even though it's only used in votes.
You said:
/** Maximum size of a line in a vote. */
MAX_VOTE_LINE_LEN 1024
But this constant does not limit all lines in the vote, just the bandwidth-file-headers line.
Please name the line limit constant after the kind of line, something like:
MAX_BANDWIDTH_HEADERS_LINE_LEN
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or MAX_BW_FILE_HEADERS_LINE_LEN to match MAX_BW_FILE_HEADERS_LEN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have two similar constants, we should change MAX_BW_FILE_HEADERS_LEN to MAX_BW_FILE_HEADER_COUNT_IN_VOTE. Otherwise people might get confused.
key_value.h isn't included in util.h: Please make a separate commit with this fix. |
Continuing in #195 |
Follows #126 after rebase to master.
@teor2345 I think i addressed all your comments.
In the end i thought it was better to add all the tests to the same function to don't duplicate all the variables.
Instead of truncating the string with the bandwidth file headers, i thought it was better to truncate the smartlist. I created a function for that but something is wrong since there's memory leaks when i use it in the test. See the last 3 commits and the FIXMEs in the code. Not ready to merge because of that.