Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2002:
[Freeciv-Dev] Re: (PR#2278) Ping version 12
Home

[Freeciv-Dev] Re: (PR#2278) Ping version 12

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] Re: (PR#2278) Ping version 12
From: "Raimar Falke via RT" <rt@xxxxxxxxxxxxxx>
Date: Sat, 9 Nov 2002 04:43:17 -0800
Reply-to: rt@xxxxxxxxxxxxxx

On Sat, Nov 09, 2002 at 02:44:55AM -0800, Raimar Falke via RT wrote:
> 
> 
> This is an updated version of the ping patch from Thomas. Changes:
>  - cleanup of the packets
>  - remove the timing.[ch] changes
>  - adding the pingtime server option
>  - a lot of other cleanups

Version 12:
 - proper initialization of ping_time
 - check for ping_time==-1
 - send the ping_info packet only every game.ping_time seconds
 - move ping_text construction into plrdlg_common

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Programming today is a race between software engineers striving to
  build bigger and better idiot-proof programs, and the Universe trying
  to produce bigger and better idiots. So far, the Universe is winning."
    -- Rich Cook

Index: client/civclient.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v
retrieving revision 1.149
diff -u -r1.149 civclient.c
--- client/civclient.c  9 Oct 2002 13:39:47 -0000       1.149
+++ client/civclient.c  9 Nov 2002 12:38:52 -0000
@@ -456,6 +456,10 @@
     handle_thaw_hint();
     break;
 
+  case PACKET_PING_INFO:
+    handle_ping_info((struct packet_ping_info *) packet);
+    break;
+
   default:
     freelog(LOG_ERROR, "Received unknown packet (type %d) from server!", type);
     /* Old clients (<= some 1.11.5-devel, capstr +1.11) used to exit()
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.259
diff -u -r1.259 packhand.c
--- client/packhand.c   7 Nov 2002 18:55:24 -0000       1.259
+++ client/packhand.c   9 Nov 2002 12:38:57 -0000
@@ -1291,6 +1291,7 @@
       pconn = fc_calloc(1, sizeof(struct connection));
       pconn->buffer = NULL;
       pconn->send_buffer = NULL;
+      pconn->ping_time = -1.0;
       if (pplayer) {
        conn_list_insert_back(&pplayer->connections, pconn);
       }
@@ -1317,6 +1318,27 @@
     sz_strlcpy(pconn->name, pinfo->name);
     sz_strlcpy(pconn->addr, pinfo->addr);
     sz_strlcpy(pconn->capability, pinfo->capability);
+  }
+  update_players_dialog();
+}
+
+/*************************************************************************
+...
+**************************************************************************/
+void handle_ping_info(struct packet_ping_info *packet)
+{
+  int i;
+
+  for (i = 0; i < packet->connections; i++) {
+    struct connection *pconn = find_conn_by_id(packet->conn_id[i]);
+
+    if (!pconn) {
+      continue;
+    }
+
+    pconn->ping_time = packet->ping_time[i];
+    freelog(LOG_DEBUG, "conn-id=%d, ping=%fs", pconn->id,
+           pconn->ping_time);
   }
   update_players_dialog();
 }
Index: client/packhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.h,v
retrieving revision 1.29
diff -u -r1.29 packhand.h
--- client/packhand.h   10 Sep 2002 14:01:06 -0000      1.29
+++ client/packhand.h   9 Nov 2002 12:38:57 -0000
@@ -20,6 +20,7 @@
 void handle_tile_info(struct packet_tile_info *packet);
 void handle_player_info(struct packet_player_info *pinfo);
 void handle_conn_info(struct packet_conn_info *pinfo);
+void handle_ping_info(struct packet_ping_info *packet);
 void handle_game_info(struct packet_game_info *pinfo);
 void handle_map_info(struct packet_map_info *pinfo);
 void handle_select_nation(struct packet_nations_used *packet);
Index: client/plrdlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/plrdlg_common.c,v
retrieving revision 1.1
diff -u -r1.1 plrdlg_common.c
--- client/plrdlg_common.c      27 Jun 2002 01:00:49 -0000      1.1
+++ client/plrdlg_common.c      9 Nov 2002 12:38:58 -0000
@@ -10,9 +10,17 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 ***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <assert.h>
 
+#include "connection.h"
+#include "fcintl.h"
+#include "game.h"
+#include "support.h"
+
 #include "plrdlg_g.h"
 
 #include "plrdlg_common.h"
@@ -54,4 +62,25 @@
 bool is_plrdlg_frozen(void)
 {
   return frozen_level > 0;
+}
+
+/******************************************************************
+ ...
+*******************************************************************/
+const char *get_ping_time_text(struct player *pplayer)
+{
+  static char buffer[32];
+
+  if (conn_list_size(&pplayer->connections) > 0
+      && conn_list_get(&pplayer->connections, 0)->ping_time != -1.0) {
+    double ping_time_in_ms =
+       1000 * conn_list_get(&pplayer->connections, 0)->ping_time;
+
+    my_snprintf(buffer, sizeof(buffer), _("%6d.%02d ms"),
+               (int) ping_time_in_ms,
+               ((int) (ping_time_in_ms * 100.0)) % 100);
+  } else {
+    buffer[0] = '\0';
+  }
+  return buffer;
 }
Index: client/plrdlg_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/plrdlg_common.h,v
retrieving revision 1.1
diff -u -r1.1 plrdlg_common.h
--- client/plrdlg_common.h      27 Jun 2002 01:00:49 -0000      1.1
+++ client/plrdlg_common.h      9 Nov 2002 12:38:58 -0000
@@ -13,11 +13,14 @@
 #ifndef FC__PLRDLG_COMMON_H
 #define FC__PLRDLG_COMMON_H
 
+struct player;
+
 #include "shared.h"            /* bool type */
 
 void plrdlg_freeze(void);
 void plrdlg_thaw(void);
 void plrdlg_force_thaw(void);
 bool is_plrdlg_frozen(void);
+const char *get_ping_time_text(struct player *pplayer);
 
 #endif  /* FC__PLRDLG_COMMON_H */
Index: client/gui-gtk/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/plrdlg.c,v
retrieving revision 1.39
diff -u -r1.39 plrdlg.c
--- client/gui-gtk/plrdlg.c     7 Nov 2002 18:55:25 -0000       1.39
+++ client/gui-gtk/plrdlg.c     9 Nov 2002 12:38:59 -0000
@@ -70,7 +70,7 @@
 static void players_list_ucallback(GtkWidget *w, gint row, gint column);
 static void players_sship_callback(GtkWidget *w, gpointer data);
 
-#define NUM_COLUMNS 12    /* number of columns in total */
+#define NUM_COLUMNS 13         /* number of columns in total */
 #define DEF_SORT_COLUMN 2 /* default sort column (1 = nation) */
 
 /****************************************************************
@@ -122,7 +122,7 @@
   static const char *titles_[NUM_COLUMNS] =
       { N_("Name"), N_("Flag"), N_("Nation"), N_("Team"), N_("Ai"),
        N_("Embassy"), N_("Dipl.State"), N_("Vision"), N_("Reputation"),
-       N_("State"), N_("Host"), N_("Idle")
+       N_("State"), N_("Host"), N_("Idle"), N_("Ping")
   };
   static gchar **titles;
   int i;
@@ -326,6 +326,7 @@
   row[9] = statebuf;
   row[10] = (char *) player_addr_hack(&game.players[i]);       /* Fixme */
   row[11] = idlebuf;
+  row[12] = get_ping_time_text(&game.players[i]);
 }
 
 #define MIN_DIMENSION 5
Index: common/connection.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/connection.h,v
retrieving revision 1.23
diff -u -r1.23 connection.h
--- common/connection.h 30 Oct 2002 22:34:03 -0000      1.23
+++ common/connection.h 9 Nov 2002 12:39:01 -0000
@@ -96,8 +96,9 @@
   struct socket_packet_buffer *buffer;
   struct socket_packet_buffer *send_buffer;
   time_t last_write;
-  bool ponged;                 /* have received a PACKET_CONN_PONG? */
 
+  double ping_time;
+  
   struct conn_list self;       /* list with this connection as single element 
*/
   char name[MAX_LEN_NAME];
   char addr[MAX_LEN_ADDR];
@@ -149,6 +150,10 @@
      * Will increase for every received packet.
      */
     int last_request_id_seen;
+
+    /* How many PACKET_CONN_PING haven't received a PACKET_CONN_PONG? */
+    int open_pings;
+    struct timer *ping_timer;
   } server;
 
   /*
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.150
diff -u -r1.150 game.c
--- common/game.c       2 Nov 2002 13:33:53 -0000       1.150
+++ common/game.c       9 Nov 2002 12:39:03 -0000
@@ -655,6 +655,7 @@
   game.netwait       = GAME_DEFAULT_NETWAIT;
   game.last_ping     = 0;
   game.pingtimeout   = GAME_DEFAULT_PINGTIMEOUT;
+  game.pingtime      = GAME_DEFAULT_PINGTIME;
   game.end_year      = GAME_DEFAULT_END_YEAR;
   game.year          = GAME_START_YEAR;
   game.turn          = 0;
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.115
diff -u -r1.115 game.h
--- common/game.h       7 Nov 2002 15:32:39 -0000       1.115
+++ common/game.h       9 Nov 2002 12:39:04 -0000
@@ -72,6 +72,7 @@
   int netwait;
   time_t last_ping;
   int pingtimeout;
+  int pingtime;
   time_t turn_start;
   int end_year;
   int year;
@@ -398,6 +399,10 @@
 #define GAME_DEFAULT_NETWAIT         4
 #define GAME_MIN_NETWAIT             0
 #define GAME_MAX_NETWAIT             20
+
+#define GAME_DEFAULT_PINGTIME               20
+#define GAME_MIN_PINGTIME                   1
+#define GAME_MAX_PINGTIME           1800
 
 #define GAME_DEFAULT_PINGTIMEOUT     60
 #define GAME_MIN_PINGTIMEOUT         60
Index: common/packets.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v
retrieving revision 1.224
diff -u -r1.224 packets.c
--- common/packets.c    7 Nov 2002 18:55:25 -0000       1.224
+++ common/packets.c    9 Nov 2002 12:39:11 -0000
@@ -447,6 +447,9 @@
   case PACKET_ATTRIBUTE_CHUNK:
     return receive_packet_attribute_chunk(pc);
 
+  case PACKET_PING_INFO:
+    return receive_packet_ping_info(pc);
+
   default:
     freelog(LOG_ERROR, "unknown packet type %d received from %s",
            type, conn_description(pc));
@@ -805,6 +808,45 @@
   dio_get_string(&din, preq->name, sizeof(preq->name));
 
   RECEIVE_PACKET_END(preq);
+}
+
+/*************************************************************************
+This is the ping packet
+**************************************************************************/
+int send_packet_ping_info(struct connection *pc,
+                         const struct packet_ping_info *packet)
+{
+  int i;
+  SEND_PACKET_START(PACKET_PING_INFO);
+
+  dio_put_uint8(&dout, packet->connections);  
+
+  for (i = 0; i < packet->connections; i++) {
+    dio_put_uint8(&dout, packet->conn_id[i]);
+    dio_put_uint32(&dout, (int) (packet->ping_time[i] * 1e6));
+  }
+
+  SEND_PACKET_END;
+}
+
+/*************************************************************************
+...
+**************************************************************************/
+struct packet_ping_info *receive_packet_ping_info(struct connection *pc)
+{
+  int i;       
+  RECEIVE_PACKET_START(packet_ping_info, packet);
+
+  dio_get_uint8(&din, &packet->connections);
+  for (i = 0; i < packet->connections; i++) {
+    int tmp;
+
+    dio_get_uint8(&din, &packet->conn_id[i]);
+    dio_get_uint32(&din, &tmp);
+    packet->ping_time[i] = tmp / 1e6;
+  }
+       
+  RECEIVE_PACKET_END(packet);
 }
 
 /*************************************************************************
Index: common/packets.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v
retrieving revision 1.128
diff -u -r1.128 packets.h
--- common/packets.h    7 Nov 2002 18:55:25 -0000       1.128
+++ common/packets.h    9 Nov 2002 12:39:13 -0000
@@ -128,6 +128,7 @@
   PACKET_SELECT_NATION_OK,
   PACKET_FREEZE_HINT,
   PACKET_THAW_HINT,
+  PACKET_PING_INFO,
   PACKET_LAST  /* leave this last */
 };
 
