updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 12 Apr 2001 14:28:26 +0000 (14:28 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 12 Apr 2001 14:28:26 +0000 (14:28 +0000)
CHANGES
apps/silc/silc.c
apps/silcd/packet_receive.c
apps/silcd/server.c
lib/silcclient/client.c
lib/silcclient/client.h
lib/silcclient/protocol.c
lib/silccore/silcpacket.c

diff --git a/CHANGES b/CHANGES
index c08ef09a64f1e25cd37bea1cfcd1db1aad5ca04d..13b650f74043c807f531f7f301ad8eb0fca5038b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Thu Apr 12 14:42:51 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * If re-key protocol is active then process the incoming packets
+         synchronously since we must assure that icoming packets encrypted
+         with the old key is processed before the new keys is set to
+         use.  This is true other packets than for REKEY packets.
+         Affected file silcd/server.c.  The same was done to client library
+         as well, affected file lib/silcclient/client.c.
+
 Thu Apr 12 12:01:52 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed bug in client and server to accept the force send if
index 0ff3e1ed0b7112a346e151dc8b43e5de1142ac24..f4a188d648f9e4b1155eb688285637094a498e69 100644 (file)
@@ -577,6 +577,13 @@ static void silc_client_process_message(SilcClientInternal app)
     (*cmd->cb)(ctx);
 
   } else {
+    if (app->conn->current_channel)
+      silc_client_send_channel_message(app->client, 
+                                      app->conn,
+                                      app->conn->current_channel, NULL,
+                                      0, "HALOO", 5, TRUE);
+
+#if 0
     /* Normal message to a channel */
     if (len && app->conn && app->conn->current_channel &&
        app->conn->current_channel->on_channel == TRUE) {
@@ -586,6 +593,7 @@ static void silc_client_process_message(SilcClientInternal app)
                                       app->conn->current_channel, NULL,
                                       0, data, strlen(data), TRUE);
     }
+#endif
   }
 
  out:
index 1855c27c9b3cf2181bbfafa789d01a82703f9db6..c5ed42a80e5e6b01160601bb5878a02db4b21b3c 100644 (file)
@@ -2060,5 +2060,5 @@ void silc_server_rekey(SilcServer server,
 
   if (proto_ctx->pfs == FALSE)
     /* Run the protocol */
-    protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);
+    protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 1);
 }
index 8ff375709fcc0c0ca15b9ac4e8d29ed5a8dd4a14..aea2f4c660ab93722d3620e9a4463ec12cd38008 100644 (file)
@@ -884,12 +884,12 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
      timeout!! */
   hb_context = silc_calloc(1, sizeof(*hb_context));
   hb_context->server = server;
