]> source.dussan.org Git - rspamd.git/commitdiff
* Check return value of each rspamd_dispatcher_write as in case of write errors sessi...
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 24 Jun 2010 14:25:16 +0000 (18:25 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 24 Jun 2010 14:25:16 +0000 (18:25 +0400)
12 files changed:
src/buffer.h
src/controller.c
src/lmtp.c
src/lmtp_proto.c
src/plugins/emails.c
src/plugins/fuzzy_check.c
src/plugins/surbl.c
src/protocol.c
src/protocol.h
src/smtp.c
src/smtp_proto.c
src/worker.c

index cbb6c190a5576660872811edcc4ff8efac85a778..c63fb8c6aca140dd8420da463d957256c0e8bda6 100644 (file)
@@ -93,7 +93,7 @@ void rspamd_set_dispatcher_policy (rspamd_io_dispatcher_t *d,
  */
 gboolean rspamd_dispatcher_write (rspamd_io_dispatcher_t *d,
                                                                                                  void *data,
-                                                                                                 size_t len, gboolean delayed, gboolean allocated);
+                                                                                                 size_t len, gboolean delayed, gboolean allocated) G_GNUC_WARN_UNUSED_RESULT;
 
 /**
  * Send specified descriptor to dispatcher
@@ -101,7 +101,7 @@ gboolean rspamd_dispatcher_write (rspamd_io_dispatcher_t *d,
  * @param fd descriptor of file
  * @param len length of data
  */
-gboolean rspamd_dispatcher_sendfile (rspamd_io_dispatcher_t *d, int fd, size_t len);
+gboolean rspamd_dispatcher_sendfile (rspamd_io_dispatcher_t *d, int fd, size_t len) G_GNUC_WARN_UNUSED_RESULT;
 
 /**
  * Pause IO events on dispatcher
index 8239d5bad2fffedf1fb5920b79d951901c197494..2644a6d08b1709e0c1ca3640e893ee0db4327f7b 100644 (file)
@@ -161,7 +161,9 @@ check_auth (struct controller_command *cmd, struct controller_session *session)
 
        if (cmd->privilleged && !session->authorized) {
                r = snprintf (out_buf, sizeof (out_buf), "not authorized" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       return 0;
+               }
                return 0;
        }
 
@@ -178,7 +180,9 @@ counter_write_callback (gpointer key, gpointer value, void *data)
        int                             r;
 
        r = snprintf (out_buf, sizeof (out_buf), "%s: %llu" CRLF, name, (unsigned long long int)cd->value);
-       rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE, FALSE);
+       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE, FALSE)) {
+               msg_warn ("cannot write to socket");
+       }
 }
 
 static gboolean
@@ -223,7 +227,9 @@ write_whole_statfile (struct controller_session *session, char *symbol, struct c
        }
 
        i = rspamd_snprintf (out_buf, sizeof (out_buf), "%uL %uL %uL" CRLF, rev, ti, pos);
-       rspamd_dispatcher_write (session->dispatcher, out_buf, i, TRUE, FALSE);
+       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, i, TRUE, FALSE)) {
+               return FALSE;
+       }
 
        if (!rspamd_dispatcher_write (session->dispatcher, out, pos, TRUE, TRUE)) {
                return FALSE;
@@ -299,7 +305,12 @@ process_sync_command (struct controller_session *session, char **args)
        
        while (binlog_sync (binlog, rev, &time, &data)) {
                r = snprintf (out_buf, sizeof (out_buf), "%lu %lu %lu" CRLF, (long unsigned)rev, (long unsigned)time, (long unsigned)data->len);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE, FALSE)) {
+                       if (data != NULL) {
+                               g_free (data);
+                       }
+                       return FALSE;
+               }
                if (!rspamd_dispatcher_write (session->dispatcher, data->data, data->len, TRUE, FALSE)) {
                        if (data != NULL) {
                                g_free (data);
@@ -388,7 +399,7 @@ process_stat_command (struct controller_session *session)
        return rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
 }
 
-static void
+static gboolean
 process_command (struct controller_command *cmd, char **cmd_args, struct controller_session *session)
 {
        char                            out_buf[BUFSIZ], *arg, *err_str;
@@ -404,23 +415,31 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                if (!arg || *arg == '\0') {
                        msg_debug ("empty password passed");
                        r = snprintf (out_buf, sizeof (out_buf), "password command requires one argument" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
                if (password == NULL) {
                        r = snprintf (out_buf, sizeof (out_buf), "password command disabled in config, authorized access unallowed" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
                if (strncmp (arg, password, strlen (arg)) == 0) {
                        session->authorized = 1;
                        r = snprintf (out_buf, sizeof (out_buf), "password accepted" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                }
                else {
                        session->authorized = 0;
                        r = snprintf (out_buf, sizeof (out_buf), "password NOT accepted" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                }
                break;
        case COMMAND_QUIT:
@@ -429,19 +448,23 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
        case COMMAND_RELOAD:
                if (check_auth (cmd, session)) {
                        r = snprintf (out_buf, sizeof (out_buf), "reload request sent" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                        kill (getppid (), SIGHUP);
                }
                break;
        case COMMAND_STAT:
                if (check_auth (cmd, session)) {
-                       (void)process_stat_command (session);
+                       return process_stat_command (session);
                }
                break;
        case COMMAND_SHUTDOWN:
                if (check_auth (cmd, session)) {
                        r = snprintf (out_buf, sizeof (out_buf), "shutdown request sent" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                        kill (getppid (), SIGTERM);
                }
                break;
@@ -466,7 +489,9 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                                uptime -= hours * 3600 + minutes * 60;
                                r = snprintf (out_buf, sizeof (out_buf), "%d hour%s %d minute%s %d second%s" CRLF, hours, hours > 1 ? "s" : " ", minutes, minutes > 1 ? "s" : " ", (int)uptime, uptime > 1 ? "s" : " ");
                        }
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                }
                break;
        case COMMAND_LEARN:
@@ -475,30 +500,38 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                        if (!arg || *arg == '\0') {
                                msg_debug ("no statfile specified in learn command");
                                r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                               return;
+                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                       return FALSE;
+                               }
+                               return TRUE;
                        }
                        arg = *(cmd_args + 1);
                        if (arg == NULL || *arg == '\0') {
                                msg_debug ("no statfile size specified in learn command");
                                r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                               return;
+                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                       return FALSE;
+                               }
+                               return TRUE;
                        }
                        size = strtoul (arg, &err_str, 10);
                        if (err_str && *err_str != '\0') {
                                msg_debug ("message size is invalid: %s", arg);
                                r = snprintf (out_buf, sizeof (out_buf), "learn size is invalid" CRLF);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                               return;
+                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                       return FALSE;
+                               }
+                               return TRUE;
                        }
 
                        session->learn_symbol = memory_pool_strdup (session->session_pool, *cmd_args);
                        cl = g_hash_table_lookup (session->cfg->classifiers_symbols, *cmd_args);
                        if (cl == NULL) {
                                r = snprintf (out_buf, sizeof (out_buf), "statfile %s is not defined" CRLF, *cmd_args);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                               return;
+                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                       return FALSE;
+                               }
+                               return TRUE;
 
                        }
                        session->learn_classifier = cl;
@@ -515,8 +548,9 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                                                arg = *(cmd_args + 1);
                                                if (!arg || *arg == '\0') {
                                                        r = snprintf (out_buf, sizeof (out_buf), "recipient is not defined" CRLF);
-                                                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                                                       return;
+                                                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                                               return FALSE;
+                                                       }
                                                }
                                                session->learn_rcpt = memory_pool_strdup (session->session_pool, arg);
                                                break;
@@ -524,8 +558,9 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                                                arg = *(cmd_args + 1);
                                                if (!arg || *arg == '\0') {
                                                        r = snprintf (out_buf, sizeof (out_buf), "from is not defined" CRLF);
-                                                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                                                       return;
+                                                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                                               return FALSE;
+                                                       }
                                                }
                                                session->learn_from = memory_pool_strdup (session->session_pool, arg);
                                                break;
@@ -536,15 +571,18 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                                                arg = *(cmd_args + 1);
                                                if (!arg || *arg == '\0') {
                                                        r = snprintf (out_buf, sizeof (out_buf), "multiplier is not defined" CRLF);
-                                                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                                                       return;
+                                                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                                               return FALSE;
+                                                       }
                                                }
                                                session->learn_multiplier = strtod (arg, NULL);
                                                break;
                                        default:
                                                r = snprintf (out_buf, sizeof (out_buf), "tokenizer is not defined" CRLF);
-                                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                                               return;
+                                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                                       return FALSE;
+                                               }
+                                               return TRUE;
                                        }
                                }
                        }
@@ -558,29 +596,37 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                if (!arg || *arg == '\0') {
                        msg_debug ("no statfile specified in weights command");
                        r = snprintf (out_buf, sizeof (out_buf), "weights command requires two arguments: statfile and message size" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
                arg = *(cmd_args + 1);
                if (arg == NULL || *arg == '\0') {
                        msg_debug ("no message size specified in weights command");
                        r = snprintf (out_buf, sizeof (out_buf), "weights command requires two arguments: statfile and message size" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
                size = strtoul (arg, &err_str, 10);
                if (err_str && *err_str != '\0') {
                        msg_debug ("message size is invalid: %s", arg);
                        r = snprintf (out_buf, sizeof (out_buf), "message size is invalid" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
 
                cl = g_hash_table_lookup (session->cfg->classifiers_symbols, *cmd_args);
                if (cl == NULL) {
                        r = snprintf (out_buf, sizeof (out_buf), "statfile %s is not defined" CRLF, *cmd_args);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
 
                }
                session->learn_classifier = cl;
@@ -591,8 +637,10 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
        case COMMAND_SYNC:
                if (!process_sync_command (session, cmd_args)) {
                        r = snprintf (out_buf, sizeof (out_buf), "FAIL" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
-                       return;
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
+                       return TRUE;
                }
                break;
        case COMMAND_HELP:
@@ -607,12 +655,15 @@ process_command (struct controller_command *cmd, char **cmd_args, struct control
                        "    stat - show different rspamd stat" CRLF 
                        "    counters - show rspamd counters" CRLF 
                        "    uptime - rspamd uptime" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                break;
        case COMMAND_COUNTERS:
                rspamd_hash_foreach (counters, counter_write_callback, session);
                break;
        }
+       return TRUE;
 }
 
 static                          gboolean
@@ -664,7 +715,9 @@ controller_read_socket (f_str_t * in, void *arg)
                        comp_list = g_completion_complete (comp, cmd, NULL);
                        switch (g_list_length (comp_list)) {
                        case 1:
-                               process_command ((struct controller_command *)comp_list->data, &params[1], session);
+                               if (! process_command ((struct controller_command *)comp_list->data, &params[1], session)) {
+                                       return FALSE;
+                               }
                                break;
                        case 0:
                                if (!process_custom_command (cmd, &params[1], session)) {
@@ -708,7 +761,9 @@ controller_read_socket (f_str_t * in, void *arg)
                        free_task (task, FALSE);
                        session->state = STATE_REPLY;
                        r = snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                        return FALSE;
                }
                if ((s = g_hash_table_lookup (session->learn_classifier->opts, "header")) != NULL) {
@@ -805,7 +860,9 @@ controller_read_socket (f_str_t * in, void *arg)
                        free_task (task, FALSE);
                        session->state = STATE_REPLY;
                        r = snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF);
-                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                               return FALSE;
+                       }
                        return FALSE;
                }
 
@@ -951,7 +1008,9 @@ accept_socket (int fd, short what, void *arg)
        new_session->s = new_async_session (new_session->session_pool, free_session, new_session);
 
        new_session->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, controller_read_socket, controller_write_socket, controller_err_socket, io_tv, (void *)new_session);
-       rspamd_dispatcher_write (new_session->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE);
+       if (! rspamd_dispatcher_write (new_session->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE)) {
+               msg_warn ("cannot write greeting");
+       }
 }
 
 void
index 385debfbb3920e03c6e2569f5f844390895eb8e0..47962ce93ec6265c708a3a54f9be089a75210ebe 100644 (file)
@@ -147,10 +147,7 @@ lmtp_read_socket (f_str_t * in, void *arg)
                r = process_message (lmtp->task);
                r = process_filters (lmtp->task);
                if (r == -1) {
-                       task->last_error = "Filter processing error";
-                       task->error_code = LMTP_FAILURE;
-                       task->state = WRITE_ERROR;
-                       lmtp_write_socket (lmtp);
+                       return FALSE;
                }
                else if (r == 0) {
                        task->state = WAIT_FILTER;
@@ -262,7 +259,9 @@ accept_socket (int fd, short what, void *arg)
        /* Set up dispatcher */
        new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, lmtp_read_socket, lmtp_write_socket, lmtp_err_socket, &io_tv, (void *)lmtp);
        new_task->dispatcher->peer_addr = new_task->client_addr.s_addr;
