Fixed outoing packet queue handling bug on very high load.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 14:50:08 +0000 (14:50 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 14:50:08 +0000 (14:50 +0000)
CHANGES
TODO-1.0
apps/silcd/server.c
lib/silcclient/client.c
lib/silccore/silcpacket.c
lib/silccore/silcpacket.h
lib/silcutil/beos/silcbeossockconn.c
lib/silcutil/os2/silcos2sockconn.c
lib/silcutil/unix/silcunixsockconn.c
lib/silcutil/unix/silcunixutil.c
lib/silcutil/win32/silcwin32sockconn.c

diff --git a/CHANGES b/CHANGES
index 451cced5bf694f9e028e96c1cda4e947093ce370..888671f12ea5f8c8669de2ae0b9f0e1fcc80a3ed 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,11 @@ Tue Mar 19 16:32:43 CET 2002  Pekka Riikonen <priikone@silcnet.org>
          lib/silcclient/client.c, client_channel.c client_prvmsg.c,
          silcd/packet_send.c, server_backup.c and packet_receive.c.
 
+       * Fixed a packet sending bug on very high load, where outgoing
+         packet queue wasn't handled correctly and packets got corrupted.
+         Affected files are lib/silcutil/*/silc*sockconn.c,
+         lib/silcclient/client.c and silcd/server.c.
+
 Mon Mar 18 21:00:41 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added macro SILC_PACKET_DATALEN which can be used during
index 6b7d01e69309ccb34d33bf693895c82f5f5f5469..b843d59b626a2fed8dec97220b28da0366a75ed8 100644 (file)
--- a/TODO-1.0
+++ b/TODO-1.0
@@ -159,10 +159,8 @@ least could be done.
 
  o EPOC specific additions/changes required:
 
-       o In lib/silccore/silcpacket.c global RNG is used.  Change the
-         interface for that function.  The PKCS#1 also calls global RNG
-         (even though it is not used currently in SILC, the interface
-         allows its use).
+       o The PKCS#1 also calls global RNG (even though it is not used 
+         currently in SILC, the interface allows its use).
 
        o Something needs to be thought to the logging globals as well, 
          like silc_debug etc.  They won't work on EPOC.  Perhaps logging
index 25c3eb06515aa315218c755812ab733fa1f1c196..cc43d3ba596fbdc7becd9668e18a9a196a17bc33 100644 (file)
@@ -1553,9 +1553,6 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
 
     server->stat.packets_sent++;
 
-    if (sock->outbuf->data - sock->outbuf->head)
-     silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
-
     /* Send the packet */
     ret = silc_packet_send(sock, TRUE);
 
index 3e33cd93e53b1b218c885b76a3e8144afb20fb2d..7fc3b8d4c0d6acba4a8eb513f25d1ba86c9deef9 100644 (file)
@@ -768,9 +768,6 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
     if (SILC_IS_DISCONNECTED(sock))
       return;
 
-    if (sock->outbuf->data - sock->outbuf->head)
-      silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
-
     ret = silc_packet_send(sock, TRUE);
 
     /* If returned -2 could not write to connection now, will do
index 5c5f6be6606e9db35031cc525e7095286e113a08..7c3f2b0d90cb40a5f0a49d5646f3b3209f923571 100644 (file)
@@ -113,10 +113,10 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
 /* Assembles a new packet to be ready for send out. */
 
 bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
-                          SilcCipher cipher, SilcHmac hmac,
-                          SilcSocketConnection sock,
-                          const unsigned char *data, SilcUInt32 data_len,
-                          const SilcBuffer assembled_packet)
+                         SilcCipher cipher, SilcHmac hmac,
+                         SilcSocketConnection sock,
+                         const unsigned char *data, SilcUInt32 data_len,
+                         const SilcBuffer assembled_packet)
 { 
   unsigned char tmppad[SILC_PACKET_MAX_PADLEN];   
   int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
@@ -132,7 +132,7 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
      padding. */
   if (!packet->truelen) {
     data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
-                                   packet->src_id_len + packet->dst_id_len);
+                                  packet->src_id_len + packet->dst_id_len);
     packet->truelen = data_len + SILC_PACKET_HEADER_LEN + 
       packet->src_id_len + packet->dst_id_len;
   }
