diff --git a/src/irc/core/irc-servers.c b/src/irc/core/irc-servers.c index be6e1229..1fc7faaa 100644 --- a/src/irc/core/irc-servers.c +++ b/src/irc/core/irc-servers.c @@ -297,6 +297,28 @@ static void sig_server_quit(IRC_SERVER_REC *server, const char *msg) g_free(str); } +void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len) +{ + if (net_sendbuffer_send(server->handle, data, len) == -1) { + /* something bad happened */ + server->connection_lost = TRUE; + return; + } + + g_get_current_time(&server->last_cmd); + + /* A bit kludgy way to do the flood protection. In ircnet, there + actually is 1sec / 100 bytes penalty, but we rather want to deal + with the max. 1000 bytes input buffer problem. If we send more + than that with the burst, we'll get excess flooded. */ + if (len < 100) + server->wait_cmd.tv_sec = 0; + else { + memcpy(&server->wait_cmd, &server->last_cmd, sizeof(GTimeVal)); + server->wait_cmd.tv_sec += 2 + len/100; + } +} + static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) { REDIRECT_REC *redirect; @@ -321,20 +343,13 @@ static void server_cmd_timeout(IRC_SERVER_REC *server, GTimeVal *now) server->cmdcount--; if (server->cmdqueue == NULL) return; - /* send command */ + /* get command */ cmd = server->cmdqueue->data; redirect = server->cmdqueue->next->data; + + /* send command */ len = strlen(cmd); - - if (net_sendbuffer_send(server->handle, cmd, len) == -1) { - /* something bad happened */ - g_warning("net_sendbuffer_send() failed: %s", - g_strerror(errno)); - return; - } - - server->wait_cmd.tv_sec = 0; - memcpy(&server->last_cmd, now, sizeof(GTimeVal)); + irc_server_send_data(server, cmd, len); /* add to rawlog without [CR+]LF (/RAWQUOTE might not have added the CR) */ diff --git a/src/irc/core/irc-servers.h b/src/irc/core/irc-servers.h index b0cd84b5..f6ee1821 100644 --- a/src/irc/core/irc-servers.h +++ b/src/irc/core/irc-servers.h @@ -106,6 +106,9 @@ void irc_server_purge_output(IRC_SERVER_REC *server, const char *target); like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */ char *irc_server_get_channels(IRC_SERVER_REC *server); +/* INTERNAL: */ +void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len); + void irc_servers_init(void); void irc_servers_deinit(void); diff --git a/src/irc/core/irc.c b/src/irc/core/irc.c index 88816404..d7afaa23 100644 --- a/src/irc/core/irc.c +++ b/src/irc/core/irc.c @@ -82,13 +82,7 @@ void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd, } if (send_now) { - if (net_sendbuffer_send(server->handle, cmd, len) == -1) { - /* something bad happened */ - server->connection_lost = TRUE; - return; - } - - g_get_current_time(&server->last_cmd); + irc_server_send_data(server, cmd, len); return; }