-       rspamd_dispatcher_write (lmtp->task->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE);
+       if (! rspamd_dispatcher_write (lmtp->task->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE)) {
+               msg_warn ("cannot write greeting");
+       }
 }
 
 /*
index 20d02e4f922160e50d76646f2bcb58487b425226..c9a58a64177db36e894452780895a984d6f86861 100644 (file)
@@ -88,7 +88,7 @@ extract_mail (memory_pool_t * pool, f_str_t * line)
        return match;
 }
 
-static void
+static gboolean
 out_lmtp_reply (struct worker_task *task, int code, char *rcode, char *msg)
 {
        char                            outbuf[OUTBUFSIZ];
@@ -100,7 +100,10 @@ out_lmtp_reply (struct worker_task *task, int code, char *rcode, char *msg)
        else {
                r = snprintf (outbuf, OUTBUFSIZ, "%d %s %s\r\n", code, rcode, msg);
        }
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE)) {
+               return FALSE;
+       }
+       return TRUE;
 }
 
 int
@@ -115,7 +118,7 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                /* Search LHLO line */
                if ((i = fstrstri (line, &lhlo_command)) == -1) {
                        msg_info ("LHLO expected but not found");
-                       out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need LHLO here");
+                       (void)out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need LHLO here");
                        return -1;
                }
                else {
@@ -130,7 +133,9 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                        /* Strlcpy makes string null terminated by design */
                        g_strlcpy (lmtp->task->helo, c, line->len - i + 1);
                        lmtp->state = LMTP_READ_FROM;
-                       out_lmtp_reply (lmtp->task, LMTP_OK, "", "Ok");
+                       if (! out_lmtp_reply (lmtp->task, LMTP_OK, "", "Ok")) {
+                               return -1;
+                       }
                        return 0;
                }
                break;