@@ -505,6 +506,15 @@
   char capability[MAX_LEN_CAPSTR];
 };
 
+/***************
+  Ping packet
+***************/
+struct packet_ping_info {
+  int connections;
+  int conn_id[MAX_NUM_PLAYERS];
+  double ping_time[MAX_NUM_PLAYERS];
+};
+
 /*********************************************************
 The server tells the client all about a spaceship:
 *********************************************************/
@@ -940,6 +950,9 @@
                          const struct packet_game_info *pinfo);
 struct packet_game_info *receive_packet_game_info(struct connection *pc);
 
+int send_packet_ping_info(struct connection *pc,
+                         const struct packet_ping_info *packet);
+struct packet_ping_info *receive_packet_ping_info(struct connection *pc);
 
 struct packet_player_info *receive_packet_player_info(struct connection *pc);
 int send_packet_player_info(struct connection *pc, 
Index: common/packets_lsend.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_lsend.c,v
retrieving revision 1.12
diff -u -r1.12 packets_lsend.c
--- common/packets_lsend.c      25 Aug 2002 11:20:59 -0000      1.12
+++ common/packets_lsend.c      9 Nov 2002 12:39:13 -0000
@@ -81,6 +81,14 @@
   conn_list_iterate_end;
 }
 
+void lsend_packet_ping_info(struct conn_list *dest,
+                         const struct packet_ping_info *packet)
+{
+  conn_list_iterate(*dest, pconn)
+    send_packet_ping_info(pconn, packet);
+  conn_list_iterate_end;
+}
+
 void lsend_packet_player_info(struct conn_list *dest, 
                            const struct packet_player_info *pinfo)
 {
Index: common/packets_lsend.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_lsend.h,v
retrieving revision 1.11
diff -u -r1.11 packets_lsend.h
--- common/packets_lsend.h      25 Aug 2002 11:20:59 -0000      1.11
+++ common/packets_lsend.h      9 Nov 2002 12:39:14 -0000
@@ -32,6 +32,8 @@
                         const struct packet_map_info *pinfo);
 void lsend_packet_game_info(struct conn_list *dest, 
                          const struct packet_game_info *pinfo);
