diff options
-rw-r--r-- | src/feature/client/transports.c | 42 | ||||
-rw-r--r-- | src/feature/client/transports.h | 1 | ||||
-rw-r--r-- | src/feature/control/control.c | 11 | ||||
-rw-r--r-- | src/feature/control/control.h | 5 | ||||
-rw-r--r-- | src/test/test_pt.c | 19 |
5 files changed, 75 insertions, 3 deletions
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c index f0400b713d..dc76e9c245 100644 --- a/src/feature/client/transports.c +++ b/src/feature/client/transports.c @@ -128,6 +128,7 @@ static void parse_method_error(const char *line, int is_server_method); #define PROTO_SMETHODS_DONE "SMETHODS DONE" #define PROTO_PROXY_DONE "PROXY DONE" #define PROTO_PROXY_ERROR "PROXY-ERROR" +#define PROTO_LOG "LOG" /** The first and only supported - at the moment - configuration protocol version. */ @@ -909,6 +910,9 @@ handle_proxy_line(const char *line, managed_proxy_t *mp) parse_proxy_error(line); goto err; + } else if (!strcmpstart(line, PROTO_LOG)) { + parse_log_line(line); + return; } else if (!strcmpstart(line, SPAWN_ERROR_MESSAGE)) { /* managed proxy launch failed: parse error message to learn why. */ int retval, child_state, saved_errno; @@ -1146,6 +1150,44 @@ parse_proxy_error(const char *line) line+strlen(PROTO_PROXY_ERROR)+1); } +/** Parses a LOG <b>line</b> and emit log events accordingly. */ +STATIC void +parse_log_line(const char *line) +{ + smartlist_t *items = smartlist_new(); + + if (strlen(line) < (strlen(PROTO_LOG) + 1)) { + log_warn(LD_PT, "Managed proxy sent us a %s line " + "with missing arguments.", PROTO_LOG); + goto done; + } + + const char *arguments = line + strlen(PROTO_LOG) + 1; + + /* The format is 'LOG <transport> <message>'. We accept empty messages. */ + smartlist_split_string(items, arguments, NULL, + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2); + + if (smartlist_len(items) < 2) { + log_warn(LD_PT, "Managed proxy sent us a %s line " + "with too few arguments.", PROTO_LOG); + goto done; + } + + const char *transport_name = smartlist_get(items, 0); + const char *message = smartlist_get(items, 1); + + log_info(LD_PT, "Managed proxy transport \"%s\" says: %s", + transport_name, message); + + /* Emit control port event. */ + control_event_transport_log(transport_name, message); + + done: + SMARTLIST_FOREACH(items, char *, s, tor_free(s)); + smartlist_free(items); +} + /** 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 59df637d81..fbb720aac6 100644 --- a/src/feature/client/transports.h +++ b/src/feature/client/transports.h @@ -128,6 +128,7 @@ STATIC int parse_version(const char *line, managed_proxy_t *mp); 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); 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/feature/control/control.c b/src/feature/control/control.c index 94679dfd22..b6505a85d6 100644 --- a/src/feature/control/control.c +++ b/src/feature/control/control.c @@ -7395,6 +7395,17 @@ control_event_transport_launched(const char *mode, const char *transport_name, mode, transport_name, fmt_addr(addr), port); } +/** A pluggable transport called <b>transport_name</b> has emitted a log + * message found in <b>message</b>. */ +void +control_event_transport_log(const char *transport_name, const char *message) +{ + send_control_event(EVENT_TRANSPORT_LOG, + "650 TRANSPORT_LOG %s %s\r\n", + transport_name, + message); +} + /** Convert rendezvous auth type to string for HS_DESC control events */ const char * diff --git a/src/feature/control/control.h b/src/feature/control/control.h index cd5402d455..eb2b5676ea 100644 --- a/src/feature/control/control.h +++ b/src/feature/control/control.h @@ -205,6 +205,8 @@ void control_event_clients_seen(const char *controller_str); void control_event_transport_launched(const char *mode, const char *transport_name, tor_addr_t *addr, uint16_t port); +void control_event_transport_log(const char *transport_name, + const char *message); const char *rend_auth_type_to_string(rend_auth_type_t auth_type); MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest)); void control_event_hs_descriptor_requested(const char *onion_address, @@ -293,7 +295,8 @@ void control_free_all(void); #define EVENT_HS_DESC 0x0021 #define EVENT_HS_DESC_CONTENT 0x0022 #define EVENT_NETWORK_LIVENESS 0x0023 -#define EVENT_MAX_ 0x0023 +#define EVENT_TRANSPORT_LOG 0x0024 +#define EVENT_MAX_ 0x0024 /* sizeof(control_connection_t.event_mask) in bits, currently a uint64_t */ #define EVENT_CAPACITY_ 0x0040 diff --git a/src/test/test_pt.c b/src/test/test_pt.c index 2501b867bb..c980276b14 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -304,11 +304,16 @@ process_read_stdout_replacement(process_t *process, buf_t *buffer) /* Generate some dummy CMETHOD lines the first 5 times. The 6th time, send 'CMETHODS DONE' to finish configuring the proxy. */ - if (times_called++ != 5) { + times_called++; + + if (times_called <= 5) { buf_add_printf(buffer, "SMETHOD mock%d 127.0.0.1:555%d\n", times_called, times_called); - } else { + } else if (times_called <= 6) { buf_add_string(buffer, "SMETHODS DONE\n"); + } else if (times_called <= 7) { + buf_add_string(buffer, "LOG mock3 Oh noes, something bad happened. " + "What do we do!?\n"); } return (int)buf_datalen(buffer); @@ -410,6 +415,16 @@ test_pt_configure_proxy(void *arg) tt_str_op(smartlist_get(controlevent_msgs, 4), OP_EQ, "650 TRANSPORT_LAUNCHED server mock5 127.0.0.1 5555\r\n"); + /* Get the log message out. */ + process_notify_event_stdout(mp->process); + + tt_int_op(controlevent_n, OP_EQ, 6); + tt_int_op(controlevent_event, OP_EQ, EVENT_TRANSPORT_LOG); + tt_int_op(smartlist_len(controlevent_msgs), OP_EQ, 6); + tt_str_op(smartlist_get(controlevent_msgs, 5), OP_EQ, + "650 TRANSPORT_LOG mock3 Oh noes, something bad happened. " + "What do we do!?\r\n"); + { /* check that the transport info were saved properly in the tor state */ config_line_t *transport_in_state = NULL; smartlist_t *transport_info_sl = smartlist_new(); |