]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: Standardize iostream error handling
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 2 Mar 2021 13:15:09 +0000 (15:15 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 11 Mar 2021 11:19:09 +0000 (11:19 +0000)
Use [io]_stream_get_disconnect_reason() for logging all errors.
None of the iostream errors are logged as error level anymore. This way
for example TLS connection problems caused by broken clients aren't
logged as errors.

src/lib-smtp/smtp-command-parser.c
src/lib-smtp/smtp-server-cmd-auth.c
src/lib-smtp/smtp-server-cmd-data.c
src/lib-smtp/smtp-server-connection.c

index e3a321d5b507b4a0deac0ccbd6e6d7e6b715a51c..32a53cc2ac3254dab90b0fd69701c569b8a33d3b 100644 (file)
@@ -387,8 +387,7 @@ static int smtp_command_parse(struct smtp_command_parser *parser)
                } else {
                        smtp_command_parser_error(
                                parser, SMTP_COMMAND_PARSE_ERROR_BROKEN_STREAM,
-                               "Stream error: %s",
-                               i_stream_get_error(parser->input));
+                               "%s", i_stream_get_disconnect_reason(parser->input));
                }
        }
        return ret;
@@ -431,8 +430,7 @@ static int smtp_command_parse_finish_data(struct smtp_command_parser *parser)
                default:
                        smtp_command_parser_error(
                                parser, SMTP_COMMAND_PARSE_ERROR_BROKEN_STREAM,
-                               "Stream error while skipping command data: "
-                               "%s", i_stream_get_error(parser->data));
+                               "%s", i_stream_get_disconnect_reason(parser->data));
                }
                return -1;
        }
index 616b9c040bdec8ae715a2e1eab2c38ba93d3f8ed..841e1866b28d4b59094453d6a3a9d4a535bff2d1 100644 (file)
@@ -76,22 +76,8 @@ static void cmd_auth_input(struct smtp_server_cmd_ctx *cmd)
                &auth_response, &error_code, &error)) <= 0) {
                /* check for disconnect */
                if (conn->conn.input->eof) {
-                       switch (conn->conn.input->stream_errno) {
-                       case 0:
-                       case EPIPE:
-                       case ECONNRESET:
-                               smtp_server_connection_close(&conn,
-                                       "Remote closed connection unexpectedly during AUTH");
-                               break;
-                       default:
-                               e_error(conn->event,
-                                       "Connection lost during AUTH: "
-                                       "read(%s) failed: %s",
-                                       i_stream_get_name(conn->conn.input),
-                                       i_stream_get_error(conn->conn.input));
-                               smtp_server_connection_close(&conn,
-                                       "Read failure");
-                       }
+                       smtp_server_connection_close(&conn,
+                               i_stream_get_disconnect_reason(conn->conn.input));
                        return;
                }
                /* handle syntax error */
index 1979a5001e312b6257eb12a55ac740334ad16252..572b52dee9655531381cf93b3731b079b6172f70 100644 (file)
@@ -244,7 +244,7 @@ static void cmd_data_input_error(struct smtp_server_cmd_ctx *cmd)
        struct smtp_server_command *command = cmd->cmd;
        struct cmd_data_context *data_cmd = command->data;
        struct istream *data_input = conn->state.data_input;
-       unsigned int stream_errno = data_input->stream_errno;
+       const char *error;
 
        conn->state.data_failed = TRUE;
 
@@ -256,18 +256,9 @@ static void cmd_data_input_error(struct smtp_server_cmd_ctx *cmd)
                return;
        }
 
-       if (stream_errno != EPIPE && stream_errno != ECONNRESET) {
-               e_error(conn->event, "Connection lost during data transfer: "
-                       "read(%s) failed: %s",
-                       i_stream_get_name(data_input),
-                       i_stream_get_error(data_input));
-               smtp_server_connection_close(&conn, "Read failure");
-       } else {
-               e_debug(conn->event, "Connection lost during data transfer: "
-                       "Remote disconnected");
-               smtp_server_connection_close(&conn,
-                       "Remote closed connection unexpectedly");
-       }
+       error = i_stream_get_disconnect_reason(data_input);
+       e_debug(conn->event, "Connection lost during data transfer: %s", error);
+       smtp_server_connection_close(&conn, error);
 }
 
 static int cmd_data_do_handle_input(struct smtp_server_cmd_ctx *cmd)
index c462238f5a953a19e9f6523b2992d4beb2aad074..5d3af140541996be75caa20333840461991a8103 100644 (file)
@@ -483,32 +483,22 @@ smtp_server_connection_handle_input(struct smtp_server_connection *conn)
                }
 
                if (ret < 0 && conn->conn.input->eof) {
-                       int stream_errno = conn->conn.input->stream_errno;
-                       if (stream_errno != 0 && stream_errno != EPIPE &&
-                           stream_errno != ECONNRESET) {
-                               e_error(conn->event,
-                                       "Connection lost: read(%s) failed: %s",
-                                       i_stream_get_name(conn->conn.input),
-                                       i_stream_get_error(conn->conn.input));
-                               smtp_server_connection_close(&conn,
-                                       "Read failure");
+                       const char *error =
+                               i_stream_get_disconnect_reason(conn->conn.input);
+                       e_debug(conn->event, "Remote closed connection: %s",
+                               error);
+
+                       if (conn->command_queue_head == NULL ||
+                           conn->command_queue_head->state <
+                           SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY) {
+                               /* No pending commands or unfinished
+                                  command; close */
+                               smtp_server_connection_close(&conn, error);
                        } else {
-                               e_debug(conn->event,
-                                       "Connection lost: Remote disconnected");
-
-                               if (conn->command_queue_head == NULL ||
-                                   conn->command_queue_head->state <
-                                       SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY) {
-                                       /* No pending commands or unfinished
-                                          command; close */
-                                       smtp_server_connection_close(&conn,
-                                               "Remote closed connection");
-                               } else {
-                                       /* A command is still processing;
-                                          only drop input io for now */
-                                       conn->input_broken = TRUE;
-                                       smtp_server_connection_input_halt(conn);
-                               }
+                               /* A command is still processing;
+                                  only drop input io for now */
+                               conn->input_broken = TRUE;
+                               smtp_server_connection_input_halt(conn);
                        }
                        return;
                }
@@ -544,8 +534,7 @@ smtp_server_connection_handle_input(struct smtp_server_connection *conn)
                                        "Command data size exceeds absolute limit");
                                return;
                        case SMTP_COMMAND_PARSE_ERROR_BROKEN_STREAM:
-                               smtp_server_connection_close(&conn,
-                                       "Command data ended prematurely");
+                               smtp_server_connection_close(&conn, error);
                                return;
                        default:
                                i_unreached();
@@ -627,18 +616,8 @@ bool smtp_server_connection_pending_command_data(
 void smtp_server_connection_handle_output_error(
        struct smtp_server_connection *conn)
 {
-       struct ostream *output = conn->conn.output;
-
-       if (output->stream_errno != EPIPE &&
-           output->stream_errno != ECONNRESET) {
-               e_error(conn->event, "Connection lost: write(%s) failed: %s",
-                       o_stream_get_name(output), o_stream_get_error(output));
-               smtp_server_connection_close(&conn, "Write failure");
-       } else {
-               e_debug(conn->event, "Connection lost: Remote disconnected");
-               smtp_server_connection_close(
-                       &conn, "Remote closed connection unexpectedly");
-       }
+       smtp_server_connection_close(&conn,
+               o_stream_get_disconnect_reason(conn->conn.output));
 }
 
 static bool