+void lsend_packet_ping_info(struct conn_list *dest,
+                         const struct packet_ping_info *packet);
 void lsend_packet_player_info(struct conn_list *dest, 
                            const struct packet_player_info *pinfo);
 void lsend_packet_conn_info(struct conn_list *dest,
Index: po/POTFILES.in
===================================================================
RCS file: /home/freeciv/CVS/freeciv/po/POTFILES.in,v
retrieving revision 1.56
diff -u -r1.56 POTFILES.in
--- po/POTFILES.in      16 Oct 2002 23:03:19 -0000      1.56
+++ po/POTFILES.in      9 Nov 2002 12:39:15 -0000
@@ -50,6 +50,7 @@
 client/helpdata.c
 client/options.c
 client/packhand.c
+client/plrdlg_common.c
 client/tilespec.c
 client/agents/cma_core.c
 client/agents/cma_fec.c
Index: server/sernet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.c,v
retrieving revision 1.97
diff -u -r1.97 sernet.c
--- server/sernet.c     7 Nov 2002 16:04:55 -0000       1.97
+++ server/sernet.c     9 Nov 2002 12:39:17 -0000
@@ -75,6 +75,7 @@
 #include "meta.h"
 #include "srv_main.h"
 #include "stdinhand.h"
+#include "timing.h"
 
 #include "sernet.h"
 
@@ -111,6 +112,8 @@
 static void start_processing_request(struct connection *pconn,
                                     int request_id);
 static void finish_processing_request(struct connection *pconn);
+static void ping_connection(struct connection *pconn);
+static void send_ping_times_to_all(void);
 
 static bool no_input = FALSE;
 
@@ -392,22 +395,35 @@
       }
     }
 