@@ -138,7 +143,7 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                /* Search MAIL FROM: line */
                if ((i = fstrstri (line, &mail_command)) == -1) {
                        msg_info ("MAIL expected but not found");
-                       out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need MAIL here");
+                       (void)out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need MAIL here");
                        return -1;
                }
                else {
@@ -148,7 +153,9 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                        fstr.len = line->len - i;
                        lmtp->task->from = extract_mail (lmtp->task->task_pool, &fstr);
                        lmtp->state = LMTP_READ_RCPT;
-                       out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Sender ok");
+                       if (! out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Sender ok")) {
+                               return -1;
+                       }
                        return 0;
                }
                break;
@@ -156,7 +163,7 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                /* Search RCPT_TO: line */
                if ((i = fstrstri (line, &rcpt_command)) == -1) {
                        msg_info ("RCPT expected but not found");
-                       out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Need RCPT here");
+                       (void)out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Need RCPT here");
                        return -1;
                }
                else {
@@ -168,13 +175,15 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                        if (*rcpt == '<' && *(rcpt + 1) == '>') {
                                /* Invalid or empty rcpt not allowed */
                                msg_info ("bad recipient");
-                               out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Bad recipient");
+                               (void)out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Bad recipient");
                                return -1;
                        }
                        /* Strlcpy makes string null terminated by design */
                        lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt);
                        lmtp->state = LMTP_READ_DATA;
-                       out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Recipient ok");
+                       if (! out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Recipient ok")) {
+                               return -1;
+                       }
                        return 0;
                }
                break;
@@ -182,7 +191,7 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                /* Search DATA line */
                if ((i = fstrstri (line, &data_command)) == -1) {
                        msg_info ("DATA expected but not found");
-                       out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need DATA here");
+                       (void)out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need DATA here");
                        return -1;
                }
                else {
@@ -197,7 +206,9 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                        g_strlcpy (rcpt, c, line->len - i + 1);
                        lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt);
                        lmtp->state = LMTP_READ_MESSAGE;
