diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-04-08 16:19:09 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-04-25 14:13:03 -0400 |
commit | 95afdb005cce04cfb87df6a75980944173c15ed7 (patch) | |
tree | 4604c7c96572b64e0ab0ab027a522ecf4f9d695d /src/feature/control/control_cmd.c | |
parent | d8b3ec865de2738144bd6bbf9f6355662e64eb25 (diff) | |
download | tor-95afdb005cce04cfb87df6a75980944173c15ed7.tar.gz tor-95afdb005cce04cfb87df6a75980944173c15ed7.zip |
Use new parser logic for SETCONF/RESETCONF code.
Here we get to throw away a LOT of unused code, since most of the
old parsing was redundant with kvline.
Diffstat (limited to 'src/feature/control/control_cmd.c')
-rw-r--r-- | src/feature/control/control_cmd.c | 108 |
1 files changed, 26 insertions, 82 deletions
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index 1848555351..cfd35e8096 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -54,8 +54,8 @@ #include "feature/rend/rend_encoded_v2_service_descriptor_st.h" #include "feature/rend/rend_service_descriptor_st.h" -static int control_setconf_helper(control_connection_t *conn, uint32_t len, - char *body, +static int control_setconf_helper(control_connection_t *conn, + const control_cmd_args_t *args, int use_defaults); /** Yield true iff <b>s</b> is the state of a control_connection_t that has @@ -195,22 +195,36 @@ config_lines_contain_flag(const config_line_t *lines, const char *flag) return line && !strcmp(line->value, ""); } +static const control_cmd_syntax_t setconf_syntax = { + .max_args=0, + .accept_keywords=true, + .kvline_flags=KV_OMIT_VALS|KV_QUOTED, +}; + /** Called when we receive a SETCONF message: parse the body and try * to update our configuration. Reply with a DONE or ERROR message. * Modifies the contents of body.*/ static int -handle_control_setconf(control_connection_t *conn, uint32_t len, char *body) +handle_control_setconf(control_connection_t *conn, + const control_cmd_args_t *args) { - return control_setconf_helper(conn, len, body, 0); + return control_setconf_helper(conn, args, 0); } +static const control_cmd_syntax_t resetconf_syntax = { + .max_args=0, + .accept_keywords=true, + .kvline_flags=KV_OMIT_VALS|KV_QUOTED, +}; + /** Called when we receive a RESETCONF message: parse the body and try * to update our configuration. Reply with a DONE or ERROR message. * Modifies the contents of body. */ static int -handle_control_resetconf(control_connection_t *conn, uint32_t len, char *body) +handle_control_resetconf(control_connection_t *conn, + const control_cmd_args_t *args) { - return control_setconf_helper(conn, len, body, 1); + return control_setconf_helper(conn, args, 1); } static const control_cmd_syntax_t getconf_syntax = { @@ -524,73 +538,17 @@ get_stream(const char *id) * contents of body. */ static int -control_setconf_helper(control_connection_t *conn, uint32_t len, char *body, +control_setconf_helper(control_connection_t *conn, + const control_cmd_args_t *args, int use_defaults) { setopt_err_t opt_err; - config_line_t *lines=NULL; - char *start = body; char *errstring = NULL; const unsigned flags = CAL_CLEAR_FIRST | (use_defaults ? CAL_USE_DEFAULTS : 0); - char *config; - smartlist_t *entries = smartlist_new(); - - /* We have a string, "body", of the format '(key(=val|="val")?)' entries - * separated by space. break it into a list of configuration entries. */ - while (*body) { - char *eq = body; - char *key; - char *entry; - while (!TOR_ISSPACE(*eq) && *eq != '=') - ++eq; - key = tor_strndup(body, eq-body); - body = eq+1; - if (*eq == '=') { - char *val=NULL; - size_t val_len=0; - if (*body != '\"') { - char *val_start = body; - while (!TOR_ISSPACE(*body)) - body++; - val = tor_strndup(val_start, body-val_start); - val_len = strlen(val); - } else { - body = (char*)extract_escaped_string(body, (len - (body-start)), - &val, &val_len); - if (!body) { - connection_write_str_to_buf("551 Couldn't parse string\r\n", conn); - SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp)); - smartlist_free(entries); - tor_free(key); - return 0; - } - } - tor_asprintf(&entry, "%s %s", key, val); - tor_free(key); - tor_free(val); - } else { - entry = key; - } - smartlist_add(entries, entry); - while (TOR_ISSPACE(*body)) - ++body; - } - - smartlist_add_strdup(entries, ""); - config = smartlist_join_strings(entries, "\n", 0, NULL); - SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp)); - smartlist_free(entries); - - if (config_get_lines(config, &lines, 0) < 0) { - log_warn(LD_CONTROL,"Controller gave us config lines we can't parse."); - connection_write_str_to_buf("551 Couldn't parse configuration\r\n", - conn); - tor_free(config); - return 0; - } - tor_free(config); + // We need a copy here, since confparse.c wants to canonicalize cases. + config_line_t *lines = config_lines_dup(args->kwargs); opt_err = options_trial_assign(lines, flags, &errstring); { @@ -2276,7 +2234,6 @@ handle_control_obsolete(control_connection_t *conn, **/ typedef enum handler_type_t { hnd_legacy, - hnd_legacy_mut, hnd_parsed, } handler_type_t; @@ -2297,15 +2254,6 @@ typedef union handler_fn_t { uint32_t arg_len, const char *args); /** - * A "legacy_mut" handler is the same as a "legacy" one, except that it may - * change the contents of the command's arguments -- for example, by - * inserting NULs. It may not deallocate them. - */ - int (*legacy_mut)(control_connection_t *conn, - uint32_t arg_len, - char *args); - - /** * A "parsed" handler expects its arguments in a pre-parsed format, in * an immutable control_cmd_args_t *object. **/ @@ -2400,8 +2348,8 @@ typedef struct control_cmd_def_t { **/ static const control_cmd_def_t CONTROL_COMMANDS[] = { - ONE_LINE(setconf, legacy_mut, 0), - ONE_LINE(resetconf, legacy_mut, 0), + ONE_LINE_PARSED(setconf, 0), + ONE_LINE_PARSED(resetconf, 0), ONE_LINE_PARSED(getconf, 0), MULTLINE_PARSED(loadconf, 0), ONE_LINE_PARSED(setevents, 0), @@ -2452,10 +2400,6 @@ handle_single_control_command(const control_cmd_def_t *def, if (def->handler.legacy(conn, cmd_data_len, args)) rv = -1; break; - case hnd_legacy_mut: - if (def->handler.legacy_mut(conn, cmd_data_len, args)) - rv = -1; - break; case hnd_parsed: { control_cmd_args_t *parsed_args; char *err=NULL; |