dovecot-2.1: director: Improved error logging for handling inval...

dovecot at dovecot.org dovecot at dovecot.org
Tue Apr 3 00:23:12 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/d6cd93e32b37
changeset: 14371:d6cd93e32b37
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Apr 03 00:23:02 2012 +0300
description:
director: Improved error logging for handling invalid commands/parameters.

diffstat:

 src/director/director-connection.c |  103 ++++++++++++++++++++++--------------
 1 files changed, 63 insertions(+), 40 deletions(-)

diffs (251 lines):

diff -r c760ac046203 -r d6cd93e32b37 src/director/director-connection.c
--- a/src/director/director-connection.c	Mon Apr 02 23:39:48 2012 +0300
+++ b/src/director/director-connection.c	Tue Apr 03 00:23:02 2012 +0300
@@ -50,6 +50,9 @@
 
 	struct user_directory_iter *user_iter;
 
+	/* set during command execution */
+	const char *cur_cmd, *cur_line;
+
 	unsigned int in:1;
 	unsigned int connected:1;
 	unsigned int version_received:1;
@@ -64,19 +67,32 @@
 static void director_connection_ping(struct director_connection *conn);
 static void director_connection_disconnected(struct director_connection **conn);
 
+static void ATTR_FORMAT(2, 3)
+director_cmd_error(struct director_connection *conn, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	i_error("director(%s): Command %s: %s (input: %s)", conn->name,
+		conn->cur_cmd, t_strdup_vprintf(fmt, args), conn->cur_line);
+	va_end(args);
+}
+
 static bool
 director_args_parse_ip_port(struct director_connection *conn,
 			    const char *const *args,
 			    struct ip_addr *ip_r, unsigned int *port_r)
 {
+	if (args[0] == NULL || args[1] == NULL) {
+		director_cmd_error(conn, "Missing IP+port parameters");
+		return FALSE;
+	}
 	if (net_addr2ip(args[0], ip_r) < 0) {
-		i_error("director(%s): Command has invalid IP address: %s",
-			conn->name, args[0]);
+		director_cmd_error(conn, "Invalid IP address: %s", args[0]);
 		return FALSE;
 	}
 	if (str_to_uint(args[1], port_r) < 0) {
-		i_error("director(%s): Command has invalid port: %s",
-			conn->name, args[1]);
+		director_cmd_error(conn, "Invalid port: %s", args[1]);
 		return FALSE;
 	}
 	return TRUE;
@@ -276,8 +292,7 @@
 	    str_to_uint(args[0], &username_hash) < 0 ||
 	    net_addr2ip(args[1], &ip) < 0 ||
 	    str_to_uint(args[2], &timestamp) < 0) {
-		i_error("director(%s): Invalid USER handshake args",
-			conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 	weak = args[3] != NULL && args[3][0] == 'w';
@@ -305,7 +320,7 @@
 	if (str_array_length(args) != 2 ||
 	    str_to_uint(args[0], &username_hash) < 0 ||
 	    net_addr2ip(args[1], &ip) < 0) {
-		i_error("director(%s): Invalid USER args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -356,9 +371,9 @@
 	struct mail_host *const *hostp;
 	unsigned int remote_ring_completed;
 
-	if (args == NULL || str_to_uint(args[0], &remote_ring_completed) < 0) {
-		i_error("director(%s): Invalid HOST-HAND-START args",
-			conn->name);
+	if (args[0] == NULL ||
+	    str_to_uint(args[0], &remote_ring_completed) < 0) {
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -391,8 +406,7 @@
 	    net_addr2ip(args[0], &ip) < 0 ||
 	    str_to_uint(args[1], &port) < 0 ||
 	    str_to_uint(args[2], &seq) < 0) {
-		i_error("director(%s): Command is missing parameters: %s",
-			conn->name, t_strarray_join(args, " "));
+		director_cmd_error(conn, "Invalid parameters");
 		return -1;
 	}
 	*_args = args + 3;
@@ -433,7 +447,7 @@
 	if (str_array_length(args) != 2 ||
 	    str_to_uint(args[0], &username_hash) < 0 ||
 	    net_addr2ip(args[1], &ip) < 0) {
-		i_error("director(%s): Invalid USER-WEAK args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -474,7 +488,7 @@
 	if (str_array_length(args) != 2 ||
 	    net_addr2ip(args[0], &ip) < 0 ||
 	    str_to_uint(args[1], &vhost_count) < 0) {
-		i_error("director(%s): Invalid HOST args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 	if (conn->ignore_host_events) {
@@ -532,7 +546,7 @@
 
 	if (str_array_length(args) != 1 ||
 	    net_addr2ip(args[0], &ip) < 0) {
-		i_error("director(%s): Invalid HOST-REMOVE args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -556,7 +570,7 @@
 
 	if (str_array_length(args) != 1 ||
 	    net_addr2ip(args[0], &ip) < 0) {
-		i_error("director(%s): Invalid HOST-FLUSH args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -582,7 +596,7 @@
 	if (str_array_length(args) != 2 ||
 	    str_to_uint(args[0], &username_hash) < 0 ||
 	    net_addr2ip(args[1], &ip) < 0) {
-		i_error("director(%s): Invalid USER-MOVE args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -602,7 +616,7 @@
 
 	if (str_array_length(args) != 1 ||
 	    str_to_uint(args[0], &username_hash) < 0) {
-		i_error("director(%s): Invalid USER-KILLED args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -623,8 +637,7 @@
 
 	if (str_array_length(args) != 1 ||
 	    str_to_uint(args[0], &username_hash) < 0) {
-		i_error("director(%s): Invalid USER-KILLED-EVERYWHERE args",
-			conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -706,17 +719,15 @@
 		return TRUE;
 	}
 	if (!conn->version_received) {
-		i_error("director(%s): Incompatible protocol", conn->name);
+		director_cmd_error(conn, "Incompatible protocol");
 		return FALSE;
 	}
 
-	if (strcmp(cmd, "ME") == 0 && !conn->me_received &&
-	    str_array_length(args) == 2)
+	if (strcmp(cmd, "ME") == 0 && !conn->me_received)
 		return director_cmd_me(conn, args);
 
 	/* only outgoing connections get a CONNECT reference */
-	if (!conn->in && strcmp(cmd, "CONNECT") == 0 &&
-	    str_array_length(args) == 2) {
+	if (!conn->in && strcmp(cmd, "CONNECT") == 0) {
 		/* remote wants us to connect elsewhere */
 		if (!director_args_parse_ip_port(conn, args, &ip, &port))
 			return FALSE;
@@ -827,7 +838,7 @@
 	if (str_array_length(args) < 3 ||
 	    !director_args_parse_ip_port(conn, args, &ip, &port) ||
 	    str_to_uint(args[2], &seq) < 0) {
-		i_error("director(%s): Invalid SYNC args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 	if (args[3] != NULL)
@@ -856,7 +867,7 @@
 
 	if (str_array_length(args) != 2 ||
 	    !director_args_parse_ip_port(conn, args, &ip, &port)) {
-		i_error("director(%s): Invalid CONNECT args", conn->name);
+		director_cmd_error(conn, "Invalid parameters");
 		return FALSE;
 	}
 
@@ -907,18 +918,9 @@
 }
 
 static bool
-director_connection_handle_line(struct director_connection *conn,
-				const char *line)
+director_connection_handle_cmd(struct director_connection *conn,
+			       const char *cmd, const char *const *args)
 {
-	const char *cmd, *const *args;
-
-	args = t_strsplit(line, "\t");
-	cmd = args[0]; args++;
-	if (cmd == NULL) {
-		i_error("director(%s): Received empty line", conn->name);
-		return FALSE;
-	}
-
 	/* ping/pong is always handled */
 	if (strcmp(cmd, "PING") == 0) {
 		director_connection_send(conn, "PONG\n");
@@ -965,11 +967,32 @@
 	if (strcmp(cmd, "CONNECT") == 0)
 		return director_cmd_connect(conn, args);
 
-	i_error("director(%s): Unknown command (in this state): %s",
-		conn->name, cmd);
+	director_cmd_error(conn, "Unknown command %s", cmd);
 	return FALSE;
 }
 
+static bool
+director_connection_handle_line(struct director_connection *conn,
+				const char *line)
+{
+	const char *cmd, *const *args;
+	bool ret;
+
+	args = t_strsplit(line, "\t");
+	cmd = args[0]; args++;
+	if (cmd == NULL) {
+		i_error("director(%s): Received empty line", conn->name);
+		return FALSE;
+	}
+
+	conn->cur_cmd = cmd;
+	conn->cur_line = line;
+	ret = director_connection_handle_cmd(conn, cmd, args);
+	conn->cur_cmd = NULL;
+	conn->cur_line = NULL;
+	return ret;
+}
+
 static void director_connection_input(struct director_connection *conn)
 {
 	struct director *dir = conn->dir;


More information about the dovecot-cvs mailing list