summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
Diffstat (limited to 'src/or')
-rw-r--r--src/or/circuitbuild.c58
-rw-r--r--src/or/circuitlist.c15
-rw-r--r--src/or/circuituse.c5
-rw-r--r--src/or/command.c10
-rw-r--r--src/or/config.c32
-rw-r--r--src/or/control.c8
-rw-r--r--src/or/directory.c9
-rw-r--r--src/or/dirserv.c7
-rw-r--r--src/or/eventdns.c6
-rw-r--r--src/or/eventdns.h4
-rw-r--r--src/or/main.c17
-rw-r--r--src/or/networkstatus.c35
-rw-r--r--src/or/or.h21
-rw-r--r--src/or/relay.c4
-rw-r--r--src/or/rendclient.c15
-rw-r--r--src/or/rendservice.c7
-rw-r--r--src/or/router.c19
-rw-r--r--src/or/routerparse.c44
-rw-r--r--src/or/test.c2
19 files changed, 216 insertions, 102 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index d78981e09b..4b5ba62fa2 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -527,9 +527,16 @@ inform_testing_reachability(void)
routerinfo_t *me = router_get_my_routerinfo();
if (!me)
return 0;
- if (me->dir_port)
+ control_event_server_status(LOG_NOTICE,
+ "CHECKING_REACHABILITY ORADDRESS=%s:%d",
+ me->address, me->or_port);
+ if (me->dir_port) {
tor_snprintf(dirbuf, sizeof(dirbuf), " and DirPort %s:%d",
me->address, me->dir_port);
+ control_event_server_status(LOG_NOTICE,
+ "CHECKING_REACHABILITY DIRADDRESS=%s:%d",
+ me->address, me->dir_port);
+ }
log(LOG_NOTICE, LD_OR, "Now checking whether ORPort %s:%d%s %s reachable... "
"(this may take up to %d minutes -- look for log "
"messages indicating success)",
@@ -537,6 +544,7 @@ inform_testing_reachability(void)
me->dir_port ? dirbuf : "",
me->dir_port ? "are" : "is",
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT/60);
+
return 1;
}
@@ -1436,13 +1444,16 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir,
/** Log a warning if the user specified an exit for the circuit that
* has been excluded from use by ExcludeNodes or ExcludeExitNodes. */
static void
-warn_if_last_router_excluded(uint8_t purpose, const extend_info_t *exit)
+warn_if_last_router_excluded(origin_circuit_t *circ, const extend_info_t *exit)
{
or_options_t *options = get_options();
routerset_t *rs = options->ExcludeNodes;
const char *description;
- int severity;
int domain = LD_CIRC;
+ uint8_t purpose = circ->_base.purpose;
+
+ if (circ->build_state->onehop_tunnel)
+ return;
switch (purpose)
{
@@ -1455,48 +1466,40 @@ warn_if_last_router_excluded(uint8_t purpose, const extend_info_t *exit)
(int)purpose);
return;
case CIRCUIT_PURPOSE_C_GENERAL:
+ if (circ->build_state->is_internal)
+ return;
description = "Requested exit node";
rs = options->_ExcludeExitNodesUnion;
- severity = LOG_WARN;
break;
case CIRCUIT_PURPOSE_C_INTRODUCING:
case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
case CIRCUIT_PURPOSE_C_INTRODUCE_ACKED:
- description = "Introduction point for hidden service";
- severity = LOG_INFO;
- break;
+ case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
+ case CIRCUIT_PURPOSE_S_CONNECT_REND:
+ case CIRCUIT_PURPOSE_S_REND_JOINED:
+ case CIRCUIT_PURPOSE_TESTING:
+ return;
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
case CIRCUIT_PURPOSE_C_REND_READY:
case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
case CIRCUIT_PURPOSE_C_REND_JOINED:
description = "Chosen rendezvous point";
- severity = LOG_WARN;
domain = LD_BUG;
break;
- case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
- description = "Chosen introduction point";
- severity = LOG_INFO;
- break;
- case CIRCUIT_PURPOSE_S_CONNECT_REND:
- case CIRCUIT_PURPOSE_S_REND_JOINED:
- description = "Client-selected rendezvous point";
- severity = LOG_INFO;
- break;
- case CIRCUIT_PURPOSE_TESTING:
- description = "Target for testing circuit";
- severity = LOG_INFO;
- break;
case CIRCUIT_PURPOSE_CONTROLLER:
rs = options->_ExcludeExitNodesUnion;
description = "Controller-selected circuit target";
- severity = LOG_WARN;
break;
}
- if (routerset_contains_extendinfo(rs, exit))
- log_fn(severity, domain, "%s '%s' is in ExcludeNodes%s. Using anyway.",
+ if (routerset_contains_extendinfo(rs, exit)) {
+ log_fn(LOG_WARN, domain, "%s '%s' is in ExcludeNodes%s. Using anyway "
+ "(circuit purpose %d).",
description,exit->nickname,
- rs==options->ExcludeNodes?"":" or ExcludeExitNodes.");
+ rs==options->ExcludeNodes?"":" or ExcludeExitNodes",
+ (int)purpose);
+ circuit_log_path(LOG_WARN, domain, circ);
+ }
return;
}
@@ -1521,7 +1524,7 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit)
}
if (exit) { /* the circuit-builder pre-requested one */
- warn_if_last_router_excluded(circ->_base.purpose, exit);
+ warn_if_last_router_excluded(circ, exit);
log_info(LD_CIRC,"Using requested exit node '%s'", exit->nickname);
exit = extend_info_dup(exit);
} else { /* we have to decide one */
@@ -1568,6 +1571,7 @@ int
circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit)
{
int err_reason = 0;
+ warn_if_last_router_excluded(circ, exit);
circuit_append_new_exit(circ, exit);
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_BUILDING);
if ((err_reason = circuit_send_next_onion_skin(circ))<0) {
@@ -1825,7 +1829,7 @@ onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
hop->extend_info = extend_info_dup(choice);
- hop->package_window = CIRCWINDOW_START;
+ hop->package_window = circuit_initial_package_window();
hop->deliver_window = CIRCWINDOW_START;
return 0;
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 252eaf9f8e..5918bdd7ae 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -361,6 +361,19 @@ circuit_purpose_to_controller_string(uint8_t purpose)
}
}
+/** Pick a reasonable package_window to start out for our circuits.
+ * Originally this was hard-coded at 1000, but now the consensus votes
+ * on the answer. See proposal 168. */
+int32_t
+circuit_initial_package_window(void)
+{
+ int32_t num = networkstatus_get_param(NULL, "circwindow", CIRCWINDOW_START);
+ /* If the consensus tells us a negative number, we'd assert. */
+ if (num < 0)
+ num = CIRCWINDOW_START;
+ return num;
+}
+
/** Initialize the common elements in a circuit_t, and add it to the global
* list. */
static void
@@ -368,7 +381,7 @@ init_circuit_base(circuit_t *circ)
{
circ->timestamp_created = time(NULL);
- circ->package_window = CIRCWINDOW_START;
+ circ->package_window = circuit_initial_package_window();
circ->deliver_window = CIRCWINDOW_START;
circuit_add(circ);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 6a54c34397..3acc0e9a74 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -724,17 +724,12 @@ circuit_testing_opened(origin_circuit_t *circ)
static void
circuit_testing_failed(origin_circuit_t *circ, int at_last_hop)
{
- routerinfo_t *me = router_get_my_routerinfo();
if (server_mode(get_options()) && check_whether_orport_reachable())
return;
- if (!me)
- return;
log_info(LD_GENERAL,
"Our testing circuit (to see if your ORPort is reachable) "
"has failed. I'll try again later.");
- control_event_server_status(LOG_WARN, "REACHABILITY_FAILED ORADDRESS=%s:%d",
- me->address, me->or_port);
/* These aren't used yet. */
(void)circ;
diff --git a/src/or/command.c b/src/or/command.c
index c36874be5c..67e463723f 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -575,7 +575,7 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
/* Consider all the other addresses; if any matches, this connection is
* "canonical." */
tor_addr_t addr;
- const char *next = decode_address_from_payload(&addr, cp, end-cp);
+ const char *next = decode_address_from_payload(&addr, cp, (int)(end-cp));
if (next == NULL) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
"Bad address in netinfo cell; closing connection.");
@@ -610,9 +610,11 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
conn->_base.address, (int)conn->_base.port,
apparent_skew>0 ? "ahead" : "behind", dbuf,
apparent_skew>0 ? "behind" : "ahead");
- control_event_general_status(LOG_WARN,
- "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
- apparent_skew, conn->_base.address, conn->_base.port);
+ if (severity == LOG_WARN) /* only tell the controller if an authority */
+ control_event_general_status(LOG_WARN,
+ "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
+ apparent_skew,
+ conn->_base.address, conn->_base.port);
}
/* XXX maybe act on my_apparent_addr, if the source is sufficiently
diff --git a/src/or/config.c b/src/or/config.c
index 3f45b1e5e2..4e2a1765dc 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -904,14 +904,14 @@ add_default_trusted_dir_authorities(authority_type_t type)
int i;
const char *dirservers[] = {
"moria1 v1 orport=9001 v3ident=E2A2AF570166665D738736D0DD58169CC61D8A8B "
- "128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
+ "128.31.0.39:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
"moria2 v1 orport=9002 128.31.0.34:9032 "
"719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
"tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
"86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
"dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
"194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
- "Tonga orport=443 bridge no-v2 82.94.251.206:80 "
+ "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
"4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
"ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
"216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
@@ -921,6 +921,8 @@ add_default_trusted_dir_authorities(authority_type_t type)
"dannenberg orport=443 no-v2 "
"v3ident=585769C78764D58426B8B52B6651A5A71137189A "
"213.73.91.31:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
+ "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
+ "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
NULL
};
for (i=0; dirservers[i]; i++) {
@@ -1224,26 +1226,29 @@ options_need_geoip_info(or_options_t *options, const char **reason_out)
/** Return the bandwidthrate that we are going to report to the authorities
* based on the config options. */
-int
+uint32_t
get_effective_bwrate(or_options_t *options)
{
- int bw = (int)options->BandwidthRate;
+ uint64_t bw = options->BandwidthRate;
if (bw > options->MaxAdvertisedBandwidth)
- bw = (int)options->MaxAdvertisedBandwidth;
+ bw = options->MaxAdvertisedBandwidth;
if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
- bw = (int)options->RelayBandwidthRate;
- return bw;
+ bw = options->RelayBandwidthRate;
+
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
}
/** Return the bandwidthburst that we are going to report to the authorities
* based on the config options. */
-int
+uint32_t
get_effective_bwburst(or_options_t *options)
{
- int bw = (int)options->BandwidthBurst;
+ uint64_t bw = options->BandwidthBurst;
if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
- bw = (int)options->RelayBandwidthBurst;
- return bw;
+ bw = options->RelayBandwidthBurst;
+ /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
+ return (uint32_t)bw;
}
/** Fetch the active option list, and take actions based on it. All of the
@@ -2499,7 +2504,8 @@ is_local_addr(const tor_addr_t *addr)
* the same /24 as last_resolved_addr will be the same as checking whether
* it was on net 0, which is already done by is_internal_IP.
*/
- if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
+ if ((last_resolved_addr & (uint32_t)0xffffff00ul)
+ == (ip & (uint32_t)0xffffff00ul))
return 1;
}
return 0;
@@ -4182,7 +4188,7 @@ options_init_from_string(const char *cf,
err:
config_free(&options_format, newoptions);
if (*msg) {
- int len = strlen(*msg)+256;
+ int len = (int)strlen(*msg)+256;
char *newmsg = tor_malloc(len);
tor_snprintf(newmsg, len, "Failed to parse/validate config: %s", *msg);
diff --git a/src/or/control.c b/src/or/control.c
index 90c99fd51a..5688b8e71f 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1789,7 +1789,11 @@ getinfo_helper_events(control_connection_t *control_conn,
*answer = tor_strdup(has_completed_circuit ? "1" : "0");
} else if (!strcmp(question, "status/enough-dir-info")) {
*answer = tor_strdup(router_have_minimum_dir_info() ? "1" : "0");
- } else if (!strcmp(question, "status/good-server-descriptor")) {
+ } else if (!strcmp(question, "status/good-server-descriptor") ||
+ !strcmp(question, "status/accepted-server-descriptor")) {
+ /* They're equivalent for now, until we can figure out how to make
+ * good-server-descriptor be what we want. See comment in
+ * control-spec.txt. */
*answer = tor_strdup(directories_have_accepted_server_descriptor()
? "1" : "0");
} else if (!strcmp(question, "status/reachability-succeeded/or")) {
@@ -2597,7 +2601,7 @@ handle_control_resolve(control_connection_t *conn, uint32_t len,
int is_reverse = 0;
(void) len; /* body is nul-terminated; it's safe to ignore the length */
- if (!(conn->event_mask & (1L<<EVENT_ADDRMAP))) {
+ if (!(conn->event_mask & ((uint32_t)1L<<EVENT_ADDRMAP))) {
log_warn(LD_CONTROL, "Controller asked us to resolve an address, but "
"isn't listening for ADDRMAP events. It probably won't see "
"the answer.");
diff --git a/src/or/directory.c b/src/or/directory.c
index 4ab2633022..5b8637a39d 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -554,11 +554,6 @@ void
connection_dir_request_failed(dir_connection_t *conn)
{
if (directory_conn_is_self_reachability_test(conn)) {
- routerinfo_t *me = router_get_my_routerinfo();
- if (me)
- control_event_server_status(LOG_WARN,
- "REACHABILITY_FAILED DIRADDRESS=%s:%d",
- me->address, me->dir_port);
return; /* this was a test fetch. don't retry. */
}
if (entry_list_can_grow(get_options()))
@@ -877,7 +872,7 @@ static char *
directory_get_consensus_url(int supports_conditional_consensus)
{
char *url;
- int len;
+ size_t len;
if (supports_conditional_consensus) {
char *authority_id_list;
@@ -2347,7 +2342,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
need_at_least = smartlist_len(want_authorities)/2+1;
SMARTLIST_FOREACH(want_authorities, const char *, d, {
char want_digest[DIGEST_LEN];
- int want_len = strlen(d)/2;
+ size_t want_len = strlen(d)/2;
if (want_len > DIGEST_LEN)
want_len = DIGEST_LEN;
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index a64a01bb80..349e383ab5 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -652,8 +652,8 @@ dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
/** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
* the list of server descriptors. Set *<b>msg</b> to a message that should be
- * passed back to the origin of this descriptor. Use <b>source</b> to produce
- * better log messages.
+ * passed back to the origin of this descriptor, or NULL if there is no such
+ * message. Use <b>source</b> to produce better log messages.
*
* Return the status of the operation
*
@@ -667,6 +667,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
routerinfo_t *ri_old;
char *desc, *nickname;
size_t desclen = 0;
+ *msg = NULL;
/* If it's too big, refuse it now. Otherwise we'll cache it all over the
* network and it'll clog everything up. */
@@ -718,7 +719,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
control_event_or_authdir_new_descriptor("REJECTED", desc, desclen, *msg);
log_info(LD_DIRSERV,
"Did not add descriptor from '%s' (source: %s): %s.",
- nickname, source, *msg);
+ nickname, source, *msg ? *msg : "(no message)");
} else {
smartlist_t *changed;
control_event_or_authdir_new_descriptor("ACCEPTED", desc, desclen, *msg);
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index 4ae17a40c3..a889e803ed 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -2385,7 +2385,7 @@ out1:
/* exported function */
int
-evdns_nameserver_add(unsigned long int address) {
+evdns_nameserver_add(uint32_t address) {
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
@@ -2416,13 +2416,13 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
cp = strchr(ip_as_string, ':');
if (*ip_as_string == '[') {
- int len;
+ size_t len;
if (!(cp = strchr(ip_as_string, ']'))) {
log(EVDNS_LOG_DEBUG, "Nameserver missing closing ]");
return 4;
}
len = cp-(ip_as_string + 1);
- if (len > (int)sizeof(buf)-1) {
+ if (len > sizeof(buf)-1) {
log(EVDNS_LOG_DEBUG, "[Nameserver] does not fit in buffer.");
return 4;
}
diff --git a/src/or/eventdns.h b/src/or/eventdns.h
index 734bacf2d2..bf3b64d08a 100644
--- a/src/or/eventdns.h
+++ b/src/or/eventdns.h
@@ -112,7 +112,7 @@
*
* API reference:
*
- * int evdns_nameserver_add(unsigned long int address)
+ * int evdns_nameserver_add(uint32_t address)
* Add a nameserver. The address should be an IP address in
* network byte order. The type of address is chosen so that
* it matches in_addr.s_addr.
@@ -258,7 +258,7 @@ typedef void (*evdns_callback_type) (int result, char type, int count, int ttl,
int evdns_init(void);
void evdns_shutdown(int fail_requests);
const char *evdns_err_to_string(int err);
-int evdns_nameserver_add(unsigned long int address);
+int evdns_nameserver_add(uint32_t address);
int evdns_count_nameservers(void);
int evdns_clear_nameservers_and_suspend(void);
int evdns_resume(void);
diff --git a/src/or/main.c b/src/or/main.c
index 60c42aaae3..ca09af0561 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1185,17 +1185,26 @@ second_elapsed_callback(int fd, short event, void *args)
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
/* every 20 minutes, check and complain if necessary */
routerinfo_t *me = router_get_my_routerinfo();
- if (me && !check_whether_orport_reachable())
+ if (me && !check_whether_orport_reachable()) {
log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that "
"its ORPort is reachable. Please check your firewalls, ports, "
"address, /etc/hosts file, etc.",
me->address, me->or_port);
- if (me && !check_whether_dirport_reachable())
+ control_event_server_status(LOG_WARN,
+ "REACHABILITY_FAILED ORADDRESS=%s:%d",
+ me->address, me->or_port);
+ }
+
+ if (me && !check_whether_dirport_reachable()) {
log_warn(LD_CONFIG,
"Your server (%s:%d) has not managed to confirm that its "
"DirPort is reachable. Please check your firewalls, ports, "
"address, /etc/hosts file, etc.",
me->address, me->dir_port);
+ control_event_server_status(LOG_WARN,
+ "REACHABILITY_FAILED DIRADDRESS=%s:%d",
+ me->address, me->dir_port);
+ }
}
/** If more than this many seconds have elapsed, probably the clock
@@ -1599,7 +1608,7 @@ dumpstats(int severity)
{
time_t now = time(NULL);
time_t elapsed;
- int rbuf_cap, wbuf_cap, rbuf_len, wbuf_len;
+ size_t rbuf_cap, wbuf_cap, rbuf_len, wbuf_len;
log(severity, LD_GENERAL, "Dumping stats:");
@@ -1635,7 +1644,7 @@ dumpstats(int severity)
log(severity, LD_GENERAL,
"Conn %d: %d/%d bytes used on OpenSSL read buffer; "
"%d/%d bytes used on write buffer.",
- i, rbuf_len, rbuf_cap, wbuf_len, wbuf_cap);
+ i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap);
}
}
}
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 573197a53f..f4a0761f7b 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -286,6 +286,10 @@ networkstatus_vote_free(networkstatus_t *ns)
SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
smartlist_free(ns->known_flags);
}
+ if (ns->net_params) {
+ SMARTLIST_FOREACH(ns->net_params, char *, c, tor_free(c));
+ smartlist_free(ns->net_params);
+ }
if (ns->supported_methods) {
SMARTLIST_FOREACH(ns->supported_methods, char *, c, tor_free(c));
smartlist_free(ns->supported_methods);
@@ -1884,6 +1888,37 @@ networkstatus_dump_bridge_status_to_file(time_t now)
tor_free(status);
}
+/** Return the value of a integer parameter from the networkstatus <b>ns</b>
+ * whose name is <b>param_name</b>. If <b>ns</b> is NULL, try loading the
+ * latest consensus ourselves. Return <b>default_val</b> if no latest
+ * consensus, or if it has no parameter called <b>param_name</b>. */
+int32_t
+networkstatus_get_param(networkstatus_t *ns, const char *param_name,
+ int32_t default_val)
+{
+ size_t name_len;
+
+ if (!ns) /* if they pass in null, go find it ourselves */
+ ns = networkstatus_get_latest_consensus();
+
+ if (!ns || !ns->net_params)
+ return default_val;
+
+ name_len = strlen(param_name);
+
+ SMARTLIST_FOREACH_BEGIN(ns->net_params, const char *, p) {
+ if (!strcmpstart(p, param_name) && p[name_len] == '=') {
+ int ok=0;
+ long v = tor_parse_long(p+name_len+1, 10, INT32_MIN, INT32_MAX, &ok,
+ NULL);
+ if (ok)
+ return (int32_t) v;
+ }
+ } SMARTLIST_FOREACH_END(p);
+
+ return default_val;
+}
+
/** If <b>question</b> is a string beginning with "ns/" in a format the
* control interface expects for a GETINFO question, set *<b>answer</b> to a
* newly-allocated string containing networkstatus lines for the appropriate
diff --git a/src/or/or.h b/src/or/or.h
index 1dcff28d6d..ae65127e36 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1655,6 +1655,10 @@ typedef struct networkstatus_t {
* not listed here, the voter has no opinion on what its value should be. */
smartlist_t *known_flags;
+ /** List of key=value strings for the parameters in this vote or
+ * consensus, sorted by key. */
+ smartlist_t *net_params;
+
/** List of networkstatus_voter_info_t. For a vote, only one element
* is included. For a consensus, one element is included for every voter
* whose vote contributed to the consensus. */
@@ -1849,9 +1853,9 @@ typedef struct crypt_path_t {
struct crypt_path_t *prev; /**< Link to previous crypt_path_t in the
* circuit. */
- int package_window; /**< How many bytes are we allowed to originate ending
+ int package_window; /**< How many cells are we allowed to originate ending
* at this step? */
- int deliver_window; /**< How many bytes are we willing to deliver originating
+ int deliver_window; /**< How many cells are we willing to deliver originating
* at this step? */
} crypt_path_t;
@@ -2785,6 +2789,7 @@ void circuit_set_n_circid_orconn(circuit_t *circ, circid_t id,
or_connection_t *conn);
void circuit_set_state(circuit_t *circ, uint8_t state);
void circuit_close_all_marked(void);
+int32_t circuit_initial_package_window(void);
origin_circuit_t *origin_circuit_new(void);
or_circuit_t *or_circuit_new(circid_t p_circ_id, or_connection_t *p_conn);
circuit_t *circuit_get_by_circid_orconn(circid_t circ_id,
@@ -2926,8 +2931,8 @@ int options_need_geoip_info(or_options_t *options, const char **reason_out);
int getinfo_helper_config(control_connection_t *conn,
const char *question, char **answer);
-int get_effective_bwrate(or_options_t *options);
-int get_effective_bwburst(or_options_t *options);
+uint32_t get_effective_bwrate(or_options_t *options);
+uint32_t get_effective_bwburst(or_options_t *options);
#ifdef CONFIG_PRIVATE
/* Used only by config.c and test.c */
@@ -3570,9 +3575,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
authority_cert_t *cert);
#ifdef DIRVOTE_PRIVATE
-char *
-format_networkstatus_vote(crypto_pk_env_t *private_key,
- networkstatus_t *v3_ns);
+char *format_networkstatus_vote(crypto_pk_env_t *private_key,
+ networkstatus_t *v3_ns);
+char *dirvote_compute_params(smartlist_t *votes);
#endif
/********************************* dns.c ***************************/
@@ -3787,6 +3792,8 @@ void signed_descs_update_status_from_consensus_networkstatus(
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
void networkstatus_dump_bridge_status_to_file(time_t now);
+int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
+ int32_t default_val);
int getinfo_helper_networkstatus(control_connection_t *conn,
const char *question, char **answer);
void networkstatus_free_all(void);
diff --git a/src/or/relay.c b/src/or/relay.c
index 3419e3d190..b26c582b82 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1358,7 +1358,7 @@ connection_edge_consider_sending_sendme(edge_connection_t *conn)
return;
}
- while (conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
+ while (conn->deliver_window <= STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log_debug(conn->cpath_layer?LD_APP:LD_EXIT,
"Outbuf %d, Queuing stream sendme.",
(int)conn->_base.outbuf_flushlen);
@@ -1472,7 +1472,7 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint)
{
// log_fn(LOG_INFO,"Considering: layer_hint is %s",
// layer_hint ? "defined" : "null");
- while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <
+ while ((layer_hint ? layer_hint->deliver_window : circ->deliver_window) <=
CIRCWINDOW_START - CIRCWINDOW_INCREMENT) {
log_debug(LD_CIRC,"Queuing circuit sendme.");
if (layer_hint)
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index a5d7c1016e..47a8818a50 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -94,9 +94,14 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
}
});
if (!intro_key) {
+ /** XXX This case probably means that the intro point vanished while
+ * we were building a circuit to it. In the future, we should find
+ * out how that happened and whether we should kill the circuits to
+ * removed intro points immediately. See task 1073. */
+ int num_intro_points = smartlist_len(entry->parsed->intro_nodes);
if (rend_cache_lookup_entry(introcirc->rend_data->onion_address,
0, &entry) > 0) {
- log_warn(LD_BUG, "We have both a v0 and a v2 rend desc for this "
+ log_info(LD_REND, "We have both a v0 and a v2 rend desc for this "
"service. The v2 desc doesn't contain the introduction "
"point (and key) to send an INTRODUCE1/2 cell to this "
"introduction point. Assuming the introduction point "
@@ -107,9 +112,9 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
/* See flyspray task 1024. */
intro_key = entry->parsed->pk;
} else {
- log_warn(LD_BUG, "Internal error: could not find intro key; we "
+ log_info(LD_REND, "Internal error: could not find intro key; we "
"only have a v2 rend desc with %d intro points.",
- smartlist_len(entry->parsed->intro_nodes));
+ num_intro_points);
goto err;
}
}
@@ -146,7 +151,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
REND_DESC_COOKIE_LEN);
v3_shift += 2+REND_DESC_COOKIE_LEN;
}
- set_uint32(tmp+v3_shift+1, htonl(time(NULL)));
+ set_uint32(tmp+v3_shift+1, htonl((uint32_t)time(NULL)));
v3_shift += 4;
} /* if version 2 only write version number */
else if (entry->parsed->protocols & (1<<2)) {
@@ -698,7 +703,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
/* set the windows to default. these are the windows
* that alice thinks bob has.
*/
- hop->package_window = CIRCWINDOW_START;
+ hop->package_window = circuit_initial_package_window();
hop->deliver_window = CIRCWINDOW_START;
onion_append_to_cpath(&circ->cpath, hop);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 2fd041d33e..d2868b738d 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1011,13 +1011,12 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
}
/* Check timestamp. */
- memcpy((char*)&ts, buf+1+v3_shift, sizeof(uint32_t));
+ ts = ntohl(get_uint32(buf+1+v3_shift));
v3_shift += 4;
- ts = ntohl(ts);
if ((now - ts) < -1 * REND_REPLAY_TIME_INTERVAL / 2 ||
(now - ts) > REND_REPLAY_TIME_INTERVAL / 2) {
log_warn(LD_REND, "INTRODUCE2 cell is too %s. Discarding.",
- (now - ts) < 0 ? "old" : "new");
+ (now - ts) < 0 ? "old" : "new");
return -1;
}
}
@@ -1557,7 +1556,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
/* set the windows to default. these are the windows
* that bob thinks alice has.
*/
- hop->package_window = CIRCWINDOW_START;
+ hop->package_window = circuit_initial_package_window();
hop->deliver_window = CIRCWINDOW_START;
onion_append_to_cpath(&circuit->cpath, hop);
diff --git a/src/or/router.c b/src/or/router.c
index 859a1e805a..fcfbe79112 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -544,7 +544,7 @@ init_keys(void)
/* Must be called after keys are initialized. */
mydesc = router_get_my_descriptor();
if (authdir_mode(options)) {
- const char *m;
+ const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
if (dirserv_add_own_fingerprint(options->Nickname, get_identity_key())) {
@@ -770,9 +770,6 @@ consider_testing_reachability(int test_or, int test_dir)
me->address, me->or_port);
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me,
CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
- control_event_server_status(LOG_NOTICE,
- "CHECKING_REACHABILITY ORADDRESS=%s:%d",
- me->address, me->or_port);
}
tor_addr_from_ipv4h(&addr, me->addr);
@@ -788,10 +785,6 @@ consider_testing_reachability(int test_or, int test_dir)
DIR_PURPOSE_FETCH_SERVERDESC,
ROUTER_PURPOSE_GENERAL,
1, "authority.z", NULL, 0, 0);
-
- control_event_server_status(LOG_NOTICE,
- "CHECKING_REACHABILITY DIRADDRESS=%s:%d",
- me->address, me->dir_port);
}
}
@@ -807,8 +800,11 @@ router_orport_found_reachable(void)
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty();
- if (!me)
+ if (!me) { /* should never happen */
+ log_warn(LD_BUG, "ORPort found reachable, but I have no routerinfo "
+ "yet. Failing to inform controller of success.");
return;
+ }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
me->address, me->or_port);
@@ -826,8 +822,11 @@ router_dirport_found_reachable(void)
can_reach_dir_port = 1;
if (!me || decide_to_advertise_dirport(get_options(), me->dir_port))
mark_my_descriptor_dirty();
- if (!me)
+ if (!me) { /* should never happen */
+ log_warn(LD_BUG, "DirPort found reachable, but I have no routerinfo "
+ "yet. Failing to inform controller of success.");
return;
+ }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
me->address, me->dir_port);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 8021158e31..4e1d0cd592 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -77,6 +77,7 @@ typedef enum {
K_VOTING_DELAY,
K_KNOWN_FLAGS,
+ K_PARAMS,
K_VOTE_DIGEST,
K_CONSENSUS_DIGEST,
K_CONSENSUS_METHODS,
@@ -383,6 +384,7 @@ static token_rule_t networkstatus_token_table[] = {
T1("valid-until", K_VALID_UNTIL, CONCAT_ARGS, NO_OBJ ),
T1("voting-delay", K_VOTING_DELAY, GE(2), NO_OBJ ),
T1("known-flags", K_KNOWN_FLAGS, ARGS, NO_OBJ ),
+ T01("params", K_PARAMS, ARGS, NO_OBJ ),
T( "fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ),
CERTIFICATE_MEMBERS
@@ -420,6 +422,7 @@ static token_rule_t networkstatus_consensus_token_table[] = {
T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
T01("consensus-method", K_CONSENSUS_METHOD, EQ(1), NO_OBJ),
+ T01("params", K_PARAMS, ARGS, NO_OBJ ),
END_OF_TABLE
};
@@ -1917,8 +1920,9 @@ routerstatus_parse_entry_from_string(memarea_t *area,
for (i=0; i < tok->n_args; ++i) {
if (!strcmpstart(tok->args[i], "Bandwidth=")) {
int ok;
- rs->bandwidth = tor_parse_ulong(strchr(tok->args[i], '=')+1, 10,
- 0, UINT32_MAX, &ok, NULL);
+ rs->bandwidth = (uint32_t)tor_parse_ulong(strchr(tok->args[i], '=')+1,
+ 10, 0, UINT32_MAX,
+ &ok, NULL);
if (!ok) {
log_warn(LD_DIR, "Invalid Bandwidth %s", escaped(tok->args[i]));
goto err;
@@ -2309,6 +2313,34 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err;
}
+ tok = find_opt_by_keyword(tokens, K_PARAMS);
+ if (tok) {
+ inorder = 1;
+ ns->net_params = smartlist_create();
+ for (i = 0; i < tok->n_args; ++i) {
+ int ok=0;
+ char *eq = strchr(tok->args[i], '=');
+ if (!eq) {
+ log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
+ goto err;
+ }
+ tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
+ if (!ok) {
+ log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
+ goto err;
+ }
+ if (i > 0 && strcmp(tok->args[i-1], tok->args[i]) >= 0) {
+ log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
+ inorder = 0;
+ }
+ smartlist_add(ns->net_params, tor_strdup(tok->args[i]));
+ }
+ if (!inorder) {
+ log_warn(LD_DIR, "params not in order");
+ goto err;
+ }
+ }
+
ns->voters = smartlist_create();
SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {
@@ -2508,6 +2540,14 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
} else {
if (tok->object_size >= INT_MAX)
goto err;
+ /* We already parsed a vote from this voter. Use the first one. */
+ if (v->signature) {
+ log_fn(LOG_PROTOCOL_WARN, LD_DIR, "We received a networkstatus "
+ "that contains two votes from the same voter. Ignoring "
+ "the second vote.");
+ continue;
+ }
+
v->signature = tor_memdup(tok->object_body, tok->object_size);
v->signature_len = (int) tok->object_size;
}
diff --git a/src/or/test.c b/src/or/test.c
index 7b7411e2f8..e06dd5951f 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -410,7 +410,7 @@ test_crypto_dh(void)
char p2[DH_BYTES];
char s1[DH_BYTES];
char s2[DH_BYTES];
- int s1len, s2len;
+ ssize_t s1len, s2len;
test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);