@@ -141,8 +141,8 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
      the data that will be encrypted. */
   if (!packet->padlen) {
     packet->padlen = (packet->long_pad ?
-                      SILC_PACKET_PADLEN_MAX(packet->truelen) :
-                      SILC_PACKET_PADLEN(packet->truelen, block_len));
+                     SILC_PACKET_PADLEN_MAX(packet->truelen) :
+                     SILC_PACKET_PADLEN(packet->truelen, block_len));
   }
 
   /* Now prepare the outgoing data buffer for packet sending and start
@@ -150,43 +150,43 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
 
   /* Return pointer to the assembled packet */
   if (!silc_packet_send_prepare(sock, packet->truelen - data_len,
-                                packet->padlen, data_len, hmac,
-                                assembled_packet))
+                               packet->padlen, data_len, hmac,
+                               assembled_packet))
     return FALSE;
 
   /* Get random padding */
   if (rng)
     for (i = 0; i < packet->padlen; i++) tmppad[i] =
-                                           silc_rng_get_byte_fast(rng);
+                                          silc_rng_get_byte_fast(rng);
   else
     for (i = 0; i < packet->padlen; i++) tmppad[i] =
-                                           silc_rng_global_get_byte_fast();
+                                          silc_rng_global_get_byte_fast();
 
   /* Create the packet. This creates the SILC header, adds padding, and
      the actual packet data. */
   ret =
     silc_buffer_format(assembled_packet,
-                       SILC_STR_UI_SHORT(packet->truelen),
-                       SILC_STR_UI_CHAR(packet->flags),
-                       SILC_STR_UI_CHAR(packet->type),
-                       SILC_STR_UI_CHAR(packet->padlen),
-                       SILC_STR_UI_CHAR(0),
-                       SILC_STR_UI_CHAR(packet->src_id_len),
-                       SILC_STR_UI_CHAR(packet->dst_id_len),
-                       SILC_STR_UI_CHAR(packet->src_id_type),
-                       SILC_STR_UI_XNSTRING(packet->src_id,
-                                            packet->src_id_len),
-                       SILC_STR_UI_CHAR(packet->dst_id_type),
-                       SILC_STR_UI_XNSTRING(packet->dst_id,
-                                            packet->dst_id_len),
-                       SILC_STR_UI_XNSTRING(tmppad, packet->padlen),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
+                      SILC_STR_UI_SHORT(packet->truelen),
+                      SILC_STR_UI_CHAR(packet->flags),
+                      SILC_STR_UI_CHAR(packet->type),
+                      SILC_STR_UI_CHAR(packet->padlen),
+                      SILC_STR_UI_CHAR(0),
+                      SILC_STR_UI_CHAR(packet->src_id_len),
+                      SILC_STR_UI_CHAR(packet->dst_id_len),
+                      SILC_STR_UI_CHAR(packet->src_id_type),
+                      SILC_STR_UI_XNSTRING(packet->src_id,
+                                           packet->src_id_len),
+                      SILC_STR_UI_CHAR(packet->dst_id_type),
+                      SILC_STR_UI_XNSTRING(packet->dst_id,
+                                           packet->dst_id_len),
+                      SILC_STR_UI_XNSTRING(tmppad, packet->padlen),
+                      SILC_STR_UI_XNSTRING(data, data_len),
+                      SILC_STR_END);
   if (ret < 0)
     return FALSE;
 
   SILC_LOG_HEXDUMP(("Assembled packet, len %d", assembled_packet->len),
-                   assembled_packet->data, assembled_packet->len);
+                  assembled_packet->data, assembled_packet->len);
 
   return TRUE;
 }
