summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2023-05-25 10:50:15 -0400
committerDavid Goulet <dgoulet@torproject.org>2023-05-25 10:50:15 -0400
commita1042f4873edd2f04787e7f60b3f9d3642b36611 (patch)
treed580598c9112303f1795dde4c9f528f5c6c4a7b5
parent970a534f03e19cc4957b200310418ff595f1d550 (diff)
parent5f432bff315f926c04ab64ae7890981c7ba736d8 (diff)
downloadtor-a1042f4873edd2f04787e7f60b3f9d3642b36611.tar.gz
tor-a1042f4873edd2f04787e7f60b3f9d3642b36611.zip
Merge branch 'tor-gitlab/mr/443'
-rw-r--r--changes/ticket336693
-rw-r--r--src/feature/client/transports.c99
-rw-r--r--src/feature/client/transports.h2
3 files changed, 88 insertions, 16 deletions
diff --git a/changes/ticket33669 b/changes/ticket33669
new file mode 100644
index 0000000000..d7ec3a5f40
--- /dev/null
+++ b/changes/ticket33669
@@ -0,0 +1,3 @@
+ o Minor features (pluggable transports):
+ - Automatically restart managed Pluggable Transport processes when their
+ process terminate. Resolves ticket 33669.
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 80903ac9e5..4d92a2a67a 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -519,8 +519,10 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
tor_assert(mp->conf_state == PT_PROTO_COMPLETED);
/* destroy the process handle and terminate the process. */
- process_set_data(mp->process, NULL);
- process_terminate(mp->process);
+ if (mp->process) {
+ process_set_data(mp->process, NULL);
+ process_terminate(mp->process);
+ }
/* destroy all its registered transports, since we will no longer
use them. */
@@ -541,7 +543,7 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
mp->proxy_supported = 0;
/* flag it as an infant proxy so that it gets launched on next tick */
- mp->conf_state = PT_PROTO_INFANT;
+ managed_proxy_set_state(mp, PT_PROTO_INFANT);
unconfigured_proxies_n++;
}
@@ -554,6 +556,8 @@ launch_managed_proxy(managed_proxy_t *mp)
smartlist_t *env = create_managed_proxy_environment(mp);
/* Configure our process. */
+ tor_assert(mp->process == NULL);
+ mp->process = process_new(mp->argv[0]);
process_set_data(mp->process, mp);
process_set_stdout_read_callback(mp->process, managed_proxy_stdout_callback);
process_set_stderr_read_callback(mp->process, managed_proxy_stderr_callback);
@@ -578,7 +582,7 @@ launch_managed_proxy(managed_proxy_t *mp)
log_info(LD_CONFIG,
"Managed proxy at '%s' has spawned with PID '%" PRIu64 "'.",
mp->argv[0], process_get_pid(mp->process));
- mp->conf_state = PT_PROTO_LAUNCHED;
+ managed_proxy_set_state(mp, PT_PROTO_LAUNCHED);
return 0;
}
@@ -648,7 +652,7 @@ configure_proxy(managed_proxy_t *mp)
/* if we haven't launched the proxy yet, do it now */
if (mp->conf_state == PT_PROTO_INFANT) {
if (launch_managed_proxy(mp) < 0) { /* launch fail */
- mp->conf_state = PT_PROTO_FAILED_LAUNCH;
+ managed_proxy_set_state(mp, PT_PROTO_FAILED_LAUNCH);
handle_finished_proxy(mp);
}
return 0;
@@ -810,8 +814,12 @@ handle_finished_proxy(managed_proxy_t *mp)
managed_proxy_destroy(mp, 1); /* annihilate it. */
break;
}
- register_proxy(mp); /* register its transports */
- mp->conf_state = PT_PROTO_COMPLETED; /* and mark it as completed. */
+
+ /* register its transports */
+ register_proxy(mp);
+
+ /* and mark it as completed. */
+ managed_proxy_set_state(mp, PT_PROTO_COMPLETED);
break;
case PT_PROTO_INFANT:
case PT_PROTO_LAUNCHED:
@@ -857,7 +865,7 @@ handle_methods_done(const managed_proxy_t *mp)
STATIC void
handle_proxy_line(const char *line, managed_proxy_t *mp)
{
- log_info(LD_GENERAL, "Got a line from managed proxy '%s': (%s)",
+ log_info(LD_PT, "Got a line from managed proxy '%s': (%s)",
mp->argv[0], line);
if (!strcmpstart(line, PROTO_ENV_ERROR)) {
@@ -881,7 +889,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
goto err;
tor_assert(mp->conf_protocol != 0);
- mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
+ managed_proxy_set_state(mp, PT_PROTO_ACCEPTING_METHODS);
return;
} else if (!strcmpstart(line, PROTO_CMETHODS_DONE)) {
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
@@ -889,7 +897,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
handle_methods_done(mp);
- mp->conf_state = PT_PROTO_CONFIGURED;
+ managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
return;
} else if (!strcmpstart(line, PROTO_SMETHODS_DONE)) {
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
@@ -897,7 +905,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
handle_methods_done(mp);
- mp->conf_state = PT_PROTO_CONFIGURED;
+ managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
return;
} else if (!strcmpstart(line, PROTO_CMETHOD_ERROR)) {
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
@@ -968,7 +976,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
return;
err:
- mp->conf_state = PT_PROTO_BROKEN;
+ managed_proxy_set_state(mp, PT_PROTO_BROKEN);
log_warn(LD_CONFIG, "Managed proxy at '%s' failed the configuration protocol"
" and will be destroyed.", mp->argv[0]);
}
@@ -1529,12 +1537,14 @@ managed_proxy_create(const smartlist_t *with_transport_list,
char **proxy_argv, int is_server)
{
managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
- mp->conf_state = PT_PROTO_INFANT;
+ managed_proxy_set_state(mp, PT_PROTO_INFANT);
mp->is_server = is_server;
mp->argv = proxy_argv;
mp->transports = smartlist_new();
mp->proxy_uri = get_pt_proxy_uri();
- mp->process = process_new(proxy_argv[0]);
+
+ /* Gets set in launch_managed_proxy(). */
+ mp->process = NULL;
mp->transports_to_launch = smartlist_new();
SMARTLIST_FOREACH(with_transport_list, const char *, transport,
@@ -1945,9 +1955,24 @@ managed_proxy_exit_callback(process_t *process, process_exit_code_t exit_code)
{
tor_assert(process);
+ managed_proxy_t *mp = process_get_data(process);
+ const char *name = mp ? mp->argv[0] : "N/A";
+
log_warn(LD_PT,
- "Pluggable Transport process terminated with status code %" PRIu64,
- exit_code);
+ "Managed proxy \"%s\" process terminated with status code %" PRIu64,
+ name, exit_code);
+
+ if (mp) {
+ /* We remove this process_t from the mp. */
+ tor_assert(mp->process == process);
+ mp->process = NULL;
+
+ /* Prepare the proxy for restart. */
+ proxy_prepare_for_restart(mp);
+
+ /* We have proxies we want to restart? */
+ pt_configure_remaining_proxies();
+ }
/* Returning true here means that the process subsystem will take care of
* calling process_free() on our process_t. */
@@ -2023,3 +2048,45 @@ managed_proxy_outbound_address(const or_options_t *options, sa_family_t family)
/* The user have not specified a preference for outgoing connections. */
return NULL;
}
+
+STATIC const char *
+managed_proxy_state_to_string(enum pt_proto_state state)
+{
+ switch (state) {
+ case PT_PROTO_INFANT:
+ return "Infant";
+ case PT_PROTO_LAUNCHED:
+ return "Launched";
+ case PT_PROTO_ACCEPTING_METHODS:
+ return "Accepting methods";
+ case PT_PROTO_CONFIGURED:
+ return "Configured";
+ case PT_PROTO_COMPLETED:
+ return "Completed";
+ case PT_PROTO_BROKEN:
+ return "Broken";
+ case PT_PROTO_FAILED_LAUNCH:
+ return "Failed to launch";
+ }
+
+ /* LCOV_EXCL_START */
+ tor_assert_unreached();
+ return NULL;
+ /* LCOV_EXCL_STOP */
+}
+
+/** Set the internal state of the given <b>mp</b> to the given <b>new_state</b>
+ * value. */
+STATIC void
+managed_proxy_set_state(managed_proxy_t *mp, enum pt_proto_state new_state)
+{
+ if (mp->conf_state == new_state)
+ return;
+
+ tor_log(LOG_INFO, LD_PT, "Managed proxy \"%s\" changed state: %s -> %s",
+ mp->argv[0],
+ managed_proxy_state_to_string(mp->conf_state),
+ managed_proxy_state_to_string(new_state));
+
+ mp->conf_state = new_state;
+}
diff --git a/src/feature/client/transports.h b/src/feature/client/transports.h
index 3f08beadba..535689537c 100644
--- a/src/feature/client/transports.h
+++ b/src/feature/client/transports.h
@@ -153,6 +153,8 @@ STATIC int managed_proxy_severity_parse(const char *);
STATIC const tor_addr_t *managed_proxy_outbound_address(const or_options_t *,
sa_family_t);
+STATIC const char *managed_proxy_state_to_string(enum pt_proto_state);
+STATIC void managed_proxy_set_state(managed_proxy_t *, enum pt_proto_state);
#endif /* defined(PT_PRIVATE) */
#endif /* !defined(TOR_TRANSPORTS_H) */