updates.
[silc.git] / lib / silcclient / client.c
index 50445d004a888aa7a3b1a638089abd2ebea723c3..89aa1c0f4b8e057eeb8d91e56b5b4ac00ded5430 100644 (file)
@@ -142,9 +142,9 @@ SilcClientConnection silc_client_add_connection(SilcClient client,
   conn = silc_calloc(1, sizeof(*conn));
 
   /* Initialize ID caches */
-  conn->client_cache = silc_idcache_alloc(0, NULL);
-  conn->channel_cache = silc_idcache_alloc(0, NULL);
-  conn->server_cache = silc_idcache_alloc(0, NULL);
+  conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, NULL);
+  conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
+  conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
   conn->client = client;
   conn->remote_host = strdup(hostname);
   conn->remote_port = port;
@@ -191,21 +191,21 @@ void silc_client_add_socket(SilcClient client, SilcSocketConnection sock)
 
   if (!client->sockets) {
     client->sockets = silc_calloc(1, sizeof(*client->sockets));
-    client->sockets[0] = sock;
+    client->sockets[0] = silc_socket_dup(sock);
     client->sockets_count = 1;
     return;
   }
 
   for (i = 0; i < client->sockets_count; i++) {
     if (client->sockets[i] == NULL) {
-      client->sockets[i] = sock;
+      client->sockets[i] = silc_socket_dup(sock);
       return;
     }
   }
 
   client->sockets = silc_realloc(client->sockets, sizeof(*client->sockets) *
                                 (client->sockets_count + 1));
-  client->sockets[client->sockets_count] = sock;
+  client->sockets[client->sockets_count] = silc_socket_dup(sock);
   client->sockets_count++;
 }
 
@@ -220,6 +220,7 @@ void silc_client_del_socket(SilcClient client, SilcSocketConnection sock)
 
   for (i = 0; i < client->sockets_count; i++) {
     if (client->sockets[i] == sock) {
+      silc_socket_free(sock);
       client->sockets[i] = NULL;
       return;
     }
@@ -319,7 +320,7 @@ int silc_client_start_key_exchange(SilcClient client,
      protocol as context. */
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->client = (void *)client;
-  proto_ctx->sock = conn->sock;
+  proto_ctx->sock = silc_socket_dup(conn->sock);
   proto_ctx->rng = client->rng;
   proto_ctx->responder = FALSE;
   proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
@@ -434,8 +435,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
     if (ctx->dest_id)
       silc_free(ctx->dest_id);
     ctx->sock->protocol = NULL;
-    silc_task_unregister_by_callback(client->timeout_queue,
-                                    silc_client_failure_callback);
+    silc_socket_free(ctx->sock);
 
     /* Notify application of failure */
     client->ops->connect(client, ctx->sock->user_data, FALSE);
@@ -521,8 +521,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
     if (ctx->dest_id)
       silc_free(ctx->dest_id);
     conn->sock->protocol = NULL;
-    silc_task_unregister_by_callback(client->timeout_queue,
-                                    silc_client_failure_callback);
+    silc_socket_free(ctx->sock);
 
     /* Notify application of failure */
     client->ops->connect(client, ctx->sock->user_data, FALSE);
@@ -554,7 +553,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
   /* Save remote ID. */
   conn->remote_id = ctx->dest_id;
   conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
-  conn->remote_id_data_len = SILC_ID_SERVER_LEN;
+  conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
 
   /* Register re-key timeout */
   conn->rekey->timeout = 3600; /* XXX hardcoded */
@@ -564,13 +563,12 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
                     (void *)conn->sock, conn->rekey->timeout, 0,
                     SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 
-  silc_task_unregister_by_callback(client->timeout_queue,
-                                  silc_client_failure_callback);
   silc_protocol_free(protocol);
   if (ctx->auth_data)
     silc_free(ctx->auth_data);
   if (ctx->ske)
     silc_ske_free(ctx->ske);
+  silc_socket_free(ctx->sock);
   silc_free(ctx);
   conn->sock->protocol = NULL;
 }
@@ -777,22 +775,11 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context)
   SilcClient client = (SilcClient)parser_context->context;
 
   /* Parse the packet */
-
-#if 0
-  /* 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
-#endif
-    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);
+  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
@@ -1101,15 +1088,19 @@ void silc_client_packet_send(SilcClient client,
   packetdata.flags = 0;
   packetdata.type = type;
   if (sock->user_data && 
-      ((SilcClientConnection)sock->user_data)->local_id_data)
+      ((SilcClientConnection)sock->user_data)->local_id_data) {
     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
-  else 
+    packetdata.src_id_len = 
+      silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
+                     SILC_ID_CLIENT);
+  } else { 
     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
-  packetdata.src_id_len = SILC_ID_CLIENT_LEN;
+    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_len = silc_id_get_len(dst_id, dst_id_type);
     packetdata.dst_id_type = dst_id_type;
   } else {
     packetdata.dst_id = NULL;
@@ -1198,15 +1189,19 @@ void silc_client_packet_send_flush(SilcClient client,
   packetdata.flags = 0;
   packetdata.type = type;
   if (sock->user_data && 
-      ((SilcClientConnection)sock->user_data)->local_id_data)
+      ((SilcClientConnection)sock->user_data)->local_id_data) {
     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
-  else 
+    packetdata.src_id_len = 
+      silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
+                     SILC_ID_CLIENT);
+  } else { 
     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
-  packetdata.src_id_len = SILC_ID_CLIENT_LEN;
+    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_len = silc_id_get_len(dst_id, dst_id_type);
     packetdata.dst_id_type = dst_id_type;
   } else {
     packetdata.dst_id = NULL;
@@ -1379,11 +1374,13 @@ void silc_client_receive_new_id(SilcClient client,
     connecting = TRUE;
 
   /* Delete old ID from ID cache */