-                       out_lmtp_reply (lmtp->task, LMTP_DATA, "", "Enter message, ending with \".\" on a line by itself");
+                       if (! out_lmtp_reply (lmtp->task, LMTP_DATA, "", "Enter message, ending with \".\" on a line by itself")) {
+                               return -1;
+                       }
                        lmtp->task->msg = fstralloc (lmtp->task->task_pool, BUFSIZ);
                        return 0;
                }
@@ -230,7 +241,9 @@ read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line)
                /* We have some input after reading dot, close connection as we have no currently support of multiply 
                 * messages per session
                 */
-               out_lmtp_reply (lmtp->task, LMTP_QUIT, "", "Bye");
+               if (! out_lmtp_reply (lmtp->task, LMTP_QUIT, "", "Bye")) {
+                       return -1;
+               }
                return 0;
                break;
        }
@@ -288,10 +301,14 @@ close_mta_connection (struct mta_callback_data *cd, gboolean is_success)
 {
        cd->task->state = CLOSING_CONNECTION;
        if (is_success) {
-               out_lmtp_reply (cd->task, LMTP_OK, "", "Delivery completed");
+               if (! out_lmtp_reply (cd->task, LMTP_OK, "", "Delivery completed")) {
+                       return;
+               }
        }
        else {
-               out_lmtp_reply (cd->task, LMTP_FAILURE, "", "Delivery failure");
+               if (! out_lmtp_reply (cd->task, LMTP_FAILURE, "", "Delivery failure")) {
+                       return;
+               }
        }
        rspamd_remove_dispatcher (cd->dispatcher);
 }
@@ -335,7 +352,9 @@ mta_read_socket (f_str_t * in, void *arg)
                else {
                        r = snprintf (outbuf, sizeof (outbuf), "HELO %s" CRLF, hostbuf);
                }
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                cd->state = LMTP_WANT_MAIL;
                break;
        case LMTP_WANT_MAIL:
@@ -345,7 +364,9 @@ mta_read_socket (f_str_t * in, void *arg)
                        return FALSE;
                }
                r = snprintf (outbuf, sizeof (outbuf), "MAIL FROM: <%s>" CRLF, cd->task->from);
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                cd->state = LMTP_WANT_RCPT;
                break;
        case LMTP_WANT_RCPT:
@@ -361,7 +382,9 @@ mta_read_socket (f_str_t * in, void *arg)
                        cur = g_list_next (cur);
                }
 
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                cd->state = LMTP_WANT_DATA;
                break;
        case LMTP_WANT_DATA:
@@ -371,7 +394,9 @@ mta_read_socket (f_str_t * in, void *arg)
                        return FALSE;
                }
                r = snprintf (outbuf, sizeof (outbuf), "DATA" CRLF);
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                cd->state = LMTP_WANT_DOT;
                break;
        case LMTP_WANT_DOT:
@@ -382,10 +407,14 @@ mta_read_socket (f_str_t * in, void *arg)
                }
                c = g_mime_object_to_string ((GMimeObject *) cd->task->message);
                r = strlen (c);
-               rspamd_dispatcher_write (cd->task->dispatcher, c, r, TRUE, TRUE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, c, r, TRUE, TRUE)) {
+                       return FALSE;
+               }
                memory_pool_add_destructor (cd->task->task_pool, (pool_destruct_func) g_free, c);
                r = snprintf (outbuf, sizeof (outbuf), CRLF "." CRLF);
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
                cd->state = LMTP_WANT_CLOSING;
        case LMTP_WANT_CLOSING:
                if (!parse_mta_str (in, cd)) {
@@ -641,7 +670,9 @@ write_lmtp_reply (struct rspamd_lmtp_proto *lmtp)
 
        debug_task ("writing reply to client");
        if (lmtp->task->error_code != 0) {
-               out_lmtp_reply (lmtp->task, lmtp->task->error_code, "", lmtp->task->last_error);
+               if (! out_lmtp_reply (lmtp->task, lmtp->task->error_code, "", lmtp->task->last_error)) {
+                       return -1;
+               }
        }
        else {
                /* Do delivery */
@@ -650,7 +681,9 @@ write_lmtp_reply (struct rspamd_lmtp_proto *lmtp)
                        return -1;
                }
                else if (r == 0) {
-                       out_lmtp_reply (lmtp->task, LMTP_OK, "", "Delivery completed");
+                       if (! out_lmtp_reply (lmtp->task, LMTP_OK, "", "Delivery completed")) {
+                               return -1;
+                       }
                }
                else {
                        return 1;
index ed67023964fc115546768b3c45b602db514b6dff..1b20b27420ad76fc71ea38ddfd2074341e6df1d5 100644 (file)
@@ -192,7 +192,9 @@ emails_command_handler (struct worker_task *task)
        outbuf[r++] = '\r';
        outbuf[r++] = '\n';
 
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE)) {
+               return -1;
+       }
        msg_info ("msg ok, id: <%s>, %d emails extracted", task->message_id, num);
 
        return 0;
index e557c0a6d2276aadde0fbe287615f6c0cc5af4f8..198cf08e4ad593ffb15335e0ed4639742486e040 100644 (file)
@@ -446,12 +446,16 @@ fuzzy_learn_callback (int fd, short what, void *arg)
                }
                else if (buf[0] == 'O' && buf[1] == 'K') {
                        r = snprintf (buf, sizeof (buf), "OK" CRLF);
-                       rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
+                               return;
+                       }
                        goto ok;
                }
                else {
                        r = snprintf (buf, sizeof (buf), "ERR" CRLF);
-                       rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE);
+                       if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
+                               return;
+                       }
                        goto ok;
                }
        }
