]> source.dussan.org Git - rspamd.git/commitdiff
Fix race condition in the controller IO.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 4 Dec 2013 23:54:44 +0000 (23:54 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 4 Dec 2013 23:54:44 +0000 (23:54 +0000)
src/controller.c
src/main.h
src/plugins/fuzzy_check.c

index d59cc297289e6ddadda7219b23d00aefadeec372..4a75c898b502210440cfe0d65df576789826570f 100644 (file)
@@ -1604,10 +1604,12 @@ controller_read_socket (f_str_t * in, void *arg)
                session->state = STATE_REPLY;
                break;
        case STATE_OTHER:
+               rspamd_dispatcher_pause (session->dispatcher);
                if (session->other_handler) {
-                       session->other_handler (session, in);
+                       if (!session->other_handler (session, in)) {
+                               return FALSE;
+                       }
                }
-               rspamd_dispatcher_pause (session->dispatcher);
                break;
        case STATE_WAIT:
                rspamd_dispatcher_pause (session->dispatcher);
@@ -1618,9 +1620,14 @@ controller_read_socket (f_str_t * in, void *arg)
        }
 
        if (session->state == STATE_REPLY || session->state == STATE_QUIT) {
-               rspamd_dispatcher_restore (session->dispatcher);
+               /* In case of normal session we restore read state, for restful session we need to terminate immediately */
+               if (!session->restful) {
+                       rspamd_dispatcher_restore (session->dispatcher);
+               }
+               else {
+                       return FALSE;
+               }
        }
-
        return TRUE;
 }
 
index 29c8a9f0c3cc0e8cae2d2f4ffa7bb9d284568455..86f916285761d3dc516f557ac1ef1c3a5d2c3daa 100644 (file)
@@ -135,7 +135,7 @@ union sa_union {
  */
 struct controller_command;
 struct controller_session;
-typedef void (*controller_func_t)(gchar **args, struct controller_session *session);
+typedef gboolean (*controller_func_t)(gchar **args, struct controller_session *session);
 
 struct controller_session {
        struct rspamd_worker *worker;                                                           /**< pointer to worker structure (controller in fact) */
@@ -168,7 +168,7 @@ struct controller_session {
        f_str_t *learn_buf;                                                                                     /**< learn input                                                                        */
        GList *parts;                                                                                           /**< extracted mime parts                                                       */
        gint in_class;                                                                                          /**< positive or negative learn                                         */
-       void (*other_handler)(struct controller_session *session, 
+       gboolean (*other_handler)(struct controller_session *session,
                        f_str_t *in);                                   /**< other command handler to execute at the end of processing */
        void *other_data;                                                                                       /**< and its data                                                                       */
        controller_func_t custom_handler;                                                       /**< custom command handler                                                     */
index 9cc9a7e885fa4ef258134ea5d063dab775feef30..304de560a0927a985447fc061bb012fbdbc0d984 100644 (file)
@@ -131,8 +131,8 @@ static struct fuzzy_ctx *fuzzy_module_ctx = NULL;
 static const gchar hex_digits[] = "0123456789abcdef";
 
 static void fuzzy_symbol_callback (struct worker_task *task, void *unused);
-static void fuzzy_add_handler (gchar **args, struct controller_session *session);
-static void fuzzy_delete_handler (gchar **args,
+static gboolean fuzzy_add_handler (gchar **args, struct controller_session *session);
+static gboolean fuzzy_delete_handler (gchar **args,
                struct controller_session *session);
 
 /* Initialization */
@@ -148,7 +148,7 @@ module_t fuzzy_check_module = {
 };
 
 static void
-parse_flags_string (struct fuzzy_rule *rule, struct config_file *cfg, ucl_object_t *val)
+parse_flags (struct fuzzy_rule *rule, struct config_file *cfg, ucl_object_t *val)
 {
        ucl_object_t *elt;
        struct fuzzy_mapping *map;
@@ -176,7 +176,7 @@ parse_flags_string (struct fuzzy_rule *rule, struct config_file *cfg, ucl_object
                                }
                                /* Add flag to hash table */
                                g_hash_table_insert (rule->mappings, GINT_TO_POINTER (map->fuzzy_flag), map);
-                               register_virtual_symbol (&cfg->cache, map->symbol, map->weight);
+                               register_virtual_symbol (&cfg->cache, map->symbol, 1.0);
                        }
                        else {
                                msg_err ("fuzzy_map parameter has no flag definition");
@@ -352,7 +352,7 @@ fuzzy_parse_rule (struct config_file *cfg, ucl_object_t *obj)
        }
        if ((value = ucl_object_find_key (obj, "fuzzy_map")) != NULL) {
                while ((cur = ucl_iterate_object (value, &it, true)) != NULL) {
-                       parse_flags_string (rule, cfg, cur);
+                       parse_flags (rule, cfg, cur);
                }
        }
 
@@ -557,7 +557,7 @@ fuzzy_io_callback (gint fd, short what, void *arg)
        return;
 
   err:
-       msg_err ("got error on IO with server %s:%d, %d, %s", session->server->name, session->server->port, errno, strerror (errno));
+       msg_err ("got error on IO with server %s, %d, %s", session->server->name, errno, strerror (errno));
   ok:
        remove_normal_event (session->task->s, fuzzy_io_fin, session);
 }
@@ -969,7 +969,7 @@ fuzzy_process_rule (struct controller_session *session, struct fuzzy_rule *rule,
        return TRUE;
 }
 
-static void
+static gboolean
 fuzzy_process_handler (struct controller_session *session, f_str_t * in)
 {
        struct fuzzy_rule *rule;
@@ -1016,7 +1016,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                        msg_warn ("write error");
                }
                rspamd_dispatcher_restore (session->dispatcher);
-               return;
+               return FALSE;
        }
        cur = fuzzy_module_ctx->fuzzy_rules;
        while (cur && res) {
@@ -1049,9 +1049,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "no hashes have been written" CRLF "END" CRLF);
                }
                if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                       return;
+                       return FALSE;
                }
-               rspamd_dispatcher_restore (session->dispatcher);
+               return FALSE;
        }
        else if (!processed) {
                session->state = STATE_REPLY;
@@ -1062,13 +1062,15 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "no fuzzy rules matched" CRLF "END" CRLF);
                }
                if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                       return;
