summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug402816
-rw-r--r--changes/ticket40221_0456
-rw-r--r--changes/ticket402573
-rw-r--r--changes/ticket402794
-rw-r--r--src/core/mainloop/connection.c2
-rw-r--r--src/core/or/protover.c2
-rw-r--r--src/feature/metrics/metrics.c21
-rw-r--r--src/feature/metrics/metrics.h1
-rw-r--r--src/feature/nodelist/networkstatus.c9
-rw-r--r--src/feature/relay/router.c33
-rw-r--r--src/rust/protover/protover.rs4
-rw-r--r--src/test/test_metrics.c32
-rw-r--r--src/test/test_protover.c3
13 files changed, 97 insertions, 29 deletions
diff --git a/changes/bug40281 b/changes/bug40281
new file mode 100644
index 0000000000..0708039f04
--- /dev/null
+++ b/changes/bug40281
@@ -0,0 +1,6 @@
+ o Minor bugfixes (logging):
+ - Avoid a spurious log message about missing subprotocol versions, when
+ the consensus that we're reading from is older than the current
+ release. . Previously we had made this message nonfatal in this case,
+ but in practice, it is never relevant when the consensus is older than
+ the current release. Fixes bug 40281; bugfix on 0.4.0.1-alpha.
diff --git a/changes/ticket40221_045 b/changes/ticket40221_045
new file mode 100644
index 0000000000..0f3ab894c2
--- /dev/null
+++ b/changes/ticket40221_045
@@ -0,0 +1,6 @@
+ o Minor features (protocol versions):
+ - Stop claiming to support the "DirCache=1" subprotocol version.
+ Technically, we stopped supporting this subprotocol back in
+ 0.4.5.1-alpha, but we needed to wait for the authorities to stop
+ listing it as "required" before we can drop support. Closes ticket
+ 40221.
diff --git a/changes/ticket40257 b/changes/ticket40257
new file mode 100644
index 0000000000..4bcebc45a1
--- /dev/null
+++ b/changes/ticket40257
@@ -0,0 +1,3 @@
+ o Minor bugfixes (metrics port):
+ - Fix a bug warning when the socket was unexpectedly closed. Fixes bug
+ 40257; bugfix on 0.4.5.1-alpha
diff --git a/changes/ticket40279 b/changes/ticket40279
new file mode 100644
index 0000000000..351db40789
--- /dev/null
+++ b/changes/ticket40279
@@ -0,0 +1,4 @@
+ o Major bugfixes (IPv6, relay):
+ - Fix a bug that prevented a relay to publish its descriptor in the case of
+ an auto-discovered IPv6 that was found unreachable for which we always
+ publish if the IPv4 is correct. Fixes bug 40279; bugfix on 0.4.5.1-alpha.
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 3d551c4ba8..85cdec6e1e 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -5242,6 +5242,8 @@ connection_reached_eof(connection_t *conn)
return connection_dir_reached_eof(TO_DIR_CONN(conn));
case CONN_TYPE_CONTROL:
return connection_control_reached_eof(TO_CONTROL_CONN(conn));
+ case CONN_TYPE_METRICS:
+ return metrics_connection_reached_eof(conn);
default:
log_err(LD_BUG,"got unexpected conn type %d.", conn->type);
tor_fragile_assert();
diff --git a/src/core/or/protover.c b/src/core/or/protover.c
index 5a87ade3da..aa96cafff9 100644
--- a/src/core/or/protover.c
+++ b/src/core/or/protover.c
@@ -398,7 +398,7 @@ protover_get_supported_protocols(void)
return
"Cons=1-2 "
"Desc=1-2 "
- "DirCache=1-2 "
+ "DirCache=2 "
"FlowCtrl=1 "
"HSDir=1-2 "
"HSIntro=3-5 "
diff --git a/src/feature/metrics/metrics.c b/src/feature/metrics/metrics.c
index 886182bc90..7a77ab1104 100644
--- a/src/feature/metrics/metrics.c
+++ b/src/feature/metrics/metrics.c
@@ -20,6 +20,7 @@
#include "lib/net/address.h"
#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
#include "core/or/connection_st.h"
#include "core/or/policies.h"
#include "core/or/port_cfg_st.h"
@@ -93,7 +94,8 @@ metrics_get_output(const metrics_format_t fmt)
/** Process what is in the inbuf of this connection of type metrics.
*
- * Return 0 on success else -1 on error which will close the connection. */
+ * Return 0 on success else -1 on error for which the connection is marked for
+ * close. */
int
metrics_connection_process_inbuf(connection_t *conn)
{
@@ -111,13 +113,14 @@ metrics_connection_process_inbuf(connection_t *conn)
goto err;
}
- const int http_status = fetch_from_buf_http(conn->inbuf, &headers, 1024,
- NULL, NULL, 1024, 0);
+ const int http_status =
+ connection_fetch_from_buf_http(conn, &headers, 1024, NULL, NULL, 1024, 0);
if (http_status < 0) {
errmsg = "HTTP/1.0 400 Bad Request\r\n\r\n";
goto err;
} else if (http_status == 0) {
/* no HTTP request yet. */
+ ret = 0;
goto done;
}
@@ -155,6 +158,7 @@ metrics_connection_process_inbuf(connection_t *conn)
log_info(LD_EDGE, "HTTP metrics error: saying %s", escaped(errmsg));
connection_buf_add(errmsg, strlen(errmsg), conn);
}
+ connection_mark_and_flush(conn);
done:
tor_free(headers);
@@ -243,6 +247,17 @@ metrics_parse_ports(or_options_t *options, smartlist_t *ports,
return ret;
}
+/** Called when conn has gotten its socket closed. */
+int
+metrics_connection_reached_eof(connection_t *conn)
+{
+ tor_assert(conn);
+
+ log_info(LD_EDGE, "Metrics connection reached EOF. Closing.");
+ connection_mark_for_close(conn);
+ return 0;
+}
+
/** Initialize the subsystem. */
void
metrics_init(void)
diff --git a/src/feature/metrics/metrics.h b/src/feature/metrics/metrics.h
index b4bbe28b27..858722de59 100644
--- a/src/feature/metrics/metrics.h
+++ b/src/feature/metrics/metrics.h
@@ -27,6 +27,7 @@ buf_t *metrics_get_output(const metrics_format_t fmt);
/* Connection. */
int metrics_connection_process_inbuf(struct connection_t *conn);
+int metrics_connection_reached_eof(struct connection_t *conn);
/* Configuration. */
int metrics_parse_ports(or_options_t *options, smartlist_t *ports,
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index ece3c9e059..80940e6092 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -2723,6 +2723,13 @@ networkstatus_check_required_protocols(const networkstatus_t *ns,
const bool consensus_postdates_this_release =
ns->valid_after >= tor_get_approx_release_date();
+ if (! consensus_postdates_this_release) {
+ // We can't meaningfully warn about this case: This consensus is from
+ // before we were released, so whatever is says about required or
+ // recommended versions may no longer be true.
+ return 0;
+ }
+
tor_assert(warning_out);
if (client_mode) {
@@ -2740,7 +2747,7 @@ networkstatus_check_required_protocols(const networkstatus_t *ns,
"%s on the Tor network. The missing protocols are: %s",
func, missing);
tor_free(missing);
- return consensus_postdates_this_release ? 1 : 0;
+ return 1;
}
if (! protover_all_supported(recommended, &missing)) {
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 60f237a700..8a7e76e33f 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -138,6 +138,18 @@ static authority_cert_t *legacy_key_certificate = NULL;
* used by tor-gencert to sign new signing keys and make new key
* certificates. */
+/** Indicate if the IPv6 address should be omitted from the descriptor when
+ * publishing it. This can happen if the IPv4 is reachable but the
+ * auto-discovered IPv6 is not. We still publish the descriptor.
+ *
+ * Only relays should look at this and only for their descriptor.
+ *
+ * XXX: The real harder fix is to never put in the routerinfo_t a non
+ * reachable address and instead use the last resolved address cache to do
+ * reachability test or anything that has to do with what address tor thinks
+ * it has. */
+static bool omit_ipv6_on_publish = false;
+
/** Return a readonly string with human readable description
* of <b>err</b>.
*/
@@ -1396,7 +1408,11 @@ decide_if_publishable_server(void)
return 0;
}
}
- if (!router_orport_seems_reachable(options, AF_INET6)) {
+ /* We could be flagged to omit the IPv6 and if so, don't check for
+ * reachability on the IPv6. This can happen if the address was
+ * auto-discovered but turns out to be non reachable. */
+ if (!omit_ipv6_on_publish &&
+ !router_orport_seems_reachable(options, AF_INET6)) {
// We have an ipv6 orport, and it doesn't seem reachable.
if (!publish_even_when_ipv6_orport_unreachable) {
return 0;
@@ -2085,7 +2101,8 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
ri->ipv4_dirport = routerconf_find_dir_port(options, 0);
/* Optionally check for an IPv6. We still publish without one. */
- if (relay_find_addr_to_publish(options, AF_INET6, RELAY_FIND_ADDR_NO_FLAG,
+ if (!omit_ipv6_on_publish &&
+ relay_find_addr_to_publish(options, AF_INET6, RELAY_FIND_ADDR_NO_FLAG,
&ri->ipv6_addr)) {
ri->ipv6_orport = routerconf_find_or_port(options, AF_INET6);
router_check_descriptor_address_consistency(&ri->ipv6_addr);
@@ -2459,18 +2476,6 @@ router_new_consensus_params(const networkstatus_t *ns)
publish_even_when_ipv6_orport_unreachable = ar || ar6;
}
-/** Indicate if the IPv6 address should be omitted from the descriptor when
- * publishing it. This can happen if the IPv4 is reachable but the
- * auto-discovered IPv6 is not. We still publish the descriptor.
- *
- * Only relays should look at this and only for their descriptor.
- *
- * XXX: The real harder fix is to never put in the routerinfo_t a non
- * reachable address and instead use the last resolved address cache to do
- * reachability test or anything that has to do with what address tor thinks
- * it has. */
-static bool omit_ipv6_on_publish = false;
-
/** Mark our descriptor out of data iff the IPv6 omit status flag is flipped
* it changes from its previous value.
*
diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs
index 0060864a2e..da87509ffa 100644
--- a/src/rust/protover/protover.rs
+++ b/src/rust/protover/protover.rs
@@ -160,7 +160,7 @@ pub(crate) fn get_supported_protocols_cstr() -> &'static CStr {
cstr!(
"Cons=1-2 \
Desc=1-2 \
- DirCache=1-2 \
+ DirCache=2 \
FlowCtrl=1 \
HSDir=1-2 \
HSIntro=3-5 \
@@ -175,7 +175,7 @@ pub(crate) fn get_supported_protocols_cstr() -> &'static CStr {
cstr!(
"Cons=1-2 \
Desc=1-2 \
- DirCache=1-2 \
+ DirCache=2 \
FlowCtrl=1 \
HSDir=1-2 \
HSIntro=3-5 \
diff --git a/src/test/test_metrics.c b/src/test/test_metrics.c
index 96eadc6b43..152dd99d23 100644
--- a/src/test/test_metrics.c
+++ b/src/test/test_metrics.c
@@ -8,6 +8,7 @@
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
+#define MAINLOOP_PRIVATE
#define METRICS_STORE_ENTRY_PRIVATE
#include "test/test.h"
@@ -17,6 +18,7 @@
#include "app/config/config.h"
#include "core/mainloop/connection.h"
+#include "core/mainloop/mainloop.h"
#include "core/or/connection_st.h"
#include "core/or/policies.h"
#include "core/or/port_cfg_st.h"
@@ -96,43 +98,62 @@ static char _c_buf[256];
#define WRITE(conn, msg) \
buf_add(conn->inbuf, (msg), (strlen(msg)));
+/* Free the previous conn object if any and allocate a new connection. In
+ * order to be allowed, set its address to 1.2.3.4 as per the policy. */
+#define NEW_ALLOWED_CONN() \
+ do { \
+ close_closeable_connections(); \
+ conn = connection_new(CONN_TYPE_METRICS, AF_INET); \
+ tor_addr_from_ipv4h(&conn->addr, 0x01020304); \
+ } while (0)
+
static void
test_connection(void *arg)
{
int ret;
- connection_t *conn = connection_new(CONN_TYPE_METRICS, AF_INET);
+ connection_t *conn = NULL;
or_options_t *options = get_options_mutable();
(void) arg;
+ /* Notice that in this test, we will allocate a new connection at every test
+ * case. This is because the metrics_connection_process_inbuf() marks for
+ * close the connection in case of an error and thus we can't call again an
+ * inbuf process function on a marked for close connection. */
+
+ tor_init_connection_lists();
+
/* Setup policy. */
set_metrics_port(options);
/* Set 1.2.3.5 IP, we should get rejected. */
+ NEW_ALLOWED_CONN();
tor_addr_from_ipv4h(&conn->addr, 0x01020305);
ret = metrics_connection_process_inbuf(conn);
tt_int_op(ret, OP_EQ, -1);
- /* Set 1.2.3.4 so from now on we are allowed to process the inbuf. */
- tor_addr_from_ipv4h(&conn->addr, 0x01020304);
-
/* No HTTP request yet. */
+ NEW_ALLOWED_CONN();
ret = metrics_connection_process_inbuf(conn);
- tt_int_op(ret, OP_EQ, -1);
+ tt_int_op(ret, OP_EQ, 0);
+ connection_free_minimal(conn);
/* Bad request. */
+ NEW_ALLOWED_CONN();
WRITE(conn, "HTTP 4.7\r\n\r\n");
ret = metrics_connection_process_inbuf(conn);
tt_int_op(ret, OP_EQ, -1);
CONTAINS(conn, "HTTP/1.0 400 Bad Request\r\n\r\n");
/* Path not found. */
+ NEW_ALLOWED_CONN();
WRITE(conn, "GET /badpath HTTP/1.0\r\n\r\n");
ret = metrics_connection_process_inbuf(conn);
tt_int_op(ret, OP_EQ, -1);
CONTAINS(conn, "HTTP/1.0 404 Not Found\r\n\r\n");
/* Method not allowed. */
+ NEW_ALLOWED_CONN();
WRITE(conn, "POST /something HTTP/1.0\r\n\r\n");
ret = metrics_connection_process_inbuf(conn);
tt_int_op(ret, OP_EQ, -1);
@@ -140,6 +161,7 @@ test_connection(void *arg)
/* Ask for metrics. The content should be above 0. We don't test the
* validity of the returned content but it is certainly not an error. */
+ NEW_ALLOWED_CONN();
WRITE(conn, "GET /metrics HTTP/1.0\r\n\r\n");
ret = metrics_connection_process_inbuf(conn);
tt_int_op(ret, OP_EQ, 0);
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index be3aeb5e40..dd65f4bbf5 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -469,9 +469,6 @@ test_protover_supported_protocols(void *arg)
/* No DirCache versions appear anywhere in the code. */
tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_DIRCACHE,
- PROTOVER_DIRCACHE_V1));
- tt_assert(protocol_list_supports_protocol(supported_protocols,
- PRT_DIRCACHE,
PROTOVER_DIRCACHE_V2));
/* No Desc versions appear anywhere in the code. */