Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] Re: (PR#8722) Fatal bugs and annoyances (resent)
Home

[Freeciv-Dev] Re: (PR#8722) Fatal bugs and annoyances (resent)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: vasc@xxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#8722) Fatal bugs and annoyances (resent)
From: "Raimar Falke" <i-freeciv-lists@xxxxxxxxxxxxx>
Date: Thu, 13 May 2004 12:37:35 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8722 >

On Thu, May 13, 2004 at 11:45:42AM -0700, Raimar Falke wrote:
> I _suspect_ that the client doesn't read from its socket. I _suspect_
> that the new connection dialog may be the cause.

I found the problem and it was really at the client part. When the
default input buffer (40960 bytes) is full read_socket_data tries to
read the unused bytes (0 in this case). It successes here but
interprets the value 0 as EOF. It closes the connection and we all saw
the affects on the server.

The attached patch enlarges the input buffer if this case happens. It
looks like this error was there all the time. But only thaw/freeze
made such big unread input buffers possible.

Ideas for the error handling welcome.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
  Zu jedem Problem gibt es eine naheliegende, einfach zu verstehende
  Loesung. Sie hat nur einen Nachteil: Sie ist falsch.

Index: common/connection.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/connection.c,v
retrieving revision 1.38
diff -u -u -r1.38 connection.c
--- common/connection.c 5 May 2004 20:39:16 -0000       1.38
+++ common/connection.c 13 May 2004 19:30:18 -0000
@@ -113,6 +113,24 @@
   close_callback = fun;
 }
 
+/**************************************************************************
+...
+**************************************************************************/
+static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf,
+                                          int extra_space)
+{
+  /* room for more? */
+  if (buf->nsize - buf->ndata < extra_space) {
+    buf->nsize = buf->ndata + extra_space;
+
+    /* added this check so we don't gobble up too much mem */
+    if (buf->nsize > MAX_LEN_BUFFER) {
+      return FALSE;
+    }
+    buf->data = (unsigned char *) fc_realloc(buf->data, buf->nsize);
+  }
+  return TRUE;
+}
 
 /**************************************************************************
   Read data from socket, and check if a packet is ready.
@@ -125,6 +143,11 @@
 {
   int didget;
 
+  if (!buffer_ensure_free_extra_space(buffer, MAX_LEN_PACKET)) {
+    freelog(LOG_ERROR, "can't grow buffer");
+    return -1;
+  }
+
   freelog(LOG_DEBUG, "try reading %d bytes", buffer->nsize - buffer->ndata);
   didget = my_readsocket(sock, (char *) (buffer->data + buffer->ndata),
                         buffer->nsize - buffer->ndata);
@@ -278,23 +301,15 @@
 
     freelog(LOG_DEBUG, "add %d bytes to %d (space=%d)", len, buf->ndata,
            buf->nsize);
-    /* room for more? */
-    if(buf->nsize - buf->ndata < len) {
-      buf->nsize = buf->ndata + len;
-
-      /* added this check so we don't gobble up too much mem */
-      if (buf->nsize > MAX_LEN_BUFFER) {
-       if (delayed_disconnect > 0) {
-         pc->delayed_disconnect = TRUE;
-         return TRUE;
-       } else {
-         if (close_callback) {
-           (*close_callback)(pc);
-         }
-         return FALSE;
-       }
+    if (!buffer_ensure_free_extra_space(buf, len)) {
+      if (delayed_disconnect > 0) {
+       pc->delayed_disconnect = TRUE;
+       return TRUE;
       } else {
-       buf->data = (unsigned char *)fc_realloc(buf->data, buf->nsize);
+       if (close_callback) {
+         (*close_callback) (pc);
+       }
+       return FALSE;
       }
     }
     memcpy(buf->data + buf->ndata, data, len);

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