Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send channel sync requests "later" in the command queue #26

Merged
merged 3 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */

#define IRSSI_ABI_VERSION 40
#define IRSSI_ABI_VERSION 41

#define DEFAULT_SERVER_ADD_PORT 6667
#define DEFAULT_SERVER_ADD_TLS_PORT 6697
Expand Down
17 changes: 11 additions & 6 deletions src/irc/core/channels-query.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
/* here are the WHOX commands we send. the full spec can be found on [1].

(1) WHOX_CHANNEL_FULL_CMD for getting the user list when we join a channel. we request the fields
c (channel), u (user), h (host), n (nick), f (flags), d (hops), a (important, account!), and
r (the real name goes last because it os the only that can contain spaces.) we request all
those fields as they are also included in the "regular" WHO reply we would get without WHOX.
c (channel), u (user), h (host), n (nick), f (flags), d (hops), a (account), and r (the real
name goes last because it is the only that can contain spaces.) we request all those fields
as they are also included in the "regular" WHO reply we would get without WHOX.

(2) WHOX_USERACCOUNT_CMD for getting the account names of people that joined. this code is
obviously only used when we don't have extended-joins. we request n (nick) and a (account)
Expand Down Expand Up @@ -265,7 +265,7 @@ static void query_send(IRC_SERVER_REC *server, int query)
cmd = NULL;
}

irc_send_cmd(server, cmd);
irc_send_cmd_later(server, cmd);

g_free(chanstr);
g_free(chanstr_commas);
Expand Down Expand Up @@ -440,6 +440,7 @@ void irc_channels_query_purge_accountquery(IRC_SERVER_REC *server, const char *n
g_free(cmd);

server->cmdcount--;
server->cmdlater--;
} else {
prev = tmp->next;
}
Expand Down Expand Up @@ -528,7 +529,10 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char
}

if (g_hash_table_size(chanrec->nicks) < settings_get_int("channel_max_who_sync") &&
server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL) {
server->isupport != NULL && g_hash_table_lookup(server->isupport, "whox") != NULL &&
server->split_servers == NULL &&
g_hash_table_size(server->chanqueries->accountqueries) <
settings_get_int("account_max_chase")) {
char *cmd;
server_redirect_event(server, "who user", 1, nick, -1,
"chanquery useraccount abort", /* failure signal */
Expand All @@ -538,7 +542,7 @@ static void sig_event_join(IRC_SERVER_REC *server, const char *data, const char
cmd = g_strdup_printf(WHOX_USERACCOUNT_CMD, nick);
g_hash_table_add(server->chanqueries->accountqueries, g_strdup(nick));
/* queue the command */
irc_send_cmd_full(server, cmd, FALSE, FALSE, FALSE);
irc_send_cmd_later(server, cmd);
g_free(cmd);
}
}
Expand Down Expand Up @@ -635,6 +639,7 @@ void channels_query_init(void)
{
settings_add_bool("misc", "channel_sync", TRUE);
settings_add_int("misc", "channel_max_who_sync", 1000);
settings_add_int("misc", "account_max_chase", 10);

signal_add("server connected", (SIGNAL_FUNC) sig_connected);
signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
Expand Down
1 change: 1 addition & 0 deletions src/irc/core/irc-servers.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct _IRC_SERVER_REC {
there actually is, to make flood control remember
how many messages can be sent before starting the
flood control */
int cmdlater; /* number of commands in queue to be sent later */
GSList *cmdqueue; /* command, redirection, ... */
gint64 wait_cmd; /* don't send anything to server before this */
gint64 last_cmd; /* last time command was sent to server */
Expand Down
59 changes: 37 additions & 22 deletions src/irc/core/irc.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ static void strip_params_colon(char *const);
/* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd'
won't be checked at all if it's 512 bytes or not, or if it contains
line feeds or not. Use with extreme caution! */
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
int send_now, int immediate, int raw)
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_when, int raw)
{
GString *str;
int len;
Expand All @@ -65,6 +64,8 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,

if (server->cmdcount == 0)
irc_servers_start_cmd_timeout();
if (server->cmdlater > server->cmdcount)
server->cmdlater = server->cmdcount;
server->cmdcount++;

if (!raw) {
Expand Down Expand Up @@ -105,7 +106,7 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
g_string_append(str, cmd);
}

if (send_now) {
if (irc_send_when == IRC_SEND_NOW) {
rawlog_output(server->rawlog, str->str);
server_redirect_command(server, str->str, server->redirect_next);
server->redirect_next = NULL;
Expand All @@ -117,25 +118,31 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
g_string_append_c(str, 10);
}

if (send_now) {
irc_server_send_data(server, str->str, str->len);
if (irc_send_when == IRC_SEND_NOW) {
irc_server_send_data(server, str->str, str->len);
g_string_free(str, TRUE);
} else {

} else if (irc_send_when == IRC_SEND_NEXT) {
/* add to queue */
if (immediate) {
server->cmdqueue = g_slist_prepend(server->cmdqueue,
server->redirect_next);
server->cmdqueue = g_slist_prepend(server->cmdqueue,
g_string_free(str, FALSE));
} else {
server->cmdqueue = g_slist_append(server->cmdqueue,
g_string_free(str, FALSE));
server->cmdqueue = g_slist_append(server->cmdqueue,
server->redirect_next);
}
server->cmdqueue = g_slist_prepend(server->cmdqueue, server->redirect_next);
server->cmdqueue = g_slist_prepend(server->cmdqueue, g_string_free(str, FALSE));
} else if (irc_send_when == IRC_SEND_NORMAL) {
guint pos = g_slist_length(server->cmdqueue);
if (pos > 2 * server->cmdlater)
pos -= 2 * server->cmdlater;
else
pos = 0;

server->cmdqueue = g_slist_insert(server->cmdqueue, server->redirect_next, pos);
server->cmdqueue = g_slist_insert(server->cmdqueue, g_string_free(str, FALSE), pos);
} else if (irc_send_when == IRC_SEND_LATER) {
server->cmdqueue = g_slist_append(server->cmdqueue, g_string_free(str, FALSE));
server->cmdqueue = g_slist_append(server->cmdqueue, server->redirect_next);
server->cmdlater++;
} else {
g_warn_if_reached();
}
server->redirect_next = NULL;

server->redirect_next = NULL;
}

/* Send command to IRC server */
Expand All @@ -149,7 +156,7 @@ void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd)
(server->cmdcount < server->max_cmds_at_once ||
server->cmd_queue_speed <= 0);

irc_send_cmd_full(server, cmd, send_now, FALSE, FALSE);
irc_send_cmd_full(server, cmd, send_now ? IRC_SEND_NOW : IRC_SEND_NORMAL, FALSE);
}