-    /* send PACKET_CONN_PING & cut mute players */
-    if ((time(NULL)>game.last_ping + game.pingtimeout)) {
-      for(i=0; i<MAX_NUM_CONNECTIONS; i++) {
-       struct connection *pconn = &connections[i];
-       if (pconn->used) {
-         send_packet_generic_empty(pconn, PACKET_CONN_PING);
+    /* Pinging around for statistics*/
+    if (time(NULL) > (game.last_ping + game.pingtime)) {
+      int open_pings_to_cut = game.pingtimeout / game.pingtime;
 
-         if (pconn->ponged) {
-           pconn->ponged = FALSE;
-         } else {
-           freelog(LOG_NORMAL, "cut connection %s due to ping timeout",
-                   conn_description(pconn));
-           close_socket_callback(pconn);
-         }
-       }
+      if (open_pings_to_cut == 0) {
+       open_pings_to_cut = 1;
       }
+
+      /* send data about the previous run */
+      send_ping_times_to_all();
+
+      conn_list_iterate(game.game_connections, pconn) {
+       if (!pconn->used) {
+         continue;
+       }
+
+       /* lazy init of ping timer */
+       if (!pconn->server.ping_timer) {
+         pconn->server.ping_timer = new_timer_start(TIMER_USER, TIMER_ACTIVE);
+       }
+       
+       if (pconn->server.open_pings >= open_pings_to_cut) {
+         /* cut mute players */
+         freelog(LOG_NORMAL, "cut connection %s due to ping timeout",
+                 conn_description(pconn));
+         close_socket_callback(pconn);
+       }
+       ping_connection(pconn);
+      } conn_list_iterate_end;
       game.last_ping = time(NULL);
     }
 
@@ -699,7 +715,6 @@
       pconn->buffer = new_socket_packet_buffer();
       pconn->send_buffer = new_socket_packet_buffer();
       pconn->last_write = 0;
-      pconn->ponged = TRUE;
       pconn->first_packet = TRUE;
       pconn->byte_swap = FALSE;
       pconn->capability[0] = '\0';
@@ -708,6 +723,9 @@
       pconn->notify_of_writable_data = NULL;
       pconn->server.currently_processed_request_id = 0;
       pconn->server.last_request_id_seen = 0;
+      pconn->server.open_pings = 0;
+      pconn->server.ping_timer = NULL;
+      pconn->ping_time = -1.0;
       pconn->incoming_packet_notify = NULL;
       pconn->outgoing_packet_notify = NULL;
 
@@ -818,4 +836,54 @@
          pconn->server.currently_processed_request_id, pconn->id);
   send_packet_generic_empty(pconn, PACKET_PROCESSING_FINISHED);
   pconn->server.currently_processed_request_id = 0;
+}
+
+/**************************************************************************
+This is the ping function
+**************************************************************************/
+static void ping_connection(struct connection *pconn)
+{
+  pconn->server.open_pings++;
+  clear_timer_start(pconn->server.ping_timer);
+  send_packet_generic_empty(pconn, PACKET_CONN_PING);
+}
+
+/**************************************************************************
+This is the pong function
+**************************************************************************/
+void handle_conn_pong(struct connection *pconn)
+{
+  pconn->server.open_pings--;
+  stop_timer(pconn->server.ping_timer);
+  pconn->ping_time = read_timer_seconds(pconn->server.ping_timer);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static void send_ping_times_to_all(void)
+{
+  struct packet_ping_info packet;
+  int i;
+
+  i = 0;
+  conn_list_iterate(game.game_connections, pconn) {
+    if (!pconn->used) {
+      continue;
+    }
+    i++;
+  } conn_list_iterate_end;
+
+  packet.connections = i;
+
+  i = 0;
+  conn_list_iterate(game.game_connections, pconn) {
+    if (!pconn->used) {
+      continue;
+    }
+    packet.conn_id[i] = pconn->id;
+    packet.ping_time[i] = pconn->ping_time;
+    i++;
+  } conn_list_iterate_end;
+  lsend_packet_ping_info(&game.est_connections, &packet);
 }
Index: server/sernet.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.h,v
retrieving revision 1.7
diff -u -r1.7 sernet.h
--- server/sernet.h     18 Sep 2000 20:36:15 -0000      1.7
+++ server/sernet.h     9 Nov 2002 12:39:17 -0000
@@ -25,5 +25,6 @@
 void close_connections_and_socket(void);
 void init_connections(void);
 void close_connection(struct connection *pconn);
+void handle_conn_pong(struct connection *pconn);
 
 #endif  /* FC__SERNET_H */
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.102
diff -u -r1.102 srv_main.c
--- server/srv_main.c   7 Nov 2002 18:55:26 -0000       1.102
+++ server/srv_main.c   9 Nov 2002 12:39:21 -0000
@@ -913,7 +913,7 @@
     handle_patrol_route(pplayer, (struct packet_goto_route *)packet);
     break;
   case PACKET_CONN_PONG:
-    pconn->ponged = TRUE;
+    handle_conn_pong(pconn);
     break;
   case PACKET_UNIT_AIRLIFT:
     handle_unit_airlift(pplayer, (struct packet_unit_request *)packet);
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.261
diff -u -r1.261 stdinhand.c
--- server/stdinhand.c  7 Nov 2002 18:55:26 -0000       1.261
+++ server/stdinhand.c  9 Nov 2002 12:39:30 -0000
@@ -726,11 +726,15 @@
             "wait at all."), NULL, 
          GAME_MIN_NETWAIT, GAME_MAX_NETWAIT, GAME_DEFAULT_NETWAIT)
 
-  GEN_INT("pingtimeout", game.pingtimeout, SSET_META, SSET_TO_CLIENT,
-         N_("Maximum seconds between PINGs"),
+  GEN_INT("pingtime", game.pingtime, SSET_META, SSET_TO_CLIENT,
+         N_("Seconds between PINGs"),
          N_("The civserver will poll the clients with a PING request "
-            "each time this period elapses. If a client doesn't reply "
-            "with a PONG before the next server PING request the "
+            "each time this period elapses."), NULL, 
+         GAME_MIN_PINGTIME, GAME_MAX_PINGTIME, GAME_DEFAULT_PINGTIME)
+
+  GEN_INT("pingtimeout", game.pingtimeout, SSET_META, SSET_TO_CLIENT,
+         N_("Time to cut a client"),
+         N_("If a client doesn't reply to a PONG in this time the "
             "client is disconnected."), NULL, 
          GAME_MIN_PINGTIMEOUT, GAME_MAX_PINGTIMEOUT, GAME_DEFAULT_PINGTIMEOUT)
 

[Prev in Thread] Current Thread [Next in Thread]