-  silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, conn->local_id);
+  if (conn->local_id) {
+    silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
+    silc_free(conn->local_id);
+  }
   
   /* Save the new ID */
-  if (conn->local_id)
-    silc_free(conn->local_id);
+
   if (conn->local_id_data)
     silc_free(conn->local_id_data);
 
@@ -1406,9 +1403,8 @@ void silc_client_receive_new_id(SilcClient client,
   conn->local_entry->id = conn->local_id;
   
   /* Put it to the ID cache */
-  silc_idcache_add(conn->client_cache, conn->nickname, strlen(conn->nickname),
-                  SILC_ID_CLIENT, conn->local_id, (void *)conn->local_entry,
-                  TRUE, FALSE);
+  silc_idcache_add(conn->client_cache, conn->nickname, conn->local_id, 
+                  (void *)conn->local_entry, FALSE);
 
   /* Notify application of successful connection. We do it here now that
      we've received the Client ID and are allowed to send traffic. */
@@ -1440,9 +1436,8 @@ SilcChannelEntry silc_client_new_channel_id(SilcClient client,
   conn->current_channel = channel;
 
   /* Put it to the ID cache */
-  silc_idcache_add(conn->channel_cache, channel_name, strlen(channel_name),
-                  SILC_ID_CHANNEL, (void *)channel->id, (void *)channel, 
-                  TRUE, FALSE);
+  silc_idcache_add(conn->channel_cache, channel_name, (void *)channel->id, 
+                  (void *)channel, FALSE);
 
   return channel;
 }
@@ -1460,8 +1455,7 @@ void silc_client_remove_from_channels(SilcClient client,
   SilcChannelEntry channel;
   SilcChannelUser chu;
 
-  if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
-                              SILC_ID_CHANNEL, &list))
+  if (!silc_idcache_get_all(conn->channel_cache, &list))
     return;
 
   silc_idcache_list_first(list, &id_cache);
@@ -1503,8 +1497,7 @@ void silc_client_replace_from_channels(SilcClient client,
   SilcChannelEntry channel;
   SilcChannelUser chu;
 
-  if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
-                              SILC_ID_CHANNEL, &list))
+  if (!silc_idcache_get_all(conn->channel_cache, &list))
     return;
 
   silc_idcache_list_first(list, &id_cache);
@@ -1626,30 +1619,6 @@ char *silc_client_chumode_char(uint32 mode)
   return strdup(string);
 }
 
-/* Failure timeout callback. If this is called then we will immediately
-   process the received failure. We always process the failure with timeout
-   since we do not want to blindly trust to received failure packets. 
-   This won't be called (the timeout is cancelled) if the failure was
-   bogus (it is bogus if remote does not close the connection after sending
-   the failure). */
-
-SILC_TASK_CALLBACK_GLOBAL(silc_client_failure_callback)
-{
-  SilcClientFailureContext *f = (SilcClientFailureContext *)context;
-
-  if (f->sock->protocol) {
-    f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
-    f->sock->protocol->execute(f->client->timeout_queue, 0,
-                              f->sock->protocol, f->sock->sock, 0, 0);
-    
-    /* Notify application */
-    f->client->ops->failure(f->client, f->sock->user_data, f->sock->protocol,
-                           (void *)f->failure);
-  }
-
-  silc_free(f);
-}
-
 /* Registers failure timeout to process the received failure packet
    with timeout. */
 
@@ -1657,22 +1626,15 @@ void silc_client_process_failure(SilcClient client,
                                 SilcSocketConnection sock,
                                 SilcPacketContext *packet)
 {
-  SilcClientFailureContext *f;
   uint32 failure = 0;
 
   if (sock->protocol) {
     if (packet->buffer->len >= 4)
       SILC_GET32_MSB(failure, packet->buffer->data);
 
-    f = silc_calloc(1, sizeof(*f));
-    f->client = client;
-    f->sock = sock;
-    f->failure = failure;
-
-    /* We will wait 5 seconds to process this failure packet */
-    silc_task_register(client->timeout_queue, sock->sock,
-                      silc_client_failure_callback, (void *)f, 5, 0,
-                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    /* Notify application */
+    client->ops->failure(client, sock->user_data, sock->protocol,
+                        (void *)failure);
   }
 }
 
@@ -1693,7 +1655,7 @@ SILC_TASK_CALLBACK(silc_client_rekey_callback)
      to the protocol. */
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->client = (void *)client;
-  proto_ctx->sock = sock;
+  proto_ctx->sock = silc_socket_dup(sock);
   proto_ctx->responder = FALSE;
   proto_ctx->pfs = conn->rekey->pfs;
       
@@ -1737,18 +1699,11 @@ SILC_TASK_CALLBACK(silc_client_rekey_final)
       silc_packet_context_free(ctx->packet);
     if (ctx->ske)
       silc_ske_free(ctx->ske);
+    silc_socket_free(ctx->sock);
     silc_free(ctx);
     return;
   }
 
-#if 0
-  /* Take the keys into use */
-  if (ctx->pfs == TRUE)
-    silc_client_protocol_rekey_generate_pfs(client, ctx);
-  else
-    silc_client_protocol_rekey_generate(client, ctx);
-#endif
-
   /* Cleanup */
   silc_protocol_free(protocol);
   sock->protocol = NULL;
@@ -1756,5 +1711,6 @@ SILC_TASK_CALLBACK(silc_client_rekey_final)
     silc_packet_context_free(ctx->packet);
   if (ctx->ske)
     silc_ske_free(ctx->ske);
+  silc_socket_free(ctx->sock);
   silc_free(ctx);
 }