Changed packet assembling interfaces.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 14:24:01 +0000 (14:24 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 14:24:01 +0000 (14:24 +0000)
CHANGES
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server_backup.c
lib/silcclient/client.c
lib/silcclient/client_channel.c
lib/silcclient/client_prvmsg.c
lib/silccore/silcpacket.c
lib/silccore/silcpacket.h

diff --git a/CHANGES b/CHANGES
index 7667f232cc3dbfc6469f5b9eead9cd0dffc1e9a3..451cced5bf694f9e028e96c1cda4e947093ce370 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,20 @@
-Tue Mar 19 12:32:43 CET 2002  Pekka Riikonen <priikone@silcnet.org>
+Tue Mar 19 16:32:43 CET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_rng_get_byte_fast function in to the
          lib/silccrypt/silcrng.[ch].
 
+       * Changed the interface of silc_packet_assemble and the
+         silc_packet_send_prepare.  If silc_packet_assmble is now
+         called the application does not call silc_packet_send_prepare
+         because the library will call it automatically.  These
+         interfaces now also return a reference to the outgoing buffer
+         which includes the assembled packet, which the application can 
+         use to encrypt the packet.
+
+         Affected files are lib/silccore/silcpacket.[ch],
+         lib/silcclient/client.c, client_channel.c client_prvmsg.c,
+         silcd/packet_send.c, server_backup.c and packet_receive.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 d3191d01ac30c0ae242c78cb0fa55236e26a77b4..61b3e4faf1d8eda17a9a9d6534352150bf636c0a 100644 (file)
@@ -1379,19 +1379,23 @@ void silc_server_command_reply(SilcServer server,
 
   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
     /* Relay the packet to the client */
+    const SilcBufferStruct p;
     
     dst_sock = (SilcSocketConnection)client->connection;
+    idata = (SilcIDListData)client;
+    
     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
                     + packet->dst_id_len + packet->padlen);
-    
-    silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
-    silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
-    
-    idata = (SilcIDListData)client;
+    if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
+                                  idata->hmac_send, (const SilcBuffer)&p)) {
+      SILC_LOG_ERROR(("Cannot send packet"));
+      return;
+    }
+    silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
     
     /* Encrypt packet */
     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
-                       dst_sock->outbuf, buffer->len);
+                       (SilcBuffer)&p, buffer->len);
     
     /* Send the packet */
     silc_server_packet_send_real(server, dst_sock, TRUE);
index e9d70fbb076fd87abdd7b702f9fe1b8c36021139..3cda68b0d0d4a4a213c3a8e80fef67b50820982a 100644 (file)
@@ -137,6 +137,7 @@ void silc_server_packet_send_dest(SilcServer server,
                                  bool force_send)
 {
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   SilcIDListData idata = (SilcIDListData)sock->user_data;
   SilcCipher cipher = NULL;
   SilcHmac hmac = NULL;
@@ -183,35 +184,23 @@ void silc_server_packet_send_dest(SilcServer server,
     packetdata.src_id_len + dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          data_len);
-
-  SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
-
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the data to the buffer */
-  if (data && data_len)
-    silc_buffer_put(sock->outbuf, data, data_len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, NULL, cipher, hmac, sock,
+                            data, data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Cannot assemble packet"));
+    goto out;
+  }
 
   /* Encrypt the packet */
-  silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, sock->outbuf->len);
+  silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet, packet.len);
 
-  SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, 
-                   sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, packet.len),
+                  packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_server_packet_send_real(server, sock, force_send);
 
+ out:
   if (packetdata.src_id)
     silc_free(packetdata.src_id);
   if (packetdata.dst_id)
@@ -239,6 +228,7 @@ void silc_server_packet_send_srcdest(SilcServer server,
                                     bool force_send)
 {
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   SilcIDListData idata;
   SilcCipher cipher = NULL;
   SilcHmac hmac = NULL;
@@ -287,35 +277,23 @@ void silc_server_packet_send_srcdest(SilcServer server,
     packetdata.src_id_len + dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          data_len);
-
-  SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
-
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the data to the buffer */
-  if (data && data_len)
-    silc_buffer_put(sock->outbuf, data, data_len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, NULL, cipher, hmac, sock, data,
+                            data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Cannot assemble packe"));
+    goto out;
+  }
 
   /* Encrypt the packet */
-  silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, sock->outbuf->len);
+  silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet, packet.len);
 
