mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
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.
This commit is contained in:
parent
d8b3ec865d
commit
95afdb005c
@ -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;
|
||||
|
||||
@ -2296,15 +2253,6 @@ typedef union handler_fn_t {
|
||||
int (*legacy)(control_connection_t *conn,
|
||||
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;
|
||||
|
@ -342,20 +342,6 @@ get_escaped_string_length(const char *start, size_t in_len_max,
|
||||
return (int)(cp - start+1);
|
||||
}
|
||||
|
||||
/** As decode_escaped_string, but does not decode the string: copies the
|
||||
* entire thing, including quotation marks. */
|
||||
const char *
|
||||
extract_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len)
|
||||
{
|
||||
int length = get_escaped_string_length(start, in_len_max, NULL);
|
||||
if (length<0)
|
||||
return NULL;
|
||||
*out_len = length;
|
||||
*out = tor_strndup(start, *out_len);
|
||||
return start+length;
|
||||
}
|
||||
|
||||
/** Given a pointer to a string starting at <b>start</b> containing
|
||||
* <b>in_len_max</b> characters, decode a string beginning with one double
|
||||
* quote, containing any number of non-quote characters or characters escaped
|
||||
|
@ -25,8 +25,6 @@ char *circuit_describe_status_for_controller(origin_circuit_t *circ);
|
||||
|
||||
size_t write_escaped_data(const char *data, size_t len, char **out);
|
||||
size_t read_escaped_data(const char *data, size_t len, char **out);
|
||||
const char *extract_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len);
|
||||
const char *decode_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len);
|
||||
void send_control_done(control_connection_t *conn);
|
||||
|
Loading…
Reference in New Issue
Block a user