Fixed detaching bugs, channel key distribution after detach,
[silc.git] / apps / silcd / packet_receive.c
index feb4e0198c0a8392c312be0e3d3f81f900ab78e4..88681d97f4a33bac7e3b172dab8df2996a760e58 100644 (file)
@@ -612,7 +612,8 @@ void silc_server_notify(SilcServer server,
        if (channel->founder_key)
          silc_pkcs_public_key_free(channel->founder_key);
        channel->founder_key = NULL;
-       silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+       silc_pkcs_public_key_payload_decode(tmp, tmp_len,
+                                           &channel->founder_key);
       }
 
       break;
@@ -718,7 +719,7 @@ void silc_server_notify(SilcServer server,
       if (channel->founder_key)
        silc_pkcs_public_key_free(channel->founder_key);
       channel->founder_key = NULL;
-      silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+      silc_pkcs_public_key_payload_decode(tmp, tmp_len, &channel->founder_key);
 
       if (!channel->founder_key || 
          (client && client->data.public_key && 
@@ -938,8 +939,8 @@ void silc_server_notify(SilcServer server,
        if (channel->founder_key) {
          /* Get public key that must be present in notify */
          tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
-         if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
-                                                  &founder_key)) {
+         if (!tmp || !silc_pkcs_public_key_payload_decode(tmp, tmp_len,
+                                                          &founder_key)) {
            chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
            silc_server_force_cumode_change(server, sock, channel, chl, mode);
            notify_sent = TRUE;
@@ -948,6 +949,7 @@ void silc_server_notify(SilcServer server,
 
          /* Now match the public key we have cached and public key sent.
             They must match. */
+#if 0 /* The key may be other than the client's in 1.2 */
          if (client && client->data.public_key && 
              !silc_pkcs_public_key_compare(channel->founder_key,
                                            client->data.public_key)) {
@@ -956,6 +958,7 @@ void silc_server_notify(SilcServer server,
            notify_sent = TRUE;
            break;
          }
+#endif
          if (!silc_pkcs_public_key_compare(channel->founder_key,
                                            founder_key)) {
            chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
@@ -3643,7 +3646,8 @@ void silc_server_resume_client(SilcServer server,
     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
                            SILC_PACKET_RESUME_CLIENT, 0, 
                            buf->data, buf->len, TRUE);
-    silc_server_backup_send(server, NULL, SILC_PACKET_RESUME_CLIENT, 0,
+    silc_server_backup_send(server, detached_client->router,
+                           SILC_PACKET_RESUME_CLIENT, 0,
                            buf->data, buf->len, TRUE, TRUE);
 
     /* As router we must deliver this packet directly to the original
@@ -3774,14 +3778,18 @@ void silc_server_resume_client(SilcServer server,
                                        channel->key_len / 8, channel->key);
       silc_free(id_string);
 
-      /* Send the key packet to client */
+      /* Send the channel key to the client */
       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
                              keyp->data, keyp->len, FALSE);
 
-      if (created && server->server_type == SILC_SERVER)
-       silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), 
-                               SILC_PACKET_CHANNEL_KEY, 0, 
-                               keyp->data, keyp->len, FALSE);
+      /* Distribute the channel key to channel */
+      if (created) {
+       silc_server_send_channel_key(server, NULL, channel,
+                                    server->server_type == SILC_ROUTER ? 
+                                    FALSE : !server->standalone);
+       silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
+                               keyp->data, keyp->len, FALSE, TRUE);
+      }
 
       silc_buffer_free(keyp);
     }
@@ -3860,15 +3868,6 @@ void silc_server_resume_client(SilcServer server,
     detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
     id_cache->expire = 0;
 
-    /* Update channel information regarding global clients on channel. */
-    if (server->server_type == SILC_SERVER) {
-      silc_hash_table_list(detached_client->channels, &htl);
-      while (silc_hash_table_get(&htl, NULL, (void **)&chl))
-       chl->channel->global_users = 
-         silc_server_channel_has_global(chl->channel);
-      silc_hash_table_list_reset(&htl);
-    }
-
     silc_schedule_task_del_by_context(server->schedule, detached_client);
 
     /* Get the new owner of the resumed client */
@@ -3895,7 +3894,7 @@ void silc_server_resume_client(SilcServer server,
     }
 
     if (server->server_type == SILC_ROUTER &&
-       sock->type == SILC_SOCKET_TYPE_ROUTER && 
+       sock->type == SILC_SOCKET_TYPE_ROUTER &&
        server_entry->server_type == SILC_ROUTER)
       local = FALSE;
 
@@ -3904,15 +3903,24 @@ void silc_server_resume_client(SilcServer server,
                                     detached_client))
       silc_idcache_del_by_context(server->global_list->clients,
                                  detached_client);
-    silc_idcache_add(local && server->server_type == SILC_ROUTER ? 
-                    server->local_list->clients : 
-                    server->global_list->clients, 
+    silc_idcache_add(local && server->server_type == SILC_ROUTER ?
+                    server->local_list->clients :
+                    server->global_list->clients,
                     detached_client->nickname,
                     detached_client->id, detached_client, FALSE, NULL);
 
     /* Change the owner of the client */
     detached_client->router = server_entry;
 
+    /* Update channel information regarding global clients on channel. */
+    if (server->server_type != SILC_ROUTER) {
+      silc_hash_table_list(detached_client->channels, &htl);
+      while (silc_hash_table_get(&htl, NULL, (void **)&chl))
+       chl->channel->global_users = 
+         silc_server_channel_has_global(chl->channel);
+      silc_hash_table_list_reset(&htl);
+    }
+
     silc_free(server_id);
   }