Merge commit 'origin/silc.1.1.branch'
[silc.git] / apps / silcd / packet_receive.c
index 04eeb0d32938ec5eb2c9c8cdf9714a295a0ff408..73424a68988fe7b2016030d9c8de39bb8f33b7a9 100644 (file)
@@ -46,8 +46,17 @@ static void silc_server_notify_process(SilcServer server,
   SilcUInt32 tmp_len, tmp2_len;
   SilcBool local, ret;
 
-  if (idata->conn_type == SILC_CONN_CLIENT ||
-      packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
+  if (idata->conn_type == SILC_CONN_CLIENT) {
+    SILC_LOG_DEBUG(("Notify received from client, drop it"));
+    return;
+  }
+
+  if (packet->src_id_type != SILC_ID_SERVER){
+    SILC_LOG_DEBUG(("Bad notify packet received"));
+    return;
+  }
+
+  if (!packet->dst_id) {
     SILC_LOG_DEBUG(("Bad notify packet received"));
     return;
   }
@@ -69,8 +78,10 @@ static void silc_server_notify_process(SilcServer server,
 
   /* Parse the Notify Payload */
   payload = silc_notify_payload_parse(buffer->data, silc_buffer_len(buffer));
-  if (!payload)
+  if (!payload) {
+    SILC_LOG_DEBUG(("Marlformed notify payload"));
     return;
+  }
 
   /* If we are router and this packet is not already broadcast packet
      we will broadcast it. The sending socket really cannot be router or
@@ -84,8 +95,10 @@ static void silc_server_notify_process(SilcServer server,
       /* Packet is destined to channel */
       if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
                          packet->dst_id_type, &channel_id,
-                         sizeof(channel_id)))
+                         sizeof(channel_id))) {
+       SILC_LOG_DEBUG(("Malformed destination ID in notify packet"));
        goto out;
+      }
 
       silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
                                   packet->type, packet->flags |