-  SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, 
-                   sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Outgoing packet (%d), len %d", sequence, packet.len),
+                   packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_server_packet_send_real(server, sock, force_send);
 
+ out:
   if (packetdata.src_id)
     silc_free(packetdata.src_id);
   if (packetdata.dst_id)
@@ -341,17 +319,23 @@ void silc_server_packet_broadcast(SilcServer server,
      not allowed to send the packet. */
   id = silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type);
   if (id && !SILC_ID_SERVER_COMPARE(id, server->router->id)) {
+    const SilcBufferStruct p;
+
     idata = (SilcIDListData)sock->user_data;
 
     silc_buffer_push(buffer, buffer->data - buffer->head);
-    silc_packet_send_prepare(sock, 0, 0, buffer->len); 
-    silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
+    if (!silc_packet_send_prepare(sock, 0, 0, buffer->len, idata->hmac_send,
+                                  (const SilcBuffer)&p)) {
+      SILC_LOG_ERROR(("Cannot send packet"));
+      silc_free(id);
+      return;
+    }
+    silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
-                       sock->outbuf, sock->outbuf->len);
+                       (SilcBuffer)&p, p.len);
 
     SILC_LOG_HEXDUMP(("Broadcasted packet (%d), len %d", idata->psn_send - 1,
-                     sock->outbuf->len),
-                    sock->outbuf->data, sock->outbuf->len);
+                     p.len), p.data, p.len);
 
     /* Now actually send the packet */
     silc_server_packet_send_real(server, sock, TRUE);
@@ -372,6 +356,7 @@ void silc_server_packet_route(SilcServer server,
                              SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
+  const SilcBufferStruct p;
   SilcIDListData idata;
 
   SILC_LOG_DEBUG(("Routing received packet"));
@@ -379,14 +364,17 @@ void silc_server_packet_route(SilcServer server,
   idata = (SilcIDListData)sock->user_data;
 
   silc_buffer_push(buffer, buffer->data - buffer->head);
-  silc_packet_send_prepare(sock, 0, 0, buffer->len); 
-  silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
+  if (!silc_packet_send_prepare(sock, 0, 0, buffer->len, idata->hmac_send,
+                                (const SilcBuffer)&p)) {
+    SILC_LOG_ERROR(("Cannot send packet"));
+    return;
+  }
+  silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
   silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
-                     sock->outbuf, sock->outbuf->len);
+                     (SilcBuffer)&p, p.len);
 
   SILC_LOG_HEXDUMP(("Routed packet (%d), len %d", idata->psn_send - 1, 
-                   sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+                  p.len), p.data, p.len);
 
   /* Now actually send the packet */
   silc_server_packet_send_real(server, sock, TRUE);
@@ -482,6 +470,7 @@ silc_server_packet_send_to_channel_real(SilcServer server,
                                        bool force_send)
 {
   int block_len;
+  const SilcBufferStruct p;
 
   if (!sock)
     return;
@@ -500,32 +489,24 @@ silc_server_packet_send_to_channel_real(SilcServer server,
   else
     packet->padlen = SILC_PACKET_PADLEN(packet->truelen, block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packet->src_id_len + 
-                          packet->dst_id_len,
-                          packet->padlen,
-                          data_len);
-
-  packet->buffer = sock->outbuf;
-
   /* Put the data to buffer, assemble and encrypt the packet. The packet
      is encrypted with normal session key shared with the client, unless
      the `channel_message' is TRUE. */
-  silc_buffer_put(sock->outbuf, data, data_len);
-  silc_packet_assemble(packet, cipher);
+  if (!silc_packet_assemble(packet, NULL, cipher, hmac, sock, data,
+                            data_len, (const SilcBuffer)&p)) {
+    SILC_LOG_ERROR(("Cannot assemble packet"));
+    return;
+  }
+
   if (channel_message)
-    silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf
+    silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p
                        SILC_PACKET_HEADER_LEN + packet->src_id_len + 
                        packet->dst_id_len + packet->padlen);
   else
-    silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, 
-                       sock->outbuf->len);
+    silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, p.len);
     
