diff --git a/Changelog b/Changelog index e5dbe10..94b8fd7 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,8 @@ [Changes 1.2.2] +* Rework the lag check to make it simpler and more reliable. This adds + a /set LAG_CHECK_INTERVAL to control the frequency of lag checks. (caf) + * Wire up /set DOUBLE_STATUS_LINE (reported by presi). (caf) * Fix ignoring of nick changes. (caf) diff --git a/include/config.h b/include/config.h index e63c6f8..3773819 100644 --- a/include/config.h +++ b/include/config.h @@ -561,7 +561,7 @@ #define DEFAULT_XTERM "rxvt" #define DEFAULT_XTERM_OPTIONS "-bg black -fg white" #define DEFAULT_DCC_DLDIR "~" - +#define DEFAULT_LAG_CHECK_INTERVAL 30 /* Time between lag check pings, in seconds */ #define DEFAULT_PAD_CHAR ' ' #define DEFAULT_USERMODE "+iw" /* change this to the default usermode */ #define DEFAULT_OPERMODE "swfck" diff --git a/include/server.h b/include/server.h index 26b083c..d9bc72f 100644 --- a/include/server.h +++ b/include/server.h @@ -94,7 +94,8 @@ typedef struct int sent; /* set if something has been sent, * used for redirect */ int lag; /* indication of lag from server CDE*/ - time_t lag_time; /* time ping sent to server CDE */ + struct timeval lag_sent; /* time lag ping sent to server CDE */ + struct timeval lag_recv; /* time last lag ping reply was recieved */ unsigned long lag_cookie; /* cookie to identify our lag check pings */ time_t last_msg; /* last mesg recieved from the server CDE */ @@ -237,9 +238,7 @@ extern SGroup *server_group_list; int BX_get_server_lag (int); void BX_set_server_lag (int, int); - time_t get_server_lagtime (int); - void set_server_lagtime (int, time_t); - unsigned long get_server_lag_cookie(int gso_index); + void server_lag_reply(int s, unsigned long cookie, struct timeval lag_recv, struct timeval lag_sent); char *BX_set_server_password (int, char *); void BX_set_server_nickname (int, char *); @@ -365,7 +364,6 @@ ChannelList *BX_get_server_channels (int); void reconnect_server(int *, int *, time_t *); int finalize_server_connect(int, int, int); int next_server(int); - int check_serverlag (void); void do_idle_server (void); /* XXXXX ick, gross, bad. XXXXX */ diff --git a/include/vars.h b/include/vars.h index f2a7c65..0a49157 100644 --- a/include/vars.h +++ b/include/vars.h @@ -163,6 +163,7 @@ enum VAR_TYPES { KICK_ON_NICKFLOOD_VAR , KICK_ON_PUBFLOOD_VAR , KICK_OPS_VAR , + LAG_CHECK_INTERVAL_VAR, LAMEIDENT_VAR, LAMELIST_VAR, LASTLOG_VAR , diff --git a/source/irc.c b/source/irc.c index ad56794..b0338a4 100644 --- a/source/irc.c +++ b/source/irc.c @@ -335,8 +335,6 @@ char *BX_update_clock(int flag) } check_channel_limits(); } - if (!((hideous - start_time) % 20)) - check_serverlag(); from_server = ofs; if (flag != RESET_TIME || new_minute) return time_str; diff --git a/source/parse.c b/source/parse.c index 9fd730b..223331c 100644 --- a/source/parse.c +++ b/source/parse.c @@ -856,35 +856,25 @@ static void p_pong(char *from, char **ArgList) char *p, *q; unsigned long cookie; struct timeval timenow, timethen; - int old_lag, new_lag; + get_time(&timenow); p = strchr(ArgList[1], '.'); if (p) { *p++ = 0; cookie = strtoul(ArgList[1] + 4, NULL, 10); - if (cookie == get_server_lag_cookie(from_server)) + q = strchr(p, '.'); + if (q) { - q = strchr(p, '.'); - if (q) - { - *q++ = 0; - timethen.tv_usec = my_atol(q); - } else - timethen.tv_usec = 0; + *q++ = 0; + timethen.tv_usec = my_atol(q); + } else + timethen.tv_usec = 0; - timethen.tv_sec = my_atol(p); - get_time(&timenow); + timethen.tv_sec = my_atol(p); - old_lag = get_server_lag(from_server); - new_lag = (int)(BX_time_diff(timethen, timenow) + 0.5); - if (old_lag != new_lag) - { - set_server_lag(from_server, new_lag); - status_update(1); - } - } + server_lag_reply(from_server, cookie, timenow, timethen); } } else if (!my_stricmp(ArgList[1], get_server_nickname(from_server))) diff --git a/source/server.c b/source/server.c index 46246c5..e8ebe2c 100644 --- a/source/server.c +++ b/source/server.c @@ -129,6 +129,7 @@ void BX_close_server (int cs_index, char *message) server_list[cs_index].server_change_pending = 0; server_list[cs_index].operator = 0; server_list[cs_index].connected = 0; + server_list[cs_index].lag = -1; server_list[cs_index].buffer = NULL; server_list[cs_index].link_look = 0; server_list[cs_index].login_flags = 0; @@ -241,6 +242,26 @@ void set_server_bits (fd_set *rd, fd_set *wr, struct timeval *wake_time) if (time_cmp(wake_time, &connect_wake_time) > 0) *wake_time = connect_wake_time; } + if (is_server_connected(i)) + { + /* Time to send another ping */ + int lag_check_interval = get_int_var(LAG_CHECK_INTERVAL_VAR); + struct timeval lag_wake_time = server_list[i].lag_sent; + lag_wake_time.tv_sec += lag_check_interval; + + if (lag_check_interval > 0 && time_cmp(wake_time, &lag_wake_time) > 0) + *wake_time = lag_wake_time; + + if (server_list[i].lag != -1) + { + /* Time that previous lag value becomes stale */ + lag_wake_time = server_list[i].lag_recv; + lag_wake_time.tv_sec += lag_check_interval + 1; + + if (time_cmp(wake_time, &lag_wake_time) > 0) + *wake_time = lag_wake_time; + } + } if (server_list[i].read > -1) FD_SET(server_list[i].read, rd); @@ -410,28 +431,6 @@ static void scan_nonblocking(void) } #endif -int check_serverlag(void) -{ - int i; - struct timeval tv; - - get_time(&tv); - - for (i = 0; i < server_list_size(); i++) - { - if (is_server_connected(i) && now != get_server_lagtime(i)) - { - set_server_lagtime(i, now); - my_send_to_server(i, "PING LAG!%lu.%ld.%ld :%s", - get_server_lag_cookie(i), - (long)tv.tv_sec, (long)tv.tv_usec, get_server_itsname(i)); - set_server_lag(i, -1); - } - } - - return 0; -} - void do_idle_server (void) { int i; @@ -445,7 +444,7 @@ void do_idle_server (void) for (i = 0; i < number_of_servers && i > -1; i++) { /* We were told to reconnect, to avoid recursion. */ - if(get_server_reconnect(i) > 0) + if (get_server_reconnect(i) > 0) { int connect_delay = get_int_var(CONNECT_DELAY_VAR); @@ -457,6 +456,29 @@ void do_idle_server (void) reconnect_server(&servernum, ×, &last_timeout); } } + + if (is_server_connected(i)) + { + int lag_check_interval = get_int_var(LAG_CHECK_INTERVAL_VAR); + + if (lag_check_interval > 0 && + time_since(&server_list[i].lag_sent) > lag_check_interval) + { + get_time(&server_list[i].lag_sent); + my_send_to_server(i, "PING LAG!%lu.%ld.%ld :%s", + server_list[i].lag_cookie, + (long)server_list[i].lag_sent.tv_sec, + (long)server_list[i].lag_sent.tv_usec, + get_server_itsname(i)); + } + if (server_list[i].lag != -1 && + time_since(&server_list[i].lag_recv) > lag_check_interval + 1) + { + /* Lag reply overdue */ + set_server_lag(i, -1); + update_all_status(current_window, NULL, 0); + } + } } } @@ -475,29 +497,13 @@ void do_server (fd_set *rd, fd_set *wr) char buffer[BIG_BUFFER_SIZE + 1]; int des, i; - static int times = 1; static time_t last_timeout = 0; -#ifdef NON_BLOCKING_CONNECTS - scan_nonblocking(); -#endif + /* Process server timeouts */ + do_idle_server(); for (i = 0; i < number_of_servers; i++) { - /* We were told to reconnect, to avoid recursion. */ - if(get_server_reconnect(i) > 0) - { - int connect_delay = get_int_var(CONNECT_DELAY_VAR); - - if (time_since(&server_list[i].connect_time) > connect_delay) - { - int servernum = i; - - set_server_reconnect(i, 0); - reconnect_server(&servernum, ×, &last_timeout); - } - } - #ifdef NON_BLOCKING_CONNECTS if (((des = server_list[i].write) > -1) && FD_ISSET(des, wr) && !(server_list[i].login_flags & LOGGED_IN)) { @@ -638,6 +644,25 @@ static time_t last_timeout = 0; window_check_servers(-1); } +/* server_lag_reply() + * + * Called when a reply to a lag check ping has been recieved. + */ +void server_lag_reply(int s, unsigned long cookie, struct timeval lag_recv, struct timeval lag_sent) +{ + if (cookie == server_list[s].lag_cookie) + { + int new_lag = (int)(BX_time_diff(lag_sent, lag_recv) + 0.5); + + server_list[s].lag_recv = lag_recv; + if (server_list[s].lag != new_lag) + { + server_list[s].lag = new_lag; + update_all_status(current_window, NULL, 0); + } + } +} + /* * find_in_server_list: given a server name, this tries to match it against * names in the server list, returning the index into the list if found, or @@ -2367,26 +2392,6 @@ void BX_set_server_lag (int gso_index, int secs) server_list[gso_index].lag = secs; } -time_t get_server_lagtime (int gso_index) -{ - if ((gso_index < 0 || gso_index >= number_of_servers)) - return 0; - return(server_list[gso_index].lag_time); -} - -void set_server_lagtime (int gso_index, time_t secs) -{ - if ((gso_index != -1 && gso_index < number_of_servers)) - server_list[gso_index].lag_time = secs; -} - -unsigned long get_server_lag_cookie(int gso_index) -{ - if ((gso_index < 0 || gso_index >= number_of_servers)) - return 0; - return server_list[gso_index].lag_cookie; -} - int BX_get_server_motd (int gsm_index) { if (gsm_index != -1 && gsm_index < number_of_servers) @@ -2401,7 +2406,10 @@ void BX_server_is_connected (int sic_index, int value) server_list[sic_index].connected = value; if (value) + { server_list[sic_index].eof = 0; + get_time(&server_list[sic_index].lag_sent); + } } void set_server_version_string (int servnum, const char *ver) diff --git a/source/vars.c b/source/vars.c index ec0404e..1ef84e0 100644 --- a/source/vars.c +++ b/source/vars.c @@ -266,6 +266,7 @@ static IrcVariable irc_variable[] = { "KICK_ON_NICKFLOOD",0, INT_TYPE_VAR, DEFAULT_KICK_ON_NICKFLOOD, NULL, NULL, 0, VIF_BITCHX }, { "KICK_ON_PUBFLOOD",0, INT_TYPE_VAR, DEFAULT_KICK_ON_PUBFLOOD, NULL, NULL, 0, VIF_BITCHX }, { "KICK_OPS",0, BOOL_TYPE_VAR, DEFAULT_KICK_OPS, NULL, NULL, 0, VIF_BITCHX }, + { "LAG_CHECK_INTERVAL",0, INT_TYPE_VAR, DEFAULT_LAG_CHECK_INTERVAL, NULL, NULL, 0, VIF_BITCHX }, { "LAMEIDENT",0, BOOL_TYPE_VAR, DEFAULT_LAME_IDENT, NULL, NULL, 0, VIF_BITCHX }, { "LAMELIST",0, BOOL_TYPE_VAR, DEFAULT_LAMELIST, NULL, NULL, 0, VIF_BITCHX }, { "LASTLOG",0, INT_TYPE_VAR, DEFAULT_LASTLOG, NULL, set_lastlog_size, 0, 0 },