mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Simplify handler logic in control_cmd.c
Now that the legacy handlers are gone, we can simplify the structures and macros here.
This commit is contained in:
parent
ddd33d39c7
commit
88d22b898e
@ -2171,16 +2171,18 @@ handle_control_del_onion(control_connection_t *conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const control_cmd_syntax_t obsolete_syntax = {
|
||||||
|
.max_args = UINT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when we get an obsolete command: tell the controller that it is
|
* Called when we get an obsolete command: tell the controller that it is
|
||||||
* obsolete.
|
* obsolete.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
handle_control_obsolete(control_connection_t *conn,
|
handle_control_obsolete(control_connection_t *conn,
|
||||||
uint32_t arg_len,
|
const control_cmd_args_t *args)
|
||||||
const char *args)
|
|
||||||
{
|
{
|
||||||
(void)arg_len;
|
|
||||||
(void)args;
|
(void)args;
|
||||||
char *command = tor_strdup(conn->current_cmd);
|
char *command = tor_strdup(conn->current_cmd);
|
||||||
tor_strupper(command);
|
tor_strupper(command);
|
||||||
@ -2190,37 +2192,10 @@ handle_control_obsolete(control_connection_t *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects an API to a controller command. See handler_fn_t for the
|
* Function pointer to a handler function for a controller command.
|
||||||
* possible types.
|
|
||||||
**/
|
**/
|
||||||
typedef enum handler_type_t {
|
typedef int (*handler_fn_t) (control_connection_t *conn,
|
||||||
hnd_legacy,
|
const control_cmd_args_t *args);
|
||||||
hnd_parsed,
|
|
||||||
} handler_type_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Union: a function pointer to a handler function for a controller command.
|
|
||||||
*
|
|
||||||
* This needs to be a union (rather than just a single pointer) since not
|
|
||||||
* all controller commands have the same type.
|
|
||||||
**/
|
|
||||||
typedef union handler_fn_t {
|
|
||||||
/**
|
|
||||||
* A "legacy" handler takes a command's arguments as a nul-terminated
|
|
||||||
* string, and their length. It may not change the contents of the
|
|
||||||
* arguments. If the command is a multiline one, then the arguments may
|
|
||||||
* extend across multiple lines.
|
|
||||||
*/
|
|
||||||
int (*legacy)(control_connection_t *conn,
|
|
||||||
uint32_t arg_len,
|
|
||||||
const char *args);
|
|
||||||
/**
|
|
||||||
* A "parsed" handler expects its arguments in a pre-parsed format, in
|
|
||||||
* an immutable control_cmd_args_t *object.
|
|
||||||
**/
|
|
||||||
int (*parsed)(control_connection_t *conn,
|
|
||||||
const control_cmd_args_t *args);
|
|
||||||
} handler_fn_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition for a controller command.
|
* Definition for a controller command.
|
||||||
@ -2230,10 +2205,6 @@ typedef struct control_cmd_def_t {
|
|||||||
* The name of the command. If the command is multiline, the name must
|
* The name of the command. If the command is multiline, the name must
|
||||||
* begin with "+". This is not case-sensitive. */
|
* begin with "+". This is not case-sensitive. */
|
||||||
const char *name;
|
const char *name;
|
||||||
/**
|
|
||||||
* Which API to use when calling the handler function.
|
|
||||||
*/
|
|
||||||
handler_type_t handler_type;
|
|
||||||
/**
|
/**
|
||||||
* A function to execute the command.
|
* A function to execute the command.
|
||||||
*/
|
*/
|
||||||
@ -2254,54 +2225,37 @@ typedef struct control_cmd_def_t {
|
|||||||
*/
|
*/
|
||||||
#define CMD_FL_WIPE (1u<<0)
|
#define CMD_FL_WIPE (1u<<0)
|
||||||
|
|
||||||
#define SYNTAX_IGNORE { 0, UINT_MAX, false }
|
|
||||||
|
|
||||||
/** Macro: declare a command with a one-line argument, a given set of flags,
|
/** Macro: declare a command with a one-line argument, a given set of flags,
|
||||||
* and a syntax definition.
|
* and a syntax definition.
|
||||||
**/
|
**/
|
||||||
#define ONE_LINE_(name, htype, flags, syntax) \
|
#define ONE_LINE(name, flags) \
|
||||||
{ #name, \
|
{ \
|
||||||
hnd_ ##htype, \
|
#name, \
|
||||||
{ .htype = handle_control_ ##name }, \
|
handle_control_ ##name, \
|
||||||
flags, \
|
flags, \
|
||||||
syntax, \
|
&name##_syntax, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Macro: declare a parsed command with a one-line argument, a given set of
|
|
||||||
* flags, and a syntax definition.
|
|
||||||
**/
|
|
||||||
#define ONE_LINE(name, htype, flags) \
|
|
||||||
ONE_LINE_(name, htype, flags, NULL)
|
|
||||||
#define ONE_LINE_PARSED(name, flags) \
|
|
||||||
ONE_LINE_(name, parsed, flags, &name ##_syntax)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macro: declare a command with a multi-line argument and a given set of
|
* Macro: declare a command with a multi-line argument and a given set of
|
||||||
* flags.
|
* flags.
|
||||||
**/
|
**/
|
||||||
#define MULTLINE_(name, htype, flags, syntax) \
|
#define MULTLINE(name, flags) \
|
||||||
{ "+"#name, \
|
{ "+"#name, \
|
||||||
hnd_ ##htype, \
|
handle_control_ ##name, \
|
||||||
{ .htype = handle_control_ ##name }, \
|
|
||||||
flags, \
|
flags, \
|
||||||
syntax \
|
&name##_syntax \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MULTLINE(name, htype, flags) \
|
|
||||||
MULTLINE_(name, htype, flags, NULL)
|
|
||||||
#define MULTLINE_PARSED(name, flags) \
|
|
||||||
MULTLINE_(name, parsed, flags, &name##_syntax)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macro: declare an obsolete command. (Obsolete commands give a different
|
* Macro: declare an obsolete command. (Obsolete commands give a different
|
||||||
* error than non-existent ones.)
|
* error than non-existent ones.)
|
||||||
**/
|
**/
|
||||||
#define OBSOLETE(name) \
|
#define OBSOLETE(name) \
|
||||||
{ #name, \
|
{ #name, \
|
||||||
hnd_legacy, \
|
handle_control_obsolete, \
|
||||||
{ .legacy = handle_control_obsolete }, \
|
|
||||||
0, \
|
0, \
|
||||||
NULL, \
|
&obsolete_syntax, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2309,35 +2263,35 @@ typedef struct control_cmd_def_t {
|
|||||||
**/
|
**/
|
||||||
static const control_cmd_def_t CONTROL_COMMANDS[] =
|
static const control_cmd_def_t CONTROL_COMMANDS[] =
|
||||||
{
|
{
|
||||||
ONE_LINE_PARSED(setconf, 0),
|
ONE_LINE(setconf, 0),
|
||||||
ONE_LINE_PARSED(resetconf, 0),
|
ONE_LINE(resetconf, 0),
|
||||||
ONE_LINE_PARSED(getconf, 0),
|
ONE_LINE(getconf, 0),
|
||||||
MULTLINE_PARSED(loadconf, 0),
|
MULTLINE(loadconf, 0),
|
||||||
ONE_LINE_PARSED(setevents, 0),
|
ONE_LINE(setevents, 0),
|
||||||
ONE_LINE_PARSED(authenticate, CMD_FL_WIPE),
|
ONE_LINE(authenticate, CMD_FL_WIPE),
|
||||||
ONE_LINE_PARSED(saveconf, 0),
|
ONE_LINE(saveconf, 0),
|
||||||
ONE_LINE_PARSED(signal, 0),
|
ONE_LINE(signal, 0),
|
||||||
ONE_LINE_PARSED(takeownership, 0),
|
ONE_LINE(takeownership, 0),
|
||||||
ONE_LINE_PARSED(dropownership, 0),
|
ONE_LINE(dropownership, 0),
|
||||||
ONE_LINE_PARSED(mapaddress, 0),
|
ONE_LINE(mapaddress, 0),
|
||||||
ONE_LINE_PARSED(getinfo, 0),
|
ONE_LINE(getinfo, 0),
|
||||||
ONE_LINE_PARSED(extendcircuit, 0),
|
ONE_LINE(extendcircuit, 0),
|
||||||
ONE_LINE_PARSED(setcircuitpurpose, 0),
|
ONE_LINE(setcircuitpurpose, 0),
|
||||||
OBSOLETE(setrouterpurpose),
|
OBSOLETE(setrouterpurpose),
|
||||||
ONE_LINE_PARSED(attachstream, 0),
|
ONE_LINE(attachstream, 0),
|
||||||
MULTLINE_PARSED(postdescriptor, 0),
|
MULTLINE(postdescriptor, 0),
|
||||||
ONE_LINE_PARSED(redirectstream, 0),
|
ONE_LINE(redirectstream, 0),
|
||||||
ONE_LINE_PARSED(closestream, 0),
|
ONE_LINE(closestream, 0),
|
||||||
ONE_LINE_PARSED(closecircuit, 0),
|
ONE_LINE(closecircuit, 0),
|
||||||
ONE_LINE_PARSED(usefeature, 0),
|
ONE_LINE(usefeature, 0),
|
||||||
ONE_LINE_PARSED(resolve, 0),
|
ONE_LINE(resolve, 0),
|
||||||
ONE_LINE_PARSED(protocolinfo, 0),
|
ONE_LINE(protocolinfo, 0),
|
||||||
ONE_LINE_PARSED(authchallenge, CMD_FL_WIPE),
|
ONE_LINE(authchallenge, CMD_FL_WIPE),
|
||||||
ONE_LINE_PARSED(dropguards, 0),
|
ONE_LINE(dropguards, 0),
|
||||||
ONE_LINE_PARSED(hsfetch, 0),
|
ONE_LINE(hsfetch, 0),
|
||||||
MULTLINE_PARSED(hspost, 0),
|
MULTLINE(hspost, 0),
|
||||||
ONE_LINE_PARSED(add_onion, CMD_FL_WIPE),
|
ONE_LINE(add_onion, CMD_FL_WIPE),
|
||||||
ONE_LINE_PARSED(del_onion, CMD_FL_WIPE),
|
ONE_LINE(del_onion, CMD_FL_WIPE),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2356,35 +2310,25 @@ handle_single_control_command(const control_cmd_def_t *def,
|
|||||||
char *args)
|
char *args)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
switch (def->handler_type) {
|
|
||||||
case hnd_legacy:
|
control_cmd_args_t *parsed_args;
|
||||||
if (def->handler.legacy(conn, cmd_data_len, args))
|
char *err=NULL;
|
||||||
rv = -1;
|
tor_assert(def->syntax);
|
||||||
break;
|
parsed_args = control_cmd_parse_args(conn->current_cmd,
|
||||||
case hnd_parsed: {
|
def->syntax,
|
||||||
control_cmd_args_t *parsed_args;
|
cmd_data_len, args,
|
||||||
char *err=NULL;
|
&err);
|
||||||
tor_assert(def->syntax);
|
if (!parsed_args) {
|
||||||
parsed_args = control_cmd_parse_args(conn->current_cmd,
|
connection_printf_to_buf(conn,
|
||||||
def->syntax,
|
"512 Bad arguments to %s: %s\r\n",
|
||||||
cmd_data_len, args,
|
conn->current_cmd, err?err:"");
|
||||||
&err);
|
tor_free(err);
|
||||||
if (!parsed_args) {
|
} else {
|
||||||
connection_printf_to_buf(conn,
|
if (BUG(err))
|
||||||
"512 Bad arguments to %s: %s\r\n",
|
tor_free(err);
|
||||||
conn->current_cmd, err?err:"");
|
if (def->handler(conn, parsed_args))
|
||||||
tor_free(err);
|
rv = 0;
|
||||||
} else {
|
control_cmd_args_free(parsed_args);
|
||||||
if (BUG(err))
|
|
||||||
tor_free(err);
|
|
||||||
if (def->handler.parsed(conn, parsed_args))
|
|
||||||
rv = 0;
|
|
||||||
control_cmd_args_free(parsed_args);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
tor_assert_unreached();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->flags & CMD_FL_WIPE)
|
if (def->flags & CMD_FL_WIPE)
|
||||||
|
Loading…
Reference in New Issue
Block a user