-  SILC_LOG_HEXDUMP(("Channel packet (%d), len %d", sequence, 
-                   sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Channel packet (%d), len %d", sequence, p.len),
+                  p.data, p.len);
 
   /* Now actually send the packet */
   silc_server_packet_send_real(server, sock, force_send);
@@ -1008,35 +989,30 @@ void silc_server_send_private_message(SilcServer server,
                                      SilcPacketContext *packet)
 {
   SilcBuffer buffer = packet->buffer;
+  const SilcBufferStruct p;
+
+  silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
+                  + packet->dst_id_len + packet->padlen);
+  if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len, hmac,
+                                (const SilcBuffer)&p)) {
+    SILC_LOG_ERROR(("Cannot send packet"));
+    return;
+  }
+  silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
 
   /* Re-encrypt and send if private messge key does not exist */
   if (!(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY)) {
-
-    silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
-                    + packet->dst_id_len + packet->padlen);
-    silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
-    silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
-
     /* Re-encrypt packet */
-    silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, buffer->len);
-
-    /* Send the packet */
-    silc_server_packet_send_real(server, dst_sock, FALSE);
-
+    silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, buffer->len);
   } else {
     /* Key exist so encrypt just header and send it */
-    silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
-                    + packet->dst_id_len + packet->padlen);
-    silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
-    silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
-
-    /* Encrypt header */
-    silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, 
+    silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, 
                        SILC_PACKET_HEADER_LEN + packet->src_id_len + 
                        packet->dst_id_len + packet->padlen);
-
-    silc_server_packet_send_real(server, dst_sock, FALSE);
   }
+
+  /* Send the packet */
+  silc_server_packet_send_real(server, dst_sock, FALSE);
 }
 
 /* Sends current motd to client */
@@ -1841,14 +1817,19 @@ void silc_server_relay_packet(SilcServer server,
                              SilcPacketContext *packet,
                              bool force_send)
 {
+  const SilcBufferStruct p;
+
   silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
                   + packet->dst_id_len + packet->padlen);
-
-  silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len);
-  silc_buffer_put(dst_sock->outbuf, packet->buffer->data, packet->buffer->len);
+  if (!silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len, hmac,
+                                (const SilcBuffer)&p)) {
+    SILC_LOG_ERROR(("Cannot send packet"));
+    return;
+  }
+  silc_buffer_put((SilcBuffer)&p, packet->buffer->data, packet->buffer->len);
   
   /* Re-encrypt packet */
-  silc_packet_encrypt(cipher, hmac, sequence, dst_sock->outbuf, 
+  silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p,
                      packet->buffer->len);
   
   /* Send the packet */
index 5888909c6a1a63d3716a345c9d98d22f82a2b8d7..b1995e691522d1f1f3a6044ef9b770bd40b6103c 100644 (file)
@@ -270,6 +270,7 @@ void silc_server_backup_broadcast(SilcServer server,
   SilcServerEntry backup;
   SilcSocketConnection sock;
   SilcBuffer buffer;
+  const SilcBufferStruct p;
   SilcIDListData idata;
   int i;
 
@@ -291,13 +292,16 @@ void silc_server_backup_broadcast(SilcServer server,
     idata = (SilcIDListData)backup;
     sock = backup->connection;
 
-    silc_packet_send_prepare(sock, 0, 0, buffer->len); 
-    silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
+    if (!silc_packet_send_prepare(sock, 0, 0, buffer->len, idata->hmac_send,
+                                 (const SilcBuffer)&p)) {
+      SILC_LOG_ERROR(("Cannot send packet"));
+      return;
+    }
+    silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++, 
-                       sock->outbuf, sock->outbuf->len);
+                       (SilcBuffer)&p, p.len);
 
-    SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", sock->outbuf->len),
-                    sock->outbuf->data, sock->outbuf->len);
+    SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", p.len), p.data, p.len);
 
     /* Now actually send the packet */
     silc_server_packet_send_real(server, sock, FALSE);
