From 512bf4efd6075ba124204ded85079696088a62bf Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 19 Mar 2002 14:50:08 +0000 Subject: [PATCH] Fixed outoing packet queue handling bug on very high load. --- CHANGES | 5 ++ TODO-1.0 | 6 +-- apps/silcd/server.c | 3 -- lib/silcclient/client.c | 3 -- lib/silccore/silcpacket.c | 70 +++++++++++++------------- lib/silccore/silcpacket.h | 18 +++---- lib/silcutil/beos/silcbeossockconn.c | 7 +++ lib/silcutil/os2/silcos2sockconn.c | 7 +++ lib/silcutil/unix/silcunixsockconn.c | 7 +++ lib/silcutil/unix/silcunixutil.c | 2 +- lib/silcutil/win32/silcwin32sockconn.c | 7 +++ 11 files changed, 80 insertions(+), 55 deletions(-) diff --git a/CHANGES b/CHANGES index 451cced5..888671f1 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,11 @@ Tue Mar 19 16:32:43 CET 2002 Pekka Riikonen 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 * Added macro SILC_PACKET_DATALEN which can be used during diff --git a/TODO-1.0 b/TODO-1.0 index 6b7d01e6..b843d59b 100644 --- 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 diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 25c3eb06..cc43d3ba 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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); diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 3e33cd93..7fc3b8d4 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -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 diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 5c5f6be6..7c3f2b0d 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -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; } diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index d4f28ede..6c855225 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -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 * diff --git a/lib/silcutil/beos/silcbeossockconn.c b/lib/silcutil/beos/silcbeossockconn.c index 3b26deec..0786f8b0 100644 --- a/lib/silcutil/beos/silcbeossockconn.c +++ b/lib/silcutil/beos/silcbeossockconn.c @@ -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); } diff --git a/lib/silcutil/os2/silcos2sockconn.c b/lib/silcutil/os2/silcos2sockconn.c index be3ae5a4..24d939be 100644 --- a/lib/silcutil/os2/silcos2sockconn.c +++ b/lib/silcutil/os2/silcos2sockconn.c @@ -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); } diff --git a/lib/silcutil/unix/silcunixsockconn.c b/lib/silcutil/unix/silcunixsockconn.c index dada9d6e..02af7cc7 100644 --- a/lib/silcutil/unix/silcunixsockconn.c +++ b/lib/silcutil/unix/silcunixsockconn.c @@ -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); } diff --git a/lib/silcutil/unix/silcunixutil.c b/lib/silcutil/unix/silcunixutil.c index cab2086a..8cb6a723 100644 --- a/lib/silcutil/unix/silcunixutil.c +++ b/lib/silcutil/unix/silcunixutil.c @@ -150,7 +150,7 @@ char *silc_get_username() } return strdup(logname); -} +} /* Returns the real name of ther user. */ diff --git a/lib/silcutil/win32/silcwin32sockconn.c b/lib/silcutil/win32/silcwin32sockconn.c index 144eeba9..52515bbe 100644 --- a/lib/silcutil/win32/silcwin32sockconn.c +++ b/lib/silcutil/win32/silcwin32sockconn.c @@ -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); } -- 2.24.0