-  silc_socket_set_heartbeat(sock, 600, hb_context,
+  silc_socket_set_heartbeat(sock, 30, hb_context,
                            silc_server_perform_heartbeat,
                            server->timeout_queue);
 
   /* Register re-key timeout */
-  idata->rekey->timeout = 3600; /* XXX hardcoded */
+  idata->rekey->timeout = 60; /* XXX hardcoded */
   idata->rekey->context = (void *)server;
   silc_task_register(server->timeout_queue, sock->sock, 
                     silc_server_rekey_callback,
@@ -1259,7 +1259,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
      timeout!! */
   hb_context = silc_calloc(1, sizeof(*hb_context));
   hb_context->server = server;
-  silc_socket_set_heartbeat(sock, 600, hb_context,
+  silc_socket_set_heartbeat(sock, 30, hb_context,
                            silc_server_perform_heartbeat,
                            server->timeout_queue);
 
@@ -1422,7 +1422,7 @@ static int silc_server_packet_decrypt_check(SilcPacketType packet_type,
 
   return FALSE;
 }
-
+  
 /* Parses whole packet, received earlier. */
 
 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
@@ -1524,21 +1524,37 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context)
     break;
   case SILC_SOCKET_TYPE_CLIENT:
     /* Parse the packet with timeout (unless protocol is active) */
-    silc_task_register(server->timeout_queue, sock->sock,
-                      silc_server_packet_parse_real,
-                      (void *)parser_context, 0, 
-                      (sock->protocol ? 1 : 100000),
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+
+    /* If REKEY protocol is active we must proccess the packets synchronously
+       since we must assure that incoming packets that are encrypted with
+       the old key is processed before the new keys is set to use. */
+    if (SILC_SERVER_IS_REKEY(sock))
+      silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ,
+                                   (void *)parser_context, sock->sock);
+    else
+      silc_task_register(server->timeout_queue, sock->sock,
+                        silc_server_packet_parse_real,
+                        (void *)parser_context, 0, 
+                        (sock->protocol ? 1 : 100000),
+                        SILC_TASK_TIMEOUT,
+                        SILC_TASK_PRI_NORMAL);
     break;
   case SILC_SOCKET_TYPE_SERVER:
   case SILC_SOCKET_TYPE_ROUTER:
     /* Packets from servers are parsed as soon as possible */
-    silc_task_register(server->timeout_queue, sock->sock,
-                      silc_server_packet_parse_real,
-                      (void *)parser_context, 0, 1,
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+
+    /* If REKEY protocol is active we must proccess the packets synchronously
+       since we must assure that incoming packets that are encrypted with
+       the old key is processed before the new keys is set to use. */
+    if (SILC_SERVER_IS_REKEY(sock))
+      silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ,
+                                   (void *)parser_context, sock->sock);
+    else
+      silc_task_register(server->timeout_queue, sock->sock,
+                        silc_server_packet_parse_real,
+                        (void *)parser_context, 0, 1,
+                        SILC_TASK_TIMEOUT,
+                        SILC_TASK_PRI_NORMAL);
     break;
   default:
     return;
@@ -1744,7 +1760,7 @@ void silc_server_packet_parse_type(SilcServer server,
 
        /* Let the protocol handle the packet */
        sock->protocol->execute(server->timeout_queue, 0, 
-                               sock->protocol, sock->sock, 0, 0);
+                               sock->protocol, sock->sock, 0, 1);
       } else {
        SilcServerKEInternalContext *proto_ctx = 
          (SilcServerKEInternalContext *)sock->protocol->context;
@@ -1790,7 +1806,7 @@ void silc_server_packet_parse_type(SilcServer server,
 
        /* Let the protocol handle the packet */
        sock->protocol->execute(server->timeout_queue, 0, 
-                               sock->protocol, sock->sock, 0, 0);
+                               sock->protocol, sock->sock, 0, 1);
       } else {
        SilcServerKEInternalContext *proto_ctx = 
          (SilcServerKEInternalContext *)sock->protocol->context;
@@ -1956,9 +1972,14 @@ void silc_server_packet_parse_type(SilcServer server,
       proto_ctx->packet = silc_packet_context_dup(packet);
 
       /* Let the protocol handle the packet */
-      sock->protocol->execute(server->timeout_queue, 0, 
-                             sock->protocol, sock->sock,
-                             0, 100000);
+      if (proto_ctx->responder == FALSE)
+       sock->protocol->execute(server->timeout_queue, 0, 
+                               sock->protocol, sock->sock,
+                               0, 0);
+      else
+       sock->protocol->execute(server->timeout_queue, 0, 
+                               sock->protocol, sock->sock,
+                               0, 100000);
     } else {
       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
                      "protocol active, packet dropped."));
@@ -2811,7 +2832,7 @@ SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
 
   silc_task_register(server->timeout_queue, 0, 
                     silc_server_channel_key_rekey,
-                    (void *)rekey, 3600, 0,
+                    (void *)rekey, 30, 0,
                     SILC_TASK_TIMEOUT,
                     SILC_TASK_PRI_NORMAL);
 }
@@ -2882,7 +2903,7 @@ void silc_server_create_channel_key(SilcServer server,
                                     silc_server_channel_key_rekey);
     silc_task_register(server->timeout_queue, 0, 
                       silc_server_channel_key_rekey,
-                      (void *)channel->rekey, 3600, 0,
+                      (void *)channel->rekey, 30, 0,
                       SILC_TASK_TIMEOUT,
                       SILC_TASK_PRI_NORMAL);
   }
@@ -2987,7 +3008,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
                                     silc_server_channel_key_rekey);
     silc_task_register(server->timeout_queue, 0, 
                       silc_server_channel_key_rekey,
-                      (void *)channel->rekey, 3600, 0,
+                      (void *)channel->rekey, 30, 0,
                       SILC_TASK_TIMEOUT,
                       SILC_TASK_PRI_NORMAL);
   }
index b0498639f2b1695e36ae120f23145979fd58d67a..bf7e71f7aca5ab25b48ff7ab7035db5fc9d8f058 100644 (file)
@@ -557,7 +557,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
   conn->remote_id_data_len = SILC_ID_SERVER_LEN;
 
   /* Register re-key timeout */