index 5cbfc58816b6f2ce3391bdb34e40e60affad063b..3e33cd93e53b1b218c885b76a3e8144afb20fb2d 100644 (file)
@@ -1184,6 +1184,7 @@ void silc_client_packet_send(SilcClient client,
                             int force_send)
 {
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   int block_len;
   SilcUInt32 sequence = 0;
 
@@ -1241,32 +1242,20 @@ void silc_client_packet_send(SilcClient client,
     packetdata.src_id_len + packetdata.dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          data_len);
-
-  SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
-
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the data to the buffer */
-  if (data && data_len)
-    silc_buffer_put(sock->outbuf, data, data_len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock, 
+                            data, data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Error assembling packet"));
+    return;
+  }
 
   /* Encrypt the packet */
   if (cipher)
-    silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf
-                       sock->outbuf->len);
+    silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet
+                        packet.len);
 
-  SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, packet.len),
+                  packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_client_packet_send_real(client, sock, force_send);
index dbc60834a5ee67f7e49a8c83ed7413cf32c51c6d..485decf0867e70e8fec29bfba533bcf6f4d2364e 100644 (file)
@@ -46,6 +46,7 @@ void silc_client_send_channel_message(SilcClient client,
   SilcSocketConnection sock = conn->sock;
   SilcBuffer payload;
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   SilcCipher cipher;
   SilcHmac hmac;
   unsigned char *id_string;
@@ -131,34 +132,27 @@ void silc_client_send_channel_message(SilcClient client,
                                          packetdata.src_id_len +
                                          packetdata.dst_id_len), block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          data_len);
-
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the channel message payload to the outgoing data buffer */
-  silc_buffer_put(sock->outbuf, data, data_len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
+                            data, data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Error assembling packet"));
+    goto out;
+  }
 
   /* Encrypt the header and padding of the packet. This is encrypted 
      with normal session key shared with our server. */
   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
-                     sock->outbuf, SILC_PACKET_HEADER_LEN + 
+                     (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
                      packetdata.padlen);
 
-  SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Packet to channel, len %d", packet.len),
+                   packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_client_packet_send_real(client, sock, force_send);
+
+ out:
   silc_buffer_free(payload);
   silc_free(id_string);
 }
index be4d8b0d70ce410f51880b201ee356152ad6498a..2ef43aec9245307d993752a0ae37fff1a546ec80 100644 (file)
@@ -44,6 +44,7 @@ void silc_client_send_private_message(SilcClient client,
   SilcSocketConnection sock = conn->sock;
   SilcBuffer buffer;
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   SilcCipher cipher;
   SilcHmac hmac;
   int block_len;
@@ -94,31 +95,22 @@ void silc_client_send_private_message(SilcClient client,
                                          packetdata.src_id_len +
                                          packetdata.dst_id_len), block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          data_len);
-  
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the actual encrypted message payload data into the buffer. */
-  silc_buffer_put(sock->outbuf, data, data_len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock, 
+                            data, data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Error assembling packet"));
+    goto out;
+  }
 
   /* Encrypt the header and padding of the packet. */
   cipher = conn->send_key;
   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
-                     sock->outbuf, SILC_PACKET_HEADER_LEN + 
+                     (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
                      packetdata.padlen);
 
-  SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Private message packet, len %d", packet.len),
+                  packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_client_packet_send_real(client, sock, force_send);
index dc68a6bb9db8e9a4054d081f5020f0d120378954..5c5f6be6606e9db35031cc525e7095286e113a08 100644 (file)
@@ -110,176 +110,141 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
     silc_buffer_pull_tail(buffer, mac_len);
 }
 