/* Send command to IRC server */
Expand All @@ -173,7 +180,7 @@ void irc_send_cmd_now(IRC_SERVER_REC *server, const char *cmd)
{
g_return_if_fail(cmd != NULL);

irc_send_cmd_full(server, cmd, TRUE, TRUE, FALSE);
irc_send_cmd_full(server, cmd, IRC_SEND_NOW, FALSE);
}

/* Send command to server putting it at the beginning of the queue of
Expand All @@ -183,7 +190,15 @@ void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd)
{
g_return_if_fail(cmd != NULL);

irc_send_cmd_full(server, cmd, FALSE, TRUE, FALSE);
irc_send_cmd_full(server, cmd, IRC_SEND_NEXT, FALSE);
}

/* Send command to server putting it at the end of the queue. */
void irc_send_cmd_later(IRC_SERVER_REC *server, const char *cmd)
{
g_return_if_fail(cmd != NULL);

irc_send_cmd_full(server, cmd, IRC_SEND_LATER, FALSE);
}

static char *split_nicks(const char *cmd, char **pre, char **nicks, char **post, int arg)
Expand Down
12 changes: 10 additions & 2 deletions src/irc/core/irc.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ typedef struct _REDIRECT_REC REDIRECT_REC;

extern char *current_server_event; /* current server event being processed */

enum {
IRC_SEND_NOW, /* */
IRC_SEND_NEXT,
IRC_SEND_NORMAL,
IRC_SEND_LATER
};

/* Send command to IRC server */
void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd);
void irc_send_cmdv(IRC_SERVER_REC *server, const char *cmd, ...) G_GNUC_PRINTF (2, 3);
Expand All @@ -42,11 +49,12 @@ void irc_send_cmd_now(IRC_SERVER_REC *server, const char *cmd);
commands to send -- it will go out as soon as possible in accordance
to the flood protection settings. */
void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd);
/* Send command to server putting it at the end of the queue. */
void irc_send_cmd_later(IRC_SERVER_REC *server, const char *cmd);
/* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd'
won't be checked at all if it's 512 bytes or not, or if it contains
line feeds or not. Use with extreme caution! */
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
int send_now, int immediate, int raw);
void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, int irc_send_when, int raw);

/* Extract a tag value from tags */
GHashTable *irc_parse_message_tags(const char *tags);
Expand Down
6 changes: 4 additions & 2 deletions src/irc/notifylist/notify-ison.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static void ison_send(IRC_SERVER_REC *server, GString *cmd)

server_redirect_event(server, "ison", 1, NULL, -1, NULL,
"event 303", "notifylist event", NULL);
irc_send_cmd(server, cmd->str);
irc_send_cmd_later(server, cmd->str);

g_string_truncate(cmd, 0);
}
Expand Down Expand Up @@ -183,7 +183,9 @@ static void whois_send(IRC_SERVER_REC *server, const char *nicks,
"", "event empty", NULL);
g_free(str);

irc_send_cmdv(server, "WHOIS %s", whois_request);
str = g_strdup_printf("WHOIS %s", whois_request);
irc_send_cmd_later(server, str);
g_free(str);
}

static void whois_send_server(IRC_SERVER_REC *server, char *nick)
Expand Down
7 changes: 7 additions & 0 deletions src/perl/irc/Server.xs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ send_raw_first(server, cmd)
CODE:
irc_send_cmd_first(server, cmd);

void
send_raw_later(server, cmd)
Irssi::Irc::Server server
char *cmd
CODE:
irc_send_cmd_later(server, cmd);

void
send_raw_split(server, cmd, nickarg, max_nicks)
Irssi::Irc::Server server
Expand Down