Skip to content
Permalink
Browse files
Add support for feature detection in transports.
  • Loading branch information
ahf committed May 11, 2019
1 parent efeb101 commit f6d74d8c4fb2306114d41d7bd25525285ff3d453
Showing with 67 additions and 3 deletions.
  1. +51 −3 src/feature/client/transports.c
  2. +7 −0 src/feature/client/transports.h
  3. +9 −0 src/test/test_pt.c
@@ -131,6 +131,7 @@ static void parse_method_error(const char *line, int is_server_method);
#define PROTO_PROXY_ERROR "PROXY-ERROR"
#define PROTO_LOG "LOG"
#define PROTO_STATUS "STATUS"
#define PROTO_FEATURES "FEATURES"

/** The first and only supported - at the moment - configuration
protocol version. */
@@ -916,16 +917,20 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
parse_proxy_error(line);
goto err;

/* We check for the additional " " after the PROTO_LOG * PROTO_STATUS
* string to make sure we can later extend this big if/else-if table with
* something that begins with "LOG" without having to get the order right.
/* We check for the additional " " after the PROTO_LOG, PROTO_STATUS, and
* PROTO_FEATURES string to make sure we can later extend this big
* if/else-if table with something that begins with "LOG" without having to
* get the order right.
* */
} else if (!strcmpstart(line, PROTO_LOG " ")) {
parse_log_line(line, mp);
return;
} else if (!strcmpstart(line, PROTO_STATUS " ")) {
parse_status_line(line, mp);
return;
} else if (!strcmpstart(line, PROTO_FEATURES " ")) {
parse_features_line(line, mp);
return;
}

log_notice(LD_GENERAL, "Unknown line received by managed proxy (%s).", line);
@@ -1213,6 +1218,46 @@ parse_log_line(const char *line, managed_proxy_t *mp)
tor_free(log_message);
}

/** Parses a FEATURES <b>line</b> line for the given <b>mp</b>. */
STATIC void
parse_features_line(const char *line, managed_proxy_t *mp)
{
tor_assert(line);
tor_assert(mp);

smartlist_t *features = NULL;

if (strlen(line) < (strlen(PROTO_FEATURES) + 1)) {
log_warn(LD_PT, "Managed proxy sent us a %s line "
"with missing argument.", PROTO_FEATURES);
goto done;
}

if (mp->features_received) {
log_warn(LD_PT, "Managed proxy sent us a FEATURES line, "
"but we already received one earlier.");
goto done;
}

/* Flag that we have received the FEATURES line. */
mp->features_received = true;

const char *data = line + strlen(PROTO_FEATURES) + 1;

features = smartlist_new();
smartlist_split_string(features, data, ",", 0, 0);

SMARTLIST_FOREACH_BEGIN(features, const char *, feature) {
/* Dormant mode feature extension. */
if (! strcmp(feature, "dormant")) {
mp->dormant_supported = true;
}
} SMARTLIST_FOREACH_END(feature);

done:
smartlist_free(features);
}

/** Parses a STATUS <b>line</b> and emit control events accordingly. */
STATIC void
parse_status_line(const char *line, managed_proxy_t *mp)
@@ -1439,6 +1484,9 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
*/
smartlist_add_asprintf(envs, "TOR_PT_EXIT_ON_STDIN_CLOSE=1");

/* Add a list of supported feature extensions. */
smartlist_add_asprintf(envs, "TOR_PT_FEATURES=dormant");

SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
set_environment_variable_in_smartlist(merged_env_vars, env_var,
tor_free_, 1);
@@ -116,6 +116,12 @@ typedef struct {
/* The 'transports' list contains all the transports this proxy has
launched. */
smartlist_t *transports;

/** Boolean: Have this PT announced its features? */
bool features_received:1;

/** Boolean: Does this PT support the Dormant feature extension? */
bool dormant_supported:1;
} managed_proxy_t;

STATIC transport_t *transport_new(const tor_addr_t *addr, uint16_t port,
@@ -129,6 +135,7 @@ STATIC void parse_env_error(const char *line);
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_features_line(const char *line, managed_proxy_t *mp);
STATIC void parse_status_line(const char *line, managed_proxy_t *mp);
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);

@@ -238,6 +238,15 @@ test_pt_protocol(void *arg)
handle_proxy_line(line, mp);
tt_assert(mp->conf_state == PT_PROTO_CONFIGURED);

/* Check features support. */
tt_assert(! mp->features_received);
tt_assert(! mp->dormant_supported);

strlcpy(line,"FEATURES dormant", sizeof(line));
handle_proxy_line(line, mp);
tt_assert(mp->features_received);
tt_assert(mp->dormant_supported);

done:
reset_mp(mp);
smartlist_free(mp->transports);

0 comments on commit f6d74d8

Please sign in to comment.