@@ -465,7 +469,9 @@ fuzzy_learn_callback (int fd, short what, void *arg)
   err:
        msg_err ("got error in IO with server %s:%d, %d, %s", session->server->name, session->server->port, errno, strerror (errno));
        r = snprintf (buf, sizeof (buf), "Error" CRLF);
-       rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE);
+       if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
+               return;
+       }
   ok:
        remove_normal_event (session->session->s, fuzzy_learn_fin, session);
 }
@@ -576,7 +582,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                free_task (task, FALSE);
                session->state = STATE_REPLY;
                r = snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       msg_warn ("write error");
+               }
                return;
        }
        else {
@@ -605,7 +613,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                                        msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno));
                                        session->state = STATE_REPLY;
                                        r = snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF);
-                                       rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                                       if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                               return;
+                                       }
                                        free_task (task, FALSE);
                                        return;
                                }
@@ -634,7 +644,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                                /* Cannot write hash */
                                session->state = STATE_REPLY;
                                r = snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF);
-                               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                                       return;
+                               }
                                free_task (task, FALSE);
                                return;
                        }
@@ -646,7 +658,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
        if (*saved == 0) {
                session->state = STATE_REPLY;
                r = snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       return;
+               }
        }
 }
 
@@ -662,7 +676,9 @@ fuzzy_controller_handler (char **args, struct controller_session *session, int c
        if (!arg || *arg == '\0') {
                msg_info ("empty content length");
                r = snprintf (out_buf, sizeof (out_buf), "fuzzy command requires length as argument" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       return;
+               }
                session->state = STATE_REPLY;
                return;
        }
@@ -670,7 +686,9 @@ fuzzy_controller_handler (char **args, struct controller_session *session, int c
        size = strtoul (arg, &err_str, 10);
        if (errno != 0 || (err_str && *err_str != '\0')) {
                r = snprintf (out_buf, sizeof (out_buf), "learn size is invalid" CRLF);
-               rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
+                       return;
+               }
                session->state = STATE_REPLY;
                return;
        }
index 810b2fbe5b24e0c5c01e6841e5a2e8bdb3ca8ffb..699bd79d18f407a786cef83495f2d352c50e020f 100644 (file)
@@ -867,9 +867,11 @@ urls_command_handler (struct worker_task *task)
        outbuf[r++] = '\r';
        outbuf[r++] = '\n';
 
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, TRUE);
-       msg_info ("msg ok, id: <%s>, %d urls extracted", task->message_id, num);
        g_tree_destroy (url_tree);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, TRUE)) {
+               return -1;
+       }
+       msg_info ("msg ok, id: <%s>, %d urls extracted", task->message_id, num);
 
        return 0;
 }
index a49682b2e79a9f2791ac15f5d1d6b7f32727d86a..7f2907f86310bf14a3d032d3238c8ed50abc4d0c 100644 (file)
@@ -414,6 +414,7 @@ struct metric_callback_data {
        char                           *log_buf;
        int                             log_offset;
        int                             log_size;
+       gboolean                        alive;
 };
 
 static void
@@ -438,7 +439,7 @@ write_hashes_to_log (struct worker_task *task, char *logbuf, int offset, int siz
        }
 }
 
-static void
+static gboolean
 show_url_header (struct worker_task *task)
 {
        int                             r = 0;
@@ -467,7 +468,9 @@ show_url_header (struct worker_task *task)
                        outbuf[r++] = '\r';
                        outbuf[r++] = '\n';
                        outbuf[r] = ' ';
-                       rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE);
+                       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE)) {
+                               return FALSE;
+                       }
                        r = 0;
                }
                /* Write url host to buf */
@@ -487,7 +490,7 @@ show_url_header (struct worker_task *task)
                }
                cur = g_list_next (cur);
        }
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+       return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
 }
 
 static void
@@ -500,6 +503,10 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data)
        struct symbol                  *s = (struct symbol *)value;
        GList                          *cur;
 
+       if (! cd->alive) {
+               return;
+       }
+
        if (s->options) {
                r = snprintf (outbuf, OUTBUFSIZ, "Symbol: %s; ", (char *)key);
                cur = s->options;
@@ -523,10 +530,12 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data)
        }
        cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "%s,", (char *)key);
 
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE)) {
+               cd->alive = FALSE;
+       }
 }
 
-static void
+static gboolean
 show_metric_symbols (struct metric_result *metric_res, struct metric_callback_data *cd)
 {
        int                             r = 0;
@@ -546,7 +555,9 @@ show_metric_symbols (struct metric_result *metric_res, struct metric_callback_da
                        cur = g_list_next (cur);
                }
                g_list_free (symbols);
-               rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
        }
        else {
                g_hash_table_foreach (metric_res->symbols, metric_symbols_callback, cd);
@@ -555,6 +566,8 @@ show_metric_symbols (struct metric_result *metric_res, struct metric_callback_da
                        cd->log_buf[--cd->log_offset] = '\0';
                }
        }
+
+       return TRUE;
 }
 
 
@@ -570,7 +583,9 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
        int                             is_spam = 0;
        double                          ms = 0, rs = 0;
 
-
+       if (! cd->alive) {
+               return;
+       }
        if (metric_name == NULL || metric_value == NULL) {
                m = g_hash_table_lookup (task->cfg->metrics, DEFAULT_METRIC);
         default_required_score = m->required_score;
@@ -653,10 +668,14 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
 #endif
        }
        else {
-               rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       cd->alive = FALSE;
+               }
 
                if (task->cmd == CMD_SYMBOLS && metric_value != NULL) {
-                       show_metric_symbols (metric_res, cd);
+                       if (! show_metric_symbols (metric_res, cd)) {
+                               cd->alive = FALSE;
+                       }
                }
        }
 #ifdef HAVE_CLOCK_GETTIME