+                       return FALSE;
                }
-               rspamd_dispatcher_restore (session->dispatcher);
+               return FALSE;
        }
+
+       return TRUE;
 }
 
-static void
+static gboolean
 fuzzy_controller_handler (gchar **args, struct controller_session *session, gint cmd)
 {
        gchar                           *arg, out_buf[BUFSIZ], *err_str;
@@ -1082,22 +1084,22 @@ fuzzy_controller_handler (gchar **args, struct controller_session *session, gint
                        msg_info ("empty content length");
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "HTTP/1.0 500 Fuzzy command requires Content-Length" CRLF CRLF);
                        if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                               return;
+                               return FALSE;
                        }
                        session->state = STATE_REPLY;
                        rspamd_dispatcher_restore (session->dispatcher);
-                       return;
+                       return FALSE;
                }
                errno = 0;
                size = strtoul (arg, &err_str, 10);
                if (errno != 0 || (err_str && *err_str != '\0')) {
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "HTTP/1.0 500 Learn size is invalid" CRLF CRLF);
                        if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                               return;
+                               return FALSE;
                        }
                        session->state = STATE_REPLY;
                        rspamd_dispatcher_restore (session->dispatcher);
-                       return;
+                       return FALSE;
                }
                arg = g_hash_table_lookup (session->kwargs, "value");
                if (arg) {
@@ -1125,20 +1127,20 @@ fuzzy_controller_handler (gchar **args, struct controller_session *session, gint
                        msg_info ("empty content length");
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "fuzzy command requires length as argument" CRLF "END" CRLF);
                        if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                               return;
+                               return FALSE;
                        }
                        session->state = STATE_REPLY;
-                       return;
+                       return FALSE;
                }
                errno = 0;
                size = strtoul (arg, &err_str, 10);
                if (errno != 0 || (err_str && *err_str != '\0')) {
                        r = rspamd_snprintf (out_buf, sizeof (out_buf), "learn size is invalid" CRLF);
                        if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
-                               return;
+                               return FALSE;
                        }
                        session->state = STATE_REPLY;
-                       return;
+                       return FALSE;
                }
                /* Process value */
                arg = args[1];
@@ -1171,16 +1173,18 @@ fuzzy_controller_handler (gchar **args, struct controller_session *session, gint
        sargs[1] = value;
        sargs[2] = flag;
        session->other_data = sargs;
+
+       return TRUE;
 }
 
-static void
+static gboolean
 fuzzy_add_handler (gchar **args, struct controller_session *session)
 {
-       fuzzy_controller_handler (args, session, FUZZY_WRITE);
+       return fuzzy_controller_handler (args, session, FUZZY_WRITE);
 }
 
-static void
+static gboolean
 fuzzy_delete_handler (gchar **args, struct controller_session *session)
 {
-       fuzzy_controller_handler (args, session, FUZZY_DEL);
+       return fuzzy_controller_handler (args, session, FUZZY_DEL);
 }