diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 58 | ||||
-rw-r--r-- | src/or/circuitlist.c | 15 | ||||
-rw-r--r-- | src/or/circuituse.c | 5 | ||||
-rw-r--r-- | src/or/command.c | 10 | ||||
-rw-r--r-- | src/or/config.c | 32 | ||||
-rw-r--r-- | src/or/control.c | 8 | ||||
-rw-r--r-- | src/or/directory.c | 9 | ||||
-rw-r--r-- | src/or/dirserv.c | 7 | ||||
-rw-r--r-- | src/or/eventdns.c | 6 | ||||
-rw-r--r-- | src/or/eventdns.h | 4 | ||||
-rw-r--r-- | src/or/main.c | 17 | ||||
-rw-r--r-- | src/or/networkstatus.c | 35 | ||||
-rw-r--r-- | src/or/or.h | 21 | ||||
-rw-r--r-- | src/or/relay.c | 4 | ||||
-rw-r--r-- | src/or/rendclient.c | 15 | ||||
-rw-r--r-- | src/or/rendservice.c | 7 | ||||
-rw-r--r-- | src/or/router.c | 19 | ||||
-rw-r--r-- | src/or/routerparse.c | 44 | ||||
-rw-r--r-- | src/or/test.c | 2 |
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); |