summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-12-16 01:12:35 +0100
committerHarald Welte <laforge@gnumonks.org>2017-12-18 23:05:50 +0000
commitc0b0b623053f16790d7d675812befe382ebdfd6e (patch)
treec53db24db8dd13b122cf033050fecf86acef25fd
parentf2e83ad40d231e87e2604ec4c97c810a8182e145 (diff)
ctrl: on parse errors, return a detailed message to sender
The recently added ctrl_cmd_parse2() returns non-NULL cmd with error messages upon parsing errors. In handle_control_read(), use ctrl_cmd_parse2() and send those back to the CTRL command sender as reply. Retain the previous "Command parser error" reply only in case ctrl_cmd_parse2() should return NULL, which shouldn't actually happen at all. Change-Id: Ie35a02555b76913bb12734a76fc40fde7ffb244d
-rw-r--r--src/ctrl/control_if.c34
-rw-r--r--tests/ctrl/ctrl_test.c2
2 files changed, 24 insertions, 12 deletions
diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c
index 5c73b631..17a012a9 100644
--- a/src/ctrl/control_if.c
+++ b/src/ctrl/control_if.c
@@ -381,14 +381,10 @@ int ctrl_handle_msg(struct ctrl_handle *ctrl, struct ctrl_connection *ccon, stru
msg->l2h = iph_ext->data;
- cmd = ctrl_cmd_parse(ccon, msg);
+ cmd = ctrl_cmd_parse2(ccon, msg);
- if (cmd) {
- cmd->ccon = ccon;
- if (ctrl_cmd_handle(ctrl, cmd, ctrl->data) != CTRL_CMD_HANDLED) {
- ctrl_cmd_send(&ccon->write_queue, cmd);
- }
- } else {
+ if (!cmd) {
+ /* should never happen */
cmd = talloc_zero(ccon, struct ctrl_cmd);
if (!cmd)
return -ENOMEM;
@@ -396,10 +392,23 @@ int ctrl_handle_msg(struct ctrl_handle *ctrl, struct ctrl_connection *ccon, stru
cmd->type = CTRL_TYPE_ERROR;
cmd->id = "err";
cmd->reply = "Command parser error.";
+ }
+
+ if (cmd->type != CTRL_TYPE_ERROR) {
+ cmd->ccon = ccon;
+ if (ctrl_cmd_handle(ctrl, cmd, ctrl->data) == CTRL_CMD_HANDLED) {
+ /* On CTRL_CMD_HANDLED, no reply needs to be sent back. */
+ talloc_free(cmd);
+ cmd = NULL;
+ }
+ }
+
+ if (cmd) {
+ /* There is a reply or error that should be reported back to the sender. */
ctrl_cmd_send(&ccon->write_queue, cmd);
+ talloc_free(cmd);
}
- talloc_free(cmd);
return 0;
}
@@ -894,13 +903,16 @@ struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *c
osmo_strlcpy((char *)msg->data, cmdstr, msgb_tailroom(msg));
msgb_put(msg, strlen(cmdstr));
- cmd = ctrl_cmd_parse(ch, msg);
+ cmd = ctrl_cmd_parse2(ch, msg);
msgb_free(msg);
if (!cmd)
return NULL;
- if (ctrl_cmd_handle(ch, cmd, NULL) < 0) {
+ if (cmd->type == CTRL_TYPE_ERROR)
+ return cmd;
+ if (ctrl_cmd_handle(ch, cmd, NULL) == CTRL_CMD_HANDLED) {
+ /* No reply should be sent back. */
talloc_free(cmd);
- return NULL;
+ cmd = NULL;
}
return cmd;
}
diff --git a/tests/ctrl/ctrl_test.c b/tests/ctrl/ctrl_test.c
index b1d4f237..39ec61a8 100644
--- a/tests/ctrl/ctrl_test.c
+++ b/tests/ctrl/ctrl_test.c
@@ -76,7 +76,7 @@ static void assert_test(struct ctrl_handle *ctrl, struct ctrl_connection *ccon,
printf("test: '%s'\n", osmo_escape_str(t->cmd_str, -1));
printf("parsing:\n");
- cmd = ctrl_cmd_parse(ctx, msg);
+ cmd = ctrl_cmd_parse2(ctx, msg);
OSMO_ASSERT(cmd);
OSMO_ASSERT(t->expect_parsed.type == cmd->type);