@@ -668,7 +687,7 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
 #endif
 }
 
-static void
+static gboolean
 show_messages (struct worker_task *task)
 {
        int                             r = 0;
@@ -681,10 +700,10 @@ show_messages (struct worker_task *task)
                cur = g_list_next (cur);
        }
 
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+       return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
 }
 
-static int
+static gboolean
 write_check_reply (struct worker_task *task)
 {
        int                             r;
@@ -694,12 +713,15 @@ write_check_reply (struct worker_task *task)
 
        r = snprintf (outbuf, sizeof (outbuf), "%s/%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER,
                                        task->proto_ver, "OK");
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE)) {
+               return FALSE;
+       }
 
        cd.task = task;
        cd.log_buf = logbuf;
        cd.log_offset = snprintf (logbuf, sizeof (logbuf), "msg ok, id: <%s>, ", task->message_id);
        cd.log_size = sizeof (logbuf);
+       cd.alive = TRUE;
 
        if (task->proto == SPAMC_PROTO) {
                /* Ignore metrics, just write report for 'default' metric */
@@ -707,9 +729,15 @@ write_check_reply (struct worker_task *task)
                if (metric_res == NULL) {
                        /* Implicit metric result */
                        show_metric_result (NULL, NULL, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                else {
                        show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
        }
        else {
@@ -718,23 +746,38 @@ write_check_reply (struct worker_task *task)
                if (metric_res == NULL) {
                        /* Implicit metric result */
                        show_metric_result (NULL, NULL, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                else {
                        show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                g_hash_table_remove (task->results, "default");
 
                /* Write result for each metric separately */
                g_hash_table_foreach (task->results, show_metric_result, &cd);
+               if (!cd.alive) {
+                       return FALSE;
+               }
                /* Messages */
-               show_messages (task);
+               if (! show_messages (task)) {
+                       return FALSE;
+               }
                /* URL stat */
-               show_url_header (task);
+               if (! show_url_header (task)) {
+                       return FALSE;
+               }
        }
        
        write_hashes_to_log (task, logbuf, cd.log_offset, cd.log_size);
        msg_info ("%s", logbuf);
-       rspamd_dispatcher_write (task->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+       if (! rspamd_dispatcher_write (task->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+               return FALSE;
+       }
 
        task->worker->srv->stat->messages_scanned++;
        if (default_score >= default_required_score) {
@@ -744,10 +787,10 @@ write_check_reply (struct worker_task *task)
                task->worker->srv->stat->messages_ham ++;
        }
 
-       return 0;
+       return TRUE;
 }
 
-static int
+static gboolean
 write_process_reply (struct worker_task *task)
 {
        int                             r;
@@ -764,6 +807,7 @@ write_process_reply (struct worker_task *task)
        cd.log_buf = logbuf;
        cd.log_offset = snprintf (logbuf, sizeof (logbuf), "msg ok, id: <%s>, ", task->message_id);
        cd.log_size = sizeof (logbuf);
+       cd.alive = TRUE;
 
        if (task->proto == SPAMC_PROTO) {
                /* Ignore metrics, just write report for 'default' metric */
@@ -771,9 +815,15 @@ write_process_reply (struct worker_task *task)
                if (metric_res == NULL) {
                        /* Implicit metric result */
                        show_metric_result (NULL, NULL, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                else {
                        show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
        }
        else {
@@ -782,24 +832,40 @@ write_process_reply (struct worker_task *task)
                if (metric_res == NULL) {
                        /* Implicit metric result */
                        show_metric_result (NULL, NULL, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                else {
                        show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd);
+                       if (! cd.alive) {
+                               return FALSE;
+                       }
                }
                g_hash_table_remove (task->results, "default");
 
                /* Write result for each metric separately */
                g_hash_table_foreach (task->results, show_metric_result, &cd);
+               if (! cd.alive) {
+                       return FALSE;
+               }
                /* Messages */
-               show_messages (task);
+               if (! show_messages (task)) {
+                       return FALSE;
+               }
        }
        write_hashes_to_log (task, logbuf, cd.log_offset, cd.log_size);
        msg_info ("%s", logbuf);
 
        outmsg = g_mime_object_to_string (GMIME_OBJECT (task->message));
+       memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, outmsg);
 
-       rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE);
-       rspamd_dispatcher_write (task->dispatcher, outmsg, strlen (outmsg), FALSE, TRUE);
+       if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE)) {
+               return FALSE;
+       }
+       if (! rspamd_dispatcher_write (task->dispatcher, outmsg, strlen (outmsg), FALSE, TRUE)) {
+               return FALSE;
+       }
 
        task->worker->srv->stat->messages_scanned++;
        if (default_score >= default_required_score) {
@@ -809,12 +875,10 @@ write_process_reply (struct worker_task *task)
                task->worker->srv->stat->messages_ham ++;
        }
 
-       memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, outmsg);
-
-       return 0;
+       return TRUE;
 }
 
-int
+gboolean
 write_reply (struct worker_task *task)
 {
        int                             r;
@@ -834,7 +898,9 @@ write_reply (struct worker_task *task)
                        debug_task ("writing error: %s", outbuf);
                }
                /* Write to bufferevent error message */
-               rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+               if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE)) {
+                       return FALSE;
+               }
        }
        else {
                switch (task->cmd) {
@@ -850,19 +916,19 @@ write_reply (struct worker_task *task)
                case CMD_SKIP:
                        r = snprintf (outbuf, sizeof (outbuf), "%s/%s 0 %s" CRLF, 
                                        (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, task->proto_ver, SPAMD_OK);
-                       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+                       return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
                        break;
                case CMD_PING:
                        r = snprintf (outbuf, sizeof (outbuf), "%s/%s 0 PONG" CRLF, 
                                        (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, task->proto_ver);
-                       rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+                       return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
                        break;
                case CMD_OTHER:
                        return task->custom_cmd->func (task);
                }
        }
 
-       return 0;
+       return FALSE;
 }
 
 void
index 4c12cc4815ddc6741deddb94a92906ddb26c68c5..d45e5c5553f2b275fc3a21e3ace4f2c212711e5e 100644 (file)
@@ -64,7 +64,7 @@ int read_rspamd_input_line (struct worker_task *task, f_str_t *line);
  * @param task task object
  * @return 0 if we wrote reply and -1 if there was some error
  */
-int write_reply (struct worker_task *task);
+gboolean write_reply (struct worker_task *task) G_GNUC_WARN_UNUSED_RESULT;
 
 
 /**
index f630c242812fcf005c10651ca87e021e5c63eec7..f2c085aba52b9a15e7f3d5a866400c4611d6be2b 100644 (file)
@@ -316,7 +316,9 @@ smtp_send_upstream_message (struct smtp_session *session)
 err:
        session->error = SMTP_ERROR_FILE;
        session->state = SMTP_STATE_CRITICAL_ERROR;
-       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+               return FALSE;
+       }
        destroy_session (session->s);
        return FALSE;
 }
@@ -405,7 +407,9 @@ process_smtp_data (struct smtp_session *session)
 err:
        session->error = SMTP_ERROR_FILE;
        session->state = SMTP_STATE_CRITICAL_ERROR;
-       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+               return FALSE;
+       }
        destroy_session (session->s);
        return FALSE;
 }
@@ -435,7 +439,9 @@ smtp_read_socket (f_str_t * in, void *arg)
                                if (session->errors > session->ctx->max_errors) {
                                        session->error = SMTP_ERROR_LIMIT;
                                        session->state = SMTP_STATE_CRITICAL_ERROR;
-                                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                               return FALSE;
+                                       }
                                        destroy_session (session->s);
                                        return FALSE;
                                }
@@ -454,7 +460,9 @@ smtp_read_socket (f_str_t * in, void *arg)
                                msg_err ("cannot write to temp file: %s", strerror (errno));
                                session->error = SMTP_ERROR_FILE;
                                session->state = SMTP_STATE_CRITICAL_ERROR;
-                               rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                       return FALSE;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -496,7 +504,9 @@ smtp_write_socket (void *arg)
 
        if (session->state == SMTP_STATE_CRITICAL_ERROR) {
                if (session->error != NULL) {
-                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                               return FALSE;
+                       }
                }
                destroy_session (session->s);
                return FALSE;
@@ -540,8 +550,12 @@ smtp_write_socket (void *arg)
                                msg_info ("%s", logbuf);
 
                                if (is_spam) {
-                                       rspamd_dispatcher_write (session->dispatcher, session->ctx->reject_message, 0, FALSE, TRUE);
-                                       rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                                       if (! rspamd_dispatcher_write (session->dispatcher, session->ctx->reject_message, 0, FALSE, TRUE)) {
+                                               return FALSE;
+                                       }
+                                       if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                               return FALSE;
+                                       }
                                        destroy_session (session->s);
                                        return FALSE;
                                }
@@ -550,13 +564,17 @@ smtp_write_socket (void *arg)
                }
                else {
                        if (session->error != NULL) {
-                               rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                       return FALSE;
+                               }
                        }
                }
        }
        else {
                if (session->error != NULL) {
-                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                               return FALSE;
+                       }
                }
        }
        
@@ -579,12 +597,16 @@ smtp_err_socket (GError * err, void *arg)
 /*
  * Write greeting to client
  */
-static void
+static gboolean
 write_smtp_greeting (struct smtp_session *session)
 {
        if (session->ctx->smtp_banner) {
-               rspamd_dispatcher_write (session->dispatcher, session->ctx->smtp_banner, 0, FALSE, TRUE);
+               if (! rspamd_dispatcher_write (session->dispatcher, session->ctx->smtp_banner, 0, FALSE, TRUE)) {
+                       return FALSE;
+               }
        }
+
+       return TRUE;
 }
 
 /*
@@ -601,7 +623,7 @@ smtp_delay_handler (int fd, short what, void *arg)
        }
        else {
                session->state = SMTP_STATE_CRITICAL_ERROR;
-               smtp_write_socket (session);
+               (void)smtp_write_socket (session);
        }
 }
 
index 06eed5cb05f9f72babb03af7090f8faa373f00c4..f0669198cef8c9de31d45ca3f9eba494cff3306f 100644 (file)
@@ -402,8 +402,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -437,8 +441,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -463,8 +471,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -483,8 +495,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -503,8 +519,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                session->error = memory_pool_alloc (session->pool, in->len + 1);
                                g_strlcpy (session->error, in->begin, in->len + 1);
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                if (session->cur_rcpt) {
                                        session->rcpt = g_list_delete_link (session->rcpt, session->cur_rcpt);
                                }
@@ -520,7 +540,9 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                        r = snprintf (outbuf, sizeof (outbuf), "RCPT TO: ");
                                        r += smtp_upstream_write_list (session->cur_rcpt, outbuf + r, sizeof (outbuf) - r);
                                        session->cur_rcpt = g_list_next (session->cur_rcpt);
-                                       rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE);
+                                       if (! rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE)) {
+                                               goto err;
+                                       }
                                }
                                else {
                                        session->upstream_state = SMTP_STATE_DATA;
@@ -529,8 +551,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                session->error = memory_pool_alloc (session->pool, in->len + 1);
                                g_strlcpy (session->error, in->begin, in->len + 1);
                                /* Write to client */
-                               rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) {
+                                       goto err;
+                               } 
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                if (session->state == SMTP_STATE_WAIT_UPSTREAM) {
                                        rspamd_dispatcher_restore (session->dispatcher);
                                        session->state = SMTP_STATE_RCPT;
@@ -545,8 +571,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -565,14 +595,18 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                        session->error = SMTP_ERROR_FILE;
                                        session->state = SMTP_STATE_CRITICAL_ERROR;
                                        rspamd_dispatcher_restore (session->dispatcher);
-                                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                               goto err;
+                                       }
                                        destroy_session (session->s);
                                        return FALSE;
                                }
                                session->state = SMTP_STATE_AFTER_DATA;
                                session->error = SMTP_ERROR_DATA_OK;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+                               if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                rspamd_dispatcher_pause (session->upstream_dispatcher);
                                rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0);
                                session->dispatcher->strip_eol = FALSE;
@@ -584,9 +618,15 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                        g_strlcpy (session->error, in->begin, in->len + 1);
                        session->state = SMTP_STATE_DATA;
                        rspamd_dispatcher_restore (session->dispatcher);
-                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
-                       rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
-                       rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, sizeof ("QUIT" CRLF) - 1, FALSE, TRUE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                               goto err;
+                       }
+                       if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                               goto err;
+                       }
+                       if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) {
+                               goto err;
+                       }
                        session->upstream_state = SMTP_STATE_END;
                        return TRUE;
                        break;