@@ -112,8 +125,10 @@ static void silc_server_notify_process(SilcServer server,
 
   type = silc_notify_get_type(payload);
   args = silc_notify_get_args(payload);
-  if (!args)
+  if (!args) {
+    SILC_LOG_DEBUG(("Notify doesn't have any arguments, drop it"));
     goto out;
+  }
 
   switch(type) {
   case SILC_NOTIFY_TYPE_JOIN:
@@ -133,7 +148,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               SILC_ID_GET_ID(id), NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -251,7 +267,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               &channel_id, NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(&channel_id, SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -339,6 +356,8 @@ static void silc_server_notify_process(SilcServer server,
     client->mode = 0;
     client->router = NULL;
     client->connection = NULL;
+    client->data.created = silc_time();
+    silc_dlist_del(server->expired_clients, client);
     silc_dlist_add(server->expired_clients, client);
     break;
 
@@ -383,7 +402,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               &channel_id, NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(&channel_id, SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -503,7 +523,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               &channel_id, NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(&channel_id, SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -823,7 +844,8 @@ static void silc_server_notify_process(SilcServer server,
        channel = silc_idlist_find_channel_by_id(server->local_list,
                                                 &channel_id, NULL);
        if (!channel) {
-         SILC_LOG_DEBUG(("Notify for unknown channel"));
+         SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                         silc_id_render(&channel_id, SILC_ID_CHANNEL)));
          goto out;
        }
       }
@@ -1010,7 +1032,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               SILC_ID_GET_ID(id), NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -1079,7 +1102,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->global_list,
                                               SILC_ID_GET_ID(id), NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -1208,12 +1232,12 @@ static void silc_server_notify_process(SilcServer server,
 
            /* Get client entry */
            client = silc_idlist_find_client_by_id(server->global_list,
-                                                  SILC_ID_GET_ID(id),
+                                                  SILC_ID_GET_ID(id2),
                                                   TRUE, &cache);
            local = FALSE;
            if (!client) {
              client = silc_idlist_find_client_by_id(server->local_list,
-                                                    SILC_ID_GET_ID(id),
+                                                    SILC_ID_GET_ID(id2),
                                                     TRUE, &cache);
              local = TRUE;
              if (!client)
@@ -1241,6 +1265,7 @@ static void silc_server_notify_process(SilcServer server,
              silc_server_del_from_watcher_list(server, client);
 
            /* Remove the client */
+           silc_dlist_del(server->expired_clients, client);
            silc_idlist_del_data(client);
            silc_idlist_del_client(local ? server->local_list :
                                   server->global_list, client);
@@ -1304,7 +1329,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               &channel_id, NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -1481,6 +1507,8 @@ static void silc_server_notify_process(SilcServer server,
       client->mode = 0;
       client->router = NULL;
       client->connection = NULL;
+      client->data.created = silc_time();
+      silc_dlist_del(server->expired_clients, client);
       silc_dlist_add(server->expired_clients, client);
       break;
     }
@@ -1564,7 +1592,8 @@ static void silc_server_notify_process(SilcServer server,
       channel = silc_idlist_find_channel_by_id(server->local_list,
                                               SILC_ID_GET_ID(id), NULL);
       if (!channel) {
-       SILC_LOG_DEBUG(("Notify for unknown channel"));
+       SILC_LOG_DEBUG(("Notify for unknown channel %s",
+                       silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
        goto out;
       }
     }
@@ -1640,6 +1669,7 @@ static void silc_server_notify_process(SilcServer server,
 
        silc_server_remove_from_channels(server, NULL, client, TRUE,
                                         NULL, TRUE, FALSE);
+       silc_dlist_del(server->expired_clients, client);
        silc_idlist_del_data(client);
        silc_idlist_del_client(server->global_list, client);
       }
@@ -1652,6 +1682,7 @@ static void silc_server_notify_process(SilcServer server,
     break;
 
   default:
+    SILC_LOG_DEBUG(("Unsupported notify %d", type));
     break;
   }
 
@@ -2120,7 +2151,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   if (silc_buffer_unformat(buffer,
                           SILC_STR_UI16_NSTRING_ALLOC(&nickname,
                                                       &nickname_len),
-                          SILC_STR_END)) {
+                          SILC_STR_END) >= 0) {
     if (nickname_len > 128) {
       nickname_len = 128;
       nickname[nickname_len - 1] = '\0';
@@ -2717,7 +2748,8 @@ static void silc_server_new_id_real(SilcServer server,
       /* As a router we keep information of all global information in our
         global list. Cell wide information however is kept in the local
         list. */
-      entry = silc_idlist_add_server(id_list, NULL, 0, &id, router,
+      entry = silc_idlist_add_server(id_list, NULL, 0,
+                                    silc_id_dup(&id, SILC_ID_SERVER), router,
                                     router_sock);
       if (!entry) {
        SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
@@ -2959,9 +2991,12 @@ static void silc_server_new_channel_process(SilcServer server,
       }
 
       /* Create the channel with the provided Channel ID */
-      channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
-                                                      channel_name,
-                                                      &channel_id, FALSE);
+      channel =
+       silc_server_create_new_channel_with_id(
+                                    server, NULL, NULL,
+                                    channel_name,
+                                    silc_id_dup(&channel_id, SILC_ID_CHANNEL),
+                                    FALSE);
       if (!channel) {
        silc_channel_payload_free(payload);
        return;
@@ -3404,6 +3439,8 @@ void silc_server_resume_client(SilcServer server,
   SilcPublicKey public_key;
   const char *cipher, *hostname, *ip;
 
+  SILC_LOG_DEBUG(("Resuming client"));
+
   silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
                              NULL, &hostname, &ip, NULL);
 
@@ -3667,6 +3704,7 @@ void silc_server_resume_client(SilcServer server,
     /* Take new keys and stuff into use in the old entry */
     silc_idlist_del_data(detached_client);
     silc_idlist_add_data(detached_client, idata);
+    idata->public_key = NULL;
 
     if (detached_client->data.public_key) {
       /* Add the resumed client's public key back to repository. */
@@ -3683,6 +3721,7 @@ void silc_server_resume_client(SilcServer server,
     detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
     detached_client->mode &= ~SILC_UMODE_DETACHED;
     server->stat.my_detached--;
+    silc_dlist_del(server->expired_clients, detached_client);
 
     /* We are finished - reset resuming client */
     detached_client->resuming_client = NULL;
@@ -3700,6 +3739,7 @@ void silc_server_resume_client(SilcServer server,
     silc_server_remove_from_channels(server, NULL, client, FALSE,
                                     NULL, FALSE, FALSE);
     silc_server_del_from_watcher_list(server, client);
+    silc_dlist_del(server->expired_clients, client);
     if (!silc_idlist_del_client(server->local_list, client))
       silc_idlist_del_client(server->global_list, client);
     client = detached_client;
@@ -3778,14 +3818,17 @@ void silc_server_resume_client(SilcServer server,
       silc_buffer_free(nidp);
     }
 
-    /* Add the client again to the ID cache to get it to correct list */
-    if (!silc_idcache_del_by_context(server->local_list->clients, client,
-                                    NULL))
-      silc_idcache_del_by_context(server->global_list->clients, client, NULL);
-    silc_free(client->id);
-    *client->id = client_id;
-    silc_idcache_add(server->local_list->clients, nicknamec,
-                    client->id, client);
+    /* Update entry */
+    if (!silc_idcache_update_by_context(server->local_list->clients, client,
+                                       &client_id, NULL, FALSE))
+      silc_idcache_update_by_context(server->global_list->clients, client,
+                                    &client_id, NULL, FALSE);
+
+    /* Move entry to local list if it is in global list */
+    if (silc_idcache_find_by_context(server->global_list->clients, client,
+                                    &id_cache))
+      silc_idcache_move(server->global_list->clients,
+                       server->local_list->clients, id_cache);
 
     /* Send some nice info to the client */
     silc_server_send_connect_notifys(server, sock, client);
@@ -3946,15 +3989,18 @@ void silc_server_resume_client(SilcServer server,
        server_entry->server_type == SILC_ROUTER)
       local = FALSE;
 
-    /* Change the client to correct list. */
-    if (!silc_idcache_del_by_context(server->local_list->clients,
-                                    detached_client, NULL))
-      silc_idcache_del_by_context(server->global_list->clients,
-                                 detached_client, NULL);
-    silc_idcache_add(local && server->server_type == SILC_ROUTER ?
-                    server->local_list->clients :
-                    server->global_list->clients, nicknamec,
-                    detached_client->id, detached_client);
+    /* Move entry to correct list */
+    if (local && server->server_type == SILC_ROUTER) {
+      if (silc_idcache_find_by_context(server->global_list->clients,
+                                      detached_client, &id_cache))
+       silc_idcache_move(server->global_list->clients,
+                         server->local_list->clients, id_cache);
+    } else {
+      if (silc_idcache_find_by_context(server->local_list->clients,
+                                      detached_client, &id_cache))
+       silc_idcache_move(server->local_list->clients,
+                         server->global_list->clients, id_cache);
+    }
 
     /* Change the owner of the client */
     detached_client->router = server_entry;