diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-11-27 21:01:27 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-11-29 09:49:27 +0100 |
commit | f7b7e3975a3806e09f7e2097fecb6d59c259fce8 (patch) | |
tree | 6c661dd46a624c28b3ab45a7590a43b692f6ab2f /src | |
parent | e51152e6a468751b0b8888abb241f091a1091d62 (diff) | |
download | weechat-f7b7e3975a3806e09f7e2097fecb6d59c259fce8.zip |
irc: add server option "anti_flood", remove server options "anti_flood_prio_{high|low}" (issue #1039)
The new option is set in milliseconds.
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/irc/irc-command.c | 35 | ||||
-rw-r--r-- | src/plugins/irc/irc-config.c | 61 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 9 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 444 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.h | 7 | ||||
-rw-r--r-- | src/plugins/irc/irc-upgrade.c | 1 |
6 files changed, 289 insertions, 268 deletions
diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index 8f6f165d5..61d977332 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -2366,11 +2366,13 @@ irc_command_quit_server (struct t_irc_server *server, const char *arguments) if (ptr_arg && ptr_arg[0]) { msg = irc_server_get_default_msg (ptr_arg, server, NULL, NULL); - irc_server_sendf (server, 0, NULL, "QUIT :%s", msg); + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, + "QUIT :%s", msg); } else { - irc_server_sendf (server, 0, NULL, "QUIT"); + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, + "QUIT"); } if (msg) @@ -5495,26 +5497,16 @@ irc_command_display_server (struct t_irc_server *server, int with_detail) IRC_COLOR_CHAT_VALUE, weechat_config_integer (server->options[IRC_SERVER_OPTION_CONNECTION_TIMEOUT]), NG_("second", "seconds", weechat_config_integer (server->options[IRC_SERVER_OPTION_CONNECTION_TIMEOUT]))); - /* anti_flood_prio_high */ - if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH])) - weechat_printf (NULL, " anti_flood_prio_high : (%d %s)", - IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH), - NG_("second", "seconds", IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH))); + /* anti_flood */ + if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_ANTI_FLOOD])) + weechat_printf (NULL, " anti_flood . . . . . : (%d %s)", + IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD), + NG_("second", "seconds", IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD))); else - weechat_printf (NULL, " anti_flood_prio_high : %s%d %s", + weechat_printf (NULL, " anti_flood . . . . . : %s%d %s", IRC_COLOR_CHAT_VALUE, - weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH]), - NG_("second", "seconds", weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH]))); - /* anti_flood_prio_low */ - if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW])) - weechat_printf (NULL, " anti_flood_prio_low. : (%d %s)", - IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW), - NG_("second", "seconds", IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW))); - else - weechat_printf (NULL, " anti_flood_prio_low. : %s%d %s", - IRC_COLOR_CHAT_VALUE, - weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW]), - NG_("second", "seconds", weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW]))); + weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD]), + NG_("second", "seconds", weechat_config_integer (server->options[IRC_SERVER_OPTION_ANTI_FLOOD]))); /* away_check */ if (weechat_config_option_is_null (server->options[IRC_SERVER_OPTION_AWAY_CHECK])) weechat_printf (NULL, " away_check . . . . . : (%d %s)", @@ -6176,7 +6168,8 @@ IRC_COMMAND_CALLBACK(squit) WEECHAT_COMMAND_MIN_ARGS(2, ""); - irc_server_sendf (ptr_server, 0, NULL, "SQUIT %s", argv_eol[1]); + irc_server_sendf (ptr_server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, + "SQUIT %s", argv_eol[1]); return WEECHAT_RC_OK; } diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index 21606cfdb..6c9973497 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -179,12 +179,7 @@ struct t_config_option *irc_config_network_whois_double_nick = NULL; /* IRC config, server section */ -struct t_config_option *irc_config_server_default[IRC_SERVER_NUM_OPTIONS] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; +struct t_config_option *irc_config_server_default[IRC_SERVER_NUM_OPTIONS]; struct t_hook *irc_config_hook_config_nick_color_options = NULL; struct t_hook *irc_config_hook_config_chat_nick_colors = NULL; struct t_hashtable *irc_config_hashtable_display_join_message = NULL; @@ -1102,6 +1097,13 @@ irc_config_server_default_change_cb (const void *pointer, void *data, irc_server_set_nicks (ptr_server, weechat_config_string (option)); break; + case IRC_SERVER_OPTION_ANTI_FLOOD: + if (ptr_server->hook_timer_anti_flood) + { + irc_server_outqueue_timer_remove (ptr_server); + irc_server_outqueue_timer_add (ptr_server); + } + break; case IRC_SERVER_OPTION_AWAY_CHECK: case IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS: if (IRC_SERVER_OPTION_INTEGER( @@ -1401,6 +1403,13 @@ irc_config_server_change_cb (const void *pointer, void *data, IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_NICKS)); break; + case IRC_SERVER_OPTION_ANTI_FLOOD: + if (ptr_server->hook_timer_anti_flood) + { + irc_server_outqueue_timer_remove (ptr_server); + irc_server_outqueue_timer_add (ptr_server); + } + break; case IRC_SERVER_OPTION_AWAY_CHECK: case IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS: if (IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_AWAY_CHECK) > 0) @@ -2503,32 +2512,19 @@ irc_config_server_new_option (struct t_config_file *config_file, callback_change_data, NULL, NULL, NULL); break; - case IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH: + case IRC_SERVER_OPTION_ANTI_FLOOD: new_option = weechat_config_new_option ( config_file, section, option_name, "integer", - N_("anti-flood for high priority queue: number of seconds " - "between two user messages or commands sent to IRC server " - "(0 = no anti-flood)"), - NULL, 0, 60, - default_value, value, - null_value_allowed, - callback_check_value, - callback_check_value_pointer, - callback_check_value_data, - callback_change, - callback_change_pointer, - callback_change_data, - NULL, NULL, NULL); - break; - case IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW: - new_option = weechat_config_new_option ( - config_file, section, - option_name, "integer", - N_("anti-flood for low priority queue: number of seconds " - "between two messages sent to IRC server (messages like " - "automatic CTCP replies) (0 = no anti-flood)"), - NULL, 0, 60, + N_("delay in milliseconds between two messages sent to server " + "(anti-flood); 0 = disable anti-flood and always send " + "all messages immediately (not recommended as you can be " + "quickly killed by the server); " + "internally there are queues with different priorities: " + "when connecting to the server all messages are sent " + "immediately and your messages have higher priority than " + "some automatic messages that are sent in background"), + NULL, 0, 60000, default_value, value, null_value_allowed, callback_check_value, @@ -3010,6 +3006,8 @@ irc_config_update_cb (const void *pointer, void *data, int irc_config_init () { + int i; + irc_config_hashtable_display_join_message = weechat_hashtable_new ( 32, WEECHAT_HASHTABLE_STRING, @@ -3031,6 +3029,11 @@ irc_config_init () WEECHAT_HASHTABLE_STRING, NULL, NULL); + for (i = 0; i < IRC_SERVER_NUM_OPTIONS; i++) + { + irc_config_server_default[i] = NULL; + } + irc_config_file = weechat_config_new (IRC_CONFIG_PRIO_NAME, &irc_config_reload, NULL, NULL); if (!irc_config_file) diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 68fe3249d..dc343d25a 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -2965,7 +2965,8 @@ IRC_PROTOCOL_CALLBACK(ping) str_params = irc_protocol_string_params (ctxt->params, 0, ctxt->num_params - 1); - irc_server_sendf (ctxt->server, 0, NULL, "PONG :%s", str_params); + irc_server_sendf (ctxt->server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, + "PONG :%s", str_params); if (str_params) free (str_params); @@ -7060,7 +7061,7 @@ IRC_PROTOCOL_CALLBACK(432) irc_server_set_nick (ctxt->server, alternate_nick); irc_server_sendf ( - ctxt->server, 0, NULL, + ctxt->server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "NICK %s%s", (ctxt->server->nick && strchr (ctxt->server->nick, ':')) ? ":" : "", ctxt->server->nick); @@ -7111,7 +7112,7 @@ IRC_PROTOCOL_CALLBACK(433) irc_server_set_nick (ctxt->server, alternate_nick); irc_server_sendf ( - ctxt->server, 0, NULL, + ctxt->server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "NICK %s%s", (ctxt->server->nick && strchr (ctxt->server->nick, ':')) ? ":" : "", ctxt->server->nick); @@ -7168,7 +7169,7 @@ IRC_PROTOCOL_CALLBACK(437) irc_server_set_nick (ctxt->server, alternate_nick); irc_server_sendf ( - ctxt->server, 0, NULL, + ctxt->server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "NICK %s%s", (ctxt->server->nick && strchr (ctxt->server->nick, ':')) ? ":" : "", ctxt->server->nick); diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 40f444b93..a1eea10ed 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -116,8 +116,7 @@ char *irc_server_options[IRC_SERVER_NUM_OPTIONS][2] = { "autorejoin", "off" }, { "autorejoin_delay", "30" }, { "connection_timeout", "60" }, - { "anti_flood_prio_high", "2" }, - { "anti_flood_prio_low", "2" }, + { "anti_flood", "2000" }, { "away_check", "0" }, { "away_check_max_nicks", "25" }, { "msg_kick", "" }, @@ -153,6 +152,7 @@ int irc_fingerprint_digest_algos_size[IRC_FINGERPRINT_NUM_ALGOS] = { 160, 256, 512 }; +void irc_server_outqueue_send (struct t_irc_server *server); void irc_server_reconnect (struct t_irc_server *server); void irc_server_free_data (struct t_irc_server *server); void irc_server_autojoin_create_buffers (struct t_irc_server *server); @@ -1697,6 +1697,7 @@ irc_server_alloc (const char *name) new_server->hook_fd = NULL; new_server->hook_timer_connection = NULL; new_server->hook_timer_sasl = NULL; + new_server->hook_timer_anti_flood = NULL; new_server->sasl_scram_client_first = NULL; new_server->sasl_scram_salted_pwd = NULL; new_server->sasl_scram_salted_pwd_size = 0; @@ -1768,7 +1769,6 @@ irc_server_alloc (const char *name) new_server->lag_last_refresh = 0; new_server->cmd_list_regexp = NULL; new_server->list = irc_list_alloc (new_server); - new_server->last_user_message = 0; new_server->last_away_check = 0; new_server->last_data_purge = 0; for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++) @@ -2323,6 +2323,8 @@ irc_server_free_data (struct t_irc_server *server) weechat_unhook (server->hook_timer_connection); if (server->hook_timer_sasl) weechat_unhook (server->hook_timer_sasl); + if (server->hook_timer_anti_flood) + weechat_unhook (server->hook_timer_anti_flood); irc_server_free_sasl_data (server); if (server->unterminated_message) free (server->unterminated_message); @@ -2798,101 +2800,188 @@ irc_server_get_tags_to_send (const char *tags) } /* - * Sends a message from out queue. + * Checks if all out queues are empty. + * + * Returns: + * 1: all out queues are empty + * 0: at least one out queue contains a message + */ + +int +irc_server_outqueue_all_empty (struct t_irc_server *server) +{ + int priority; + + for (priority = 0; priority < IRC_SERVER_NUM_OUTQUEUES_PRIO; priority++) + { + if (server->outqueue[priority]) + return 0; + } + return 1; +} + +/* + * Timer called to send out queue (anti-flood). + */ + +int +irc_server_outqueue_timer_cb (const void *pointer, void *data, int remaining_calls) +{ + struct t_irc_server *server; + + /* make C compiler happy */ + (void) data; + (void) remaining_calls; + + server = (struct t_irc_server *)pointer; + + irc_server_outqueue_send (server); + + return WEECHAT_RC_OK; +} + +/* + * Removes anti-flood timer form a server (if set). */ void -irc_server_outqueue_send (struct t_irc_server *server) +irc_server_outqueue_timer_remove (struct t_irc_server *server) +{ + if (!server) + return; + + if (server->hook_timer_anti_flood) + { + weechat_unhook (server->hook_timer_anti_flood); + server->hook_timer_anti_flood = NULL; + } +} + +/* + * Adds anti-flood timer in a server (removes it first if already set). + */ + +void +irc_server_outqueue_timer_add (struct t_irc_server *server) +{ + if (!server) + return; + + if (server->hook_timer_anti_flood) + irc_server_outqueue_timer_remove (server); + + server->hook_timer_anti_flood = weechat_hook_timer ( + IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD), + 0, 0, + &irc_server_outqueue_timer_cb, + server, NULL); +} + +/* + * Sends one message from out queue. + */ + +void +irc_server_outqueue_send_one_msg (struct t_irc_server *server, + struct t_irc_outqueue *message) { - time_t time_now; char *pos, *tags_to_send; - int priority, anti_flood; - time_now = time (NULL); + if (!server || !message) + return; - /* detect if system clock has been changed (now lower than before) */ - if (server->last_user_message > time_now) - server->last_user_message = time_now; + if (message->message_before_mod) + { + pos = strchr (message->message_before_mod, '\r'); + if (pos) + pos[0] = '\0'; + irc_raw_print (server, IRC_RAW_FLAG_SEND, message->message_before_mod); + if (pos) + pos[0] = '\r'; + } - for (priority = 0; priority < IRC_SERVER_NUM_OUTQUEUES_PRIO; priority++) + if (message->message_after_mod) { - switch (priority) + pos = strchr (message->message_after_mod, '\r'); + if (pos) + pos[0] = '\0'; + + irc_raw_print ( + server, + IRC_RAW_FLAG_SEND | ((message->modified) ? IRC_RAW_FLAG_MODIFIED : 0), + message->message_after_mod); + + /* send signal with command that will be sent to server */ + (void) irc_server_send_signal ( + server, + "irc_out", + message->command, + message->message_after_mod, + NULL); + tags_to_send = irc_server_get_tags_to_send (message->tags); + (void) irc_server_send_signal ( + server, + "irc_outtags", + message->command, + message->message_after_mod, + (tags_to_send) ? tags_to_send : ""); + if (tags_to_send) + free (tags_to_send); + + if (pos) + pos[0] = '\r'; + + /* send command */ + irc_server_send (server, + message->message_after_mod, + strlen (message->message_after_mod)); + + /* start redirection if redirect is set */ + if (message->redirect) { - case 0: /* immediate send */ - anti_flood = 0; - break; - case 1: /* high priority */ - anti_flood = IRC_SERVER_OPTION_INTEGER( - server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH); - break; - default: /* low priority */ - anti_flood = IRC_SERVER_OPTION_INTEGER( - server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW); - break; + irc_redirect_init_command (message->redirect, + message->message_after_mod); } - if (server->outqueue[priority] - && (time_now >= server->last_user_message + anti_flood)) - { - if (server->outqueue[priority]->message_before_mod) - { - pos = strchr (server->outqueue[priority]->message_before_mod, - '\r'); - if (pos) - pos[0] = '\0'; - irc_raw_print (server, IRC_RAW_FLAG_SEND, - server->outqueue[priority]->message_before_mod); - if (pos) - pos[0] = '\r'; - } - if (server->outqueue[priority]->message_after_mod) - { - pos = strchr (server->outqueue[priority]->message_after_mod, - '\r'); - if (pos) - pos[0] = '\0'; - - irc_raw_print (server, IRC_RAW_FLAG_SEND | - ((server->outqueue[priority]->modified) ? IRC_RAW_FLAG_MODIFIED : 0), - server->outqueue[priority]->message_after_mod); - - /* send signal with command that will be sent to server */ - (void) irc_server_send_signal ( - server, "irc_out", - server->outqueue[priority]->command, - server->outqueue[priority]->message_after_mod, - NULL); - tags_to_send = irc_server_get_tags_to_send ( - server->outqueue[priority]->tags); - (void) irc_server_send_signal ( - server, "irc_outtags", - server->outqueue[priority]->command, - server->outqueue[priority]->message_after_mod, - (tags_to_send) ? tags_to_send : ""); - if (tags_to_send) - free (tags_to_send); + } +} - if (pos) - pos[0] = '\r'; +/* + * Sends one or multiple message from out queues, by order of priority + * (immediate/high/low), then from oldest message to newest in queue. + */ - /* send command */ - irc_server_send ( - server, server->outqueue[priority]->message_after_mod, - strlen (server->outqueue[priority]->message_after_mod)); - server->last_user_message = time_now; +void +irc_server_outqueue_send (struct t_irc_server *server) +{ + int priority, anti_flood; - /* start redirection if redirect is set */ - if (server->outqueue[priority]->redirect) - { - irc_redirect_init_command ( - server->outqueue[priority]->redirect, - server->outqueue[priority]->message_after_mod); - } - } - irc_server_outqueue_free (server, priority, - server->outqueue[priority]); + if (irc_server_outqueue_all_empty (server)) + { + irc_server_outqueue_timer_remove (server); + return; + } + + anti_flood = IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD); + + for (priority = 0; priority < IRC_SERVER_NUM_OUTQUEUES_PRIO; priority++) + { + if (!server->outqueue[priority]) + continue; + + irc_server_outqueue_send_one_msg (server, server->outqueue[priority]); + irc_server_outqueue_free (server, priority, server->outqueue[priority]); + + /* + * continue to send for immediate priority (= 0), + * exit loop now for high/low priorities (> 0) if anti flood is enabled + */ + if ((priority > 0) && (anti_flood > 0)) break; - } } + + /* schedule next send if anti-flood is enabled */ + if ((anti_flood > 0) && !server->hook_timer_anti_flood) + irc_server_outqueue_timer_add (server); } /* @@ -2903,13 +2992,9 @@ irc_server_outqueue_send (struct t_irc_server *server) * queue_msg is priority: * 1 = higher priority, for user messages * 2 = lower priority, for other messages (like auto reply to CTCP queries) - * - * Returns: - * 1: OK - * 0: error */ -int +void irc_server_send_one_msg (struct t_irc_server *server, int flags, const char *message, const char *nick, const char *command, const char *channel, @@ -2919,13 +3004,9 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags, const char *ptr_msg, *ptr_chan_nick; char *new_msg, *pos, *tags_to_send, *msg_encoded; char str_modifier[128], modifier_data[1024]; - int rc, queue_msg, add_to_queue, first_message, anti_flood; - int pos_channel, pos_text, pos_encode; - time_t time_now; + int first_message, queue_msg, pos_channel, pos_text, pos_encode; struct t_irc_redirect *ptr_redirect; - rc = 1; - /* run modifier "irc_out_xxx" */ snprintf (str_modifier, sizeof (str_modifier), "irc_out_%s", @@ -3017,7 +3098,7 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags, if (msg_encoded) ptr_msg = msg_encoded; - while (rc && ptr_msg && ptr_msg[0]) + while (ptr_msg && ptr_msg[0]) { pos = strchr (ptr_msg, '\n'); if (pos) @@ -3025,101 +3106,41 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags, snprintf (buffer, sizeof (buffer), "%s\r\n", ptr_msg); - /* anti-flood: look whether we should queue outgoing message or not */ - time_now = time (NULL); - - /* detect if system clock has been changed (now lower than before) */ - if (server->last_user_message > time_now) - server->last_user_message = time_now; - - /* get queue from flags */ - queue_msg = 0; if (flags & IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE) - queue_msg = 1; + queue_msg = 0; else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_HIGH) - queue_msg = 2; + queue_msg = 1; else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_LOW) - queue_msg = 3; - - switch (queue_msg - 1) - { - case 0: - anti_flood = 0; - break; - case 1: - anti_flood = IRC_SERVER_OPTION_INTEGER( - server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH); - break; - default: - anti_flood = IRC_SERVER_OPTION_INTEGER( - server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW); - break; - } - - add_to_queue = 0; - if ((queue_msg > 0) - && (server->outqueue[queue_msg - 1] - || ((anti_flood > 0) - && (time_now - server->last_user_message < anti_flood)))) + queue_msg = 2; + else { - add_to_queue = queue_msg; + /* + * if connected to server (message 001 received), consider + * it's low priority (otherwise send immediately) + */ + queue_msg = (server->is_connected) ? 2 : 0; } tags_to_send = irc_server_get_tags_to_send (tags); ptr_redirect = irc_redirect_search_available (server); - if (add_to_queue > 0) - { - /* queue message (do not send anything now) */ - irc_server_outqueue_add (server, add_to_queue - 1, command, - (new_msg && first_message) ? message : NULL, - buffer, - (new_msg) ? 1 : 0, - tags_to_send, - ptr_redirect); - /* mark redirect as "used" */ - if (ptr_redirect) - ptr_redirect->assigned_to_command = 1; - } - else - { - if (first_message) - { - irc_raw_print (server, IRC_RAW_FLAG_SEND, message); - } - if (new_msg) - { - irc_raw_print (server, - IRC_RAW_FLAG_SEND | IRC_RAW_FLAG_MODIFIED, - ptr_msg); - } + /* queue message (do not send anything now) */ + irc_server_outqueue_add (server, + queue_msg, + command, + (new_msg && first_message) ? message : NULL, + buffer, + (new_msg) ? 1 : 0, + tags_to_send, + ptr_redirect); - /* send signal with command that will be sent to server */ - (void) irc_server_send_signal ( - server, "irc_out", - (command) ? command : "unknown", - ptr_msg, - NULL); - (void) irc_server_send_signal ( - server, "irc_outtags", - (command) ? command : "unknown", - ptr_msg, - (tags_to_send) ? tags_to_send : ""); - - if (irc_server_send (server, buffer, strlen (buffer)) <= 0) - rc = 0; - else - { - if (queue_msg > 0) - server->last_user_message = time_now; - } - if (ptr_redirect) - irc_redirect_init_command (ptr_redirect, buffer); - } + /* mark redirect as "used" */ + if (ptr_redirect) + ptr_redirect->assigned_to_command = 1; if (tags_to_send) - free (tags_to_send); + free (tags_to_send); if (pos) { @@ -3142,8 +3163,6 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags, if (new_msg) free (new_msg); - - return rc; } /* @@ -3293,9 +3312,8 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags, str_message = weechat_hashtable_get (hashtable, hash_key); if (!str_message) break; - if (!irc_server_send_one_msg (server, flags, str_message, - nick, command, channel, tags)) - break; + irc_server_send_one_msg (server, flags, str_message, + nick, command, channel, tags); if (!multiline && list_messages) { snprintf (hash_key, sizeof (hash_key), "args%d", number); @@ -3319,6 +3337,17 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags, free (new_msg); free (vbuffer); + /* send all messages with "immediate" priority */ + while (server->outqueue[0]) + { + irc_server_outqueue_send_one_msg (server, server->outqueue[0]); + irc_server_outqueue_free (server, 0, server->outqueue[0]); + } + + /* send any other messages, if any, possibly with anti-flood */ + if (!server->hook_timer_anti_flood) + irc_server_outqueue_send (server); + return list_messages; } @@ -4008,15 +4037,15 @@ irc_server_timer_cb (const void *pointer, void *data, int remaining_calls) if (!ptr_server->is_connected) continue; - /* send queued messages */ - irc_server_outqueue_send (ptr_server); - /* check for lag */ if ((weechat_config_integer (irc_config_network_lag_check) > 0) && (ptr_server->lag_check_time.tv_sec == 0) && (current_time >= ptr_server->lag_next_check)) { - irc_server_sendf (ptr_server, 0, NULL, "PING %s", + irc_server_sendf (ptr_server, + IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, + NULL, /* tags */ + "PING %s", (ptr_server->current_address) ? ptr_server->current_address : "weechat"); gettimeofday (&(ptr_server->lag_check_time), NULL); @@ -4202,6 +4231,12 @@ irc_server_close_connection (struct t_irc_server *server) } irc_server_free_sasl_data (server); + if (server->hook_timer_anti_flood) + { + weechat_unhook (server->hook_timer_anti_flood); + server->hook_timer_anti_flood = NULL; + } + if (server->hook_fd) { weechat_unhook (server->hook_fd); @@ -4364,7 +4399,7 @@ irc_server_login (struct t_irc_server *server) if (password && password[0]) { irc_server_sendf ( - server, 0, NULL, + server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "PASS %s%s", ((password[0] == ':') || (strchr (password, ' '))) ? ":" : "", password); @@ -4384,18 +4419,19 @@ irc_server_login (struct t_irc_server *server) if (irc_server_sasl_enabled (server) || (capabilities && capabilities[0])) { - irc_server_sendf (server, 0, NULL, "CAP LS " IRC_SERVER_VERSION_CAP); + irc_server_sendf (server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, + "CAP LS " IRC_SERVER_VERSION_CAP); } username2 = (username && username[0]) ? weechat_string_replace (username, " ", "_") : strdup ("weechat"); irc_server_sendf ( - server, 0, NULL, + server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "NICK %s%s", (server->nick && strchr (server->nick, ':')) ? ":" : "", server->nick); irc_server_sendf ( - server, 0, NULL, + server, IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE, NULL, "USER %s 0 * :%s", (username2) ? username2 : "weechat", (realname && realname[0]) ? realname : ((username2) ? username2 : "weechat")); @@ -6482,6 +6518,7 @@ irc_server_hdata_server_cb (const void *pointer, void *data, WEECHAT_HDATA_VAR(struct t_irc_server, hook_fd, POINTER, 0, NULL, "hook"); WEECHAT_HDATA_VAR(struct t_irc_server, hook_timer_connection, POINTER, 0, NULL, "hook"); WEECHAT_HDATA_VAR(struct t_irc_server, hook_timer_sasl, POINTER, 0, NULL, "hook"); + WEECHAT_HDATA_VAR(struct t_irc_server, hook_timer_anti_flood, POINTER, 0, NULL, "hook"); WEECHAT_HDATA_VAR(struct t_irc_server, sasl_scram_client_first, STRING, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, sasl_scram_salted_pwd, OTHER, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, sasl_scram_salted_pwd_size, INTEGER, 0, NULL, NULL); @@ -6542,7 +6579,6 @@ irc_server_hdata_server_cb (const void *pointer, void *data, WEECHAT_HDATA_VAR(struct t_irc_server, lag_last_refresh, TIME, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, cmd_list_regexp, POINTER, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, list, POINTER, 0, NULL, "irc_list"); - WEECHAT_HDATA_VAR(struct t_irc_server, last_user_message, TIME, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, last_away_check, TIME, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, last_data_purge, TIME, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_irc_server, outqueue, POINTER, 0, NULL, NULL); @@ -6711,11 +6747,8 @@ irc_server_add_to_infolist (struct t_infolist *infolist, if (!weechat_infolist_new_var_integer (ptr_item, "connection_timeout", IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_CONNECTION_TIMEOUT))) return 0; - if (!weechat_infolist_new_var_integer (ptr_item, "anti_flood_prio_high", - IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH))) - return 0; - if (!weechat_infolist_new_var_integer (ptr_item, "anti_flood_prio_low", - IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW))) + if (!weechat_infolist_new_var_integer (ptr_item, "anti_flood", + IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_ANTI_FLOOD))) return 0; if (!weechat_infolist_new_var_integer (ptr_item, "away_check", IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_AWAY_CHECK))) @@ -6920,8 +6953,6 @@ irc_server_add_to_infolist (struct t_infolist *infolist, return 0; if (!weechat_infolist_new_var_integer (ptr_item, "disable_autojoin", server->disable_autojoin)) return 0; - if (!weechat_infolist_new_var_time (ptr_item, "last_user_message", server->last_user_message)) - return 0; if (!weechat_infolist_new_var_time (ptr_item, "last_away_check", server->last_away_check)) return 0; if (!weechat_infolist_new_var_time (ptr_item, "last_data_purge", server->last_data_purge)) @@ -7185,20 +7216,13 @@ irc_server_print_log () else weechat_log_printf (" connection_timeout. . . . : %d", weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_CONNECTION_TIMEOUT])); - /* anti_flood_prio_high */ - if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH])) - weechat_log_printf (" anti_flood_prio_high. . . : null (%d)", - IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH)); - else - weechat_log_printf (" anti_flood_prio_high. . . : %d", - weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH])); - /* anti_flood_prio_low */ - if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW])) - weechat_log_printf (" anti_flood_prio_low . . . : null (%d)", - IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW)); + /* anti_flood */ + if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD])) + weechat_log_printf (" anti_flood. . . . . . . . : null (%d)", + IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_ANTI_FLOOD)); else - weechat_log_printf (" anti_flood_prio_low . . . : %d", - weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW])); + weechat_log_printf (" anti_flood. . . . . . . . : %d", + weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_ANTI_FLOOD])); /* away_check */ if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AWAY_CHECK])) weechat_log_printf (" away_check. . . . . . . . : null (%d)", @@ -7254,6 +7278,7 @@ irc_server_print_log () weechat_log_printf (" hook_fd . . . . . . . . . : 0x%lx", ptr_server->hook_fd); weechat_log_printf (" hook_timer_connection . . : 0x%lx", ptr_server->hook_timer_connection); weechat_log_printf (" hook_timer_sasl . . . . . : 0x%lx", ptr_server->hook_timer_sasl); + weechat_log_printf (" hook_timer_anti_flood . . : 0x%lx", ptr_server->hook_timer_anti_flood); weechat_log_printf (" sasl_scram_client_first . : '%s'", ptr_server->sasl_scram_client_first); weechat_log_printf (" sasl_scram_salted_pwd . . : (hidden)"); weechat_log_printf (" sasl_scram_salted_pwd_size: %d", ptr_server->sasl_scram_salted_pwd_size); @@ -7331,7 +7356,6 @@ irc_server_print_log () weechat_log_printf (" channels. . . . . . . . : 0x%lx", ptr_server->list->channels); weechat_log_printf (" filter_channels . . . . : 0x%lx", ptr_server->list->filter_channels); } - weechat_log_printf (" last_user_message . . . . : %lld", (long long)ptr_server->last_user_message); weechat_log_printf (" last_away_check . . . . . : %lld", (long long)ptr_server->last_away_check); weechat_log_printf (" last_data_purge . . . . . : %lld", (long long)ptr_server->last_data_purge); for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++) diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h index 2b6b652d7..1e807a186 100644 --- a/src/plugins/irc/irc-server.h +++ b/src/plugins/irc/irc-server.h @@ -83,8 +83,7 @@ enum t_irc_server_option IRC_SERVER_OPTION_AUTOREJOIN, /* auto rejoin channels when kicked */ IRC_SERVER_OPTION_AUTOREJOIN_DELAY, /* delay before auto rejoin */ IRC_SERVER_OPTION_CONNECTION_TIMEOUT, /* timeout for connection */ - IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_HIGH, /* anti-flood (high priority) */ - IRC_SERVER_OPTION_ANTI_FLOOD_PRIO_LOW, /* anti-flood (low priority) */ + IRC_SERVER_OPTION_ANTI_FLOOD, /* anti-flood (in ms) */ IRC_SERVER_OPTION_AWAY_CHECK, /* delay between away checks */ IRC_SERVER_OPTION_AWAY_CHECK_MAX_NICKS, /* max nicks for away check */ IRC_SERVER_OPTION_MSG_KICK, /* default kick message */ @@ -217,6 +216,7 @@ struct t_irc_server struct t_hook *hook_fd; /* hook for server socket */ struct t_hook *hook_timer_connection; /* timer for connection */ struct t_hook *hook_timer_sasl; /* timer for SASL authentication */ + struct t_hook *hook_timer_anti_flood; /* anti-flood timer */ char *sasl_scram_client_first; /* first message sent for SASL SCRAM */ char *sasl_scram_salted_pwd; /* salted password for SASL SCRAM */ int sasl_scram_salted_pwd_size; /* size of salted password for SASL SCRAM*/ @@ -282,7 +282,6 @@ struct t_irc_server time_t lag_last_refresh; /* last refresh of lag item */ regex_t *cmd_list_regexp; /* compiled Regular Expression for /list */ struct t_irc_list *list; /* /list buffer management */ - time_t last_user_message; /* time of last user message (anti flood)*/ time_t last_away_check; /* time of last away check on server */ time_t last_data_purge; /* time of last purge (some hashtables) */ struct t_irc_outqueue *outqueue[IRC_SERVER_NUM_OUTQUEUES_PRIO]; @@ -413,6 +412,8 @@ extern int irc_server_send_signal (struct t_irc_server *server, const char *full_message, const char *tags); extern void irc_server_set_send_default_tags (const char *tags); +extern void irc_server_outqueue_timer_remove (struct t_irc_server *server); +extern void irc_server_outqueue_timer_add (struct t_irc_server *server); extern struct t_arraylist *irc_server_sendf (struct t_irc_server *server, int flags, const char *tags, diff --git a/src/plugins/irc/irc-upgrade.c b/src/plugins/irc/irc-upgrade.c index fa82d20e8..8745477d1 100644 --- a/src/plugins/irc/irc-upgrade.c +++ b/src/plugins/irc/irc-upgrade.c @@ -663,7 +663,6 @@ irc_upgrade_read_cb (const void *pointer, void *data, memcpy (&(irc_upgrade_current_server->lag_check_time), buf, size); irc_upgrade_current_server->lag_next_check = weechat_infolist_time (infolist, "lag_next_check"); irc_upgrade_current_server->lag_last_refresh = weechat_infolist_time (infolist, "lag_last_refresh"); - irc_upgrade_current_server->last_user_message = weechat_infolist_time (infolist, "last_user_message"); irc_upgrade_current_server->last_away_check = weechat_infolist_time (infolist, "last_away_check"); irc_upgrade_current_server->last_data_purge = weechat_infolist_time (infolist, "last_data_purge"); } |