-  conn->rekey->timeout = 60; /* XXX hardcoded */
+  conn->rekey->timeout = 30; /* XXX hardcoded */
   conn->rekey->context = (void *)client;
   silc_task_register(client->timeout_queue, conn->sock->sock, 
                     silc_client_rekey_callback,
@@ -636,7 +636,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
       silc_buffer_push(sock->outbuf, 
                       sock->outbuf->data - sock->outbuf->head);
 
-    ret = silc_client_packet_send_real(client, sock, TRUE, TRUE);
+    ret = silc_client_packet_send_real(client, sock, TRUE, FALSE);
 
     /* If returned -2 could not write to connection now, will do
        it later. */
@@ -776,13 +776,22 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context)
   SilcClient client = (SilcClient)parser_context->context;
 
   /* Parse the packet */
-  silc_task_register(client->timeout_queue, parser_context->sock->sock, 
-                    silc_client_packet_parse_real,
-                    (void *)parser_context, 0, 1, 
-                    SILC_TASK_TIMEOUT,
-                    SILC_TASK_PRI_NORMAL);
+
+  /* If REKEY protocol is active we must proccess the packets synchronously
+     since we must assure that incoming packets that are encrypted with
+     the old key is processed before the new keys is set to use. */
+  if (SILC_CLIENT_IS_REKEY(parser_context->sock))
+    silc_client_packet_parse_real(client->timeout_queue, SILC_TASK_READ,
+                                 (void *)parser_context, 
+                                 parser_context->sock->sock);
+  else
+    silc_task_register(client->timeout_queue, parser_context->sock->sock, 
+                      silc_client_packet_parse_real,
+                      (void *)parser_context, 0, 1, 
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_NORMAL);
 }
-  
+
 /* Parses the packet type and calls what ever routines the packet type
    requires. This is done for all incoming packets. */
 
@@ -1029,10 +1038,15 @@ void silc_client_packet_parse_type(SilcClient client,
        silc_packet_context_free(proto_ctx->packet);
       
       proto_ctx->packet = silc_packet_context_dup(packet);
-      
+
       /* Let the protocol handle the packet */
-      sock->protocol->execute(client->timeout_queue, 0, 
-                             sock->protocol, sock->sock, 0, 100000);
+      if (proto_ctx->responder == FALSE)
+       sock->protocol->execute(client->timeout_queue, 0, 
+                               sock->protocol, sock->sock, 0, 0);
+      else
+       /* Let the protocol handle the packet */
+       sock->protocol->execute(client->timeout_queue, 0, 
+                               sock->protocol, sock->sock, 0, 100000);
     } else {
       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
                      "protocol active, packet dropped."));
@@ -1133,6 +1147,103 @@ void silc_client_packet_send(SilcClient client,
   silc_client_packet_send_real(client, sock, force_send, FALSE);
 }
 
+void silc_client_packet_send_flush(SilcClient client, 
+                                  SilcSocketConnection sock,
+                                  SilcPacketType type, 
+                                  void *dst_id,
+                                  SilcIdType dst_id_type,
+                                  SilcCipher cipher,
+                                  SilcHmac hmac,
+                                  unsigned char *data, 
+                                  uint32 data_len)
+{
+  SilcPacketContext packetdata;
+
+  /* First flush the packet queue. */
+  
+  if (sock->outbuf->data - sock->outbuf->head)
+    silc_buffer_push(sock->outbuf, 
+                    sock->outbuf->data - sock->outbuf->head);
+  
+  silc_client_packet_send_real(client, sock, TRUE, TRUE);
+  
+  /* The packet has been sent and now it is time to set the connection
+     back to only for input. When there is again some outgoing data 
+     available for this connection it will be set for output as well. 
+     This call clears the output setting and sets it only for input. */
+  SILC_CLIENT_SET_CONNECTION_FOR_INPUT(sock->sock);
+  SILC_UNSET_OUTBUF_PENDING(sock);
+  silc_buffer_clear(sock->outbuf);
+
+  SILC_LOG_DEBUG(("Sending packet, type %d", type));
+
+  /* Get data used in the packet sending, keys and stuff */
+  if ((!cipher || !hmac || !dst_id) && sock->user_data) {
+    if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
+      cipher = ((SilcClientConnection)sock->user_data)->send_key;
+
+    if (!hmac && ((SilcClientConnection)sock->user_data)->hmac)
+      hmac = ((SilcClientConnection)sock->user_data)->hmac;
+
+    if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
+      dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
+      dst_id_type = SILC_ID_SERVER;
+    }
+  }
+
+  /* Set the packet context pointers */
+  packetdata.flags = 0;
+  packetdata.type = type;
+  if (sock->user_data && 
+      ((SilcClientConnection)sock->user_data)->local_id_data)
+    packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
+  else 
+    packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
+  packetdata.src_id_len = SILC_ID_CLIENT_LEN;
+  packetdata.src_id_type = SILC_ID_CLIENT;
+  if (dst_id) {
+    packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
+    packetdata.dst_id_len = silc_id_get_len(dst_id_type);
+    packetdata.dst_id_type = dst_id_type;
+  } else {
+    packetdata.dst_id = NULL;
+    packetdata.dst_id_len = 0;
+    packetdata.dst_id_type = SILC_ID_NONE;
+  }
+  packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
+    packetdata.src_id_len + packetdata.dst_id_len;
+  packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
+
+  /* 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);
+
+  /* Encrypt the packet */
+  if (cipher)
+    silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
+
+  SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
+                  sock->outbuf->data, sock->outbuf->len);
+
+  /* Now actually send the packet */
+  silc_client_packet_send_real(client, sock, TRUE, TRUE);
+}
+
 /* Closes connection to remote end. Free's all allocated data except
    for some information such as nickname etc. that are valid at all time. 
    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
index 4730a65a3f33e08ab9f0b3591b33395b9fc42fda..d9e856f5295b53a30e8a1acd221a4981038a49b0 100644 (file)
@@ -294,4 +294,14 @@ void silc_client_notify_by_server(SilcClient client,
 void silc_client_private_message(SilcClient client, 
                                 SilcSocketConnection sock, 
                                 SilcPacketContext *packet);
+
+void silc_client_packet_send_flush(SilcClient client, 
+                                  SilcSocketConnection sock,
+                                  SilcPacketType type, 
+                                  void *dst_id,
+                                  SilcIdType dst_id_type,
+                                  SilcCipher cipher,
+                                  SilcHmac hmac,
+                                  unsigned char *data, 
+                                  uint32 data_len);
 #endif
index 801a5b95ac4f78dd25013b56b7b4617663673757..a6ced2c02a68f955bf5f2aadaac3d331259c3404 100644 (file)
@@ -741,8 +741,8 @@ silc_client_protocol_rekey_send_packet(SilcSKE ske,
   SilcClient client = (SilcClient)ctx->client;
 
   /* Send the packet immediately */