-/* Assembles a new packet to be ready for send out. The buffer sent as
-   argument must include the data to be sent and it must not be encrypted. 
-   The packet also must have enough free space so that the SILC header
-   and padding maybe added to the packet. The packet is encrypted after 
-   this function has returned.
-
-   The buffer sent as argument should be something like following:
-
-   --------------------------------------------
-   | head             | data           | tail |
-   --------------------------------------------
-   ^                  ^
-   58 bytes           x bytes
-
-   So that the SILC header and 1 - 16 bytes of padding can fit to
-   the buffer. After assembly the buffer might look like this:
-
-   --------------------------------------------
-   | data                              |      |
-   --------------------------------------------
-   ^                                   ^
-   Start of assembled packet
-
-   Packet construct is as follows:
-
-   n bytes       SILC Header
-      2 bytes     Payload length
-      1 byte      Flags
-      1 byte      Packet type
-      1 byte      Padding length
-      1 byte      RESERVED
-      1 bytes     Source ID Length
-      1 bytes     Destination ID Length
-      1 byte      Source ID Type
-      n bytes     Source ID
-      1 byte      Destination ID Type
-      n bytes     Destination ID
-
-   1 - 16 bytes    Padding
-
-   n bytes        Data payload
-
-   All fields in the packet will be authenticated by MAC. The MAC is
-   not computed here, it must be computed separately before encrypting
-   the packet.
-
-*/
-
-void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher)
-{
-  unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
+/* 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)
+{ 
+  unsigned char tmppad[SILC_PACKET_MAX_PADLEN];   
   int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
-  int i;
+  int i, ret;
 
   SILC_LOG_DEBUG(("Assembling outgoing packet"));
-  
+
+  /* Calculate the packet's length and padding length if upper layer
+     didn't already do it. */
+
   /* Get the true length of the packet. This is saved as payload length
      into the packet header. This does not include the length of the
      padding. */
-  if (!ctx->truelen) {
-    ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN + 
-      ctx->src_id_len + ctx->dst_id_len;
-    if (ctx->truelen > SILC_PACKET_MAX_LEN) {
-      ctx->truelen -= (ctx->truelen - SILC_PACKET_MAX_LEN);
-      silc_buffer_push_tail(ctx->buffer, (ctx->truelen - SILC_PACKET_MAX_LEN));
-    }
+  if (!packet->truelen) {
+    data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_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;
   }
 
   /* Calculate the length of the padding. The padding is calculated from
      the data that will be encrypted. */
-  if (!ctx->padlen) {
-    if (ctx->long_pad)
-      ctx->padlen = SILC_PACKET_PADLEN_MAX(ctx->truelen);
-    else
-      ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen, block_len);
+  if (!packet->padlen) {
+    packet->padlen = (packet->long_pad ?
+                      SILC_PACKET_PADLEN_MAX(packet->truelen) :
+                      SILC_PACKET_PADLEN(packet->truelen, block_len));
   }
 
-  /* Put the start of the data section to the right place. */
-  silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN + 
-                  ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
+  /* Now prepare the outgoing data buffer for packet sending and start
+     assembling the packet. */
+
+  /* Return pointer to the assembled packet */
+  if (!silc_packet_send_prepare(sock, packet->truelen - data_len,
+                                packet->padlen, data_len, hmac,
+                                assembled_packet))
+    return FALSE;
 
   /* Get random padding */
-#if 1
-  for (i = 0; i < ctx->padlen; i++) tmppad[i] = 
-                                     silc_rng_global_get_byte_fast();
-#else
-  /* XXX: For testing - to be removed */
-  memset(tmppad, 65, sizeof(tmppad));
-#endif
-
-  /* Create the packet. This creates the SILC header and adds padding,
-     rest of the buffer remains as it is. */
-  silc_buffer_format(ctx->buffer, 
-                    SILC_STR_UI_SHORT(ctx->truelen),
-                    SILC_STR_UI_CHAR(ctx->flags),
-                    SILC_STR_UI_CHAR(ctx->type),
-                    SILC_STR_UI_CHAR(ctx->padlen),
-                    SILC_STR_UI_CHAR(0),
-                    SILC_STR_UI_CHAR(ctx->src_id_len),
-                    SILC_STR_UI_CHAR(ctx->dst_id_len),
-                    SILC_STR_UI_CHAR(ctx->src_id_type),
-                    SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
-                    SILC_STR_UI_CHAR(ctx->dst_id_type),
-                    SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
-                    SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
-                    SILC_STR_END);
-
-  SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len), 
-                  ctx->buffer->data, ctx->buffer->len);
+  if (rng)
+    for (i = 0; i < packet->padlen; i++) tmppad[i] =
+                                           silc_rng_get_byte_fast(rng);
+  else
+    for (i = 0; i < packet->padlen; i++) tmppad[i] =
+                                           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);
+  if (ret < 0)
+    return FALSE;
+
+  SILC_LOG_HEXDUMP(("Assembled packet, len %d", assembled_packet->len),
+                   assembled_packet->data, assembled_packet->len);
 