@@ -598,8 +638,12 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                                /* XXX: assume upstream errors as critical errors */
                                session->state = SMTP_STATE_CRITICAL_ERROR;
                                rspamd_dispatcher_restore (session->dispatcher);
-                               rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
-                               rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                               if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                                       goto err;
+                               }
+                               if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                                       goto err;
+                               }
                                destroy_session (session->s);
                                return FALSE;
                        }
@@ -612,13 +656,20 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
                        msg_err ("got upstream reply at unexpected state: %d, reply: %V", session->upstream_state, in);
                        session->state = SMTP_STATE_CRITICAL_ERROR;
                        rspamd_dispatcher_restore (session->dispatcher);
-                       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
-                       rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+                       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+                               goto err;
+                       }
+                       if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+                               goto err;
+                       }
                        destroy_session (session->s);
                        return FALSE;
        }
 
        return TRUE;
+err:
+       msg_warn ("write error occured");
+       return FALSE;
 }
 
 void 
@@ -631,8 +682,12 @@ smtp_upstream_err_socket (GError *err, void *arg)
        session->state = SMTP_STATE_CRITICAL_ERROR;
        /* XXX: assume upstream errors as critical errors */
        rspamd_dispatcher_restore (session->dispatcher);
-       rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
-       rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE);
+       if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+               return;
+       }
+       if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+               return;
+       }
        upstream_fail (&session->upstream->up, session->session_time);
        destroy_session (session->s);
 }
