mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Merge branch 'tor-gitlab/mr/443'
This commit is contained in:
commit
a1042f4873
3
changes/ticket33669
Normal file
3
changes/ticket33669
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
o Minor features (pluggable transports):
|
||||||
|
- Automatically restart managed Pluggable Transport processes when their
|
||||||
|
process terminate. Resolves ticket 33669.
|
@ -519,8 +519,10 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
|
|||||||
tor_assert(mp->conf_state == PT_PROTO_COMPLETED);
|
tor_assert(mp->conf_state == PT_PROTO_COMPLETED);
|
||||||
|
|
||||||
/* destroy the process handle and terminate the process. */
|
/* destroy the process handle and terminate the process. */
|
||||||
|
if (mp->process) {
|
||||||
process_set_data(mp->process, NULL);
|
process_set_data(mp->process, NULL);
|
||||||
process_terminate(mp->process);
|
process_terminate(mp->process);
|
||||||
|
}
|
||||||
|
|
||||||
/* destroy all its registered transports, since we will no longer
|
/* destroy all its registered transports, since we will no longer
|
||||||
use them. */
|
use them. */
|
||||||
@ -541,7 +543,7 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
|
|||||||
mp->proxy_supported = 0;
|
mp->proxy_supported = 0;
|
||||||
|
|
||||||
/* flag it as an infant proxy so that it gets launched on next tick */
|
/* 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++;
|
unconfigured_proxies_n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,6 +556,8 @@ launch_managed_proxy(managed_proxy_t *mp)
|
|||||||
smartlist_t *env = create_managed_proxy_environment(mp);
|
smartlist_t *env = create_managed_proxy_environment(mp);
|
||||||
|
|
||||||
/* Configure our process. */
|
/* Configure our process. */
|
||||||
|
tor_assert(mp->process == NULL);
|
||||||
|
mp->process = process_new(mp->argv[0]);
|
||||||
process_set_data(mp->process, mp);
|
process_set_data(mp->process, mp);
|
||||||
process_set_stdout_read_callback(mp->process, managed_proxy_stdout_callback);
|
process_set_stdout_read_callback(mp->process, managed_proxy_stdout_callback);
|
||||||
process_set_stderr_read_callback(mp->process, managed_proxy_stderr_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,
|
log_info(LD_CONFIG,
|
||||||
"Managed proxy at '%s' has spawned with PID '%" PRIu64 "'.",
|
"Managed proxy at '%s' has spawned with PID '%" PRIu64 "'.",
|
||||||
mp->argv[0], process_get_pid(mp->process));
|
mp->argv[0], process_get_pid(mp->process));
|
||||||
mp->conf_state = PT_PROTO_LAUNCHED;
|
managed_proxy_set_state(mp, PT_PROTO_LAUNCHED);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -648,7 +652,7 @@ configure_proxy(managed_proxy_t *mp)
|
|||||||
/* if we haven't launched the proxy yet, do it now */
|
/* if we haven't launched the proxy yet, do it now */
|
||||||
if (mp->conf_state == PT_PROTO_INFANT) {
|
if (mp->conf_state == PT_PROTO_INFANT) {
|
||||||
if (launch_managed_proxy(mp) < 0) { /* launch fail */
|
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);
|
handle_finished_proxy(mp);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -810,8 +814,12 @@ handle_finished_proxy(managed_proxy_t *mp)
|
|||||||
managed_proxy_destroy(mp, 1); /* annihilate it. */
|
managed_proxy_destroy(mp, 1); /* annihilate it. */
|
||||||
break;
|
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;
|
break;
|
||||||
case PT_PROTO_INFANT:
|
case PT_PROTO_INFANT:
|
||||||
case PT_PROTO_LAUNCHED:
|
case PT_PROTO_LAUNCHED:
|
||||||
@ -857,7 +865,7 @@ handle_methods_done(const managed_proxy_t *mp)
|
|||||||
STATIC void
|
STATIC void
|
||||||
handle_proxy_line(const char *line, managed_proxy_t *mp)
|
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);
|
mp->argv[0], line);
|
||||||
|
|
||||||
if (!strcmpstart(line, PROTO_ENV_ERROR)) {
|
if (!strcmpstart(line, PROTO_ENV_ERROR)) {
|
||||||
@ -881,7 +889,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
tor_assert(mp->conf_protocol != 0);
|
tor_assert(mp->conf_protocol != 0);
|
||||||
mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
|
managed_proxy_set_state(mp, PT_PROTO_ACCEPTING_METHODS);
|
||||||
return;
|
return;
|
||||||
} else if (!strcmpstart(line, PROTO_CMETHODS_DONE)) {
|
} else if (!strcmpstart(line, PROTO_CMETHODS_DONE)) {
|
||||||
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
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);
|
handle_methods_done(mp);
|
||||||
|
|
||||||
mp->conf_state = PT_PROTO_CONFIGURED;
|
managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
|
||||||
return;
|
return;
|
||||||
} else if (!strcmpstart(line, PROTO_SMETHODS_DONE)) {
|
} else if (!strcmpstart(line, PROTO_SMETHODS_DONE)) {
|
||||||
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
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);
|
handle_methods_done(mp);
|
||||||
|
|
||||||
mp->conf_state = PT_PROTO_CONFIGURED;
|
managed_proxy_set_state(mp, PT_PROTO_CONFIGURED);
|
||||||
return;
|
return;
|
||||||
} else if (!strcmpstart(line, PROTO_CMETHOD_ERROR)) {
|
} else if (!strcmpstart(line, PROTO_CMETHOD_ERROR)) {
|
||||||
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
|
||||||
@ -968,7 +976,7 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
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"
|
log_warn(LD_CONFIG, "Managed proxy at '%s' failed the configuration protocol"
|
||||||
" and will be destroyed.", mp->argv[0]);
|
" 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)
|
char **proxy_argv, int is_server)
|
||||||
{
|
{
|
||||||
managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
|
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->is_server = is_server;
|
||||||
mp->argv = proxy_argv;
|
mp->argv = proxy_argv;
|
||||||
mp->transports = smartlist_new();
|
mp->transports = smartlist_new();
|
||||||
mp->proxy_uri = get_pt_proxy_uri();
|
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();
|
mp->transports_to_launch = smartlist_new();
|
||||||
SMARTLIST_FOREACH(with_transport_list, const char *, transport,
|
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);
|
tor_assert(process);
|
||||||
|
|
||||||
|
managed_proxy_t *mp = process_get_data(process);
|
||||||
|
const char *name = mp ? mp->argv[0] : "N/A";
|
||||||
|
|
||||||
log_warn(LD_PT,
|
log_warn(LD_PT,
|
||||||
"Pluggable Transport process terminated with status code %" PRIu64,
|
"Managed proxy \"%s\" process terminated with status code %" PRIu64,
|
||||||
exit_code);
|
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
|
/* Returning true here means that the process subsystem will take care of
|
||||||
* calling process_free() on our process_t. */
|
* 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. */
|
/* The user have not specified a preference for outgoing connections. */
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
@ -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 *,
|
STATIC const tor_addr_t *managed_proxy_outbound_address(const or_options_t *,
|
||||||
sa_family_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(PT_PRIVATE) */
|
||||||
|
|
||||||
#endif /* !defined(TOR_TRANSPORTS_H) */
|
#endif /* !defined(TOR_TRANSPORTS_H) */
|
||||||
|
Loading…
Reference in New Issue
Block a user