-  SILC_LOG_DEBUG(("Outgoing packet assembled"));
+  return TRUE;
 }
 
 /* Prepare outgoing data buffer for packet sending. This moves the data
    area so that new packet may be added into it. If needed this allocates
    more space to the buffer. This handles directly the connection's
-   outgoing buffer in SilcSocketConnection object. */
+   outgoing buffer in SilcSocketConnection object, and returns the
+   pointer to that buffer into the `packet'. */
 
-void silc_packet_send_prepare(SilcSocketConnection sock,
-                             SilcUInt32 header_len,
-                             SilcUInt32 padlen,
-                             SilcUInt32 data_len)
-{
-  int totlen, oldlen;
+bool silc_packet_send_prepare(SilcSocketConnection sock,
+                              SilcUInt32 header_len,
+                              SilcUInt32 pad_len,
+                              SilcUInt32 data_len,
+                              SilcHmac hmac,
+                              const SilcBuffer packet)
+{ 
+  int totlen;
+  unsigned char *oldptr;
+  int mac_len = hmac ? silc_hmac_len(hmac) : 0;
+
+  if (!packet)
+    return FALSE;
 
-  totlen = header_len + padlen + data_len;
+  totlen = header_len + pad_len + data_len;
 
   /* Prepare the outgoing buffer for packet sending. */
   if (!sock->outbuf) {
     /* Allocate new buffer. This is done only once per connection. */
     SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
-    
-    if (totlen > SILC_PACKET_DEFAULT_SIZE)
-      sock->outbuf = silc_buffer_alloc(totlen);
-    else
-      sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
-    silc_buffer_pull_tail(sock->outbuf, totlen);
-    silc_buffer_pull(sock->outbuf, header_len + padlen);
-  } else {
-    if (SILC_IS_OUTBUF_PENDING(sock)) {
-      /* There is some pending data in the buffer. */
-
-      /* Allocate more space if needed */
-      if ((sock->outbuf->end - sock->outbuf->tail) < 
-         (totlen + 20)) {
-       SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
-       sock->outbuf = silc_buffer_realloc(sock->outbuf, 
-                                          sock->outbuf->truelen +
-                                          (totlen * 2));
-      }
 
-      oldlen = sock->outbuf->len;
-      silc_buffer_pull_tail(sock->outbuf, totlen);
-      silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
-    } else {
+    sock->outbuf = silc_buffer_alloc(totlen > SILC_PACKET_DEFAULT_SIZE ?
+                                     totlen : SILC_PACKET_DEFAULT_SIZE);
+    if (!sock->outbuf)
+      return FALSE;
+  } else {
+    if (!SILC_IS_OUTBUF_PENDING(sock)) {
       /* Buffer is free for use */
       silc_buffer_clear(sock->outbuf);
-
-      /* Allocate more space if needed */
-      if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + 20)) {
-       SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
-       sock->outbuf = silc_buffer_realloc(sock->outbuf, 
-                                          sock->outbuf->truelen + 
-                                          (totlen * 2));
-      }
-
-      silc_buffer_pull_tail(sock->outbuf, totlen);
-      silc_buffer_pull(sock->outbuf, header_len + padlen);
     }
   }
+
+  /* Allocate more space if needed */
+  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));
+    if (!sock->outbuf)
+      return FALSE;
+  }
+
+  /* Pull data area for the new packet, and return pointer to the start of
+     the data area and save the pointer in to the `packet'. */
+  oldptr = silc_buffer_pull_tail(sock->outbuf, totlen + mac_len);
+  silc_buffer_set(packet, oldptr, totlen + mac_len);
+  silc_buffer_push_tail(packet, mac_len);
+
+  return TRUE;
 }
 
 /******************************************************************************
index a944d332f6fb65e96e0e91819f19a3f49a614cc7..d4f28ededd3fc87a0661f2c6b73ae2d7af564ebd 100644 (file)
@@ -434,78 +434,62 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
  *
  * SYNOPSIS
  *
- *    void silc_packet_assemble(SilcPacketContext *ctx);
+ *    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);
  *
  * DESCRIPTION
  *
- *    Assembles a new packet to be ready for send out. The buffer sent as
- *    argument must include the data to be sent and it must not be encrypted. 
- *    The packet also must have enough free space so that the SILC header
- *    and padding maybe added to the packet. The packet is encrypted after 
- *    this function has returned.
- *
- *    The buffer sent as argument should be something like following:
- *
- *    --------------------------------------------
- *    | head             | data           | tail |
- *    --------------------------------------------
- *    ^                  ^
- *    58 bytes           x bytes
- *
- *    So that the SILC header and 1 - 16 bytes of padding can fit to
- *    the buffer. After assembly the buffer might look like this:
- *
- *    --------------------------------------------
- *    | data                              |      |
- *    --------------------------------------------
- *    ^                                   ^
- *    Start of assembled packet
- *
- *    Packet construct is as follows (* = won't be encrypted):
- *
- *    n bytes       SILC Header
- *      2 bytes     Payload length  (*)
- *      1 byte      Flags
- *      1 byte      Packet type
- *      2 bytes     Source ID Length
- *      2 bytes     Destination ID Length
- *      1 byte      Source ID Type
- *      n bytes     Source ID
- *      1 byte      Destination ID Type
- *      n bytes     Destination ID
- *
- *    1 - 16 bytes    Padding
- *
- *    n bytes        Data payload
- *
- *    All fields in the packet will be authenticated by MAC. The MAC is
- *    not computed here, it must be computed separately before encrypting
- *    the packet.
+ *    Assembles new packet to be ready for encrypting and sending out.
+ *    The `packet' is filled by caller to include the packet header specific
+ *    values.  This prepares the socket connection's `sock' outoing buffer
+ *    for sending data, and returns the assembled packet to the 
+ *    `assembled_packet' pointer sent by the caller.  The `assembled_packet'
+ *    is a reference to the socket connection's outgoing buffer.  The
+ *    returned packet can be encrypted, and then sent to network by calling
+ *    silc_packet_send function.
  *
  ***/
