aboutsummaryrefslogtreecommitdiff
path: root/src/core/or
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2023-08-25 16:55:40 +0000
committerDavid Goulet <dgoulet@torproject.org>2023-08-25 16:55:40 +0000
commit4f21fc0fe4d54d61983dc44d2ea27786bbe3edbf (patch)
tree85d18caad4738c127fdbbfddb7460d66ce24d7b6 /src/core/or
parent99a19a0da6c7cf3af14682c554b01ff2d695f314 (diff)
parentbb16c1b02075f523e1aa7589c549786f071b1573 (diff)
downloadtor-4f21fc0fe4d54d61983dc44d2ea27786bbe3edbf.tar.gz
tor-4f21fc0fe4d54d61983dc44d2ea27786bbe3edbf.zip
Merge branch 'reapply-exit-policy-on-reload' into 'main'
reapply exit policy on reload Closes #40676 See merge request tpo/core/tor!735
Diffstat (limited to 'src/core/or')
-rw-r--r--src/core/or/connection_edge.c71
-rw-r--r--src/core/or/connection_edge.h2
-rw-r--r--src/core/or/policies.c2
3 files changed, 74 insertions, 1 deletions
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index f21779a80c..900d639959 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -105,6 +105,7 @@
#include "lib/buf/buffers.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
+#include "lib/encoding/confline.h"
#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
@@ -4237,6 +4238,76 @@ my_exit_policy_rejects(const tor_addr_t *addr,
return 0;
}
+/* Reapply exit policy to existing connections, possibly terminating
+ * connections
+ * no longer allowed by the policy.
+ */
+void
+connection_reapply_exit_policy(config_line_t *changes)
+{
+ int marked_for_close = 0;
+ smartlist_t *conn_list = NULL;
+ smartlist_t *policy = NULL;
+ int config_change_relevant = 0;
+
+ if (get_options()->ReevaluateExitPolicy == 0) {
+ return;
+ }
+
+ for (const config_line_t *line = changes;
+ line && !config_change_relevant;
+ line = line->next) {
+ const char* exit_policy_options[] = {
+ "ExitRelay",
+ "ExitPolicy",
+ "ReducedExitPolicy",
+ "ReevaluateExitPolicy",
+ "IPv6Exit",
+ NULL
+ };
+ for (unsigned int i = 0; exit_policy_options[i] != NULL; ++i) {
+ if (strcmp(line->key, exit_policy_options[i]) == 0) {
+ config_change_relevant = 1;
+ break;
+ }
+ }
+ }
+
+ if (!config_change_relevant) {
+ /* Policy did not change: no need to iterate over connections */
+ return;
+ }
+
+ // we can't use router_compare_to_my_exit_policy as it depend on the
+ // descriptor, which is regenerated asynchronously, so we have to parse the
+ // policy ourselves.
+ // We don't verify for our own IP, it's not part of the configuration.
+ if (BUG(policies_parse_exit_policy_from_options(get_options(), NULL, NULL,
+ &policy) != 0)) {
+ return;
+ }
+
+ conn_list = connection_list_by_type_purpose(CONN_TYPE_EXIT,
+ EXIT_PURPOSE_CONNECT);
+
+ SMARTLIST_FOREACH_BEGIN(conn_list, connection_t *, conn) {
+ addr_policy_result_t verdict = compare_tor_addr_to_addr_policy(&conn->addr,
+ conn->port,
+ policy);
+ if (verdict != ADDR_POLICY_ACCEPTED) {
+ connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_EXITPOLICY);
+ connection_mark_for_close(conn);
+ ++marked_for_close;
+ }
+ } SMARTLIST_FOREACH_END(conn);
+
+ smartlist_free(conn_list);
+ smartlist_free(policy);
+
+ log_info(LD_GENERAL, "Marked %d connections to be closed as no longer "
+ "allowed per ExitPolicy", marked_for_close);
+}
+
/** Return true iff the consensus allows network reentry. The default value is
* false if the parameter is not found. */
static bool
diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h
index 59fc17dea5..1bb0e6d368 100644
--- a/src/core/or/connection_edge.h
+++ b/src/core/or/connection_edge.h
@@ -13,6 +13,7 @@
#define TOR_CONNECTION_EDGE_H
#include "lib/testsupport/testsupport.h"
+#include "lib/encoding/confline.h"
#include "feature/hs/hs_service.h"
@@ -101,6 +102,7 @@ void connection_entry_set_controller_wait(entry_connection_t *conn);
void connection_ap_about_to_close(entry_connection_t *edge_conn);
void connection_exit_about_to_close(edge_connection_t *edge_conn);
+void connection_reapply_exit_policy(config_line_t *changes);
MOCK_DECL(int,
connection_ap_handshake_send_begin,(entry_connection_t *ap_conn));
diff --git a/src/core/or/policies.c b/src/core/or/policies.c
index 1864b84d5e..4641632b60 100644
--- a/src/core/or/policies.c
+++ b/src/core/or/policies.c
@@ -1066,7 +1066,7 @@ socks_policy_permits_address(const tor_addr_t *addr)
}
/** Return 1 if <b>addr</b> is permitted to connect to our metrics port,
- * based on <b>socks_policy</b>. Else return 0.
+ * based on <b>metrics_policy</b>. Else return 0.
*/
int
metrics_policy_permits_address(const tor_addr_t *addr)