-  silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
-                         packet->data, packet->len, FALSE);
+  silc_client_packet_send_flush(client, ctx->sock, type, NULL, 0, NULL, NULL,
+                               packet->data, packet->len);
 }
 
 /* Performs re-key as defined in the SILC protocol specification. */
@@ -815,9 +815,9 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
           */
 
          /* Send the REKEY_DONE to indicate we will take new keys into use */
-         silc_client_packet_send(client, ctx->sock, 
-                                 SILC_PACKET_REKEY_DONE, 
-                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
+         silc_client_packet_send_flush(client, ctx->sock, 
+                                       SILC_PACKET_REKEY_DONE, 
+                                       NULL, 0, NULL, NULL, NULL, 0);
 
          /* The protocol ends in next stage. */
          protocol->state = SILC_PROTOCOL_STATE_END;
@@ -829,8 +829,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
         */
 
        /* Start the re-key by sending the REKEY packet */
-       silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, 
-                               NULL, 0, NULL, NULL, NULL, 0, FALSE);
+       silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY, 
+                                     NULL, 0, NULL, NULL, NULL, 0);
 
        if (ctx->pfs == TRUE) {
          /* 
@@ -867,9 +867,9 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
 
          /* Send the REKEY_DONE to indicate we will take new keys into use 
             now. */ 
-         silc_client_packet_send(client, ctx->sock, 
-                                 SILC_PACKET_REKEY_DONE, 
-                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
+         silc_client_packet_send_flush(client, ctx->sock, 
+                                       SILC_PACKET_REKEY_DONE, 
+                                       NULL, 0, NULL, NULL, NULL, 0);
 
          /* The protocol ends in next stage. */
          protocol->state = SILC_PROTOCOL_STATE_END;
@@ -932,8 +932,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey)
 
     /* Send the REKEY_DONE to indicate we will take new keys into use 
        now. */ 
-    silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
-                           NULL, 0, NULL, NULL, NULL, 0, FALSE);
+    silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
+                                 NULL, 0, NULL, NULL, NULL, 0);
     
     /* The protocol ends in next stage. */
     protocol->state = SILC_PROTOCOL_STATE_END;
index 80be09c46b9b704e1d9c4ff2f48cc41bc0aba1fd..1708226e1bfffec89beb06e29edb1d236bd1b259 100644 (file)
@@ -479,6 +479,7 @@ static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
     /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
     if (memcmp(mac, buffer->tail, mac_len)) {
       SILC_LOG_ERROR(("MAC failed"));
+      assert(FALSE);
       return FALSE;
     }