-void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher);
+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);
 
 /****f* silccore/SilcPacketAPI/silc_packet_send_prepare
  *
  * SYNOPSIS
  *
- *    void silc_packet_send_prepare(SilcSocketConnection sock,
+ *    bool silc_packet_send_prepare(SilcSocketConnection sock,
  *                                  SilcUInt32 header_len,
- *                                  SilcUInt32 padlen,
- *                                  SilcUInt32 data_len);
+ *                                  SilcUInt32 pad_len,
+ *                                  SilcUInt32 data_len,
+ *                                  SilcHmac hmac,
+ *                                  const SilcBuffer packet);
  *
  * DESCRIPTION
  *
- *    Prepare outgoing data buffer for packet sending. This moves the data
- *    area so that new packet may be added into it. If needed this allocates
- *    more space to the buffer. This handles directly the connection's
- *    outgoing buffer in SilcSocketConnection object.
+ *    This function can be used to prepare the outgoing data buffer in
+ *    the socket connection specified by `sock' for packet sending.
+ *    This is used internally by packet sending routines, but application
+ *    may call this if it doesn't call silc_packet_assemble function.
+ *    If that function is called then application must not call this since
+ *    that function calls this internally.
+ *
+ *    This returns the prepared data area into the `packet' pointer provided
+ *    caller, which can be used then to add data to it, and later encrypt
+ *    it.  The `packet' includes reference to the socket connection's
+ *    outgoing buffer.
  *
  ***/
-void silc_packet_send_prepare(SilcSocketConnection sock,
-                             SilcUInt32 header_len,
-                             SilcUInt32 padlen,
-                             SilcUInt32 data_len);
+bool silc_packet_send_prepare(SilcSocketConnection sock,
+                              SilcUInt32 header_len,
+                              SilcUInt32 pad_len,
+                              SilcUInt32 data_len,
+                              SilcHmac hmac,
+                              const SilcBuffer packet);
 
 /****f* silccore/SilcPacketAPI/silc_packet_receive
  *