@@ -643,7 +698,9 @@ smtp_upstream_finalize_connection (gpointer data)
        struct smtp_session            *session = data;
        
        if (session->state != SMTP_STATE_CRITICAL_ERROR) {
-               rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, 0, FALSE, TRUE);
+               if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, 0, FALSE, TRUE)) {
+                       msg_warn ("cannot send correctly closing message to upstream");
+               }
        }
        rspamd_remove_dispatcher (session->upstream_dispatcher);
        session->upstream_dispatcher = NULL;
index 5e803cc785ca602113b7614f614c24ee304971e5..13880bdfa08b821e690568931a0e26516c997188 100644 (file)
@@ -158,7 +158,10 @@ fin_custom_filters (struct worker_task *task)
                if (filt->after_connect) {
                        filt->after_connect (&output, &log, curd->data);
                        if (output != NULL) {
-                               rspamd_dispatcher_write (task->dispatcher, output, strlen (output), FALSE, FALSE);
+                               if (! rspamd_dispatcher_write (task->dispatcher, output, strlen (output), FALSE, FALSE)) {
+                                       g_free (output);
+                                       return;
+                               }
                                g_free (output);
                        }
                        if (log != NULL) {
@@ -190,7 +193,10 @@ parse_line_custom (struct worker_task *task, f_str_t *in)
                                res = FALSE;
                        }
                        if (output != NULL) {
-                               rspamd_dispatcher_write (task->dispatcher, output, strlen (output), FALSE, FALSE);
+                               if (! rspamd_dispatcher_write (task->dispatcher, output, strlen (output), FALSE, FALSE)) {
+                                       g_free (output);
+                                       return FALSE;
+                               }
                                g_free (output);
                        }
                        if (curd->next) {
@@ -349,7 +355,9 @@ write_socket (void *arg)
 
        switch (task->state) {
        case WRITE_REPLY:
-               write_reply (task);
+               if (! write_reply (task)) {
+                       return FALSE;
+               }
                if (is_custom) {
                        fin_custom_filters (task);
                }
@@ -357,7 +365,9 @@ write_socket (void *arg)
                return FALSE;
                break;
        case WRITE_ERROR:
-               write_reply (task);
+               if (! write_reply (task)) {
+                       return FALSE;
+               }
                if (is_custom) {
                        fin_custom_filters (task);
                }