@@ -198,11 +198,11 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
    pointer to that buffer into the `packet'. */
 
 bool silc_packet_send_prepare(SilcSocketConnection sock,
-                              SilcUInt32 header_len,
-                              SilcUInt32 pad_len,
-                              SilcUInt32 data_len,
-                              SilcHmac hmac,
-                              const SilcBuffer packet)
+                             SilcUInt32 header_len,
+                             SilcUInt32 pad_len,
+                             SilcUInt32 data_len,
+                             SilcHmac hmac,
+                             const SilcBuffer packet)
 { 
   int totlen;
   unsigned char *oldptr;
@@ -219,7 +219,7 @@ bool silc_packet_send_prepare(SilcSocketConnection sock,
     SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
 
     sock->outbuf = silc_buffer_alloc(totlen > SILC_PACKET_DEFAULT_SIZE ?
-                                     totlen : SILC_PACKET_DEFAULT_SIZE);
+                                    totlen : SILC_PACKET_DEFAULT_SIZE);
     if (!sock->outbuf)
       return FALSE;
   } else {
@@ -233,7 +233,7 @@ bool silc_packet_send_prepare(SilcSocketConnection sock,
   if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + mac_len)) {
     SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
     sock->outbuf = silc_buffer_realloc(sock->outbuf,
-                                       sock->outbuf->truelen + (totlen * 2));
+                                      sock->outbuf->truelen + (totlen * 2));
     if (!sock->outbuf)
       return FALSE;
   }
index d4f28ededd3fc87a0661f2c6b73ae2d7af564ebd..6c855225041d47d4afd4431f7861f889d3ea1c7f 100644 (file)
@@ -453,10 +453,10 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
  *
  ***/
 bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
-                          SilcCipher cipher, SilcHmac hmac,
-                          SilcSocketConnection sock,
-                          const unsigned char *data, SilcUInt32 data_len,
-                          const SilcBuffer assembled_packet);
+                         SilcCipher cipher, SilcHmac hmac,
+                         SilcSocketConnection sock,
+                         const unsigned char *data, SilcUInt32 data_len,
+                         const SilcBuffer assembled_packet);
 
 /****f* silccore/SilcPacketAPI/silc_packet_send_prepare
  *
@@ -485,11 +485,11 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
  *
  ***/
 bool silc_packet_send_prepare(SilcSocketConnection sock,
-                              SilcUInt32 header_len,
-                              SilcUInt32 pad_len,
-                              SilcUInt32 data_len,
-                              SilcHmac hmac,
-                              const SilcBuffer packet);
+                             SilcUInt32 header_len,
+                             SilcUInt32 pad_len,
+                             SilcUInt32 data_len,
+                             SilcHmac hmac,
+                             const SilcBuffer packet);
 
 /****f* silccore/SilcPacketAPI/silc_packet_receive
  *
index 3b26deec127abe927e45526c0714f5ba7f0f33b2..0786f8b01cf7941b1e81e00c83328be106c1eb95 100644 (file)
@@ -52,6 +52,13 @@ int silc_socket_write(SilcSocketConnection sock)
       return -1;
     }
 
+    if (ret < src->len) {
+      SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
+                     ret, src->len));
+      silc_buffer_pull(src, ret);
+      return -2;
+    }
+
     silc_buffer_pull(src, ret);
   }
 
index be3ae5a447edd8e056a431ba0831b3ca59d90d78..24d939bee35be8f16bbe3a2380795283f5d1fca7 100644 (file)
@@ -50,6 +50,13 @@ int silc_socket_write(SilcSocketConnection sock)
       return -1;
     }
 
+    if (ret < src->len) {
+      SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
+                     ret, src->len));
+      silc_buffer_pull(src, ret);
+      return -2;
+    }
+
     silc_buffer_pull(src, ret);
   }
 
index dada9d6e73cb49a2255f88ae64bd04abe12d51ed..02af7cc747646009ef560a7fc0db57570587e436 100644 (file)
@@ -50,6 +50,13 @@ int silc_socket_write(SilcSocketConnection sock)
       return -1;
     }
 
+    if (ret < src->len) {
+      SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
+                     ret, src->len));
+      silc_buffer_pull(src, ret);
+      return -2;
+    }
+
     silc_buffer_pull(src, ret);
   }
 
index cab2086ad838fa197b81a71bd86275c966c8171b..8cb6a723f10db57e57b256888d35e5f8aa600ef1 100644 (file)
@@ -150,7 +150,7 @@ char *silc_get_username()
   }
   
   return strdup(logname);
-}                          
+}
 
 /* Returns the real name of ther user. */
 
index 144eeba9acc998ac7f728b324c15c2c3a1a82c36..52515bbe82455d7869988cc2039ed0f989754e8f 100644 (file)
@@ -51,6 +51,13 @@ int silc_socket_write(SilcSocketConnection sock)
       return -1;
     }
 
+    if (ret < src->len) {
+      SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
+                     ret, src->len));
+      silc_buffer_pull(src, ret);
+      return -2;
+    }
+
     silc_buffer_pull(src, ret);
   }