aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2022-03-24 19:13:41 +0000
committerDavid Goulet <dgoulet@torproject.org>2024-06-18 15:15:20 -0400
commitb6e260e69946dc6ce9c7de64438d5af29959d037 (patch)
tree70279845441ad1ef505a5c62e28272f84c390897
parent0c1a39a955b91062ab2f012b2a9ea9675babec08 (diff)
downloadtor-b6e260e69946dc6ce9c7de64438d5af29959d037.tar.gz
tor-b6e260e69946dc6ce9c7de64438d5af29959d037.zip
Add support for PT STATUS TYPE=version messages.
This patch adds support for handling the version status message. Once we receive such message, we add the given version string to the managed_proxy_t instance. Note this value can be NULL and the value can change throughout the lifetime of the PT as multiple status version messages are handled. See: tpo/core/tor#11101
-rw-r--r--src/feature/client/transports.c36
-rw-r--r--src/feature/client/transports.h7
-rw-r--r--src/test/test_pt.c35
3 files changed, 78 insertions, 0 deletions
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 4d92a2a67a..7c5132695a 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -741,6 +741,9 @@ managed_proxy_destroy(managed_proxy_t *mp,
/* free the outgoing proxy URI */
tor_free(mp->proxy_uri);
+ /* free our version, if any is set. */
+ tor_free(mp->version);
+
/* do we want to terminate our process if it's still running? */
if (also_terminate_process && mp->process) {
/* Note that we do not call process_free(mp->process) here because we let
@@ -1293,6 +1296,9 @@ parse_status_line(const char *line, managed_proxy_t *mp)
goto done;
}
+ /* Handle the different messages. */
+ handle_status_message(values, mp);
+
/* Prepend the PT name. */
config_line_prepend(&values, "PT", mp->argv[0]);
status_message = kvline_encode(values, KV_QUOTED);
@@ -1306,6 +1312,36 @@ parse_status_line(const char *line, managed_proxy_t *mp)
tor_free(status_message);
}
+STATIC void
+handle_status_message(const config_line_t *values,
+ managed_proxy_t *mp)
+{
+ const config_line_t *message_type = config_line_find(values, "TYPE");
+
+ /* Check if we have a TYPE field? */
+ if (message_type == NULL) {
+ log_debug(LD_PT, "Managed proxy \"%s\" wrote a STATUS line without "
+ "a defined message TYPE", mp->argv[0]);
+ return;
+ }
+
+ /* Handle VERSION messages. */
+ if (! strcasecmp(message_type->value, "version")) {
+ const config_line_t *version = config_line_find(values, "VERSION");
+
+ if (version == NULL) {
+ log_warn(LD_PT, "Managed proxy \"%s\" wrote a STATUS TYPE=version line "
+ "with a missing VERSION field", mp->argv[0]);
+ return;
+ }
+
+ tor_free(mp->version);
+ mp->version = tor_strdup(version->value);
+
+ return;
+ }
+}
+
/** Return a newly allocated string that tor should place in
* TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
* manged proxy in <b>mp</b>. Return NULL if no such options are found. */
diff --git a/src/feature/client/transports.h b/src/feature/client/transports.h
index 535689537c..1f6c10961d 100644
--- a/src/feature/client/transports.h
+++ b/src/feature/client/transports.h
@@ -114,11 +114,16 @@ typedef struct {
/* transports to-be-launched by this proxy */
smartlist_t *transports_to_launch;
+ /** Version as set by STATUS TYPE=version messages. */
+ char *version;
+
/* The 'transports' list contains all the transports this proxy has
launched. */
smartlist_t *transports;
} managed_proxy_t;
+struct config_line_t;
+
STATIC transport_t *transport_new(const tor_addr_t *addr, uint16_t port,
const char *name, int socks_ver,
const char *extra_info_args);
@@ -131,6 +136,8 @@ STATIC void parse_proxy_error(const char *line);
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
STATIC void parse_log_line(const char *line, managed_proxy_t *mp);
STATIC void parse_status_line(const char *line, managed_proxy_t *mp);
+STATIC void handle_status_message(const struct config_line_t *values,
+ managed_proxy_t *mp);
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
STATIC void managed_proxy_destroy(managed_proxy_t *mp,
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 07c5032933..e97b0b2087 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -143,6 +143,40 @@ test_pt_parsing(void *arg)
}
static void
+test_pt_status_parsing(void *arg)
+{
+ char line[200];
+ char *test_binary = tor_strdup("test-pt");
+ char *argv[] = {
+ test_binary,
+ NULL,
+ };
+
+ managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
+ (void)arg;
+ mp->conf_state = PT_PROTO_INFANT;
+ mp->transports = smartlist_new();
+ mp->argv = argv;
+
+ /* STATUS TYPE=version messages. */
+ tt_ptr_op(mp->version, OP_EQ, NULL);
+ strlcpy(line, "STATUS TRANSPORT=x "
+ "TYPE=version "
+ "VERSION=\"1.33.7-hax beta\"",
+ sizeof(line));
+ handle_proxy_line(line, mp);
+ tt_str_op(mp->version, OP_EQ, "1.33.7-hax beta");
+
+ reset_mp(mp);
+
+ done:
+ reset_mp(mp);
+ smartlist_free(mp->transports);
+ tor_free(mp);
+ tor_free(test_binary);
+}
+
+static void
test_pt_get_transport_options(void *arg)
{
char **execve_args;
@@ -590,6 +624,7 @@ test_get_pt_proxy_uri(void *arg)
struct testcase_t pt_tests[] = {
PT_LEGACY(parsing),
+ PT_LEGACY(status_parsing),
PT_LEGACY(protocol),
{ "get_transport_options", test_pt_get_transport_options, TT_FORK,
NULL, NULL },