updates.
[silc.git] / apps / silcd / server.c
index 9047fa072da57f3fd3e853bbdc2e4fbc3e04afb7..02b1cc894524885a72876b72154f1b7585d0580a 100644 (file)
@@ -245,7 +245,7 @@ int silc_server_init(SilcServer server)
       SILC_LOG_ERROR(("Could not add ourselves to cache"));
       goto err0;
     }
-    id_entry->data.registered = TRUE;
+    id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
     
     /* Add ourselves also to the socket table. The entry allocated above
        is sent as argument for fast referencing in the future. */
@@ -868,7 +868,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   silc_buffer_free(packet);
   silc_free(id_string);
 
-  SILC_LOG_DEBUG(("Connected to router %s", sock->hostname));
+  SILC_LOG_INFO(("Connected to router %s", sock->hostname));
 
   /* Add the connected router to local server list */
   server->standalone = FALSE;
@@ -889,7 +889,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   server->id_entry->router = id_entry;
   server->router = id_entry;
   idata = (SilcIDListData)sock->user_data;
-  idata->registered = TRUE;
+  idata->status |= SILC_IDLIST_STATUS_REGISTERED;
 
   /* Perform keepalive. The `hb_context' will be freed automatically
      when finally calling the silc_socket_free function. XXX hardcoded 
@@ -1241,7 +1241,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
     return;
   }
 
-  switch(ctx->conn_type) {
+  switch (ctx->conn_type) {
   case SILC_SOCKET_TYPE_CLIENT:
     {
       SilcClientEntry client;
@@ -1646,19 +1646,19 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context)
   case SILC_SOCKET_TYPE_CLIENT:
     /* Parse the packet with timeout */
     silc_schedule_task_add(server->schedule, sock->sock,
-                      silc_server_packet_parse_real,
-                      (void *)parser_context, 0, 100000,
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+                          silc_server_packet_parse_real,
+                          (void *)parser_context, 0, 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_schedule_task_add(server->schedule, sock->sock,
-                      silc_server_packet_parse_real,
-                      (void *)parser_context, 0, 1,
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+                          silc_server_packet_parse_real,
+                          (void *)parser_context, 0, 1,
+                          SILC_TASK_TIMEOUT,
+                          SILC_TASK_PRI_NORMAL);
     break;
   default:
     return;
@@ -1677,7 +1677,7 @@ void silc_server_packet_parse_type(SilcServer server,
   SILC_LOG_DEBUG(("Parsing packet type %d", type));
 
   /* Parse the packet type */
-  switch(type) {
+  switch (type) {
   case SILC_PACKET_DISCONNECT:
     SILC_LOG_DEBUG(("Disconnect packet"));
     if (packet->flags & SILC_PACKET_FLAG_LIST)
@@ -2094,9 +2094,9 @@ void silc_server_create_connection(SilcServer server,
   sconn->remote_port = port;
 
   silc_schedule_task_add(server->schedule, 0, 
-                    silc_server_connect_router,
-                    (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
-                    SILC_TASK_PRI_NORMAL);
+                        silc_server_connect_router,
+                        (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
+                        SILC_TASK_PRI_NORMAL);
 }
 
 SILC_TASK_CALLBACK(silc_server_close_connection_final)
@@ -2236,10 +2236,10 @@ void silc_server_free_client_data(SilcServer server,
   i->server = server;
   i->client = client;
   silc_schedule_task_add(server->schedule, 0, 
-                    silc_server_free_client_data_timeout,
-                    (void *)i, 300, 0,
-                    SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
-  client->data.registered = FALSE;
+                        silc_server_free_client_data_timeout,
+                        (void *)i, 300, 0,
+                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+  client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
   client->router = NULL;
   client->connection = NULL;
 
@@ -2259,7 +2259,7 @@ void silc_server_free_sock_user_data(SilcServer server,
 {
   SILC_LOG_DEBUG(("Start"));
 
-  switch(sock->type) {
+  switch (sock->type) {
   case SILC_SOCKET_TYPE_CLIENT:
     {
       SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
@@ -2464,7 +2464,7 @@ int silc_server_remove_clients_by_server(SilcServer server,
     if (silc_idcache_list_first(list, &id_cache)) {
       while (id_cache) {
        client = (SilcClientEntry)id_cache->context;
-       if (client->data.registered == FALSE) {
+       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -2516,7 +2516,7 @@ int silc_server_remove_clients_by_server(SilcServer server,
     if (silc_idcache_list_first(list, &id_cache)) {
       while (id_cache) {
        client = (SilcClientEntry)id_cache->context;
-       if (client->data.registered == FALSE) {
+       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -2606,6 +2606,11 @@ int silc_server_remove_clients_by_server(SilcServer server,
   while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
     if (!silc_server_create_channel_key(server, channel, 0))
       return FALSE;
+
+    /* Do not send the channel key if private channel key mode is set */
+    if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
+      continue;
+
     silc_server_send_channel_key(server, NULL, channel, 
                                 server->server_type == SILC_ROUTER ? 
                                 FALSE : !server->standalone);
@@ -2935,9 +2940,9 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server,
   SILC_LOG_DEBUG(("Creating new channel"));
 
   if (!cipher)
-    cipher = "aes-256-cbc";
+    cipher = SILC_DEFAULT_CIPHER;
   if (!hmac)
-    hmac = "hmac-sha1-96";
+    hmac = SILC_DEFAULT_HMAC;
 
   /* Allocate cipher */
   if (!silc_cipher_alloc(cipher, &key))
@@ -3013,9 +3018,9 @@ silc_server_create_new_channel_with_id(SilcServer server,
   SILC_LOG_DEBUG(("Creating new channel"));
 
   if (!cipher)
-    cipher = "aes-256-cbc";
+    cipher = SILC_DEFAULT_CIPHER;
   if (!hmac)
-    hmac = "hmac-sha1-96";
+    hmac = SILC_DEFAULT_HMAC;
 
   /* Allocate cipher */
   if (!silc_cipher_alloc(cipher, &key))
@@ -3065,8 +3070,11 @@ SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
   SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
   SilcServer server = (SilcServer)rekey->context;
 
+  rekey->task = NULL;
+
   if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
     return;
+
   silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
 }
 
@@ -3090,7 +3098,7 @@ bool silc_server_create_channel_key(SilcServer server,
   }
 
   if (!channel->channel_key)
-    if (!silc_cipher_alloc("aes-256-cbc", &channel->channel_key))
+    if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key))
       return FALSE;
 
   if (key_len)
@@ -3120,7 +3128,7 @@ bool silc_server_create_channel_key(SilcServer server,
 
   /* Generate HMAC key from the channel key data and set it */
   if (!channel->hmac)
-    silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
+    silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
   silc_hash_make(channel->hmac->hash, channel->key, len, hash);
   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
   memset(hash, 0, sizeof(hash));
@@ -3131,12 +3139,15 @@ bool silc_server_create_channel_key(SilcServer server,
     channel->rekey->context = (void *)server;
     channel->rekey->channel = channel;
     channel->rekey->key_len = key_len;
+    if (channel->rekey->task)
+      silc_schedule_task_del(server->schedule, channel->rekey->task);
 
-    silc_schedule_task_add(server->schedule, 0, 
-                      silc_server_channel_key_rekey,
-                      (void *)channel->rekey, 3600, 0,
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+    channel->rekey->task = 
+      silc_schedule_task_add(server->schedule, 0, 
+                            silc_server_channel_key_rekey,
+                            (void *)channel->rekey, 3600, 0,
+                            SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
   }
 
   return TRUE;
@@ -3224,7 +3235,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
 
   /* Generate HMAC key from the channel key data and set it */
   if (!channel->hmac)
-    silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
+    silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
   silc_hash_make(channel->hmac->hash, tmp, tmp_len, hash);
   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
 
@@ -3236,19 +3247,19 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
       channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
     channel->rekey->context = (void *)server;
     channel->rekey->channel = channel;
+    if (channel->rekey->task)
+      silc_schedule_task_del(server->schedule, channel->rekey->task);
 
-    silc_schedule_task_del_by_callback(server->schedule,
-                                    silc_server_channel_key_rekey);
-    silc_schedule_task_add(server->schedule, 0, 
-                      silc_server_channel_key_rekey,
-                      (void *)channel->rekey, 3600, 0,
-                      SILC_TASK_TIMEOUT,
-                      SILC_TASK_PRI_NORMAL);
+    channel->rekey->task = 
+      silc_schedule_task_add(server->schedule, 0, 
+                            silc_server_channel_key_rekey,
+                            (void *)channel->rekey, 3600, 0,
+                            SILC_TASK_TIMEOUT,
+                            SILC_TASK_PRI_NORMAL);
   }
 
  out:
-  if (id)
-    silc_free(id);
+  silc_free(id);
   if (payload)
     silc_channel_key_payload_free(payload);
 
@@ -3275,6 +3286,7 @@ void silc_server_perform_heartbeat(SilcSocketConnection sock,
    form is dictated by the New ID payload. */
 
 static void silc_server_announce_get_servers(SilcServer server,
+                                            SilcServerEntry remote,
                                             SilcIDList id_list,
                                             SilcBuffer *servers)
 {
@@ -3289,6 +3301,14 @@ static void silc_server_announce_get_servers(SilcServer server,
       while (id_cache) {
        entry = (SilcServerEntry)id_cache->context;
 
+       /* Do not announce the one we've sending our announcements and
+          do not announce ourself. */
+       if (entry == remote || entry == server->id_entry) {
+         if (!silc_idcache_list_next(list, &id_cache))
+           break;
+         continue;
+       }
+
        idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
 
        *servers = silc_buffer_realloc(*servers, 
@@ -3319,10 +3339,12 @@ void silc_server_announce_servers(SilcServer server)
   SILC_LOG_DEBUG(("Announcing servers"));
 
   /* Get servers in local list */
-  silc_server_announce_get_servers(server, server->local_list, &servers);
+  silc_server_announce_get_servers(server, server->router,
+                                  server->local_list, &servers);
 
   /* Get servers in global list */
-  silc_server_announce_get_servers(server, server->global_list, &servers);
+  silc_server_announce_get_servers(server, server->router,
+                                  server->global_list, &servers);
 
   if (servers) {
     silc_buffer_push(servers, servers->data - servers->head);
@@ -3711,9 +3733,6 @@ void silc_server_save_users_on_channel(SilcServer server,
 {
   int i;
 
-  /* Cache the received Client ID's and modes. This cache expires
-     whenever server sends notify message to channel. It means two things;
-     some user has joined or leaved the channel. XXX TODO! */
   for (i = 0; i < user_count; i++) {
     uint16 idp_len;
     uint32 mode;
@@ -3764,7 +3783,7 @@ void silc_server_save_users_on_channel(SilcServer server,
        continue;
       }
 
-      client->data.registered = TRUE;
+      client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
     }
 
     silc_free(client_id);
@@ -3933,9 +3952,13 @@ SilcClientEntry silc_server_get_client_resolve(SilcServer server,
   if (!client || !client->nickname || !client->username) {
     SilcBuffer buffer, idp;
 
+    client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
+    client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
+    client->resolve_cmd_ident = ++server->cmd_ident;
+
     idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
     buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
-                                           ++server->cmd_ident, 1,
+                                           server->cmd_ident, 1,
                                            3, idp->data, idp->len);
     silc_server_packet_send(server, client ? client->router->connection :
                            server->router->connection,