Sun Aug 24 12:58:30 CEST 2003 Jochen Eisinger <c0ffee@penguin-breeder.org>
authorJochen Eisinger <coffee@silcnet.org>
Sun, 24 Aug 2003 11:03:33 +0000 (11:03 +0000)
committerJochen Eisinger <coffee@silcnet.org>
Sun, 24 Aug 2003 11:03:33 +0000 (11:03 +0000)
* Use SILC_COMMAND_PING to estimate the round-trip time to the
  server. Use this time to display a lag and disconnect when it
  exceeds a specified limit.

  Affected files are irssi/src/silc/core/silc-{lag,core}.c.

CHANGES
apps/irssi/src/silc/core/Makefile.am
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-lag.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index f9414e3cd93dd70bce64bddd7cdc420fe07895f7..da247f3cdd3b5fb2541c8bc58907e766cab69902 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+Sun Aug 24 12:58:30 CEST 2003  Jochen Eisinger <c0ffee@penguin-breeder.org>
+
+       * Use SILC_COMMAND_PING to estimate the round-trip time to the
+         server. Use this time to display a lag and disconnect when it
+         exceeds a specified limit.
+
+         Affected files are irssi/src/silc/core/silc-{lag,core}.c.
+
 Thu Apr 24 19:50:25 EEST 2003  Pekka Riikonen <priikone@silcnet.org>
 
        * Deny '@' and '!' from nicknames since they are reserved
index 006178be04b154c42d9eeac195a41d68019c63c6..98f3398f0b3c3f717bfdc9b85ee67b8e290132dc 100644 (file)
@@ -22,7 +22,8 @@ libsilc_core_a_SOURCES = \
        silc-queries.c \
        silc-servers.c \
        silc-expandos.c \
-       silc-servers-reconnect.c
+       silc-servers-reconnect.c \
+       silc-lag.c
 
 noinst_HEADERS = \
        module.h \
@@ -33,5 +34,5 @@ noinst_HEADERS = \
        silc-nicklist.h \
        silc-commands.h \
        silc-queries.h \
-       silc-servers.h
+       silc-servers.h 
 
index bf572810b301fbd6dd4d3dbdc54a2d3f114693a2..421fe6fc5874bd4ef432666f32c78bf229c94d53 100644 (file)
@@ -52,6 +52,9 @@ extern bool silc_debug_hexdump;
 void silc_expandos_init(void);
 void silc_expandos_deinit(void);
 
+void silc_lag_init(void);
+void silc_lag_deinit(void);
+
 static int my_silc_scheduler(void)
 {
   silc_client_run_one(silc_client);
@@ -478,6 +481,7 @@ void silc_core_init(void)
   silc_channels_init();
   silc_queries_init();
   silc_expandos_init();
+  silc_lag_init();
 
   idletag = g_timeout_add(5, (GSourceFunc) my_silc_scheduler, NULL);
 
@@ -498,6 +502,7 @@ void silc_core_deinit(void)
     silc_channels_deinit();
     silc_queries_deinit();
     silc_expandos_deinit();
+    silc_lag_deinit();
     
     chat_protocol_unregister("SILC");
     
diff --git a/apps/irssi/src/silc/core/silc-lag.c b/apps/irssi/src/silc/core/silc-lag.c
new file mode 100644 (file)
index 0000000..1c5ad51
--- /dev/null
@@ -0,0 +1,106 @@
+#include "module.h"
+#include "signals.h"
+#include "misc.h"
+#include "settings.h"
+
+#include "silc-servers.h"
+
+#define        SILC_CLIENT_LAG_PING_ID 0x1337
+
+static int timeout_tag;
+static void lag_event_pong(SILC_SERVER_REC *server, 
+               SilcClientCommandReplyContext cmd);
+
+static void lag_get(SILC_SERVER_REC *server)
+{
+       SilcBuffer idp;
+       g_get_current_time(&server->lag_sent);
+       server->lag_last_check = time(NULL);
+
+       /* register pending callback & send ping */
+       silc_client_command_pending(server->conn, SILC_COMMAND_PING,
+                       SILC_CLIENT_LAG_PING_ID,
+                       (SilcCommandCb)lag_event_pong, (void *)server);
+       idp = silc_id_payload_encode(server->conn->remote_id, SILC_ID_SERVER);
+       silc_client_command_send(silc_client, server->conn,
+                       SILC_COMMAND_PING, SILC_CLIENT_LAG_PING_ID,
+                       1, 1, idp->data, idp->len);
+       silc_buffer_free(idp);
+}
+
+static void lag_event_pong(SILC_SERVER_REC *server,
+                          SilcClientCommandReplyContext cmd)
+{
+       GTimeVal now;
+
+       if (cmd->error != SILC_STATUS_OK) {
+
+               /* if the ping failed for some reason, try it again */
+               lag_get(server);
+               return;
+
+       }
+
+       if (server->lag_sent.tv_sec == 0) {
+               /* not expecting lag reply.. */
+               return;
+       }
+
+       g_get_current_time(&now);
+       server->lag = (int) get_timeval_diff(&now, &server->lag_sent);
+       memset(&server->lag_sent, 0, sizeof(server->lag_sent));
+
+       signal_emit("server lag", 1, server);
+}
+
+static int sig_check_lag(void)
+{
+       GSList *tmp, *next;
+       time_t now;
+       int lag_check_time, max_lag;
+
+       lag_check_time = settings_get_int("lag_check_time");
+       max_lag = settings_get_int("lag_max_before_disconnect");
+
+       if (lag_check_time <= 0)
+               return 1;
+
+       now = time(NULL);
+       for (tmp = servers; tmp != NULL; tmp = next) {
+               SILC_SERVER_REC *rec = tmp->data;
+
+               next = tmp->next;
+               if (!IS_SILC_SERVER(rec))
+                       continue;
+
+               if (rec->lag_sent.tv_sec != 0) {
+                       /* waiting for lag reply */
+                       if (max_lag > 1 && now-rec->lag_sent.tv_sec > max_lag) {
+                               /* too much lag, disconnect */
+                               signal_emit("server lag disconnect", 1, rec);
+                               rec->connection_lost = TRUE;
+                               server_disconnect((SERVER_REC *) rec);
+                       }
+               } else if (rec->lag_last_check+lag_check_time < now &&
+                        rec->cmdcount == 0 && rec->connected) {
+                       /* no commands in buffer - get the lag */
+                       lag_get(rec);
+               }
+       }
+
+       return 1;
+}
+
+void silc_lag_init(void)
+{
+       /* silc-client will need those... silc-plugin uses irc defaults */
+       settings_add_int("misc", "lag_check_time", 60);
+       settings_add_int("misc", "lag_max_before_disconnect", 300); 
+
+       timeout_tag = g_timeout_add(1000, (GSourceFunc) sig_check_lag, NULL);
+}
+
+void silc_lag_deinit(void)
+{
+       g_source_remove(timeout_tag);
+}