Preliminary SILC Server 1.1 commit.
[silc.git] / apps / silcd / server.c
1 /*
2
3   server.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2005, 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "serverincludes.h"
21 #include "server_internal.h"
22
23 /************************* Types and definitions ***************************/
24
25 SILC_TASK_CALLBACK(silc_server_get_stats);
26 SILC_TASK_CALLBACK(silc_server_connect_router);
27 SILC_TASK_CALLBACK(silc_server_do_rekey);
28 static void silc_server_accept_new_connection(SilcNetStatus status,
29                                               SilcStream stream,
30                                               void *context);
31 static void silc_server_packet_parse_type(SilcServer server,
32                                           SilcPacketStream sock,
33                                           SilcPacket packet);
34
35
36 /************************ Static utility functions **************************/
37
38 /* SKE public key verification callback */
39
40 static void
41 silc_server_verify_key(SilcSKE ske,
42                        SilcPublicKey public_key,
43                        void *context,
44                        SilcSKEVerifyCbCompletion completion,
45                        void *completion_context)
46 {
47   SilcPacketStream sock = context;
48   SilcUnknownEntry entry = silc_packet_get_context(sock);
49
50   SILC_LOG_DEBUG(("Verifying public key"));
51
52   if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
53     SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
54                       entry->hostname, entry->ip, entry->port,
55                       silc_pkcs_get_type(public_key)));
56     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
57                completion_context);
58     return;
59   }
60
61   /* We accept all keys without explicit verification */
62   completion(ske, SILC_SKE_STATUS_OK, completion_context);
63 }
64
65
66 /************************ Packet engine callbacks ***************************/
67
68 /* Packet engine callback to receive a packet */
69
70 static SilcBool silc_server_packet_receive(SilcPacketEngine engine,
71                                            SilcPacketStream stream,
72                                            SilcPacket packet,
73                                            void *callback_context,
74                                            void *stream_context)
75 {
76   SilcServer server = callback_context;
77   SilcIDListData idata = stream_context;
78
79   /* Packets we do not handle */
80   switch (packet->type) {
81   case SILC_PACKET_HEARTBEAT:
82   case SILC_PACKET_SUCCESS:
83   case SILC_PACKET_FAILURE:
84   case SILC_PACKET_REJECT:
85   case SILC_PACKET_KEY_EXCHANGE:
86   case SILC_PACKET_KEY_EXCHANGE_1:
87   case SILC_PACKET_KEY_EXCHANGE_2:
88   case SILC_PACKET_REKEY_DONE:
89   case SILC_PACKET_CONNECTION_AUTH:
90     return FALSE;
91     break;
92   }
93
94   /* Only specific packets can come without source ID present. */
95   if ((!packet->src_id ||
96        !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) &&
97       packet->type != SILC_PACKET_NEW_CLIENT &&
98       packet->type != SILC_PACKET_NEW_SERVER &&
99       packet->type != SILC_PACKET_DISCONNECT)
100     return FALSE;
101
102   /* NEW_CLIENT and NEW_SERVER are accepted only without source ID
103      and for unregistered connection. */
104   if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT ||
105                          packet->type == SILC_PACKET_NEW_SERVER) &&
106       (idata->status & SILC_IDLIST_STATUS_REGISTERED))
107     return FALSE;
108
109   /* Process packet */
110   silc_server_packet_parse_type(server, stream, packet);
111
112   return TRUE;
113 }
114
115 /* Packet engine callback to indicate end of stream */
116
117 static void silc_server_packet_eos(SilcPacketEngine engine,
118                                    SilcPacketStream stream,
119                                    void *callback_context,
120                                    void *stream_context)
121 {
122   SILC_LOG_DEBUG(("End of stream received"));
123 }
124
125 /* Packet engine callback to indicate error */
126
127 static void silc_server_packet_error(SilcPacketEngine engine,
128                                      SilcPacketStream stream,
129                                      SilcPacketError error,
130                                      void *callback_context,
131                                      void *stream_context)
132 {
133
134 }
135
136 /* Packet stream callbacks */
137 static SilcPacketCallbacks silc_server_stream_cbs =
138 {
139   silc_server_packet_receive,
140   silc_server_packet_eos,
141   silc_server_packet_error
142 };
143
144 /* Parses the packet type and calls what ever routines the packet type
145    requires. This is done for all incoming packets. */
146
147 static void silc_server_packet_parse_type(SilcServer server,
148                                           SilcPacketStream sock,
149                                           SilcPacket packet)
150 {
151   SilcPacketType type = packet->type;
152   SilcIDListData idata = silc_packet_get_context(sock);
153
154   SILC_LOG_DEBUG(("Received %s packet [flags %d]",
155                   silc_get_packet_name(type), packet->flags));
156
157   /* Parse the packet type */
158   switch (type) {
159   case SILC_PACKET_NOTIFY:
160     /*
161      * Received notify packet. Server can receive notify packets from
162      * router. Server then relays the notify messages to clients if needed.
163      */
164     if (packet->flags & SILC_PACKET_FLAG_LIST)
165       silc_server_notify_list(server, sock, packet);
166     else
167       silc_server_notify(server, sock, packet);
168     break;
169
170     /*
171      * Private Message packets
172      */
173   case SILC_PACKET_PRIVATE_MESSAGE:
174     /*
175      * Received private message packet. The packet is coming from either
176      * client or server.
177      */
178     if (packet->flags & SILC_PACKET_FLAG_LIST)
179       break;
180     idata->last_receive = time(NULL);
181     silc_server_private_message(server, sock, packet);
182     break;
183
184     /*
185      * Channel packets
186      */
187   case SILC_PACKET_CHANNEL_MESSAGE:
188     /*
189      * Received channel message. Channel messages are special packets
190      * (although probably most common ones) thus they are handled
191      * specially.
192      */
193     if (packet->flags & SILC_PACKET_FLAG_LIST)
194       break;
195     idata->last_receive = time(NULL);
196     silc_server_channel_message(server, sock, packet);
197     break;
198
199     /*
200      * Command packets
201      */
202   case SILC_PACKET_COMMAND:
203     /*
204      * Recived command. Processes the command request and allocates the
205      * command context and calls the command.
206      */
207     if (packet->flags & SILC_PACKET_FLAG_LIST)
208       break;
209     server->stat.commands_received++;
210     silc_server_command_process(server, sock, packet);
211     break;
212
213   case SILC_PACKET_COMMAND_REPLY:
214     /*
215      * Received command reply packet. Received command reply to command. It
216      * may be reply to command sent by us or reply to command sent by client
217      * that we've routed further.
218      */
219     if (packet->flags & SILC_PACKET_FLAG_LIST)
220       break;
221     server->stat.commands_received++;
222     silc_server_command_reply(server, sock, packet);
223     break;
224
225   case SILC_PACKET_DISCONNECT:
226     {
227       SilcStatus status;
228       char *message = NULL;
229
230       if (packet->flags & SILC_PACKET_FLAG_LIST)
231         break;
232       if (silc_buffer_len(&packet->buffer) < 1)
233         break;
234
235       status = (SilcStatus)packet->buffer.data[0];
236       if (silc_buffer_len(&packet->buffer) > 1 &&
237           silc_utf8_valid(packet->buffer.data + 1, silc_buffer_len(&packet->buffer) - 1))
238         message = silc_memdup(packet->buffer.data + 1,
239                               silc_buffer_len(&packet->buffer) - 1);
240
241 #if 0
242       SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
243                      sock->ip, sock->hostname,
244                      silc_get_status_message(status), status,
245                      message ? message : ""));
246 #endif
247       silc_free(message);
248
249       /* Do not switch to backup in case of error */
250       server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE);
251
252       /* If backup disconnected then mark that resuming will not be allowed */
253 #if 0
254       if (server->server_type == SILC_ROUTER && !server->backup_router &&
255           sock->type == SILC_CONN_SERVER && sock->user_data) {
256         SilcServerEntry server_entry = sock->user_data;
257         if (server_entry->server_type == SILC_BACKUP_ROUTER)
258           server->backup_closed = TRUE;
259       }
260
261       /* Handle the disconnection from our end too */
262       if (sock->user_data && SILC_IS_LOCAL(sock->user_data))
263         silc_server_free_sock_user_data(server, sock, NULL);
264       SILC_SET_DISCONNECTING(sock);
265       silc_server_close_connection(server, sock);
266       server->backup_noswitch = FALSE;
267 #endif
268     }
269     break;
270
271   case SILC_PACKET_CHANNEL_KEY:
272     /*
273      * Received key for channel. As channels are created by the router
274      * the keys are as well. We will distribute the key to all of our
275      * locally connected clients on the particular channel. Router
276      * never receives this channel and thus is ignored.
277      */
278     if (packet->flags & SILC_PACKET_FLAG_LIST)
279       break;
280     silc_server_channel_key(server, sock, packet);
281     break;
282
283   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
284     /*
285      * Private message key packet.
286      */
287     if (packet->flags & SILC_PACKET_FLAG_LIST)
288       break;
289     silc_server_private_message_key(server, sock, packet);
290     break;
291
292   case SILC_PACKET_CONNECTION_AUTH_REQUEST:
293     /*
294      * Connection authentication request packet. When we receive this packet
295      * we will send to the other end information about our mandatory
296      * authentication method for the connection. This packet maybe received
297      * at any time.
298      */
299     if (packet->flags & SILC_PACKET_FLAG_LIST)
300       break;
301     silc_server_connection_auth_request(server, sock, packet);
302     break;
303
304   case SILC_PACKET_NEW_ID:
305     /*
306      * Received New ID packet. This includes some new ID that has been
307      * created. It may be for client, server or channel. This is the way
308      * to distribute information about new registered entities in the
309      * SILC network.
310      */
311     if (packet->flags & SILC_PACKET_FLAG_LIST)
312       silc_server_new_id_list(server, sock, packet);
313     else
314       silc_server_new_id(server, sock, packet);
315     break;
316
317   case SILC_PACKET_NEW_CLIENT:
318     /*
319      * Received new client packet. This includes client information that
320      * we will use to create initial client ID. After creating new
321      * ID we will send it to the client.
322      */
323     if (packet->flags & SILC_PACKET_FLAG_LIST)
324       break;
325     silc_server_new_client(server, sock, packet);
326     break;
327
328   case SILC_PACKET_NEW_SERVER:
329     /*
330      * Received new server packet. This includes Server ID and some other
331      * information that we may save. This is received after server has
332      * connected to us.
333      */
334     if (packet->flags & SILC_PACKET_FLAG_LIST)
335       break;
336     silc_server_new_server(server, sock, packet);
337     break;
338
339   case SILC_PACKET_NEW_CHANNEL:
340     /*
341      * Received new channel packet. Information about new channel in the
342      * network are distributed using this packet.
343      */
344     if (packet->flags & SILC_PACKET_FLAG_LIST)
345       silc_server_new_channel_list(server, sock, packet);
346     else
347       silc_server_new_channel(server, sock, packet);
348     break;
349
350   case SILC_PACKET_HEARTBEAT:
351     /*
352      * Received heartbeat.
353      */
354     if (packet->flags & SILC_PACKET_FLAG_LIST)
355       break;
356     break;
357
358   case SILC_PACKET_KEY_AGREEMENT:
359     /*
360      * Received heartbeat.
361      */
362     if (packet->flags & SILC_PACKET_FLAG_LIST)
363       break;
364     silc_server_key_agreement(server, sock, packet);
365     break;
366
367   case SILC_PACKET_REKEY:
368     /*
369      * Received re-key packet. The sender wants to regenerate the session
370      * keys.
371      */
372     if (packet->flags & SILC_PACKET_FLAG_LIST)
373       break;
374     /* XXX handle rekey */
375     break;
376
377   case SILC_PACKET_FTP:
378     /* FTP packet */
379     if (packet->flags & SILC_PACKET_FLAG_LIST)
380       break;
381     silc_server_ftp(server, sock, packet);
382     break;
383
384   case SILC_PACKET_RESUME_CLIENT:
385     /* Resume client */
386     if (packet->flags & SILC_PACKET_FLAG_LIST)
387       break;
388     silc_server_resume_client(server, sock, packet);
389     break;
390
391   case SILC_PACKET_RESUME_ROUTER:
392     /* Resume router packet received. This packet is received for backup
393        router resuming protocol. */
394     if (packet->flags & SILC_PACKET_FLAG_LIST)
395       break;
396 #if 0
397     silc_server_backup_resume_router(server, sock, packet);
398 #endif
399     break;
400
401   default:
402     SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
403     break;
404   }
405 }
406
407 /****************************** Server API **********************************/
408
409 /* Allocates a new SILC server object. This has to be done before the server
410    can be used. After allocation one must call silc_server_init to initialize
411    the server. The new allocated server object is returned to the new_server
412    argument. */
413
414 SilcBool silc_server_alloc(SilcServer *new_server)
415 {
416   SilcServer server;
417
418   SILC_LOG_DEBUG(("Allocating new server object"));
419
420   server = silc_calloc(1, sizeof(*server));
421   if (!server)
422     return FALSE;
423   server->server_type = SILC_SERVER;
424   server->standalone = TRUE;
425   server->local_list = silc_calloc(1, sizeof(*server->local_list));
426   if (!server->local_list)
427     return FALSE;
428   server->global_list = silc_calloc(1, sizeof(*server->global_list));
429   if (!server->global_list)
430     return FALSE;
431   server->pending_commands = silc_dlist_init();
432   if (!server->pending_commands)
433     return FALSE;
434   server->listeners = silc_dlist_init();
435   if (!server->listeners)
436     return FALSE;
437   server->repository = silc_skr_alloc();
438   if (!server->repository)
439     return FALSE;
440
441   *new_server = server;
442
443   return TRUE;
444 }
445
446 /* Free's the SILC server object. This is called at the very end before
447    the program ends. */
448
449 void silc_server_free(SilcServer server)
450 {
451   SilcList list;
452   SilcIDCacheEntry cache;
453
454   if (!server)
455     return;
456
457   silc_server_backup_free(server);
458   silc_server_config_unref(&server->config_ref);
459   if (server->pk_hash)
460     silc_hash_table_free(server->pk_hash);
461   if (server->rng)
462     silc_rng_free(server->rng);
463   if (server->public_key)
464     silc_pkcs_public_key_free(server->public_key);
465   if (server->private_key)
466     silc_pkcs_private_key_free(server->private_key);
467   if (server->pending_commands)
468     silc_dlist_uninit(server->pending_commands);
469   if (server->id_entry)
470     silc_idlist_del_server(server->local_list, server->id_entry);
471
472   /* Delete all channels */
473   if (silc_idcache_get_all(server->local_list->channels, &list)) {
474     silc_list_start(list);
475     while ((cache = silc_list_get(list)))
476       silc_idlist_del_channel(server->local_list, cache->context);
477   }
478   if (silc_idcache_get_all(server->global_list->channels, &list)) {
479     silc_list_start(list);
480     while ((cache = silc_list_get(list)))
481       silc_idlist_del_channel(server->global_list, cache->context);
482   }
483
484   /* Delete all clients */
485   if (silc_idcache_get_all(server->local_list->clients, &list)) {
486     silc_list_start(list);
487     while ((cache = silc_list_get(list)))
488       silc_idlist_del_client(server->local_list, cache->context);
489   }
490   if (silc_idcache_get_all(server->global_list->clients, &list)) {
491     silc_list_start(list);
492     while ((cache = silc_list_get(list)))
493       silc_idlist_del_client(server->global_list, cache->context);
494   }
495
496   /* Delete all servers */
497   if (silc_idcache_get_all(server->local_list->servers, &list)) {
498     silc_list_start(list);
499     while ((cache = silc_list_get(list)))
500       silc_idlist_del_server(server->local_list, cache->context);
501   }
502   if (silc_idcache_get_all(server->global_list->servers, &list)) {
503     while ((cache = silc_list_get(list)))
504       silc_idlist_del_server(server->global_list, cache->context);
505   }
506
507   silc_idcache_free(server->local_list->clients);
508   silc_idcache_free(server->local_list->servers);
509   silc_idcache_free(server->local_list->channels);
510   silc_idcache_free(server->global_list->clients);
511   silc_idcache_free(server->global_list->servers);
512   silc_idcache_free(server->global_list->channels);
513   silc_hash_table_free(server->watcher_list);
514   silc_hash_table_free(server->watcher_list_pk);
515
516   silc_hash_free(server->md5hash);
517   silc_hash_free(server->sha1hash);
518   silc_hmac_unregister_all();
519   silc_hash_unregister_all();
520   silc_cipher_unregister_all();
521   silc_pkcs_unregister_all();
522
523   silc_free(server->local_list);
524   silc_free(server->global_list);
525   silc_free(server->server_name);
526   silc_free(server->id_string);
527   silc_free(server->purge_i);
528   silc_free(server->purge_g);
529   silc_free(server);
530 }
531
532 /* Creates a new server listener. */
533
534 static SilcNetListener
535 silc_server_listen(SilcServer server, const char *server_ip, SilcUInt16 port)
536 {
537   SilcNetListener listener;
538
539   listener =
540     silc_net_tcp_create_listener(&server_ip, 1, port, TRUE,
541                                  server->config->require_reverse_lookup,
542                                  server->schedule,
543                                  silc_server_accept_new_connection, server);
544   if (!listener) {
545     SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
546                            server_ip, port));
547     return NULL;
548   }
549
550   return listener;
551 }
552
553 /* Adds a secondary listener. */
554
555 SilcBool silc_server_init_secondary(SilcServer server)
556 {
557 #if 0
558   int sock = 0;
559   SilcPacketStream newsocket = NULL;
560   SilcServerConfigServerInfoInterface *interface;
561
562   for (interface = server->config->server_info->secondary; interface;
563        interface = interface->next, sock++) {
564
565     if (!silc_server_listen(server,
566         interface->server_ip, interface->port, &sock_list[sock]))
567       goto err;
568
569     /* Set socket to non-blocking mode */
570     silc_net_set_socket_nonblock(sock_list[sock]);
571
572     /* Add ourselves also to the socket table. The entry allocated above
573        is sent as argument for fast referencing in the future. */
574     silc_socket_alloc(sock_list[sock],
575                       SILC_CONN_SERVER, NULL, &newsocket);
576     server->sockets[sock_list[sock]] = newsocket;
577     SILC_SET_LISTENER(newsocket);
578
579     /* Perform name and address lookups to resolve the listenning address
580        and port. */
581     if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
582                             &newsocket->ip)) {
583       if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
584         !newsocket->ip) {
585         SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
586                       newsocket->hostname ? newsocket->hostname :
587                       newsocket->ip ? newsocket->ip : ""));
588         server->stat.conn_failures++;
589         goto err;
590       }
591       if (!newsocket->hostname)
592         newsocket->hostname = strdup(newsocket->ip);
593     }
594     newsocket->port = silc_net_get_local_port(sock);
595
596     newsocket->user_data = (void *)server->id_entry;
597     silc_schedule_task_add(server->schedule, sock_list[sock],
598                            silc_server_accept_new_connection,
599                            (void *)server, 0, 0,
600                            SILC_TASK_FD,
601                            SILC_TASK_PRI_NORMAL);
602   }
603
604   return TRUE;
605
606  err:
607   do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
608 #endif /* 0 */
609   return FALSE;
610 }
611
612 /* Initializes the entire SILC server. This is called always before running
613    the server. This is called only once at the initialization of the program.
614    This binds the server to its listenning port. After this function returns
615    one should call silc_server_run to start the server. This returns TRUE
616    when everything is ok to run the server. Configuration file must be
617    read and parsed before calling this. */
618
619 SilcBool silc_server_init(SilcServer server)
620 {
621   SilcServerID *id;
622   SilcServerEntry id_entry;
623   SilcIDListPurge purge;
624   SilcNetListener listener;
625   SilcUInt16 *port;
626   char **ip;
627
628   SILC_LOG_DEBUG(("Initializing server"));
629
630   server->starttime = time(NULL);
631
632   /* Take config object for us */
633   silc_server_config_ref(&server->config_ref, server->config,
634                          server->config);
635
636 #ifdef SILC_DEBUG
637   /* Set debugging on if configured */
638   if (server->config->debug_string) {
639     silc_log_debug(TRUE);
640     silc_log_set_debug_string(server->config->debug_string);
641   }
642 #endif /* SILC_DEBUG */
643
644   /* Steal public and private key from the config object */
645   server->public_key = server->config->server_info->public_key;
646   server->private_key = server->config->server_info->private_key;
647   server->config->server_info->public_key = NULL;
648   server->config->server_info->private_key = NULL;
649
650   /* Register all configured ciphers, PKCS and hash functions. */
651   if (!silc_server_config_register_ciphers(server))
652     silc_cipher_register_default();
653   if (!silc_server_config_register_pkcs(server))
654     silc_pkcs_register_default();
655   if (!silc_server_config_register_hashfuncs(server))
656     silc_hash_register_default();
657   if (!silc_server_config_register_hmacs(server))
658     silc_hmac_register_default();
659
660   /* Initialize random number generator for the server. */
661   server->rng = silc_rng_alloc();
662   silc_rng_init(server->rng);
663   silc_rng_global_init(server->rng);
664
665   /* Initialize hash functions for server to use */
666   silc_hash_alloc("md5", &server->md5hash);
667   silc_hash_alloc("sha1", &server->sha1hash);
668
669   /* Initialize the scheduler */
670   server->schedule = silc_schedule_init(server->config->param.connections_max,
671                                         server);
672   if (!server->schedule)
673     goto err;
674
675   /* First, register log files configuration for error output */
676   silc_server_config_setlogfiles(server);
677
678   /* Initialize ID caches */
679   server->local_list->clients =
680     silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
681                        server);
682   server->local_list->servers =
683     silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL);
684   server->local_list->channels =
685     silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL);
686
687   /* These are allocated for normal server as well as these hold some
688      global information that the server has fetched from its router. For
689      router these are used as they are supposed to be used on router. */
690   server->global_list->clients =
691     silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
692                        server);
693   server->global_list->servers =
694     silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL);
695   server->global_list->channels =
696     silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL);
697
698   /* Init watcher lists */
699   server->watcher_list =
700     silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
701                           silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
702                           NULL, NULL, TRUE);
703   if (!server->watcher_list)
704     goto err;
705   server->watcher_list_pk =
706     silc_hash_table_alloc(1, silc_hash_public_key, NULL,
707                           silc_hash_public_key_compare, NULL,
708                           NULL, NULL, TRUE);
709   if (!server->watcher_list_pk)
710     goto err;
711
712   /* Init public key list */
713   server->pk_hash =
714     silc_hash_table_alloc(0, silc_hash_public_key, NULL,
715                           silc_hash_public_key_compare, NULL,
716                           NULL, NULL, TRUE);
717
718   if (!server->pk_hash)
719     goto err;
720
721   /* Create TCP listener */
722   listener = silc_server_listen(
723                    server,
724                    server->config->server_info->primary == NULL ? NULL :
725                    server->config->server_info->primary->server_ip,
726                    server->config->server_info->primary == NULL ? 0 :
727                    server->config->server_info->primary->port);
728   if (!listener)
729     goto err;
730
731   silc_dlist_add(server->listeners, listener);
732
733 #if 0
734   /* Perform name and address lookups to resolve the listenning address
735      and port. */
736   if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
737                                     &newsocket->ip)) {
738     if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
739         !newsocket->ip) {
740       SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
741                       newsocket->hostname ? newsocket->hostname :
742                       newsocket->ip ? newsocket->ip : ""));
743       server->stat.conn_failures++;
744       goto err;
745     }
746     if (!newsocket->hostname)
747       newsocket->hostname = strdup(newsocket->ip);
748   }
749   newsocket->port = silc_net_get_local_port(sock);
750 #endif
751
752   /* Create a Server ID for the server. */
753   port = silc_net_listener_get_port(listener, NULL);
754   ip = silc_net_listener_get_ip(listener, NULL);
755   silc_id_create_server_id(ip[0], port[0], server->rng, &id);
756   if (!id)
757     goto err;
758
759   silc_free(port);
760   silc_free(ip[0]);
761   silc_free(ip);
762
763   server->id = id;
764   server->server_name = server->config->server_info->server_name;
765   server->config->server_info->server_name = NULL;
766
767   /* Add ourselves to the server list. We don't have a router yet
768      beacuse we haven't established a route yet. It will be done later.
769      For now, NULL is sent as router. This allocates new entry to
770      the ID list. */
771   id_entry =
772     silc_idlist_add_server(server->local_list, strdup(server->server_name),
773                            server->server_type, server->id, NULL, NULL);
774   if (!id_entry) {
775     SILC_LOG_ERROR(("Could not add ourselves to cache"));
776     goto err;
777   }
778   id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
779   server->id_entry = id_entry;
780
781   /* Create secondary TCP listeners */
782   if (silc_server_init_secondary(server) == FALSE)
783     goto err;
784
785   /* Create connections to configured routers. */
786   silc_server_create_connections(server);
787
788   server->listenning = TRUE;
789
790   /* Allocate the entire socket list that is used in server. Eventually
791      all connections will have entry in this table (it is a table of
792      pointers to the actual object that is allocated individually
793      later). */
794   server->sockets = silc_calloc(server->config->param.connections_max,
795                                 sizeof(*server->sockets));
796   if (!server->sockets)
797     goto err;
798
799   /* If server connections has been configured then we must be router as
800      normal server cannot have server connections, only router connections. */
801   if (server->config->servers) {
802     SilcServerConfigServer *ptr = server->config->servers;
803
804     server->server_type = SILC_ROUTER;
805     while (ptr) {
806       if (ptr->backup_router) {
807         server->server_type = SILC_BACKUP_ROUTER;
808         server->backup_router = TRUE;
809         server->id_entry->server_type = SILC_BACKUP_ROUTER;
810         break;
811       }
812       ptr = ptr->next;
813     }
814   }
815
816   /* Register the ID Cache purge task. This periodically purges the ID cache
817      and removes the expired cache entries. */
818
819   /* Clients local list */
820   server->purge_i = purge = silc_calloc(1, sizeof(*purge));
821   purge->cache = server->local_list->clients;
822   purge->timeout = 600;
823   silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
824                                  (void *)purge, purge->timeout, 0);
825
826   /* Clients global list */
827   server->purge_g = purge = silc_calloc(1, sizeof(*purge));
828   purge->cache = server->global_list->clients;
829   purge->timeout = 300;
830   silc_schedule_task_add_timeout(server->schedule, silc_idlist_purge,
831                                  (void *)purge, purge->timeout, 0);
832
833   /* If we are normal server we'll retrieve network statisticial information
834      once in a while from the router. */
835   if (server->server_type != SILC_ROUTER)
836     silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
837                                    server, 10, 0);
838
839   if (server->server_type == SILC_ROUTER)
840     server->stat.routers++;
841
842   /* Start packet engine */
843   server->packet_engine =
844     silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER,
845                              &silc_server_stream_cbs, server);
846   if (!server->packet_engine)
847     goto err;
848
849   SILC_LOG_DEBUG(("Server initialized"));
850
851   /* We are done here, return succesfully */
852   return TRUE;
853
854  err:
855   silc_server_config_unref(&server->config_ref);
856   return FALSE;
857 }
858
859 #if 0
860 /* Task callback to close a socket connection after rehash */
861
862 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
863 {
864   SilcServer server = context;
865   SilcPacketStream sock = server->sockets[fd];
866
867   if (!sock)
868     return;
869
870   SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
871                  sock->hostname, sock->port,
872                  (sock->type == SILC_CONN_UNKNOWN ? "Unknown" :
873                   sock->type == SILC_CONN_CLIENT ? "Client" :
874                   sock->type == SILC_CONN_SERVER ? "Server" :
875                   "Router")));
876   silc_schedule_task_del_by_context(server->schedule, sock);
877   silc_server_disconnect_remote(server, sock,
878                                 SILC_STATUS_ERR_BANNED_FROM_SERVER,
879                                 "This connection is removed from "
880                                 "configuration");
881   if (sock->user_data)
882     silc_server_free_sock_user_data(server, sock, NULL);
883 }
884 #endif /* 0 */
885
886 /* This function basically reads the config file again and switches the config
887    object pointed by the server object. After that, we have to fix various
888    things such as the server_name and the listening ports.
889    Keep in mind that we no longer have the root privileges at this point. */
890
891 SilcBool silc_server_rehash(SilcServer server)
892 {
893 #if 0
894   SilcServerConfig newconfig;
895
896   SILC_LOG_INFO(("Rehashing server"));
897
898   /* Reset the logging system */
899   silc_log_quick(TRUE);
900   silc_log_flush_all();
901
902   /* Start the main rehash phase (read again the config file) */
903   newconfig = silc_server_config_alloc(server->config_file, server);
904   if (!newconfig) {
905     SILC_LOG_ERROR(("Rehash FAILED."));
906     return FALSE;
907   }
908
909   /* Reinit scheduler if necessary */
910   if (newconfig->param.connections_max > server->config->param.connections_max)
911     if (!silc_schedule_reinit(server->schedule,
912                               newconfig->param.connections_max))
913       return FALSE;
914
915   /* Fix the server_name field */
916   if (strcmp(server->server_name, newconfig->server_info->server_name)) {
917     silc_free(server->server_name);
918
919     /* Check server name */
920     server->server_name =
921       silc_identifier_check(newconfig->server_info->server_name,
922                             strlen(newconfig->server_info->server_name),
923                             SILC_STRING_LOCALE, 256, NULL);
924     if (!server->server_name) {
925       SILC_LOG_ERROR(("Malformed server name string '%s'",
926                       server->config->server_info->server_name));
927       return FALSE;
928     }
929
930     /* Update the idcache list with a fresh pointer */
931     silc_free(server->id_entry->server_name);
932     server->id_entry->server_name = strdup(server->server_name);
933     if (!silc_idcache_del_by_context(server->local_list->servers,
934                                      server->id_entry))
935       return FALSE;
936     if (!silc_idcache_add(server->local_list->servers,
937                           strdup(server->id_entry->server_name),
938                           server->id_entry->id, server->id_entry, 0, NULL))
939       return FALSE;
940   }
941
942   /* Set logging */
943   silc_server_config_setlogfiles(server);
944
945   /* Change new key pair if necessary */
946   if (newconfig->server_info->public_key &&
947       !silc_pkcs_public_key_compare(server->public_key,
948                                     newconfig->server_info->public_key)) {
949     silc_pkcs_public_key_free(server->public_key);
950     silc_pkcs_private_key_free(server->private_key);
951     server->public_key = newconfig->server_info->public_key;
952     server->private_key = newconfig->server_info->private_key;
953     newconfig->server_info->public_key = NULL;
954     newconfig->server_info->private_key = NULL;
955
956     /* Allocate PKCS context for local public and private keys */
957     silc_pkcs_free(server->pkcs);
958     if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
959       return FALSE;
960     silc_pkcs_public_key_set(server->pkcs, server->public_key);
961     silc_pkcs_private_key_set(server->pkcs, server->private_key);
962   }
963
964   /* Check for unconfigured server and router connections and close
965      connections that were unconfigured. */
966
967   if (server->config->routers) {
968     SilcServerConfigRouter *ptr;
969     SilcServerConfigRouter *newptr;
970     SilcBool found;
971
972     for (ptr = server->config->routers; ptr; ptr = ptr->next) {
973       found = FALSE;
974
975       /* Check whether new config has this one too */
976       for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
977         if (silc_string_compare(newptr->host, ptr->host) &&
978             newptr->port == ptr->port &&
979             newptr->initiator == ptr->initiator) {
980           found = TRUE;
981           break;
982         }
983       }
984
985       if (!found && ptr->host) {
986         /* Remove this connection */
987         SilcPacketStream sock;
988         sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
989                                                ptr->host, ptr->port);
990         if (sock && !SILC_IS_LISTENER(sock))
991           silc_schedule_task_add(server->schedule, sock->sock,
992                                  silc_server_rehash_close_connection,
993                                  server, 0, 1, SILC_TASK_TIMEOUT,
994                                  SILC_TASK_PRI_NORMAL);
995       }
996     }
997   }
998
999   if (server->config->servers) {
1000     SilcServerConfigServer *ptr;
1001     SilcServerConfigServer *newptr;
1002     SilcBool found;
1003
1004     for (ptr = server->config->servers; ptr; ptr = ptr->next) {
1005       found = FALSE;
1006
1007       /* Check whether new config has this one too */
1008       for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
1009         if (silc_string_compare(newptr->host, ptr->host)) {
1010           found = TRUE;
1011           break;
1012         }
1013       }
1014
1015       if (!found && ptr->host) {
1016         /* Remove this connection */
1017         SilcPacketStream sock;
1018         sock = silc_server_find_socket_by_host(server, SILC_CONN_SERVER,
1019                                                ptr->host, 0);
1020         if (sock && !SILC_IS_LISTENER(sock))
1021           silc_schedule_task_add(server->schedule, sock->sock,
1022                                  silc_server_rehash_close_connection,
1023                                  server, 0, 1, SILC_TASK_TIMEOUT,
1024                                  SILC_TASK_PRI_NORMAL);
1025       }
1026     }
1027   }
1028
1029   if (server->config->clients) {
1030     SilcServerConfigClient *ptr;
1031     SilcServerConfigClient *newptr;
1032     SilcBool found;
1033
1034     for (ptr = server->config->clients; ptr; ptr = ptr->next) {
1035       found = FALSE;
1036
1037       /* Check whether new config has this one too */
1038       for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
1039         if (silc_string_compare(newptr->host, ptr->host)) {
1040           found = TRUE;
1041           break;
1042         }
1043       }
1044
1045       if (!found && ptr->host) {
1046         /* Remove this connection */
1047         SilcPacketStream sock;
1048         sock = silc_server_find_socket_by_host(server, SILC_CONN_CLIENT,
1049                                                ptr->host, 0);
1050         if (sock)
1051           silc_schedule_task_add(server->schedule, sock->sock,
1052                                  silc_server_rehash_close_connection,
1053                                  server, 0, 1, SILC_TASK_TIMEOUT,
1054                                  SILC_TASK_PRI_NORMAL);
1055       }
1056     }
1057   }
1058
1059   /* Create connections after rehash */
1060   silc_server_create_connections(server);
1061
1062   /* Check whether our router status has changed */
1063   if (newconfig->servers) {
1064     SilcServerConfigServer *ptr = newconfig->servers;
1065
1066     server->server_type = SILC_ROUTER;
1067     while (ptr) {
1068       if (ptr->backup_router) {
1069         server->server_type = SILC_BACKUP_ROUTER;
1070         server->backup_router = TRUE;
1071         server->id_entry->server_type = SILC_BACKUP_ROUTER;
1072         break;
1073       }
1074       ptr = ptr->next;
1075     }
1076   }
1077
1078   /* Our old config is gone now. We'll unreference our reference made in
1079      silc_server_init and then destroy it since we are destroying it
1080      underneath the application (layer which called silc_server_init). */
1081   silc_server_config_unref(&server->config_ref);
1082   silc_server_config_destroy(server->config);
1083
1084   /* Take new config context */
1085   server->config = newconfig;
1086   silc_server_config_ref(&server->config_ref, server->config, server->config);
1087
1088 #ifdef SILC_DEBUG
1089   /* Set debugging on if configured */
1090   if (server->config->debug_string) {
1091     silc_log_debug(TRUE);
1092     silc_log_set_debug_string(server->config->debug_string);
1093   }
1094 #endif /* SILC_DEBUG */
1095
1096   SILC_LOG_DEBUG(("Server rehashed"));
1097 #endif /* 0 */
1098
1099   return TRUE;
1100 }
1101
1102 /* The heart of the server. This runs the scheduler thus runs the server.
1103    When this returns the server has been stopped and the program will
1104    be terminated. */
1105
1106 void silc_server_run(SilcServer server)
1107 {
1108   SILC_LOG_INFO(("SILC Server started"));
1109
1110   /* Start the scheduler, the heart of the SILC server. When this returns
1111      the program will be terminated. */
1112   silc_schedule(server->schedule);
1113 }
1114
1115 /* Stops the SILC server. This function is used to shutdown the server.
1116    This is usually called after the scheduler has returned. After stopping
1117    the server one should call silc_server_free. */
1118
1119 void silc_server_stop(SilcServer server)
1120 {
1121   SilcDList list;
1122   SilcPacketStream ps;
1123
1124   SILC_LOG_INFO(("SILC Server shutting down"));
1125
1126   server->server_shutdown = TRUE;
1127
1128   /* Close all connections */
1129   if (server->packet_engine) {
1130     list = silc_packet_engine_get_streams(server->packet_engine);
1131
1132     silc_dlist_start(list);
1133     while ((ps = silc_dlist_get(list))) {
1134       SilcIDListData idata = silc_packet_get_context(ps);
1135
1136       if (idata)
1137         idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
1138
1139       silc_server_disconnect_remote(server, ps, SILC_STATUS_OK,
1140                                     "Server is shutting down");
1141       silc_server_free_sock_user_data(server, ps,
1142                                       "Server is shutting down");
1143     }
1144   }
1145
1146   /* We are not connected to network anymore */
1147   server->standalone = TRUE;
1148
1149   silc_schedule_stop(server->schedule);
1150   silc_schedule_uninit(server->schedule);
1151   server->schedule = NULL;
1152
1153   SILC_LOG_DEBUG(("Server stopped"));
1154 }
1155
1156 #if 0
1157 /* Parses whole packet, received earlier. */
1158
1159 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1160 {
1161   SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1162   SilcServer server = (SilcServer)parse_ctx->context;
1163   SilcPacketStream sock = parse_ctx->sock;
1164   SilcPacket *packet = parse_ctx->packet;
1165   SilcIDListData idata = (SilcIDListData)sock->user_data;
1166   int ret;
1167
1168   if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1169     SILC_LOG_DEBUG(("Connection is disconnected"));
1170     goto out;
1171   }
1172
1173   server->stat.packets_received++;
1174
1175   /* Parse the packet */
1176   if (parse_ctx->normal)
1177     ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1178   else
1179     ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1180
1181   /* If entry is disabled ignore what we got. */
1182   if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
1183       ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
1184       ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE &&
1185       ret != SILC_PACKET_KEY_EXCHANGE_1 && ret != SILC_PACKET_KEY_EXCHANGE_2) {
1186     SILC_LOG_DEBUG(("Connection is disabled (packet %s dropped)",
1187                     silc_get_packet_name(ret)));
1188     goto out;
1189   }
1190
1191   if (ret == SILC_PACKET_NONE) {
1192     SILC_LOG_DEBUG(("Error parsing packet"));
1193     goto out;
1194   }
1195
1196   /* Check that the the current client ID is same as in the client's packet. */
1197   if (sock->type == SILC_CONN_CLIENT) {
1198     SilcClientEntry client = (SilcClientEntry)sock->user_data;
1199     if (client && client->id && packet->src_id) {
1200       void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1201                                 packet->src_id_type);
1202       if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1203         silc_free(id);
1204         SILC_LOG_DEBUG(("Packet source is not same as sender"));
1205         goto out;
1206       }
1207       silc_free(id);
1208     }
1209   }
1210
1211   if (server->server_type == SILC_ROUTER) {
1212     /* Route the packet if it is not destined to us. Other ID types but
1213        server are handled separately after processing them. */
1214     if (packet->dst_id && !(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1215         packet->dst_id_type == SILC_ID_SERVER &&
1216         sock->type != SILC_CONN_CLIENT &&
1217         memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1218       SilcPacketStream conn;
1219
1220       /* Route the packet to fastest route for the destination ID */
1221       void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1222                                 packet->dst_id_type);
1223       if (!id)
1224         goto out;
1225
1226       conn = silc_server_route_get(server, id, packet->dst_id_type);
1227       if (!conn) {
1228         SILC_LOG_WARNING(("Packet to unknown server ID %s, dropped (no route)",
1229                           silc_id_render(id, SILC_ID_SERVER)));
1230         goto out;
1231       }
1232
1233       silc_server_packet_route(server, conn, packet);
1234       silc_free(id);
1235       goto out;
1236     }
1237   }
1238
1239   /* Parse the incoming packet type */
1240   silc_server_packet_parse_type(server, sock, packet);
1241
1242   /* Broadcast packet if it is marked as broadcast packet and it is
1243      originated from router and we are router. */
1244   if (server->server_type == SILC_ROUTER &&
1245       sock->type == SILC_CONN_ROUTER &&
1246       packet->flags & SILC_PACKET_FLAG_BROADCAST) {
1247     /* Broadcast to our primary route */
1248     silc_server_packet_broadcast(server, SILC_PRIMARY_ROUTE(server), packet);
1249
1250     /* If we have backup routers then we need to feed all broadcast
1251        data to those servers. */
1252     silc_server_backup_broadcast(server, sock, packet);
1253   }
1254
1255  out:
1256   silc_packet_context_free(packet);
1257   silc_free(parse_ctx);
1258 }
1259 #endif /* 0 */
1260
1261
1262 /******************************* Connecting *********************************/
1263
1264 /* Free connection context */
1265
1266 static void silc_server_connection_free(SilcServerConnection sconn)
1267 {
1268   silc_dlist_del(sconn->server->conns, sconn);
1269   silc_server_config_unref(&sconn->conn);
1270   silc_free(sconn->remote_host);
1271   silc_free(sconn->backup_replace_ip);
1272   silc_free(sconn);
1273 }
1274
1275 /* Creates connection to a remote router. */
1276
1277 void silc_server_create_connection(SilcServer server,
1278                                    SilcBool reconnect,
1279                                    const char *remote_host, SilcUInt32 port,
1280                                    SilcServerConnectCallback callback,
1281                                    void *context)
1282 {
1283   SilcServerConnection sconn;
1284
1285   /* Allocate connection object for hold connection specific stuff. */
1286   sconn = silc_calloc(1, sizeof(*sconn));
1287   if (!sconn)
1288     return;
1289   sconn->remote_host = strdup(remote_host);
1290   sconn->remote_port = port;
1291   sconn->no_reconnect = reconnect == FALSE;
1292   sconn->callback = callback;
1293   sconn->callback_context = context;
1294
1295   silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1296                                  sconn, 0, 0);
1297 }
1298
1299 /* Connection authentication completion callback */
1300
1301 static void
1302 silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success,
1303                           void *context)
1304 {
1305   SilcServerConnection sconn = context;
1306   SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1307   SilcServer server = entry->server;
1308   SilcServerConfigServer *conn;
1309   SilcServerConfigConnParams *param;
1310   SilcIDListData idata;
1311   SilcServerEntry id_entry;
1312   unsigned char id[32];
1313   SilcUInt32 id_len;
1314   SilcID remote_id;
1315
1316   SILC_LOG_DEBUG(("Connection authentication completed"));
1317
1318   if (success == FALSE) {
1319     /* Authentication failed */
1320     /* XXX retry connecting */
1321
1322     silc_server_disconnect_remote(server, sconn->sock,
1323                                   SILC_STATUS_ERR_AUTH_FAILED, NULL);
1324     return;
1325   }
1326
1327   SILC_LOG_INFO(("Connected to %s %s",
1328                  SILC_CONNTYPE_STRING(entry->data.conn_type),
1329                  sconn->remote_host));
1330
1331   /* Create the actual entry for remote entity */
1332   switch (entry->data.conn_type) {
1333   case SILC_CONN_SERVER:
1334     SILC_LOG_DEBUG(("Remote is SILC server"));
1335
1336     /* Add new server.  The server must register itself to us before it
1337        becomes registered to SILC network. */
1338     id_entry = silc_idlist_add_server(server->local_list,
1339                                       strdup(sconn->remote_host),
1340                                       SILC_SERVER, NULL, NULL, sconn->sock);
1341     if (!id_entry) {
1342       silc_server_disconnect_remote(server, sconn->sock,
1343                                     SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1344       silc_server_connection_free(sconn);
1345       silc_free(entry);
1346       return;
1347     }
1348
1349     silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1350     break;
1351
1352   case SILC_CONN_ROUTER:
1353     SILC_LOG_DEBUG(("Remote is SILC router"));
1354
1355     /* Register to network */
1356     silc_id_id2str(server->id, SILC_ID_SERVER, id, sizeof(id), &id_len);
1357     if (!silc_packet_send_va(sconn->sock, SILC_PACKET_NEW_SERVER, 0,
1358                              SILC_STR_UI_SHORT(id_len),
1359                              SILC_STR_DATA(id, id_len),
1360                              SILC_STR_UI_SHORT(strlen(server->server_name)),
1361                              SILC_STR_DATA(server->server_name,
1362                                            strlen(server->server_name)),
1363                              SILC_STR_END)) {
1364       silc_server_disconnect_remote(server, sconn->sock,
1365                                     SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1366       silc_server_connection_free(sconn);
1367       silc_free(entry);
1368       return;
1369     }
1370
1371     /* Get remote ID */
1372     silc_packet_get_ids(sconn->sock, NULL, NULL, NULL, &remote_id);
1373
1374     /* Check that we do not have this ID already */
1375     id_entry = silc_idlist_find_server_by_id(server->local_list,
1376                                              &remote_id.u.server_id,
1377                                              TRUE, NULL);
1378     if (id_entry) {
1379       silc_idcache_del_by_context(server->local_list->servers, id_entry, NULL);
1380     } else {
1381       id_entry = silc_idlist_find_server_by_id(server->global_list,
1382                                                &remote_id.u.server_id,
1383                                                TRUE, NULL);
1384       if (id_entry)
1385         silc_idcache_del_by_context(server->global_list->servers, id_entry,
1386                                     NULL);
1387     }
1388
1389     SILC_LOG_DEBUG(("New server id(%s)",
1390                     silc_id_render(&remote_id.u.server_id, SILC_ID_SERVER)));
1391
1392     /* Add the connected router to global server list.  Router is sent
1393        as NULL since it's local to us. */
1394     id_entry = silc_idlist_add_server(server->global_list,
1395                                       strdup(sconn->remote_host),
1396                                       SILC_ROUTER, &remote_id.u.server_id,
1397                                       NULL, sconn->sock);
1398     if (!id_entry) {
1399       silc_server_disconnect_remote(server, sconn->sock,
1400                                     SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1401       silc_server_connection_free(sconn);
1402       silc_free(entry);
1403       return;
1404     }
1405
1406     /* Registered */
1407     silc_idlist_add_data(id_entry, (SilcIDListData)entry);
1408     idata = (SilcIDListData)entry;
1409     idata->status |= (SILC_IDLIST_STATUS_REGISTERED |
1410                       SILC_IDLIST_STATUS_LOCAL);
1411
1412     if (!sconn->backup) {
1413       /* Mark this router our primary router if we're still standalone */
1414       if (server->standalone) {
1415         SILC_LOG_DEBUG(("This connection is our primary router"));
1416         server->id_entry->router = id_entry;
1417         server->router = id_entry;
1418         server->router->server_type = SILC_ROUTER;
1419         server->standalone = FALSE;
1420         server->backup_primary = FALSE;
1421
1422         /* Announce data if we are not backup router (unless not as primary
1423            currently).  Backup router announces later at the end of
1424            resuming protocol. */
1425         if (server->backup_router && server->server_type == SILC_ROUTER) {
1426           SILC_LOG_DEBUG(("Announce data after resume protocol"));
1427         } else {
1428           /* If we are router then announce our possible servers.  Backup
1429              router announces also global servers. */
1430           if (server->server_type == SILC_ROUTER)
1431             silc_server_announce_servers(server,
1432                                          server->backup_router ? TRUE : FALSE,
1433                                          0, SILC_PRIMARY_ROUTE(server));
1434
1435           /* Announce our clients and channels to the router */
1436           silc_server_announce_clients(server, 0, SILC_PRIMARY_ROUTE(server));
1437           silc_server_announce_channels(server, 0, SILC_PRIMARY_ROUTE(server));
1438         }
1439
1440 #if 0
1441         /* If we are backup router then this primary router is whom we are
1442            backing up. */
1443         if (server->server_type == SILC_BACKUP_ROUTER)
1444           silc_server_backup_add(server, server->id_entry, sock->ip,
1445                                  sconn->remote_port, TRUE);
1446 #endif /* 0 */
1447       }
1448     } else {
1449       /* Add this server to be our backup router */
1450       id_entry->server_type = SILC_BACKUP_ROUTER;
1451       silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
1452                              sconn->backup_replace_port, FALSE);
1453     }
1454
1455     break;
1456
1457   default:
1458     silc_server_disconnect_remote(server, sconn->sock,
1459                                   SILC_STATUS_ERR_AUTH_FAILED, NULL);
1460     silc_server_connection_free(sconn);
1461     silc_free(entry);
1462     return;
1463   }
1464
1465   conn = sconn->conn.ref_ptr;
1466   param = &server->config->param;
1467   if (conn && conn->param)
1468     param = conn->param;
1469
1470   /* Register rekey timeout */
1471   sconn->rekey_timeout = param->key_exchange_rekey;
1472   silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
1473                                  sconn->sock, sconn->rekey_timeout, 0);
1474
1475 #if 0
1476   /* Perform keepalive. */
1477   silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
1478                             silc_server_perform_heartbeat,
1479                             server->schedule);
1480
1481  out:
1482   /* Call the completion callback to indicate that we've connected to
1483      the router */
1484   if (sconn && sconn->callback)
1485     (*sconn->callback)(server, id_entry, sconn->callback_context);
1486
1487   /* Free the temporary connection data context */
1488   if (sconn) {
1489     silc_server_config_unref(&sconn->conn);
1490     silc_free(sconn->remote_host);
1491     silc_free(sconn->backup_replace_ip);
1492     silc_free(sconn);
1493   }
1494   if (sconn == server->router_conn)
1495     server->router_conn = NULL;
1496 #endif /* 0 */
1497
1498   silc_free(entry);
1499 }
1500
1501 /* SKE completion callback */
1502
1503 static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status,
1504                                      SilcSKESecurityProperties prop,
1505                                      SilcSKEKeyMaterial keymat,
1506                                      SilcSKERekeyMaterial rekey,
1507                                      void *context)
1508 {
1509   SilcServerConnection sconn = context;
1510   SilcUnknownEntry entry = silc_packet_get_context(sconn->sock);
1511   SilcServer server = entry->server;
1512   SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1513   SilcAuthMethod auth_meth = SILC_AUTH_NONE;
1514   void *auth_data = NULL;
1515   SilcUInt32 auth_data_len = 0;
1516   SilcConnAuth connauth;
1517   SilcCipher send_key, receive_key;
1518   SilcHmac hmac_send, hmac_receive;
1519   SilcHash hash;
1520
1521   if (status != SILC_SKE_STATUS_OK) {
1522     /* SKE failed */
1523     SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
1524                     silc_ske_map_status(status), entry->hostname, entry->ip));
1525
1526     /* XXX retry connecting */
1527     silc_ske_free(ske);
1528     silc_server_disconnect_remote(server, sconn->sock,
1529                                   SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1530     silc_server_connection_free(sconn);
1531     return;
1532   }
1533
1534   SILC_LOG_DEBUG(("Setting keys into use"));
1535
1536   /* Set the keys into use.  The data will be encrypted after this. */
1537   if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
1538                          &hmac_send, &hmac_receive, &hash)) {
1539
1540     /* XXX retry connecting */
1541
1542     /* Error setting keys */
1543     silc_ske_free(ske);
1544     silc_server_disconnect_remote(server, sconn->sock,
1545                                   SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
1546     silc_server_connection_free(sconn);
1547     return;
1548   }
1549   silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send,
1550                        hmac_receive, FALSE);
1551
1552   SILC_LOG_DEBUG(("Starting connection authentication"));
1553
1554   connauth = silc_connauth_alloc(server->schedule, ske,
1555                                  server->config->conn_auth_timeout);
1556   if (!connauth) {
1557     /* XXX retry connecting */
1558
1559     /** Error allocating auth protocol */
1560     silc_ske_free(ske);
1561     silc_server_disconnect_remote(server, sconn->sock,
1562                                   SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
1563     silc_server_connection_free(sconn);
1564     return;
1565   }
1566
1567   /* Get authentication method */
1568   if (conn) {
1569     if (conn->passphrase) {
1570       if (conn->publickeys && !server->config->prefer_passphrase_auth) {
1571         auth_meth = SILC_AUTH_PUBLIC_KEY;
1572         auth_data = server->private_key;
1573       } else {
1574         auth_meth = SILC_AUTH_PASSWORD;
1575         auth_data = conn->passphrase;
1576         auth_data_len = conn->passphrase_len;
1577       }
1578     } else {
1579       auth_meth = SILC_AUTH_PUBLIC_KEY;
1580       auth_data = server->private_key;
1581     }
1582   }
1583
1584   /* Start connection authentication */
1585   silc_connauth_initiator(connauth, server->server_type == SILC_ROUTER ?
1586                           SILC_CONN_ROUTER : SILC_CONN_SERVER, auth_meth,
1587                           auth_data, auth_data_len,
1588                           silc_server_ke_auth_compl, sconn);
1589 }
1590
1591 /* Function that is called when the network connection to a router has
1592    been established.  This will continue with the key exchange protocol
1593    with the remote router. */
1594
1595 void silc_server_start_key_exchange(SilcServerConnection sconn)
1596 {
1597   SilcServer server = sconn->server;
1598   SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1599   SilcUnknownEntry entry;
1600   SilcSKEParamsStruct params;
1601   SilcSKE ske;
1602
1603   /* Cancel any possible retry timeouts */
1604   silc_schedule_task_del_by_context(server->schedule, sconn);
1605
1606   /* Create packet stream */
1607   sconn->sock = silc_packet_stream_create(server->packet_engine,
1608                                           server->schedule, sconn->stream);
1609   if (!sconn->sock) {
1610     SILC_LOG_ERROR(("Cannot connect: cannot create packet stream"));
1611     silc_stream_destroy(sconn->stream);
1612     silc_server_connection_free(sconn);
1613     return;
1614   }
1615   server->stat.conn_num++;
1616
1617   /* Set source ID to packet stream */
1618   if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, &server->id,
1619                            0, NULL)) {
1620     silc_packet_stream_destroy(sconn->sock);
1621     silc_server_connection_free(sconn);
1622     return;
1623   }
1624
1625   /* Create entry for remote entity */
1626   entry = silc_calloc(1, sizeof(*entry));
1627   if (!entry) {
1628     silc_packet_stream_destroy(sconn->sock);
1629     silc_server_connection_free(sconn);
1630     return;
1631   }
1632   entry->server = server;
1633   silc_packet_set_context(sconn->sock, entry);
1634
1635   /* Set Key Exchange flags from configuration, but fall back to global
1636      settings too. */
1637   memset(&params, 0, sizeof(params));
1638   SILC_GET_SKE_FLAGS(conn, params.flags);
1639   if (server->config->param.key_exchange_pfs)
1640     params.flags |= SILC_SKE_SP_FLAG_PFS;
1641
1642   /* Start SILC Key Exchange protocol */
1643   SILC_LOG_DEBUG(("Starting key exchange protocol"));
1644   ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
1645                        server->public_key, server->private_key, sconn->sock);
1646   if (!ske) {
1647     silc_free(entry);
1648     silc_packet_stream_destroy(sconn->sock);
1649     silc_server_connection_free(sconn);
1650     return;
1651   }
1652   silc_ske_set_callbacks(ske, silc_server_verify_key,
1653                          silc_server_ke_completed, sconn->sock);
1654
1655   /* Start key exchange protocol */
1656   params.version = silc_version_string;
1657   params.timeout_secs = server->config->key_exchange_timeout;
1658   silc_ske_initiator(ske, sconn->sock, &params, NULL);
1659 }
1660
1661 /* Timeout callback that will be called to retry connecting to remote
1662    router. This is used by both normal and router server. This will wait
1663    before retrying the connecting. The timeout is generated by exponential
1664    backoff algorithm. */
1665
1666 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
1667 {
1668   SilcServerConnection sconn = context;
1669   SilcServer server = sconn->server;
1670   SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
1671   SilcServerConfigConnParams *param =
1672                 (conn->param ? conn->param : &server->config->param);
1673
1674   SILC_LOG_INFO(("Retrying connecting to %s:%d", sconn->remote_host,
1675                  sconn->remote_port));
1676
1677   /* Calculate next timeout */
1678   if (sconn->retry_count >= 1) {
1679     sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
1680     if (sconn->retry_timeout > param->reconnect_interval_max)
1681       sconn->retry_timeout = param->reconnect_interval_max;
1682   } else {
1683     sconn->retry_timeout = param->reconnect_interval;
1684   }
1685   sconn->retry_count++;
1686   sconn->retry_timeout = sconn->retry_timeout +
1687     (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
1688
1689   /* If we've reached max retry count, give up. */
1690   if ((sconn->retry_count > param->reconnect_count) &&
1691       !param->reconnect_keep_trying) {
1692     SILC_LOG_ERROR(("Could not connect, giving up"));
1693     silc_server_connection_free(sconn);
1694     return;
1695   }
1696
1697   SILC_LOG_DEBUG(("Retrying connecting %d seconds", sconn->retry_timeout));
1698
1699   /* We will lookup a fresh pointer later */
1700   silc_server_config_unref(&sconn->conn);
1701
1702   /* Wait before retrying */
1703   silc_schedule_task_del_by_context(server->schedule, sconn);
1704   silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router,
1705                                  sconn, sconn->retry_timeout, 0);
1706 }
1707
1708 /* Callback for async connection to remote router */
1709
1710 static void silc_server_connection_established(SilcNetStatus status,
1711                                                SilcStream stream,
1712                                                void *context)
1713 {
1714   SilcServerConnection sconn = context;
1715   SilcServer server = sconn->server;
1716
1717   silc_schedule_task_del_by_context(server->schedule, sconn);
1718   sconn->op = NULL;
1719
1720   switch (status) {
1721   case SILC_NET_OK:
1722     SILC_LOG_DEBUG(("Connection to %s:%d established",
1723                     sconn->remote_host, sconn->remote_port));
1724
1725     /* Continue with key exchange protocol */
1726     sconn->stream = stream;
1727     silc_server_start_key_exchange(sconn);
1728     break;
1729
1730   case SILC_NET_UNKNOWN_IP:
1731   case SILC_NET_UNKNOWN_HOST:
1732     SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1733                     sconn->remote_host, sconn->remote_port,
1734                     silc_net_get_error_string(status)));
1735     silc_server_connection_free(sconn);
1736     break;
1737
1738   default:
1739     SILC_LOG_ERROR(("Could not connect to %s:%d: %s",
1740                     sconn->remote_host, sconn->remote_port,
1741                     silc_net_get_error_string(status)));
1742     if (!sconn->no_reconnect) {
1743       silc_schedule_task_add_timeout(sconn->server->schedule,
1744                                      silc_server_connect_to_router_retry,
1745                                      sconn, 1, 0);
1746     } else {
1747       silc_server_connection_free(sconn);
1748     }
1749     break;
1750   }
1751 }
1752
1753 /* Generic routine to use connect to a router. */
1754
1755 SILC_TASK_CALLBACK(silc_server_connect_router)
1756 {
1757   SilcServerConnection sconn = context;
1758   SilcServer server = sconn->server;
1759   SilcServerConfigRouter *rconn;
1760
1761   silc_schedule_task_del_by_context(server->schedule, sconn);
1762
1763   /* Don't connect if we are shutting down. */
1764   if (server->server_shutdown) {
1765     silc_server_connection_free(sconn);
1766     return;
1767   }
1768
1769   SILC_LOG_INFO(("Connecting to the %s %s on port %d",
1770                  (sconn->backup ? "backup router" : "router"),
1771                  sconn->remote_host, sconn->remote_port));
1772
1773   if (!server->no_conf) {
1774     /* Find connection configuration */
1775     rconn = silc_server_config_find_router_conn(server, sconn->remote_host,
1776                                                 sconn->remote_port);
1777     if (!rconn) {
1778       SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect",
1779                      (sconn->backup ? "backup router" : "router"),
1780                      sconn->remote_host, sconn->remote_port));
1781       silc_server_connection_free(sconn);
1782       return;
1783     }
1784     silc_server_config_ref(&sconn->conn, server->config, (void *)rconn);
1785   }
1786
1787   /* Connect to remote host */
1788   sconn->op =
1789     silc_net_tcp_connect((!server->config->server_info->primary ? NULL :
1790                           server->config->server_info->primary->server_ip),
1791                          sconn->remote_host, sconn->remote_port,
1792                          server->schedule, silc_server_connection_established,
1793                          sconn);
1794   if (!sconn->op) {
1795     SILC_LOG_ERROR(("Could not connect to router %s:%d",
1796                     sconn->remote_host, sconn->remote_port));
1797     silc_server_connection_free(sconn);
1798     return;
1799   }
1800
1801   /* Add to connection list */
1802   silc_dlist_add(server->conns, sconn);
1803 }
1804
1805 /* This function connects to our primary router or if we are a router this
1806    establishes all our primary routes. This is called at the start of the
1807    server to do authentication and key exchange with our router - called
1808    from schedule. */
1809
1810 SILC_TASK_CALLBACK(silc_server_connect_to_router)
1811 {
1812   SilcServer server = context;
1813   SilcServerConnection sconn;
1814   SilcServerConfigRouter *ptr;
1815
1816   /* Don't connect if we are shutting down. */
1817   if (server->server_shutdown)
1818     return;
1819
1820   SILC_LOG_DEBUG(("We are %s",
1821                   (server->server_type == SILC_SERVER ?
1822                    "normal server" : server->server_type == SILC_ROUTER ?
1823                    "router" : "backup router/normal server")));
1824
1825   /* XXX */
1826   if (!server->config->routers) {
1827     /* There wasn't a configured router, we will continue but we don't
1828        have a connection to outside world.  We will be standalone server. */
1829     SILC_LOG_DEBUG(("No router(s), we are standalone"));
1830     server->standalone = TRUE;
1831     return;
1832   }
1833
1834   /* Create the connections to all our routes */
1835   for (ptr = server->config->routers; ptr; ptr = ptr->next) {
1836
1837     SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
1838                     ptr->backup_router ? "Backup router" : "Router",
1839                     ptr->initiator ? "Initiator" : "Responder",
1840                     ptr->host, ptr->port));
1841
1842     if (server->server_type == SILC_ROUTER && ptr->backup_router &&
1843         ptr->initiator == FALSE && !server->backup_router &&
1844         !silc_server_config_get_backup_router(server))
1845       server->wait_backup = TRUE;
1846
1847     if (!ptr->initiator)
1848       continue;
1849
1850     /* Check whether we are connecting or connected to this host already */
1851     if (silc_server_num_sockets_by_remote(server,
1852                                           silc_net_is_ip(ptr->host) ?
1853                                           ptr->host : NULL,
1854                                           silc_net_is_ip(ptr->host) ?
1855                                           NULL : ptr->host, ptr->port)) {
1856       SILC_LOG_DEBUG(("We are already connected to %s:%d",
1857                       ptr->host, ptr->port));
1858
1859       /* If we don't have primary router and this connection is our
1860          primary router we are in desync.  Reconnect to the primary. */
1861       if (server->standalone && !server->router) {
1862         /* XXX */
1863         SilcPacketStream sock;
1864         SilcServerConfigRouter *primary =
1865           silc_server_config_get_primary_router(server);
1866         if (primary != ptr)
1867           continue;
1868         sock = silc_server_find_socket_by_host(server, SILC_CONN_ROUTER,
1869                                                ptr->host, ptr->port);
1870         if (!sock)
1871           continue;
1872         server->backup_noswitch = TRUE;
1873 #if 0
1874         if (sock->user_data)
1875           silc_server_free_sock_user_data(server, sock, NULL);
1876         silc_server_disconnect_remote(server, sock, 0, NULL);
1877 #endif /* 0 */
1878         server->backup_noswitch = FALSE;
1879         SILC_LOG_DEBUG(("Reconnecting to primary router"));
1880       } else {
1881         continue;
1882       }
1883     }
1884
1885     /* Allocate connection object for hold connection specific stuff. */
1886     sconn = silc_calloc(1, sizeof(*sconn));
1887     if (!sconn)
1888       continue;
1889     sconn->remote_host = strdup(ptr->host);
1890     sconn->remote_port = ptr->port;
1891     sconn->backup = ptr->backup_router;
1892     if (sconn->backup) {
1893       sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
1894       sconn->backup_replace_port = ptr->backup_replace_port;
1895     }
1896
1897     /* XXX */
1898     if (!server->router_conn && !sconn->backup)
1899       server->router_conn = sconn;
1900
1901     /* Connect */
1902     silc_server_connect_router(server->schedule, server, SILC_TASK_EXPIRE,
1903                                0, sconn);
1904   }
1905 }
1906
1907
1908 /************************ Accepting new connection **************************/
1909
1910 /* After this is called, server don't wait for backup router anymore.
1911    This gets called automatically even after we have backup router
1912    connection established. */
1913
1914 SILC_TASK_CALLBACK(silc_server_backup_router_wait)
1915 {
1916   SilcServer server = context;
1917   server->wait_backup = FALSE;
1918 }
1919
1920 /* Authentication data callback */
1921
1922 static SilcBool
1923 silc_server_accept_get_auth(SilcConnAuth connauth,
1924                             SilcConnectionType conn_type,
1925                             unsigned char **passphrase,
1926                             SilcUInt32 *passphrase_len,
1927                             SilcSKR *repository,
1928                             void *context)
1929 {
1930   SilcPacketStream sock = context;
1931   SilcUnknownEntry entry = silc_packet_get_context(sock);
1932   SilcServer server = entry->server;
1933
1934   SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
1935
1936   /* Remote end is client */
1937   if (conn_type == SILC_CONN_CLIENT) {
1938     SilcServerConfigClient *cconfig = entry->cconfig.ref_ptr;
1939     if (!cconfig)
1940       return FALSE;
1941
1942     *passphrase = cconfig->passphrase;
1943     *passphrase_len = cconfig->passphrase_len;
1944     if (cconfig->publickeys)
1945       *repository = server->repository;
1946
1947     entry->data.conn_type = conn_type;
1948     return TRUE;
1949   }
1950
1951   /* Remote end is server */
1952   if (conn_type == SILC_CONN_SERVER) {
1953     SilcServerConfigServer *sconfig = entry->sconfig.ref_ptr;
1954     if (!sconfig)
1955       return FALSE;
1956
1957     *passphrase = sconfig->passphrase;
1958     *passphrase_len = sconfig->passphrase_len;
1959     if (sconfig->publickeys)
1960       *repository = server->repository;
1961
1962     entry->data.conn_type = conn_type;
1963     return TRUE;
1964   }
1965
1966   /* Remote end is router */
1967   if (conn_type == SILC_CONN_ROUTER) {
1968     SilcServerConfigRouter *rconfig = entry->rconfig.ref_ptr;
1969     if (!rconfig)
1970       return FALSE;
1971
1972     *passphrase = rconfig->passphrase;
1973     *passphrase_len = rconfig->passphrase_len;
1974     if (rconfig->publickeys)
1975       *repository = server->repository;
1976
1977     entry->data.conn_type = conn_type;
1978     return TRUE;
1979   }
1980
1981   return FALSE;
1982 }
1983
1984 /* Authentication completion callback. */
1985
1986 static void
1987 silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success,
1988                               void *context)
1989 {
1990   SilcPacketStream sock = context;
1991   SilcUnknownEntry entry = silc_packet_get_context(sock);
1992   SilcServer server = entry->server;
1993   SilcServerConfigConnParams *param;
1994   void *id_entry;
1995
1996   if (success == FALSE) {
1997     /* Authentication failed */
1998     SILC_LOG_INFO(("Authentication failed for %s (%s) [%s]", entry->hostname,
1999                    entry->ip, SILC_CONNTYPE_STRING(entry->data.conn_type)));
2000     server->stat.auth_failures++;
2001     silc_server_disconnect_remote(server, sock,
2002                                   SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2003     goto out;
2004   }
2005
2006   SILC_LOG_DEBUG(("Checking whether connection is allowed"));
2007
2008   switch (entry->data.conn_type) {
2009   case SILC_CONN_CLIENT:
2010     {
2011       SilcClientEntry client;
2012       SilcServerConfigClient *conn = entry->cconfig.ref_ptr;
2013
2014       /* Verify whether this connection is after all allowed to connect */
2015       if (!silc_server_connection_allowed(server, sock, entry->data.conn_type,
2016                                           &server->config->param,
2017                                           conn->param,
2018                                           silc_connauth_get_ske(connauth))) {
2019         server->stat.auth_failures++;
2020         goto out;
2021       }
2022
2023       /* If we are primary router and we have backup router configured
2024          but it has not connected to use yet, do not accept any other
2025          connection. */
2026       if (server->wait_backup && server->server_type == SILC_ROUTER &&
2027           !server->backup_router) {
2028         SilcServerConfigRouter *router;
2029         router = silc_server_config_get_backup_router(server);
2030         if (router && strcmp(server->config->server_info->primary->server_ip,
2031                              entry->ip) &&
2032             silc_server_find_socket_by_host(server,
2033                                             SILC_CONN_SERVER,
2034                                             router->backup_replace_ip, 0)) {
2035           SILC_LOG_INFO(("Will not accept connections because we do "
2036                          "not have backup router connection established"));
2037           silc_server_disconnect_remote(server, sock,
2038                                         SILC_STATUS_ERR_PERM_DENIED,
2039                                         "We do not have connection to backup "
2040                                         "router established, try later");
2041           server->stat.auth_failures++;
2042
2043           /* From here on, wait 20 seconds for the backup router to appear. */
2044           silc_schedule_task_add_timeout(server->schedule,
2045                                          silc_server_backup_router_wait,
2046                                          (void *)server, 20, 0);
2047           goto out;
2048         }
2049       }
2050
2051       SILC_LOG_DEBUG(("Remote host is client"));
2052       SILC_LOG_INFO(("Connection %s (%s) is client", entry->hostname,
2053                      entry->ip));
2054
2055       /* Add the client to the client ID cache. The nickname and Client ID
2056          and other information is created after we have received NEW_CLIENT
2057          packet from client. */
2058       client = silc_idlist_add_client(server->local_list,
2059                                       NULL, NULL, NULL, NULL, NULL, sock);
2060       if (!client) {
2061         SILC_LOG_ERROR(("Could not add new client to cache"));
2062         server->stat.auth_failures++;
2063         silc_server_disconnect_remote(server, sock,
2064                                       SILC_STATUS_ERR_AUTH_FAILED, NULL);
2065         goto out;
2066       }
2067       entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2068
2069       /* Statistics */
2070       server->stat.my_clients++;
2071       server->stat.clients++;
2072       server->stat.cell_clients++;
2073
2074       /* Get connection parameters */
2075       if (conn->param) {
2076         param = conn->param;
2077
2078         if (!param->keepalive_secs)
2079           param->keepalive_secs = server->config->param.keepalive_secs;
2080
2081         if (!param->qos && server->config->param.qos) {
2082           param->qos = server->config->param.qos;
2083           param->qos_rate_limit = server->config->param.qos_rate_limit;
2084           param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2085           param->qos_limit_sec = server->config->param.qos_limit_sec;
2086           param->qos_limit_usec = server->config->param.qos_limit_usec;
2087         }
2088
2089         /* Check if to be anonymous connection */
2090         if (param->anonymous)
2091           client->mode |= SILC_UMODE_ANONYMOUS;
2092       }
2093
2094       /* Add public key to hash list (for whois using attributes) */
2095       if (!silc_hash_table_find_by_context(server->pk_hash,
2096                                            entry->data.public_key,
2097                                            client, NULL))
2098         silc_hash_table_add(server->pk_hash,
2099                             entry->data.public_key, client);
2100
2101       id_entry = (void *)client;
2102       break;
2103     }
2104
2105   case SILC_CONN_SERVER:
2106   case SILC_CONN_ROUTER:
2107     {
2108       SilcServerEntry new_server;
2109       SilcBool initiator = FALSE;
2110       SilcBool backup_local = FALSE;
2111       SilcBool backup_router = FALSE;
2112       char *backup_replace_ip = NULL;
2113       SilcUInt16 backup_replace_port = 0;
2114       SilcServerConfigServer *sconn = entry->sconfig.ref_ptr;
2115       SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
2116
2117       /* If we are backup router and this is incoming server connection
2118          and we do not have connection to primary router, do not allow
2119          the connection. */
2120       if (server->server_type == SILC_BACKUP_ROUTER &&
2121           entry->data.conn_type == SILC_CONN_SERVER &&
2122           !SILC_PRIMARY_ROUTE(server)) {
2123         SILC_LOG_INFO(("Will not accept server connection because we do "
2124                        "not have primary router connection established"));
2125         silc_server_disconnect_remote(server, sock,
2126                                       SILC_STATUS_ERR_PERM_DENIED,
2127                                       "We do not have connection to primary "
2128                                       "router established, try later");
2129         server->stat.auth_failures++;
2130         goto out;
2131       }
2132
2133       if (entry->data.conn_type == SILC_CONN_ROUTER) {
2134         /* Verify whether this connection is after all allowed to connect */
2135         if (!silc_server_connection_allowed(server, sock,
2136                                             entry->data.conn_type,
2137                                             &server->config->param,
2138                                             rconn ? rconn->param : NULL,
2139                                             silc_connauth_get_ske(connauth))) {
2140           server->stat.auth_failures++;
2141           goto out;
2142         }
2143
2144         if (rconn) {
2145           if (rconn->param) {
2146             param = rconn->param;
2147
2148             if (!param->keepalive_secs)
2149               param->keepalive_secs = server->config->param.keepalive_secs;
2150
2151             if (!param->qos && server->config->param.qos) {
2152               param->qos = server->config->param.qos;
2153               param->qos_rate_limit = server->config->param.qos_rate_limit;
2154               param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2155               param->qos_limit_sec = server->config->param.qos_limit_sec;
2156               param->qos_limit_usec = server->config->param.qos_limit_usec;
2157             }
2158           }
2159
2160           initiator = rconn->initiator;
2161           backup_local = rconn->backup_local;
2162           backup_router = rconn->backup_router;
2163           backup_replace_ip = rconn->backup_replace_ip;
2164           backup_replace_port = rconn->backup_replace_port;
2165         }
2166       }
2167
2168       if (entry->data.conn_type == SILC_CONN_SERVER) {
2169         /* Verify whether this connection is after all allowed to connect */
2170         if (!silc_server_connection_allowed(server, sock,
2171                                             entry->data.conn_type,
2172                                             &server->config->param,
2173                                             sconn ? sconn->param : NULL,
2174                                             silc_connauth_get_ske(connauth))) {
2175           server->stat.auth_failures++;
2176           goto out;
2177         }
2178         if (sconn) {
2179           if (sconn->param) {
2180             param = sconn->param;
2181
2182             if (!param->keepalive_secs)
2183               param->keepalive_secs = server->config->param.keepalive_secs;
2184
2185             if (!param->qos && server->config->param.qos) {
2186               param->qos = server->config->param.qos;
2187               param->qos_rate_limit = server->config->param.qos_rate_limit;
2188               param->qos_bytes_limit = server->config->param.qos_bytes_limit;
2189               param->qos_limit_sec = server->config->param.qos_limit_sec;
2190               param->qos_limit_usec = server->config->param.qos_limit_usec;
2191             }
2192           }
2193
2194           backup_router = sconn->backup_router;
2195         }
2196       }
2197
2198       /* If we are primary router and we have backup router configured
2199          but it has not connected to use yet, do not accept any other
2200          connection. */
2201 #if 0
2202       if (server->wait_backup && server->server_type == SILC_ROUTER &&
2203           !server->backup_router && !backup_router) {
2204         SilcServerConfigRouter *router;
2205         router = silc_server_config_get_backup_router(server);
2206         if (router && strcmp(server->config->server_info->primary->server_ip,
2207                              ip) &&
2208             silc_server_find_socket_by_host(server,
2209                                             SILC_CONN_SERVER,
2210                                             router->backup_replace_ip, 0)) {
2211           SILC_LOG_INFO(("Will not accept connections because we do "
2212                          "not have backup router connection established"));
2213           silc_server_disconnect_remote(server, sock,
2214                                         SILC_STATUS_ERR_PERM_DENIED,
2215                                         "We do not have connection to backup "
2216                                         "router established, try later");
2217           server->stat.auth_failures++;
2218
2219           /* From here on, wait 20 seconds for the backup router to appear. */
2220           silc_schedule_task_add_timeout(server->schedule,
2221                                          silc_server_backup_router_wait,
2222                                          (void *)server, 20, 0);
2223           goto out;
2224         }
2225       }
2226 #endif /* 0 */
2227
2228       SILC_LOG_DEBUG(("Remote host is %s",
2229                       entry->data.conn_type == SILC_CONN_SERVER ?
2230                       "server" : (backup_router ?
2231                                   "backup router" : "router")));
2232       SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname,
2233                      entry->ip, entry->data.conn_type == SILC_CONN_SERVER ?
2234                      "server" : (backup_router ?
2235                                  "backup router" : "router")));
2236
2237       /* Add the server into server cache. The server name and Server ID
2238          is updated after we have received NEW_SERVER packet from the
2239          server. We mark ourselves as router for this server if we really
2240          are router. */
2241       new_server =
2242         silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ?
2243                                 server->local_list : (backup_router ?
2244                                                       server->local_list :
2245                                                       server->global_list)),
2246                                NULL,
2247                                (entry->data.conn_type == SILC_CONN_SERVER ?
2248                                 SILC_SERVER : SILC_ROUTER),
2249                                NULL,
2250                                (entry->data.conn_type == SILC_CONN_SERVER ?
2251                                 server->id_entry : (backup_router ?
2252                                                     server->id_entry : NULL)),
2253                                sock);
2254       if (!new_server) {
2255         SILC_LOG_ERROR(("Could not add new server to cache"));
2256         silc_server_disconnect_remote(server, sock,
2257                                       SILC_STATUS_ERR_AUTH_FAILED, NULL);
2258         server->stat.auth_failures++;
2259         goto out;
2260       }
2261       entry->data.status |= SILC_IDLIST_STATUS_LOCAL;
2262
2263       id_entry = (void *)new_server;
2264
2265       /* If the incoming connection is router and marked as backup router
2266          then add it to be one of our backups */
2267       if (entry->data.conn_type == SILC_CONN_ROUTER && backup_router) {
2268         /* Change it back to SERVER type since that's what it really is. */
2269         if (backup_local)
2270           entry->data.conn_type = SILC_CONN_SERVER;
2271         new_server->server_type = SILC_BACKUP_ROUTER;
2272
2273         SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2274                                ("Backup router %s is now online",
2275                                 entry->hostname));
2276
2277         /* Remove the backup waiting with timeout */
2278         silc_schedule_task_add_timeout(server->schedule,
2279                                        silc_server_backup_router_wait,
2280                                        (void *)server, 10, 0);
2281       }
2282
2283       /* Statistics */
2284       if (entry->data.conn_type == SILC_CONN_SERVER) {
2285         server->stat.my_servers++;
2286         server->stat.servers++;
2287       } else {
2288         server->stat.my_routers++;
2289         server->stat.routers++;
2290       }
2291
2292       /* Check whether this connection is to be our primary router connection
2293          if we do not already have the primary route. */
2294       if (!backup_router &&
2295           server->standalone && entry->data.conn_type == SILC_CONN_ROUTER) {
2296         if (silc_server_config_is_primary_route(server) && !initiator)
2297           break;
2298
2299         SILC_LOG_DEBUG(("We are not standalone server anymore"));
2300         server->standalone = FALSE;
2301         if (!server->id_entry->router) {
2302           server->id_entry->router = id_entry;
2303           server->router = id_entry;
2304         }
2305       }
2306
2307       break;
2308     }
2309
2310   default:
2311     goto out;
2312     break;
2313   }
2314
2315   /* Add the common data structure to the ID entry. */
2316   silc_idlist_add_data(id_entry, (SilcIDListData)entry);
2317   silc_packet_set_context(sock, id_entry);
2318
2319   /* Connection has been fully established now. Everything is ok. */
2320   SILC_LOG_DEBUG(("New connection authenticated"));
2321
2322   /* XXX Add connection to server->conns so that we know we have connection
2323      to this peer. */
2324   /* XXX */
2325
2326 #if 0
2327   /* Perform keepalive. */
2328   if (param->keepalive_secs)
2329     silc_socket_set_heartbeat(sock, param->keepalive_secs, server,
2330                               silc_server_perform_heartbeat,
2331                               server->schedule);
2332
2333   /* Perform Quality of Service */
2334   if (param->qos)
2335     silc_socket_set_qos(sock, param->qos_rate_limit, param->qos_bytes_limit,
2336                         param->qos_limit_sec, param->qos_limit_usec,
2337                         server->schedule);
2338 #endif
2339
2340   silc_server_config_unref(&entry->cconfig);
2341   silc_server_config_unref(&entry->sconfig);
2342   silc_server_config_unref(&entry->rconfig);
2343   silc_free(entry);
2344
2345  out:
2346   silc_ske_free(silc_connauth_get_ske(connauth));
2347   silc_connauth_free(connauth);
2348 }
2349
2350 /* SKE completion callback.  We set the new keys into use here. */
2351
2352 static void
2353 silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status,
2354                              SilcSKESecurityProperties prop,
2355                              SilcSKEKeyMaterial keymat,
2356                              SilcSKERekeyMaterial rekey,
2357                              void *context)
2358 {
2359   SilcPacketStream sock = context;
2360   SilcUnknownEntry entry = silc_packet_get_context(sock);
2361   SilcServer server = entry->server;
2362   SilcConnAuth connauth;
2363   SilcCipher send_key, receive_key;
2364   SilcHmac hmac_send, hmac_receive;
2365   SilcHash hash;
2366
2367   if (status != SILC_SKE_STATUS_OK) {
2368     /* SKE failed */
2369     SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
2370                     silc_ske_map_status(status), entry->hostname, entry->ip));
2371     silc_ske_free(ske);
2372     silc_server_disconnect_remote(server, sock,
2373                                   SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2374     return;
2375   }
2376
2377   SILC_LOG_DEBUG(("Setting keys into use"));
2378
2379   /* Set the keys into use.  The data will be encrypted after this. */
2380   if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key,
2381                          &hmac_send, &hmac_receive, &hash)) {
2382     /* Error setting keys */
2383     silc_ske_free(ske);
2384     silc_server_disconnect_remote(server, sock,
2385                                   SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
2386     return;
2387   }
2388   silc_packet_set_keys(sock, send_key, receive_key, hmac_send,
2389                        hmac_receive, FALSE);
2390
2391   SILC_LOG_DEBUG(("Starting connection authentication"));
2392   server->stat.auth_attempts++;
2393
2394   connauth = silc_connauth_alloc(server->schedule, ske,
2395                                  server->config->conn_auth_timeout);
2396   if (!connauth) {
2397     /** Error allocating auth protocol */
2398     silc_ske_free(ske);
2399     silc_server_disconnect_remote(server, sock,
2400                                   SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2401     return;
2402   }
2403
2404   /* Start connection authentication */
2405   silc_connauth_responder(connauth, silc_server_accept_get_auth,
2406                           silc_server_accept_auth_compl, sock);
2407 }
2408
2409 /* Accept new TCP connection */
2410
2411 static void silc_server_accept_new_connection(SilcNetStatus status,
2412                                               SilcStream stream,
2413                                               void *context)
2414 {
2415   SilcServer server = context;
2416   SilcPacketStream packet_stream;
2417   SilcServerConfigClient *cconfig = NULL;
2418   SilcServerConfigServer *sconfig = NULL;
2419   SilcServerConfigRouter *rconfig = NULL;
2420   SilcServerConfigDeny *deny;
2421   SilcUnknownEntry entry;
2422   SilcSKE ske;
2423   SilcSKEParamsStruct params;
2424   char *hostname, *ip;
2425   SilcUInt16 port;
2426
2427   SILC_LOG_DEBUG(("Accepting new connection"));
2428
2429   /* Check for maximum allowed connections */
2430   server->stat.conn_attempts++;
2431 #if 0
2432   if (silc_server_num_connections(server) >
2433       server->config->param.connections_max) {
2434     SILC_LOG_ERROR(("Refusing connection, server is full"));
2435     server->stat.conn_failures++;
2436     silc_stream_destroy(stream);
2437     return;
2438   }
2439 #endif
2440
2441   /* Get hostname, IP and port */
2442   if (!silc_socket_stream_get_info(stream, NULL, (const char **)&hostname,
2443                                    (const char **)&ip, &port)) {
2444     /* Bad socket stream */
2445     server->stat.conn_failures++;
2446     silc_stream_destroy(stream);
2447     return;
2448   }
2449
2450   /* Create packet stream */
2451   packet_stream = silc_packet_stream_create(server->packet_engine,
2452                                             server->schedule, stream);
2453   if (!packet_stream) {
2454     SILC_LOG_ERROR(("Refusing connection, cannot create packet stream"));
2455     server->stat.conn_failures++;
2456     silc_stream_destroy(stream);
2457     return;
2458   }
2459   server->stat.conn_num++;
2460
2461   /* Set source ID to packet stream */
2462   if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, &server->id,
2463                            0, NULL)) {
2464     /* Out of memory */
2465     server->stat.conn_failures++;
2466     silc_packet_stream_destroy(packet_stream);
2467     return;
2468   }
2469
2470   /* Check whether this connection is denied to connect to us. */
2471   deny = silc_server_config_find_denied(server, ip);
2472   if (!deny)
2473     deny = silc_server_config_find_denied(server, hostname);
2474   if (deny) {
2475     /* The connection is denied */
2476     SILC_LOG_INFO(("Connection %s (%s) is denied", hostname, ip));
2477     silc_server_disconnect_remote(server, packet_stream,
2478                                   SILC_STATUS_ERR_BANNED_FROM_SERVER,
2479                                   deny->reason);
2480     return;
2481   }
2482
2483   /* Check whether we have configured this sort of connection at all. We
2484      have to check all configurations since we don't know what type of
2485      connection this is. */
2486   if (!(cconfig = silc_server_config_find_client(server, ip)))
2487     cconfig = silc_server_config_find_client(server, hostname);
2488   if (!(sconfig = silc_server_config_find_server_conn(server, ip)))
2489     sconfig = silc_server_config_find_server_conn(server, hostname);
2490   if (server->server_type == SILC_ROUTER)
2491     if (!(rconfig = silc_server_config_find_router_conn(server, ip, port)))
2492       rconfig = silc_server_config_find_router_conn(server, hostname, port);
2493   if (!cconfig && !sconfig && !rconfig) {
2494     SILC_LOG_INFO(("Connection %s (%s) is not allowed", hostname, ip));
2495     server->stat.conn_failures++;
2496     silc_server_disconnect_remote(server, packet_stream,
2497                                   SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL);
2498     return;
2499   }
2500
2501   /* The connection is allowed */
2502   entry = silc_calloc(1, sizeof(*entry));
2503   if (!entry) {
2504     server->stat.conn_failures++;
2505     silc_server_disconnect_remote(server, packet_stream,
2506                                   SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2507     return;
2508   }
2509   entry->hostname = hostname;
2510   entry->ip = ip;
2511   entry->port = port;
2512   entry->server = server;
2513   silc_packet_set_context(packet_stream, entry);
2514
2515   silc_server_config_ref(&entry->cconfig, server->config, cconfig);
2516   silc_server_config_ref(&entry->sconfig, server->config, sconfig);
2517   silc_server_config_ref(&entry->rconfig, server->config, rconfig);
2518
2519   /* Take flags for key exchange. Since we do not know what type of connection
2520      this is, we go through all found configurations and use the global ones
2521      as well. This will result always into strictest key exchange flags. */
2522   memset(&params, 0, sizeof(params));
2523   SILC_GET_SKE_FLAGS(cconfig, params.flags);
2524   SILC_GET_SKE_FLAGS(sconfig, params.flags);
2525   SILC_GET_SKE_FLAGS(rconfig, params.flags);
2526   if (server->config->param.key_exchange_pfs)
2527     params.flags |= SILC_SKE_SP_FLAG_PFS;
2528
2529   SILC_LOG_INFO(("Incoming connection %s (%s)", hostname, ip));
2530   server->stat.conn_attempts++;
2531
2532   /* Start SILC Key Exchange protocol */
2533   SILC_LOG_DEBUG(("Starting key exchange protocol"));
2534   ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2535                        server->public_key, server->private_key,
2536                        packet_stream);
2537   if (!ske) {
2538     server->stat.conn_failures++;
2539     silc_server_disconnect_remote(server, packet_stream,
2540                                   SILC_STATUS_ERR_RESOURCE_LIMIT, NULL);
2541     return;
2542   }
2543   silc_ske_set_callbacks(ske, silc_server_verify_key,
2544                          silc_server_accept_completed, packet_stream);
2545
2546   /* Start key exchange protocol */
2547   params.version = silc_version_string;
2548   params.timeout_secs = server->config->key_exchange_timeout;
2549   silc_ske_responder(ske, packet_stream, &params);
2550 }
2551
2552
2553 /********************************** Rekey ***********************************/
2554
2555 /* Initiator rekey completion callback */
2556
2557 static void silc_server_rekey_completion(SilcSKE ske,
2558                                          SilcSKEStatus status,
2559                                          const SilcSKESecurityProperties prop,
2560                                          const SilcSKEKeyMaterial keymat,
2561                                          SilcSKERekeyMaterial rekey,
2562                                          void *context)
2563 {
2564   SilcPacketStream sock = context;
2565   SilcIDListData idata = silc_packet_get_context(sock);
2566   SilcServer server = idata->sconn->server;
2567
2568   idata->sconn->op = NULL;
2569   if (status != SILC_SKE_STATUS_OK) {
2570     SILC_LOG_ERROR(("Error during rekey protocol with %s",
2571                     idata->sconn->remote_host));
2572     return;
2573   }
2574
2575   SILC_LOG_DEBUG(("Rekey protocol completed with %s:%d [%s]",
2576                   idata->sconn->remote_host, idata->sconn->remote_port,
2577                   SILC_CONNTYPE_STRING(idata->conn_type)));
2578
2579   /* Save rekey data for next rekey */
2580   idata->rekey = rekey;
2581
2582   /* Register new rekey timeout */
2583   silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2584                                  sock, idata->sconn->rekey_timeout, 0);
2585 }
2586
2587 /* Rekey callback.  Start rekey as initiator */
2588
2589 SILC_TASK_CALLBACK(silc_server_do_rekey)
2590 {
2591   SilcServer server = app_context;
2592   SilcPacketStream sock = context;
2593   SilcIDListData idata = silc_packet_get_context(sock);
2594   SilcSKE ske;
2595
2596   /* Do not execute rekey with disabled connections */
2597   if (idata->status & SILC_IDLIST_STATUS_DISABLED)
2598     return;
2599
2600   /* If another protocol is active do not start rekey */
2601   if (idata->sconn->op) {
2602     SILC_LOG_DEBUG(("Waiting for other protocol to finish before rekeying"));
2603     silc_schedule_task_add_timeout(server->schedule, silc_server_do_rekey,
2604                                    sock, 60, 0);
2605     return;
2606   }
2607
2608   SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]",
2609                   idata->sconn->remote_host, idata->sconn->remote_port,
2610                   SILC_CONNTYPE_STRING(idata->conn_type)));
2611
2612   /* Allocate SKE */
2613   ske = silc_ske_alloc(server->rng, server->schedule, server->repository,
2614                        server->public_key, server->private_key, sock);
2615   if (!ske)
2616     return;
2617
2618   /* Set SKE callbacks */
2619   silc_ske_set_callbacks(ske, NULL, silc_server_rekey_completion, sock);
2620
2621   /* Perform rekey */
2622   idata->sconn->op = silc_ske_rekey_initiator(ske, sock, idata->rekey);
2623 }
2624
2625
2626 /****************************** Disconnection *******************************/
2627
2628 /* Destroys packet stream. */
2629
2630 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2631 {
2632   silc_packet_stream_destroy(context);
2633 }
2634
2635 /* Closes connection to socket connection */
2636
2637 void silc_server_close_connection(SilcServer server,
2638                                   SilcPacketStream sock)
2639 {
2640   SilcIDListData idata = silc_packet_get_context(sock);
2641   char tmp[128];
2642   const char *hostname;
2643   SilcUInt16 port;
2644
2645 #if 0
2646   /* If any protocol is active cancel its execution. It will call
2647      the final callback which will finalize the disconnection. */
2648   if (sock->protocol && sock->protocol->protocol &&
2649       sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
2650     SILC_LOG_DEBUG(("Cancelling protocol, calling final callback"));
2651     silc_protocol_cancel(sock->protocol, server->schedule);
2652     sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2653     silc_protocol_execute_final(sock->protocol, server->schedule);
2654     sock->protocol = NULL;
2655     return;
2656   }
2657 #endif
2658
2659   memset(tmp, 0, sizeof(tmp));
2660   //  silc_socket_get_error(sock, tmp, sizeof(tmp));
2661   silc_socket_stream_get_info(sock, NULL, &hostname, NULL, &port);
2662   SILC_LOG_INFO(("Closing connection %s:%d [%s] %s", hostname, port,
2663                  SILC_CONNTYPE_STRING(idata->conn_type),
2664                  tmp[0] ? tmp : ""));
2665
2666   //  silc_socket_set_qos(sock, 0, 0, 0, 0, NULL);
2667
2668   /* Close connection with timeout */
2669   server->stat.conn_num--;
2670   silc_schedule_task_add_timeout(server->schedule,
2671                                  silc_server_close_connection_final,
2672                                  sock, 0, 1);
2673 }
2674
2675 /* Sends disconnect message to remote connection and disconnects the
2676    connection. */
2677
2678 void silc_server_disconnect_remote(SilcServer server,
2679                                    SilcPacketStream sock,
2680                                    SilcStatus status, ...)
2681 {
2682   unsigned char buf[512];
2683   va_list ap;
2684   char *cp;
2685
2686   if (!sock)
2687     return;
2688
2689   SILC_LOG_DEBUG(("Disconnecting remote host"));
2690
2691   va_start(ap, status);
2692   cp = va_arg(ap, char *);
2693   if (cp)
2694     silc_vsnprintf(buf, sizeof(buf), cp, ap);
2695   va_end(ap);
2696
2697   /* Send SILC_PACKET_DISCONNECT */
2698   silc_packet_send_va(sock, SILC_PACKET_DISCONNECT, 0,
2699                       SILC_STR_UI_CHAR(status),
2700                       SILC_STR_UI8_STRING(cp ? buf : NULL),
2701                       SILC_STR_END);
2702
2703   /* Close connection */
2704   silc_server_close_connection(server, sock);
2705 }
2706
2707 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2708 {
2709   SilcClientEntry client = context;
2710
2711   assert(!silc_hash_table_count(client->channels));
2712
2713   silc_idlist_del_data(client);
2714   //  silc_idcache_purge_by_context(server->local_list->clients, client);
2715 }
2716
2717 /* Frees client data and notifies about client's signoff. */
2718
2719 void silc_server_free_client_data(SilcServer server,
2720                                   SilcPacketStream sock,
2721                                   SilcClientEntry client,
2722                                   int notify,
2723                                   const char *signoff)
2724 {
2725   SILC_LOG_DEBUG(("Freeing client data"));
2726
2727   if (client->id) {
2728     /* Check if anyone is watching this nickname */
2729     if (server->server_type == SILC_ROUTER)
2730       silc_server_check_watcher_list(server, client, NULL,
2731                                      SILC_NOTIFY_TYPE_SIGNOFF);
2732
2733     /* Send SIGNOFF notify to routers. */
2734     if (notify)
2735       silc_server_send_notify_signoff(server, SILC_PRIMARY_ROUTE(server),
2736                                       SILC_BROADCAST(server), client->id,
2737                                       signoff);
2738   }
2739
2740   /* Remove client from all channels */
2741   if (notify)
2742     silc_server_remove_from_channels(server, NULL, client,
2743                                      TRUE, (char *)signoff, TRUE, FALSE);
2744   else
2745     silc_server_remove_from_channels(server, NULL, client,
2746                                      FALSE, NULL, FALSE, FALSE);
2747
2748   /* Remove this client from watcher list if it is */
2749   silc_server_del_from_watcher_list(server, client);
2750
2751   /* Remove this client from the public key hash list */
2752   if (client->data.public_key)
2753     silc_hash_table_del_by_context(server->pk_hash,
2754                                    client->data.public_key, client);
2755
2756   /* Update statistics */
2757   server->stat.my_clients--;
2758   server->stat.clients--;
2759   if (server->stat.cell_clients)
2760     server->stat.cell_clients--;
2761   SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
2762   SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
2763   silc_schedule_task_del_by_context(server->schedule, client);
2764
2765   /* We will not delete the client entry right away. We will take it
2766      into history (for WHOWAS command) for 5 minutes, unless we're
2767      shutting down server. */
2768   if (!server->server_shutdown) {
2769     silc_schedule_task_add_timeout(server->schedule,
2770                                    silc_server_free_client_data_timeout,
2771                                    client, 600, 0);
2772     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2773     client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
2774     client->mode = 0;
2775     client->router = NULL;
2776     client->connection = NULL;
2777   } else {
2778     /* Delete directly since we're shutting down server */
2779     silc_idlist_del_data(client);
2780     silc_idlist_del_client(server->local_list, client);
2781   }
2782 }
2783
2784 /* Frees user_data pointer from socket connection object. This also sends
2785    appropriate notify packets to the network to inform about leaving
2786    entities. */
2787
2788 void silc_server_free_sock_user_data(SilcServer server,
2789                                      SilcPacketStream sock,
2790                                      const char *signoff_message)
2791 {
2792   SilcIDListData idata = silc_packet_get_context(sock);
2793
2794   if (!idata)
2795     return;
2796
2797   switch (idata->conn_type) {
2798   case SILC_CONN_CLIENT:
2799     {
2800       SilcClientEntry client_entry = (SilcClientEntry)idata;
2801       silc_server_free_client_data(server, sock, client_entry, TRUE,
2802                                    signoff_message);
2803       break;
2804     }
2805
2806   case SILC_CONN_SERVER:
2807   case SILC_CONN_ROUTER:
2808     {
2809       SilcServerEntry user_data = (SilcServerEntry)idata;
2810       SilcServerEntry backup_router = NULL;
2811
2812       SILC_LOG_DEBUG(("Freeing server data"));
2813
2814       if (user_data->id)
2815         backup_router = silc_server_backup_get(server, user_data->id);
2816
2817       if (!server->backup_router && server->server_type == SILC_ROUTER &&
2818           backup_router == server->id_entry &&
2819           idata->conn_type != SILC_CONN_ROUTER)
2820         backup_router = NULL;
2821
2822       if (server->server_shutdown || server->backup_noswitch)
2823         backup_router = NULL;
2824
2825       /* If this was our primary router connection then we're lost to
2826          the outside world. */
2827       if (server->router == user_data) {
2828         /* Check whether we have a backup router connection */
2829         if (!backup_router || backup_router == user_data) {
2830           if (!server->no_reconnect)
2831             silc_server_create_connections(server);
2832           server->id_entry->router = NULL;
2833           server->router = NULL;
2834           server->standalone = TRUE;
2835           server->backup_primary = FALSE;
2836           backup_router = NULL;
2837         } else {
2838           if (server->id_entry != backup_router) {
2839             SILC_LOG_INFO(("New primary router is backup router %s",
2840                            backup_router->server_name));
2841             server->id_entry->router = backup_router;
2842             server->router = backup_router;
2843             server->router_connect = time(0);
2844             server->backup_primary = TRUE;
2845             backup_router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
2846
2847             /* Send START_USE to backup router to indicate we have switched */
2848             silc_server_backup_send_start_use(server,
2849                                               backup_router->connection,
2850                                               FALSE);
2851           } else {
2852             SILC_LOG_INFO(("We are now new primary router in this cell"));
2853             server->id_entry->router = NULL;
2854             server->router = NULL;
2855             server->standalone = TRUE;
2856           }
2857
2858           /* We stop here to take a breath */
2859           sleep(2);
2860
2861 #if 0
2862           if (server->backup_router) {
2863             server->server_type = SILC_ROUTER;
2864
2865             /* We'll need to constantly try to reconnect to the primary
2866                router so that we'll see when it comes back online. */
2867             silc_server_backup_reconnect(server, sock->ip, sock->port,
2868                                          silc_server_backup_connected,
2869                                          NULL);
2870           }
2871 #endif /* 0 */
2872
2873           /* Mark this connection as replaced */
2874           silc_server_backup_replaced_add(server, user_data->id,
2875                                           backup_router);
2876         }
2877       } else if (backup_router) {
2878         SILC_LOG_INFO(("Enabling the use of backup router %s",
2879                        backup_router->server_name));
2880
2881         /* Mark this connection as replaced */
2882         silc_server_backup_replaced_add(server, user_data->id,
2883                                         backup_router);
2884       } else if (server->server_type == SILC_SERVER &&
2885                  idata->conn_type == SILC_CONN_ROUTER) {
2886         /* Reconnect to the router (backup) */
2887         if (!server->no_reconnect)
2888           silc_server_create_connections(server);
2889       }
2890
2891       if (user_data->server_name)
2892         SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE,
2893                                ("Server %s signoff", user_data->server_name));
2894
2895       if (!backup_router) {
2896         /* Remove all servers that are originated from this server, and
2897            remove the clients of those servers too. */
2898         silc_server_remove_servers_by_server(server, user_data, TRUE);
2899
2900 #if 0
2901         /* Remove the clients that this server owns as they will become
2902            invalid now too.  For backup router the server is actually
2903            coming from the primary router, so mark that as the owner
2904            of this entry. */
2905         if (server->server_type == SILC_BACKUP_ROUTER &&
2906             sock->type == SILC_CONN_SERVER)
2907           silc_server_remove_clients_by_server(server, server->router,
2908                                                user_data, TRUE);
2909         else
2910 #endif
2911           silc_server_remove_clients_by_server(server, user_data,
2912                                                user_data, TRUE);
2913
2914         /* Remove channels owned by this server */
2915         if (server->server_type == SILC_SERVER)
2916           silc_server_remove_channels_by_server(server, user_data);
2917       } else {
2918         /* Enable local server connections that may be disabled */
2919         silc_server_local_servers_toggle_enabled(server, TRUE);
2920
2921         /* Update the client entries of this server to the new backup
2922            router.  If we are the backup router we also resolve the real
2923            servers for the clients.  After updating is over this also
2924            removes the clients that this server explicitly owns. */
2925         silc_server_update_clients_by_server(server, user_data,
2926                                              backup_router, TRUE);
2927
2928         /* If we are router and just lost our primary router (now standlaone)
2929            we remove everything that was behind it, since we don't know
2930            any better. */
2931         if (server->server_type == SILC_ROUTER && server->standalone)
2932           /* Remove all servers that are originated from this server, and
2933              remove the clients of those servers too. */
2934           silc_server_remove_servers_by_server(server, user_data, TRUE);
2935
2936         /* Finally remove the clients that are explicitly owned by this
2937            server.  They go down with the server. */
2938         silc_server_remove_clients_by_server(server, user_data,
2939                                              user_data, TRUE);
2940
2941         /* Update our server cache to use the new backup router too. */
2942         silc_server_update_servers_by_server(server, user_data, backup_router);
2943         if (server->server_type == SILC_SERVER)
2944           silc_server_update_channels_by_server(server, user_data,
2945                                                 backup_router);
2946
2947         /* Send notify about primary router going down to local operators */
2948         if (server->backup_router)
2949           SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
2950                                  SILC_NOTIFY_TYPE_NONE,
2951                                  ("%s switched to backup router %s "
2952                                   "(we are primary router now)",
2953                                   server->server_name, server->server_name));
2954         else if (server->router)
2955           SILC_SERVER_SEND_OPERS(server, FALSE, TRUE,
2956                                  SILC_NOTIFY_TYPE_NONE,
2957                                  ("%s switched to backup router %s",
2958                                   server->server_name,
2959                                   server->router->server_name));
2960       }
2961       server->backup_noswitch = FALSE;
2962
2963       /* Free the server entry */
2964       silc_server_backup_del(server, user_data);
2965       silc_server_backup_replaced_del(server, user_data);
2966       silc_idlist_del_data(user_data);
2967       if (!silc_idlist_del_server(server->local_list, user_data))
2968         silc_idlist_del_server(server->global_list, user_data);
2969       if (idata->conn_type == SILC_CONN_SERVER) {
2970         server->stat.my_servers--;
2971         server->stat.servers--;
2972       } else {
2973         server->stat.my_routers--;
2974         server->stat.routers--;
2975       }
2976       if (server->server_type == SILC_ROUTER)
2977         server->stat.cell_servers--;
2978
2979       if (backup_router && backup_router != server->id_entry) {
2980         /* Announce all of our stuff that was created about 5 minutes ago.
2981            The backup router knows all the other stuff already. */
2982         if (server->server_type == SILC_ROUTER)
2983           silc_server_announce_servers(server, FALSE, time(0) - 300,
2984                                        backup_router->connection);
2985
2986         /* Announce our clients and channels to the router */
2987         silc_server_announce_clients(server, time(0) - 300,
2988                                      backup_router->connection);
2989         silc_server_announce_channels(server, time(0) - 300,
2990                                       backup_router->connection);
2991       }
2992       break;
2993     }
2994
2995   default:
2996     {
2997       SilcUnknownEntry entry = (SilcUnknownEntry)idata;
2998
2999       SILC_LOG_DEBUG(("Freeing unknown connection data"));
3000
3001       silc_idlist_del_data(idata);
3002       silc_free(entry);
3003       break;
3004     }
3005   }
3006 }
3007
3008 /* Removes client from all channels it has joined. This is used when client
3009    connection is disconnected. If the client on a channel is last, the
3010    channel is removed as well. This sends the SIGNOFF notify types. */
3011
3012 void silc_server_remove_from_channels(SilcServer server,
3013                                       SilcPacketStream sock,
3014                                       SilcClientEntry client,
3015                                       SilcBool notify,
3016                                       const char *signoff_message,
3017                                       SilcBool keygen,
3018                                       SilcBool killed)
3019 {
3020   SilcChannelEntry channel;
3021   SilcChannelClientEntry chl;
3022   SilcHashTableList htl;
3023   SilcBuffer clidp = NULL;
3024
3025   if (!client)
3026     return;
3027
3028   if (notify && !client->id)
3029     notify = FALSE;
3030
3031   SILC_LOG_DEBUG(("Removing client %s from joined channels",
3032                   notify ? silc_id_render(client->id, SILC_ID_CLIENT) : ""));
3033
3034   if (notify) {
3035     clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3036     if (!clidp)
3037       notify = FALSE;
3038   }
3039
3040   /* Remove the client from all channels. The client is removed from
3041      the channels' user list. */
3042   silc_hash_table_list(client->channels, &htl);
3043   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3044     channel = chl->channel;
3045
3046     /* Remove channel if this is last client leaving the channel, unless
3047        the channel is permanent. */
3048     if (server->server_type != SILC_SERVER &&
3049         silc_hash_table_count(channel->user_list) < 2) {
3050       silc_server_channel_delete(server, channel);
3051       continue;
3052     }
3053
3054     silc_hash_table_del(client->channels, channel);
3055     silc_hash_table_del(channel->user_list, client);
3056     channel->user_count--;
3057
3058     /* If there is no global users on the channel anymore mark the channel
3059        as local channel. Do not check if the removed client is local client. */
3060     if (server->server_type == SILC_SERVER && channel->global_users &&
3061         chl->client->router && !silc_server_channel_has_global(channel))
3062       channel->global_users = FALSE;
3063
3064     memset(chl, 'A', sizeof(*chl));
3065     silc_free(chl);
3066
3067     /* Update statistics */
3068     if (SILC_IS_LOCAL(client))
3069       server->stat.my_chanclients--;
3070     if (server->server_type == SILC_ROUTER) {
3071       server->stat.cell_chanclients--;
3072       server->stat.chanclients--;
3073     }
3074
3075     /* If there is not at least one local user on the channel then we don't
3076        need the channel entry anymore, we can remove it safely, unless the
3077        channel is permanent channel */
3078     if (server->server_type == SILC_SERVER &&
3079         !silc_server_channel_has_local(channel)) {
3080       /* Notify about leaving client if this channel has global users. */
3081       if (notify && channel->global_users)
3082         silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3083                                            SILC_NOTIFY_TYPE_SIGNOFF,
3084                                            signoff_message ? 2 : 1,
3085                                            clidp->data, silc_buffer_len(clidp),
3086                                            signoff_message, signoff_message ?
3087                                            strlen(signoff_message) : 0);
3088
3089       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3090       silc_server_channel_delete(server, channel);
3091       continue;
3092     }
3093
3094     /* Send notify to channel about client leaving SILC and channel too */
3095     if (notify)
3096       silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3097                                          SILC_NOTIFY_TYPE_SIGNOFF,
3098                                          signoff_message ? 2 : 1,
3099                                          clidp->data, silc_buffer_len(clidp),
3100                                          signoff_message, signoff_message ?
3101                                          strlen(signoff_message) : 0);
3102
3103     if (killed && clidp) {
3104       /* Remove the client from channel's invite list */
3105       if (channel->invite_list &&
3106           silc_hash_table_count(channel->invite_list)) {
3107         SilcBuffer ab;
3108         SilcArgumentPayload iargs;
3109         ab = silc_argument_payload_encode_one(NULL, clidp->data,
3110                                               silc_buffer_len(clidp), 3);
3111         iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3112         silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
3113         silc_buffer_free(ab);
3114         silc_argument_payload_free(iargs);
3115       }
3116     }
3117
3118     /* Don't create keys if we are shutting down */
3119     if (server->server_shutdown)
3120       continue;
3121
3122     /* Re-generate channel key if needed */
3123     if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3124       if (!silc_server_create_channel_key(server, channel, 0))
3125         continue;
3126
3127       /* Send the channel key to the channel. The key of course is not sent
3128          to the client who was removed from the channel. */
3129       silc_server_send_channel_key(server, client->connection, channel,
3130                                    server->server_type == SILC_ROUTER ?
3131                                    FALSE : !server->standalone);
3132     }
3133   }
3134
3135   silc_hash_table_list_reset(&htl);
3136   if (clidp)
3137     silc_buffer_free(clidp);
3138 }
3139
3140 /* Removes client from one channel. This is used for example when client
3141    calls LEAVE command to remove itself from the channel. Returns TRUE
3142    if channel still exists and FALSE if the channel is removed when
3143    last client leaves the channel. If `notify' is FALSE notify messages
3144    are not sent. */
3145
3146 SilcBool silc_server_remove_from_one_channel(SilcServer server,
3147                                          SilcPacketStream sock,
3148                                          SilcChannelEntry channel,
3149                                          SilcClientEntry client,
3150                                          SilcBool notify)
3151 {
3152   SilcChannelClientEntry chl;
3153   SilcBuffer clidp;
3154
3155   SILC_LOG_DEBUG(("Removing %s from channel %s",
3156                   silc_id_render(client->id, SILC_ID_CLIENT),
3157                   channel->channel_name));
3158
3159   /* Get the entry to the channel, if this client is not on the channel
3160      then return Ok. */
3161   if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
3162     return TRUE;
3163
3164   /* Remove channel if this is last client leaving the channel, unless
3165      the channel is permanent. */
3166   if (server->server_type != SILC_SERVER &&
3167       silc_hash_table_count(channel->user_list) < 2) {
3168     silc_server_channel_delete(server, channel);
3169     return FALSE;
3170   }
3171
3172   silc_hash_table_del(client->channels, channel);
3173   silc_hash_table_del(channel->user_list, client);
3174   channel->user_count--;
3175
3176   /* If there is no global users on the channel anymore mark the channel
3177      as local channel. Do not check if the client is local client. */
3178   if (server->server_type == SILC_SERVER && channel->global_users &&
3179       chl->client->router && !silc_server_channel_has_global(channel))
3180     channel->global_users = FALSE;
3181
3182   memset(chl, 'O', sizeof(*chl));
3183   silc_free(chl);
3184
3185   /* Update statistics */
3186   if (SILC_IS_LOCAL(client))
3187     server->stat.my_chanclients--;
3188   if (server->server_type == SILC_ROUTER) {
3189     server->stat.cell_chanclients--;
3190     server->stat.chanclients--;
3191   }
3192
3193   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3194   if (!clidp)
3195     notify = FALSE;
3196
3197   /* If there is not at least one local user on the channel then we don't
3198      need the channel entry anymore, we can remove it safely, unless the
3199      channel is permanent channel */
3200   if (server->server_type == SILC_SERVER &&
3201       !silc_server_channel_has_local(channel)) {
3202     /* Notify about leaving client if this channel has global users. */
3203     if (notify && channel->global_users)
3204       silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3205                                          SILC_NOTIFY_TYPE_LEAVE, 1,
3206                                          clidp->data, silc_buffer_len(clidp));
3207
3208     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
3209     silc_server_channel_delete(server, channel);
3210     silc_buffer_free(clidp);
3211     return FALSE;
3212   }
3213
3214   /* Send notify to channel about client leaving the channel */
3215   if (notify)
3216     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3217                                        SILC_NOTIFY_TYPE_LEAVE, 1,
3218                                        clidp->data, silc_buffer_len(clidp));
3219
3220   silc_buffer_free(clidp);
3221   return TRUE;
3222 }
3223
3224 #if 0
3225 /* Timeout callback. This is called if connection is idle or for some
3226    other reason is not responding within some period of time. This
3227    disconnects the remote end. */
3228
3229 SILC_TASK_CALLBACK(silc_server_timeout_remote)
3230 {
3231   SilcServer server = (SilcServer)context;
3232   SilcPacketStream sock = server->sockets[fd];
3233
3234   SILC_LOG_DEBUG(("Start"));
3235
3236   if (!sock)
3237     return;
3238
3239   SILC_LOG_ERROR(("No response from %s (%s), Connection timeout",
3240                   sock->hostname, sock->ip));
3241
3242   /* If we have protocol active we must assure that we call the protocol's
3243      final callback so that all the memory is freed. */
3244   if (sock->protocol && sock->protocol->protocol &&
3245       sock->protocol->protocol->type != SILC_PROTOCOL_SERVER_BACKUP) {
3246     protocol = sock->protocol->protocol->type;
3247     silc_protocol_cancel(sock->protocol, server->schedule);
3248     sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
3249     silc_protocol_execute_final(sock->protocol, server->schedule);
3250     sock->protocol = NULL;
3251     return;
3252   }
3253
3254   silc_server_disconnect_remote(server, sock,
3255                                 protocol ==
3256                                 SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
3257                                 SILC_STATUS_ERR_AUTH_FAILED :
3258                                 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
3259                                 "Connection timeout");
3260
3261   if (sock->user_data)
3262     silc_server_free_sock_user_data(server, sock, NULL);
3263 }
3264 #endif /* 0 */
3265
3266 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
3267    function may be used only by router. In real SILC network all channels
3268    are created by routers thus this function is never used by normal
3269    server. */
3270
3271 SilcChannelEntry silc_server_create_new_channel(SilcServer server,
3272                                                 SilcServerID *router_id,
3273                                                 char *cipher,
3274                                                 char *hmac,
3275                                                 char *channel_name,
3276                                                 int broadcast)
3277 {
3278   SilcChannelID *channel_id;
3279   SilcChannelEntry entry;
3280   SilcCipher send_key, receive_key;
3281   SilcHmac newhmac;
3282
3283   SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3284
3285   if (!cipher)
3286     cipher = SILC_DEFAULT_CIPHER;
3287   if (!hmac)
3288     hmac = SILC_DEFAULT_HMAC;
3289
3290   /* Allocate cipher */
3291   if (!silc_cipher_alloc(cipher, &send_key))
3292     return NULL;
3293   if (!silc_cipher_alloc(cipher, &receive_key)) {
3294     silc_cipher_free(send_key);
3295     return NULL;
3296   }
3297
3298   /* Allocate hmac */
3299   if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3300     silc_cipher_free(send_key);
3301     silc_cipher_free(receive_key);
3302     return NULL;
3303   }
3304
3305   channel_name = strdup(channel_name);
3306
3307   /* Create the channel ID */
3308   if (!silc_id_create_channel_id(server, router_id, server->rng,
3309                                  &channel_id)) {
3310     silc_free(channel_name);
3311     silc_cipher_free(send_key);
3312     silc_cipher_free(receive_key);
3313     silc_hmac_free(newhmac);
3314     return NULL;
3315   }
3316
3317   /* Create the channel */
3318   entry = silc_idlist_add_channel(server->local_list, channel_name,
3319                                   SILC_CHANNEL_MODE_NONE, channel_id,
3320                                   NULL, send_key, receive_key, newhmac);
3321   if (!entry) {
3322     silc_free(channel_name);
3323     silc_cipher_free(send_key);
3324     silc_cipher_free(receive_key);
3325     silc_hmac_free(newhmac);
3326     silc_free(channel_id);
3327     return NULL;
3328   }
3329
3330   entry->cipher = strdup(cipher);
3331   entry->hmac_name = strdup(hmac);
3332
3333   /* Now create the actual key material */
3334   if (!silc_server_create_channel_key(server, entry,
3335                                       silc_cipher_get_key_len(send_key) / 8)) {
3336     silc_idlist_del_channel(server->local_list, entry);
3337     return NULL;
3338   }
3339
3340   /* Notify other routers about the new channel. We send the packet
3341      to our primary route. */
3342   if (broadcast)
3343     silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3344                                  channel_name, entry->id,
3345                                  silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3346                                  entry->mode);
3347
3348   /* Distribute to backup routers */
3349   if (broadcast && server->server_type == SILC_ROUTER) {
3350     SilcBuffer packet;
3351     unsigned char cid[32];
3352     SilcUInt32 name_len = strlen(channel_name);
3353     SilcUInt32 id_len;
3354
3355     silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3356     packet = silc_channel_payload_encode(channel_name, name_len,
3357                                          cid, id_len, entry->mode);
3358     silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3359                             packet->data, silc_buffer_len(packet), FALSE,
3360                             TRUE);
3361     silc_buffer_free(packet);
3362   }
3363
3364   server->stat.my_channels++;
3365   if (server->server_type == SILC_ROUTER) {
3366     server->stat.channels++;
3367     server->stat.cell_channels++;
3368     entry->users_resolved = TRUE;
3369   }
3370
3371   return entry;
3372 }
3373
3374 /* Same as above but creates the channel with Channel ID `channel_id. */
3375
3376 SilcChannelEntry
3377 silc_server_create_new_channel_with_id(SilcServer server,
3378                                        char *cipher,
3379                                        char *hmac,
3380                                        char *channel_name,
3381                                        SilcChannelID *channel_id,
3382                                        int broadcast)
3383 {
3384   SilcChannelEntry entry;
3385   SilcCipher send_key, receive_key;
3386   SilcHmac newhmac;
3387
3388   SILC_LOG_DEBUG(("Creating new channel %s", channel_name));
3389
3390   if (!cipher)
3391     cipher = SILC_DEFAULT_CIPHER;
3392   if (!hmac)
3393     hmac = SILC_DEFAULT_HMAC;
3394
3395   /* Allocate cipher */
3396   if (!silc_cipher_alloc(cipher, &send_key))
3397     return NULL;
3398   if (!silc_cipher_alloc(cipher, &receive_key)) {
3399     silc_cipher_free(send_key);
3400     return NULL;
3401   }
3402
3403   /* Allocate hmac */
3404   if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3405     silc_cipher_free(send_key);
3406     silc_cipher_free(receive_key);
3407     return NULL;
3408   }
3409
3410   channel_name = strdup(channel_name);
3411
3412   /* Create the channel */
3413   entry = silc_idlist_add_channel(server->local_list, channel_name,
3414                                   SILC_CHANNEL_MODE_NONE, channel_id,
3415                                   NULL, send_key, receive_key, newhmac);
3416   if (!entry) {
3417     silc_cipher_free(send_key);
3418     silc_cipher_free(receive_key);
3419     silc_hmac_free(newhmac);
3420     silc_free(channel_name);
3421     return NULL;
3422   }
3423
3424   /* Now create the actual key material */
3425   if (!silc_server_create_channel_key(server, entry,
3426                                       silc_cipher_get_key_len(send_key) / 8)) {
3427     silc_idlist_del_channel(server->local_list, entry);
3428     return NULL;
3429   }
3430
3431   /* Notify other routers about the new channel. We send the packet
3432      to our primary route. */
3433   if (broadcast)
3434     silc_server_send_new_channel(server, SILC_PRIMARY_ROUTE(server), TRUE,
3435                                  channel_name, entry->id,
3436                                  silc_id_get_len(entry->id, SILC_ID_CHANNEL),
3437                                  entry->mode);
3438
3439   /* Distribute to backup routers */
3440   if (broadcast && server->server_type == SILC_ROUTER) {
3441     SilcBuffer packet;
3442     unsigned char cid[32];
3443     SilcUInt32 name_len = strlen(channel_name);
3444     SilcUInt32 id_len;
3445
3446     silc_id_id2str(entry->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
3447     packet = silc_channel_payload_encode(channel_name, name_len,
3448                                          cid, id_len, entry->mode);
3449     silc_server_backup_send(server, NULL, SILC_PACKET_NEW_CHANNEL, 0,
3450                             packet->data, silc_buffer_len(packet), FALSE,
3451                             TRUE);
3452     silc_buffer_free(packet);
3453   }
3454
3455   server->stat.my_channels++;
3456   if (server->server_type == SILC_ROUTER) {
3457     server->stat.channels++;
3458     server->stat.cell_channels++;
3459     entry->users_resolved = TRUE;
3460   }
3461
3462   return entry;
3463 }
3464
3465 /* Channel's key re-key timeout callback. */
3466
3467 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
3468 {
3469   SilcServer server = app_context;
3470   SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
3471
3472   rekey->task = NULL;
3473
3474   /* Return now if we are shutting down */
3475   if (server->server_shutdown)
3476     return;
3477
3478   if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
3479     return;
3480
3481   silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
3482 }
3483
3484 /* Generates new channel key. This is used to create the initial channel key
3485    but also to re-generate new key for channel. If `key_len' is provided
3486    it is the bytes of the key length. */
3487
3488 SilcBool silc_server_create_channel_key(SilcServer server,
3489                                         SilcChannelEntry channel,
3490                                         SilcUInt32 key_len)
3491 {
3492   int i;
3493   unsigned char channel_key[32], hash[SILC_HASH_MAXLEN];
3494   SilcUInt32 len;
3495
3496   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3497     SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
3498     return TRUE;
3499   }
3500
3501   SILC_LOG_DEBUG(("Generating channel %s key", channel->channel_name));
3502
3503   if (!channel->send_key)
3504     if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->send_key)) {
3505       channel->send_key = NULL;
3506       return FALSE;
3507     }
3508   if (!channel->receive_key)
3509     if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->receive_key)) {
3510       silc_cipher_free(channel->send_key);
3511       channel->send_key = channel->receive_key = NULL;
3512       return FALSE;
3513     }
3514
3515   if (key_len)
3516     len = key_len;
3517   else if (channel->key_len)
3518     len = channel->key_len / 8;
3519   else
3520     len = silc_cipher_get_key_len(channel->send_key) / 8;
3521
3522   /* Create channel key */
3523   for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
3524
3525   /* Set the key */
3526   silc_cipher_set_key(channel->send_key, channel_key, len * 8, TRUE);
3527   silc_cipher_set_key(channel->receive_key, channel_key, len * 8, FALSE);
3528
3529   /* Remove old key if exists */
3530   if (channel->key) {
3531     memset(channel->key, 0, channel->key_len / 8);
3532     silc_free(channel->key);
3533   }
3534
3535   /* Save the key */
3536   channel->key_len = len * 8;
3537   channel->key = silc_memdup(channel_key, len);
3538   memset(channel_key, 0, sizeof(channel_key));
3539
3540   /* Generate HMAC key from the channel key data and set it */
3541   if (!channel->hmac)
3542     if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3543       memset(channel->key, 0, channel->key_len / 8);
3544       silc_free(channel->key);
3545       silc_cipher_free(channel->send_key);
3546       silc_cipher_free(channel->receive_key);
3547       channel->send_key = channel->receive_key = NULL;
3548       return FALSE;
3549     }
3550   silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
3551   silc_hmac_set_key(channel->hmac, hash,
3552                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3553   memset(hash, 0, sizeof(hash));
3554
3555   if (server->server_type == SILC_ROUTER) {
3556     if (!channel->rekey)
3557       channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3558     channel->rekey->channel = channel;
3559     channel->rekey->key_len = key_len;
3560     if (channel->rekey->task)
3561       silc_schedule_task_del(server->schedule, channel->rekey->task);
3562
3563     channel->rekey->task =
3564       silc_schedule_task_add_timeout(server->schedule,
3565                                      silc_server_channel_key_rekey,
3566                                      (void *)channel->rekey,
3567                                      server->config->channel_rekey_secs, 0);
3568   }
3569
3570   return TRUE;
3571 }
3572
3573 /* Saves the channel key found in the encoded `key_payload' buffer. This
3574    function is used when we receive Channel Key Payload and also when we're
3575    processing JOIN command reply. Returns entry to the channel. */
3576
3577 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
3578                                               SilcBuffer key_payload,
3579                                               SilcChannelEntry channel)
3580 {
3581   SilcChannelKeyPayload payload = NULL;
3582   SilcChannelID id;
3583   unsigned char *tmp, hash[SILC_HASH_MAXLEN];
3584   SilcUInt32 tmp_len;
3585   char *cipher;
3586
3587   /* Decode channel key payload */
3588   payload = silc_channel_key_payload_parse(key_payload->data,
3589                                            silc_buffer_len(key_payload));
3590   if (!payload) {
3591     SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
3592     channel = NULL;
3593     goto out;
3594   }
3595
3596   /* Get the channel entry */
3597   if (!channel) {
3598
3599     /* Get channel ID */
3600     tmp = silc_channel_key_get_id(payload, &tmp_len);
3601     if (!silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL, &id, sizeof(id))) {
3602       channel = NULL;
3603       goto out;
3604     }
3605
3606     channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
3607     if (!channel) {
3608       channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
3609       if (!channel) {
3610         if (server->server_type == SILC_ROUTER)
3611           SILC_LOG_ERROR(("Received key for non-existent channel %s",
3612                           silc_id_render(&id, SILC_ID_CHANNEL)));
3613         goto out;
3614       }
3615     }
3616   }
3617
3618   SILC_LOG_DEBUG(("Saving new channel %s key", channel->channel_name));
3619
3620   tmp = silc_channel_key_get_key(payload, &tmp_len);
3621   if (!tmp) {
3622     channel = NULL;
3623     goto out;
3624   }
3625
3626   cipher = silc_channel_key_get_cipher(payload, NULL);
3627   if (!cipher) {
3628     channel = NULL;
3629     goto out;
3630   }
3631
3632   /* Remove old key if exists */
3633   if (channel->key) {
3634     memset(channel->key, 0, channel->key_len / 8);
3635     silc_free(channel->key);
3636     silc_cipher_free(channel->send_key);
3637     silc_cipher_free(channel->receive_key);
3638   }
3639
3640   /* Create new cipher */
3641   if (!silc_cipher_alloc(cipher, &channel->send_key)) {
3642     channel->send_key = NULL;
3643     channel = NULL;
3644     goto out;
3645   }
3646   if (!silc_cipher_alloc(cipher, &channel->receive_key)) {
3647     silc_cipher_free(channel->send_key);
3648     channel->send_key = channel->receive_key = NULL;
3649     channel = NULL;
3650     goto out;
3651   }
3652
3653   if (channel->cipher)
3654     silc_free(channel->cipher);
3655   channel->cipher = strdup(cipher);
3656
3657   /* Save the key */
3658   channel->key_len = tmp_len * 8;
3659   channel->key = silc_memdup(tmp, tmp_len);
3660   silc_cipher_set_key(channel->send_key, tmp, channel->key_len, TRUE);
3661   silc_cipher_set_key(channel->receive_key, tmp, channel->key_len, FALSE);
3662
3663   /* Generate HMAC key from the channel key data and set it */
3664   if (!channel->hmac)
3665     if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
3666       memset(channel->key, 0, channel->key_len / 8);
3667       silc_free(channel->key);
3668       silc_cipher_free(channel->send_key);
3669       silc_cipher_free(channel->receive_key);
3670       channel->send_key = channel->receive_key = NULL;
3671       return FALSE;
3672     }
3673   silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3674   silc_hmac_set_key(channel->hmac, hash,
3675                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3676
3677   memset(hash, 0, sizeof(hash));
3678   memset(tmp, 0, tmp_len);
3679
3680   if (server->server_type == SILC_ROUTER) {
3681     if (!channel->rekey)
3682       channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3683     channel->rekey->channel = channel;
3684     if (channel->rekey->task)
3685       silc_schedule_task_del(server->schedule, channel->rekey->task);
3686
3687     channel->rekey->task =
3688       silc_schedule_task_add_timeout(server->schedule,
3689                                      silc_server_channel_key_rekey,
3690                                      (void *)channel->rekey,
3691                                      server->config->channel_rekey_secs, 0);
3692   }
3693
3694  out:
3695   if (payload)
3696     silc_channel_key_payload_free(payload);
3697
3698   return channel;
3699 }
3700
3701 /* Returns assembled of all servers in the given ID list. The packet's
3702    form is dictated by the New ID payload. */
3703
3704 static void silc_server_announce_get_servers(SilcServer server,
3705                                              SilcServerEntry remote,
3706                                              SilcIDList id_list,
3707                                              SilcBuffer *servers,
3708                                              unsigned long creation_time)
3709 {
3710   SilcList list;
3711   SilcIDCacheEntry id_cache;
3712   SilcServerEntry entry;
3713   SilcBuffer idp;
3714
3715   /* Go through all clients in the list */
3716   if (silc_idcache_get_all(id_list->servers, &list)) {
3717     silc_list_start(list);
3718     while ((id_cache = silc_list_get(list))) {
3719       entry = (SilcServerEntry)id_cache->context;
3720
3721       /* Do not announce the one we've sending our announcements and
3722          do not announce ourself. Also check the creation time if it's
3723          provided. */
3724       if ((entry == remote) || (entry == server->id_entry) ||
3725           (creation_time && entry->data.created < creation_time))
3726         continue;
3727
3728       idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3729
3730       *servers = silc_buffer_realloc(*servers,
3731                                      (*servers ?
3732                                       silc_buffer_truelen((*servers)) +
3733                                       silc_buffer_len(idp) :
3734                                       silc_buffer_len(idp)));
3735       silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3736       silc_buffer_put(*servers, idp->data, silc_buffer_len(idp));
3737       silc_buffer_pull(*servers, silc_buffer_len(idp));
3738       silc_buffer_free(idp);
3739     }
3740   }
3741 }
3742
3743 static SilcBuffer
3744 silc_server_announce_encode_notify(SilcNotifyType notify, SilcUInt32 argc, ...)
3745 {
3746   va_list ap;
3747   SilcBuffer p;
3748
3749   va_start(ap, argc);
3750   p = silc_notify_payload_encode(notify, argc, ap);
3751   va_end(ap);
3752
3753   return p;
3754 }
3755
3756 /* This function is used by router to announce existing servers to our
3757    primary router when we've connected to it. If `creation_time' is non-zero
3758    then only the servers that has been created after the `creation_time'
3759    will be announced. */
3760
3761 void silc_server_announce_servers(SilcServer server, SilcBool global,
3762                                   unsigned long creation_time,
3763                                   SilcPacketStream remote)
3764 {
3765   SilcBuffer servers = NULL;
3766
3767   SILC_LOG_DEBUG(("Announcing servers"));
3768
3769   /* Get servers in local list */
3770   silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3771                                    server->local_list, &servers,
3772                                    creation_time);
3773
3774   if (global)
3775     /* Get servers in global list */
3776     silc_server_announce_get_servers(server, silc_packet_get_context(remote),
3777                                      server->global_list, &servers,
3778                                      creation_time);
3779
3780   if (servers) {
3781     silc_buffer_push(servers, servers->data - servers->head);
3782     SILC_LOG_HEXDUMP(("servers"), servers->data, silc_buffer_len(servers));
3783
3784     /* Send the packet */
3785     silc_server_packet_send(server, remote,
3786                             SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3787                             servers->data, silc_buffer_len(servers));
3788
3789     silc_buffer_free(servers);
3790   }
3791 }
3792
3793 /* Returns assembled packet of all clients in the given ID list. The
3794    packet's form is dictated by the New ID Payload. */
3795
3796 static void silc_server_announce_get_clients(SilcServer server,
3797                                              SilcIDList id_list,
3798                                              SilcBuffer *clients,
3799                                              SilcBuffer *umodes,
3800                                              unsigned long creation_time)
3801 {
3802   SilcList list;
3803   SilcIDCacheEntry id_cache;
3804   SilcClientEntry client;
3805   SilcBuffer idp;
3806   SilcBuffer tmp;
3807   unsigned char mode[4];
3808
3809   /* Go through all clients in the list */
3810   if (silc_idcache_get_all(id_list->clients, &list)) {
3811     silc_list_start(list);
3812     while ((id_cache = silc_list_get(list))) {
3813       client = (SilcClientEntry)id_cache->context;
3814
3815       if (creation_time && client->data.created < creation_time)
3816         continue;
3817       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
3818         continue;
3819       if (!client->connection && !client->router)
3820         continue;
3821
3822       idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3823
3824       *clients = silc_buffer_realloc(*clients,
3825                                      (*clients ?
3826                                       silc_buffer_truelen((*clients)) +
3827                                       silc_buffer_len(idp) :
3828                                       silc_buffer_len(idp)));
3829       silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3830       silc_buffer_put(*clients, idp->data, silc_buffer_len(idp));
3831       silc_buffer_pull(*clients, silc_buffer_len(idp));
3832
3833       SILC_PUT32_MSB(client->mode, mode);
3834       tmp =
3835         silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE,
3836                                            2, idp->data, silc_buffer_len(idp),
3837                                            mode, 4);
3838       *umodes = silc_buffer_realloc(*umodes,
3839                                     (*umodes ?
3840                                      silc_buffer_truelen((*umodes)) +
3841                                      silc_buffer_len(tmp) :
3842                                      silc_buffer_len(tmp)));
3843       silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data));
3844       silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp));
3845       silc_buffer_pull(*umodes, silc_buffer_len(tmp));
3846       silc_buffer_free(tmp);
3847
3848       silc_buffer_free(idp);
3849     }
3850   }
3851 }
3852
3853 /* This function is used to announce our existing clients to our router
3854    when we've connected to it. If `creation_time' is non-zero then only
3855    the clients that has been created after the `creation_time' will be
3856    announced. */
3857
3858 void silc_server_announce_clients(SilcServer server,
3859                                   unsigned long creation_time,
3860                                   SilcPacketStream remote)
3861 {
3862   SilcBuffer clients = NULL;
3863   SilcBuffer umodes = NULL;
3864
3865   SILC_LOG_DEBUG(("Announcing clients"));
3866
3867   /* Get clients in local list */
3868   silc_server_announce_get_clients(server, server->local_list,
3869                                    &clients, &umodes, creation_time);
3870
3871   /* As router we announce our global list as well */
3872   if (server->server_type == SILC_ROUTER)
3873     silc_server_announce_get_clients(server, server->global_list,
3874                                      &clients, &umodes, creation_time);
3875
3876   if (clients) {
3877     silc_buffer_push(clients, clients->data - clients->head);
3878     SILC_LOG_HEXDUMP(("clients"), clients->data, silc_buffer_len(clients));
3879
3880     /* Send the packet */
3881     silc_server_packet_send(server, remote,
3882                             SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3883                             clients->data, silc_buffer_len(clients));
3884
3885     silc_buffer_free(clients);
3886   }
3887
3888   if (umodes) {
3889     silc_buffer_push(umodes, umodes->data - umodes->head);
3890     SILC_LOG_HEXDUMP(("umodes"), umodes->data, silc_buffer_len(umodes));
3891
3892     /* Send the packet */
3893     silc_server_packet_send(server, remote,
3894                             SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3895                             umodes->data, silc_buffer_len(umodes));
3896
3897     silc_buffer_free(umodes);
3898   }
3899 }
3900
3901 /* Returns channel's topic for announcing it */
3902
3903 void silc_server_announce_get_channel_topic(SilcServer server,
3904                                             SilcChannelEntry channel,
3905                                             SilcBuffer *topic)
3906 {
3907   SilcBuffer chidp;
3908
3909   if (channel->topic) {
3910     chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3911     *topic = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_TOPIC_SET, 2,
3912                                                 chidp->data,
3913                                                 silc_buffer_len(chidp),
3914                                                 channel->topic,
3915                                                 strlen(channel->topic));
3916     silc_buffer_free(chidp);
3917   }
3918 }
3919
3920 /* Returns channel's invite and ban lists */
3921
3922 void silc_server_announce_get_inviteban(SilcServer server,
3923                                         SilcChannelEntry channel,
3924                                         SilcBuffer *invite,
3925                                         SilcBuffer *ban)
3926 {
3927   SilcBuffer list, idp, idp2, tmp2;
3928   SilcUInt32 type;
3929   SilcHashTableList htl;
3930   const unsigned char a[1] = { 0x03 };
3931
3932   idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
3933
3934   /* Encode invite list */
3935   if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3936     list = silc_buffer_alloc_size(2);
3937     type = silc_hash_table_count(channel->invite_list);
3938     SILC_PUT16_MSB(type, list->data);
3939     silc_hash_table_list(channel->invite_list, &htl);
3940     while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
3941       list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
3942                                               type);
3943     silc_hash_table_list_reset(&htl);
3944
3945     idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
3946     *invite =
3947       silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_INVITE, 5,
3948                                          idp->data, silc_buffer_len(idp),
3949                                          channel->channel_name,
3950                                          strlen(channel->channel_name),
3951                                          idp2->data, silc_buffer_len(idp2),
3952                                          a, 1,
3953                                          list->data, silc_buffer_len(list));
3954     silc_buffer_free(idp2);
3955     silc_buffer_free(list);
3956   }
3957
3958   /* Encode ban list */
3959   if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
3960     list = silc_buffer_alloc_size(2);
3961     type = silc_hash_table_count(channel->ban_list);
3962     SILC_PUT16_MSB(type, list->data);
3963     silc_hash_table_list(channel->ban_list, &htl);
3964     while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
3965       list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
3966                                               type);
3967     silc_hash_table_list_reset(&htl);
3968
3969     *ban =
3970       silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_BAN, 3,
3971                                          idp->data, silc_buffer_len(idp),
3972                                          a, 1,
3973                                          list->data, silc_buffer_len(list));
3974     silc_buffer_free(list);
3975   }
3976
3977   silc_buffer_free(idp);
3978 }
3979
3980 /* Returns assembled packets for channel users of the `channel'. */
3981
3982 void silc_server_announce_get_channel_users(SilcServer server,
3983                                             SilcChannelEntry channel,
3984                                             SilcBuffer *channel_modes,
3985                                             SilcBuffer *channel_users,
3986                                             SilcBuffer *channel_users_modes)
3987 {
3988   SilcChannelClientEntry chl;
3989   SilcHashTableList htl;
3990   SilcBuffer chidp, clidp, csidp;
3991   SilcBuffer tmp, fkey = NULL, chpklist;
3992   int len;
3993   unsigned char mode[4], ulimit[4];
3994   char *hmac;
3995
3996   SILC_LOG_DEBUG(("Start"));
3997
3998   chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3999   csidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
4000   chpklist = silc_server_get_channel_pk_list(server, channel, TRUE, FALSE);
4001
4002   /* CMODE notify */
4003   SILC_PUT32_MSB(channel->mode, mode);
4004   if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4005     SILC_PUT32_MSB(channel->user_limit, ulimit);
4006   hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
4007   if (channel->founder_key)
4008     fkey = silc_public_key_payload_encode(channel->founder_key);
4009   tmp =
4010     silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
4011                                        8, csidp->data,
4012                                        silc_buffer_len(csidp),
4013                                        mode, sizeof(mode),
4014                                        NULL, 0,
4015                                        hmac, hmac ? strlen(hmac) : 0,
4016                                        channel->passphrase,
4017                                        channel->passphrase ?
4018                                        strlen(channel->passphrase) : 0,
4019                                        fkey ? fkey->data : NULL,
4020                                        fkey ? silc_buffer_len(fkey) : 0,
4021                                        chpklist ? chpklist->data : NULL,
4022                                        chpklist ?
4023                                        silc_buffer_len(chpklist) : 0,
4024                                        (channel->mode &
4025                                         SILC_CHANNEL_MODE_ULIMIT ?
4026                                         ulimit : NULL),
4027                                        (channel->mode &
4028                                         SILC_CHANNEL_MODE_ULIMIT ?
4029                                         sizeof(ulimit) : 0));
4030   len = silc_buffer_len(tmp);
4031   *channel_modes =
4032     silc_buffer_realloc(*channel_modes,
4033                         (*channel_modes ?
4034                          silc_buffer_truelen((*channel_modes)) + len : len));
4035   silc_buffer_pull_tail(*channel_modes,
4036                         ((*channel_modes)->end -
4037                          (*channel_modes)->data));
4038   silc_buffer_put(*channel_modes, tmp->data, silc_buffer_len(tmp));
4039   silc_buffer_pull(*channel_modes, len);
4040   silc_buffer_free(tmp);
4041   silc_buffer_free(fkey);
4042   fkey = NULL;
4043
4044   /* Now find all users on the channel */
4045   silc_hash_table_list(channel->user_list, &htl);
4046   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4047     clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4048
4049     /* JOIN Notify */
4050     tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
4051                                              clidp->data,
4052                                              silc_buffer_len(clidp),
4053                                              chidp->data,
4054                                              silc_buffer_len(chidp));
4055     len = silc_buffer_len(tmp);
4056     *channel_users =
4057       silc_buffer_realloc(*channel_users,
4058                           (*channel_users ?
4059                            silc_buffer_truelen((*channel_users)) + len : len));
4060     silc_buffer_pull_tail(*channel_users,
4061                           ((*channel_users)->end -
4062                            (*channel_users)->data));
4063
4064     silc_buffer_put(*channel_users, tmp->data, silc_buffer_len(tmp));
4065     silc_buffer_pull(*channel_users, len);
4066     silc_buffer_free(tmp);
4067
4068     /* CUMODE notify for mode change on the channel */
4069     SILC_PUT32_MSB(chl->mode, mode);
4070     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
4071       fkey = silc_public_key_payload_encode(channel->founder_key);
4072     tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
4073                                              4, csidp->data,
4074                                              silc_buffer_len(csidp),
4075                                              mode, sizeof(mode),
4076                                              clidp->data,
4077                                              silc_buffer_len(clidp),
4078                                              fkey ? fkey->data : NULL,
4079                                              fkey ? silc_buffer_len(fkey) : 0);
4080     len = silc_buffer_len(tmp);
4081     *channel_users_modes =
4082       silc_buffer_realloc(*channel_users_modes,
4083                           (*channel_users_modes ?
4084                            silc_buffer_truelen((*channel_users_modes)) +
4085                            len : len));
4086     silc_buffer_pull_tail(*channel_users_modes,
4087                           ((*channel_users_modes)->end -
4088                            (*channel_users_modes)->data));
4089
4090     silc_buffer_put(*channel_users_modes, tmp->data, silc_buffer_len(tmp));
4091     silc_buffer_pull(*channel_users_modes, len);
4092     silc_buffer_free(tmp);
4093     silc_buffer_free(fkey);
4094     fkey = NULL;
4095     silc_buffer_free(clidp);
4096   }
4097   silc_hash_table_list_reset(&htl);
4098   silc_buffer_free(chidp);
4099   silc_buffer_free(csidp);
4100 }
4101
4102 /* Returns assembled packets for all channels and users on those channels
4103    from the given ID List. The packets are in the form dictated by the
4104    New Channel and New Channel User payloads. */
4105
4106 void silc_server_announce_get_channels(SilcServer server,
4107                                        SilcIDList id_list,
4108                                        SilcBuffer *channels,
4109                                        SilcBuffer **channel_modes,
4110                                        SilcBuffer *channel_users,
4111                                        SilcBuffer **channel_users_modes,
4112                                        SilcUInt32 *channel_users_modes_c,
4113                                        SilcBuffer **channel_topics,
4114                                        SilcBuffer **channel_invites,
4115                                        SilcBuffer **channel_bans,
4116                                        SilcChannelID ***channel_ids,
4117                                        unsigned long creation_time)
4118 {
4119   SilcList list;
4120   SilcIDCacheEntry id_cache;
4121   SilcChannelEntry channel;
4122   unsigned char cid[32];
4123   SilcUInt32 id_len;
4124   SilcUInt16 name_len;
4125   int len;
4126   int i = *channel_users_modes_c;
4127   SilcBool announce;
4128
4129   SILC_LOG_DEBUG(("Start"));
4130
4131   /* Go through all channels in the list */
4132   if (silc_idcache_get_all(id_list->channels, &list)) {
4133     silc_list_start(list);
4134     while ((id_cache = silc_list_get(list))) {
4135       channel = (SilcChannelEntry)id_cache->context;
4136
4137       if (creation_time && channel->created < creation_time)
4138         announce = FALSE;
4139       else
4140         announce = TRUE;
4141
4142       silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4143       name_len = strlen(channel->channel_name);
4144
4145       if (announce) {
4146         len = 4 + name_len + id_len + 4;
4147         *channels =
4148           silc_buffer_realloc(*channels,
4149                               (*channels ?
4150                                silc_buffer_truelen((*channels)) +
4151                                len : len));
4152         silc_buffer_pull_tail(*channels,
4153                               ((*channels)->end - (*channels)->data));
4154         silc_buffer_format(*channels,
4155                            SILC_STR_UI_SHORT(name_len),
4156                            SILC_STR_UI_XNSTRING(channel->channel_name,
4157                                                 name_len),
4158                            SILC_STR_UI_SHORT(id_len),
4159                              SILC_STR_UI_XNSTRING(cid, id_len),
4160                            SILC_STR_UI_INT(channel->mode),
4161                            SILC_STR_END);
4162         silc_buffer_pull(*channels, len);
4163       }
4164
4165       if (creation_time && channel->updated < creation_time)
4166         announce = FALSE;
4167       else
4168         announce = TRUE;
4169
4170       if (announce) {
4171         /* Channel user modes */
4172         *channel_users_modes = silc_realloc(*channel_users_modes,
4173                                             sizeof(**channel_users_modes) *
4174                                             (i + 1));
4175         (*channel_users_modes)[i] = NULL;
4176         *channel_modes = silc_realloc(*channel_modes,
4177                                       sizeof(**channel_modes) * (i + 1));
4178         (*channel_modes)[i] = NULL;
4179         *channel_ids = silc_realloc(*channel_ids,
4180                                       sizeof(**channel_ids) * (i + 1));
4181         (*channel_ids)[i] = NULL;
4182         silc_server_announce_get_channel_users(server, channel,
4183                                                &(*channel_modes)[i],
4184                                                channel_users,
4185                                                &(*channel_users_modes)[i]);
4186         (*channel_ids)[i] = channel->id;
4187
4188         /* Channel's topic */
4189         *channel_topics = silc_realloc(*channel_topics,
4190                                        sizeof(**channel_topics) * (i + 1));
4191         (*channel_topics)[i] = NULL;
4192         silc_server_announce_get_channel_topic(server, channel,
4193                                                &(*channel_topics)[i]);
4194
4195         /* Channel's invite and ban list */
4196         *channel_invites = silc_realloc(*channel_invites,
4197                                         sizeof(**channel_invites) * (i + 1));
4198         (*channel_invites)[i] = NULL;
4199         *channel_bans = silc_realloc(*channel_bans,
4200                                      sizeof(**channel_bans) * (i + 1));
4201         (*channel_bans)[i] = NULL;
4202         silc_server_announce_get_inviteban(server, channel,
4203                                            &(*channel_invites)[i],
4204                                            &(*channel_bans)[i]);
4205
4206         (*channel_users_modes_c)++;
4207
4208         i++;
4209       }
4210     }
4211   }
4212 }
4213
4214 /* This function is used to announce our existing channels to our router
4215    when we've connected to it. This also announces the users on the
4216    channels to the router. If the `creation_time' is non-zero only the
4217    channels that was created after the `creation_time' are announced.
4218    Note that the channel users are still announced even if the `creation_time'
4219    was provided. */
4220
4221 void silc_server_announce_channels(SilcServer server,
4222                                    unsigned long creation_time,
4223                                    SilcPacketStream remote)
4224 {
4225   SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL;
4226   SilcBuffer *channel_users_modes = NULL;
4227   SilcBuffer *channel_topics = NULL;
4228   SilcBuffer *channel_invites = NULL;
4229   SilcBuffer *channel_bans = NULL;
4230   SilcUInt32 channel_users_modes_c = 0;
4231   SilcChannelID **channel_ids = NULL;
4232
4233   SILC_LOG_DEBUG(("Announcing channels and channel users"));
4234
4235   /* Get channels and channel users in local list */
4236   silc_server_announce_get_channels(server, server->local_list,
4237                                     &channels, &channel_modes,
4238                                     &channel_users,
4239                                     &channel_users_modes,
4240                                     &channel_users_modes_c,
4241                                     &channel_topics,
4242                                     &channel_invites,
4243                                     &channel_bans,
4244                                     &channel_ids, creation_time);
4245
4246   /* Get channels and channel users in global list */
4247   if (server->server_type != SILC_SERVER)
4248     silc_server_announce_get_channels(server, server->global_list,
4249                                       &channels, &channel_modes,
4250                                       &channel_users,
4251                                       &channel_users_modes,
4252                                       &channel_users_modes_c,
4253                                       &channel_topics,
4254                                       &channel_invites,
4255                                       &channel_bans,
4256                                       &channel_ids, creation_time);
4257
4258   if (channels) {
4259     silc_buffer_push(channels, channels->data - channels->head);
4260     SILC_LOG_HEXDUMP(("channels"), channels->data, silc_buffer_len(channels));
4261
4262     /* Send the packet */
4263     silc_server_packet_send(server, remote,
4264                             SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
4265                             channels->data, silc_buffer_len(channels));
4266
4267     silc_buffer_free(channels);
4268   }
4269
4270   if (channel_users) {
4271     silc_buffer_push(channel_users, channel_users->data - channel_users->head);
4272     SILC_LOG_HEXDUMP(("channel users"), channel_users->data,
4273                      silc_buffer_len(channel_users));
4274
4275     /* Send the packet */
4276     silc_server_packet_send(server, remote,
4277                             SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4278                             channel_users->data, silc_buffer_len(channel_users));
4279
4280     silc_buffer_free(channel_users);
4281   }
4282
4283   if (channel_modes) {
4284     int i;
4285
4286     for (i = 0; i < channel_users_modes_c; i++) {
4287       if (!channel_modes[i])
4288         continue;
4289       silc_buffer_push(channel_modes[i],
4290                        channel_modes[i]->data -
4291                        channel_modes[i]->head);
4292       SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data,
4293                        silc_buffer_len(channel_modes[i]));
4294       silc_server_packet_send_dest(server, remote,
4295                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4296                                    channel_ids[i], SILC_ID_CHANNEL,
4297                                    channel_modes[i]->data,
4298                                    silc_buffer_len(channel_modes[i]));
4299       silc_buffer_free(channel_modes[i]);
4300     }
4301     silc_free(channel_modes);
4302   }
4303
4304   if (channel_users_modes) {
4305     int i;
4306
4307     for (i = 0; i < channel_users_modes_c; i++) {
4308       if (!channel_users_modes[i])
4309         continue;
4310       silc_buffer_push(channel_users_modes[i],
4311                        channel_users_modes[i]->data -
4312                        channel_users_modes[i]->head);
4313       SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data,
4314                        silc_buffer_len(channel_users_modes[i]));
4315       silc_server_packet_send_dest(server, remote,
4316                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4317                                    channel_ids[i], SILC_ID_CHANNEL,
4318                                    channel_users_modes[i]->data,
4319                                    silc_buffer_len(channel_users_modes[i]));
4320       silc_buffer_free(channel_users_modes[i]);
4321     }
4322     silc_free(channel_users_modes);
4323   }
4324
4325   if (channel_topics) {
4326     int i;
4327
4328     for (i = 0; i < channel_users_modes_c; i++) {
4329       if (!channel_topics[i])
4330         continue;
4331
4332       silc_buffer_push(channel_topics[i],
4333                        channel_topics[i]->data -
4334                        channel_topics[i]->head);
4335       SILC_LOG_HEXDUMP(("channel topic"), channel_topics[i]->data,
4336                        silc_buffer_len(channel_topics[i]));
4337       silc_server_packet_send_dest(server, remote,
4338                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4339                                    channel_ids[i], SILC_ID_CHANNEL,
4340                                    channel_topics[i]->data,
4341                                    silc_buffer_len(channel_topics[i]));
4342       silc_buffer_free(channel_topics[i]);
4343     }
4344     silc_free(channel_topics);
4345   }
4346
4347   if (channel_invites) {
4348     int i;
4349
4350     for (i = 0; i < channel_users_modes_c; i++) {
4351       if (!channel_invites[i])
4352         continue;
4353
4354       silc_buffer_push(channel_invites[i],
4355                        channel_invites[i]->data -
4356                        channel_invites[i]->head);
4357       SILC_LOG_HEXDUMP(("channel invite list"), channel_invites[i]->data,
4358                        silc_buffer_len(channel_invites[i]));
4359       silc_server_packet_send_dest(server, remote,
4360                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4361                                    channel_ids[i], SILC_ID_CHANNEL,
4362                                    channel_invites[i]->data,
4363                                    silc_buffer_len(channel_invites[i]));
4364       silc_buffer_free(channel_invites[i]);
4365     }
4366     silc_free(channel_invites);
4367   }
4368
4369   if (channel_bans) {
4370     int i;
4371
4372     for (i = 0; i < channel_users_modes_c; i++) {
4373       if (!channel_bans[i])
4374         continue;
4375
4376       silc_buffer_push(channel_bans[i],
4377                        channel_bans[i]->data -
4378                        channel_bans[i]->head);
4379       SILC_LOG_HEXDUMP(("channel ban list"), channel_bans[i]->data,
4380                        silc_buffer_len(channel_bans[i]));
4381       silc_server_packet_send_dest(server, remote,
4382                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
4383                                    channel_ids[i], SILC_ID_CHANNEL,
4384                                    channel_bans[i]->data,
4385                                    silc_buffer_len(channel_bans[i]));
4386       silc_buffer_free(channel_bans[i]);
4387     }
4388     silc_free(channel_bans);
4389   }
4390
4391   silc_free(channel_ids);
4392 }
4393
4394 /* Announces WATCH list. */
4395
4396 void silc_server_announce_watches(SilcServer server,
4397                                   SilcPacketStream remote)
4398 {
4399   SilcHashTableList htl;
4400   SilcBuffer buffer, idp, args, pkp;
4401   SilcClientEntry client;
4402   void *key;
4403
4404   SILC_LOG_DEBUG(("Announcing watch list"));
4405
4406   /* XXX because way we save the nicks (hash) we cannot announce them. */
4407
4408   /* XXX we should send all public keys in one command if client is
4409      watching more than one key */
4410   silc_hash_table_list(server->watcher_list_pk, &htl);
4411   while (silc_hash_table_get(&htl, &key, (void *)&client)) {
4412     if (!client || !client->id)
4413       continue;
4414
4415     server->stat.commands_sent++;
4416
4417     idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4418     args = silc_buffer_alloc_size(2);
4419     silc_buffer_format(args,
4420                        SILC_STR_UI_SHORT(1),
4421                        SILC_STR_END);
4422     pkp = silc_public_key_payload_encode(key);
4423     args = silc_argument_payload_encode_one(args, pkp->data,
4424                                             silc_buffer_len(pkp), 0x00);
4425     buffer = silc_command_payload_encode_va(SILC_COMMAND_WATCH,
4426                                             ++server->cmd_ident, 2,
4427                                             1, idp->data, silc_buffer_len(idp),
4428                                             4, args->data,
4429                                             silc_buffer_len(args));
4430
4431     /* Send command */
4432     silc_server_packet_send(server, remote, SILC_PACKET_COMMAND, 0,
4433                             buffer->data, silc_buffer_len(buffer));
4434
4435     silc_buffer_free(pkp);
4436     silc_buffer_free(args);
4437     silc_buffer_free(idp);
4438     silc_buffer_free(buffer);
4439   }
4440   silc_hash_table_list_reset(&htl);
4441 }
4442
4443 /* Assembles user list and users mode list from the `channel'. */
4444
4445 SilcBool silc_server_get_users_on_channel(SilcServer server,
4446                                       SilcChannelEntry channel,
4447                                       SilcBuffer *user_list,
4448                                       SilcBuffer *mode_list,
4449                                       SilcUInt32 *user_count)
4450 {
4451   SilcChannelClientEntry chl;
4452   SilcHashTableList htl;
4453   SilcBuffer client_id_list;
4454   SilcBuffer client_mode_list;
4455   SilcBuffer idp;
4456   SilcUInt32 list_count = 0, len = 0;
4457
4458   if (!silc_hash_table_count(channel->user_list))
4459     return FALSE;
4460
4461   silc_hash_table_list(channel->user_list, &htl);
4462   while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4463     len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
4464   silc_hash_table_list_reset(&htl);
4465
4466   client_id_list = silc_buffer_alloc(len);
4467   client_mode_list =
4468     silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
4469   silc_buffer_pull_tail(client_id_list, silc_buffer_truelen(client_id_list));
4470   silc_buffer_pull_tail(client_mode_list,
4471                         silc_buffer_truelen(client_mode_list));
4472
4473   silc_hash_table_list(channel->user_list, &htl);
4474   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4475     /* Client ID */
4476     idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
4477     silc_buffer_put(client_id_list, idp->data, silc_buffer_len(idp));
4478     silc_buffer_pull(client_id_list, silc_buffer_len(idp));
4479     silc_buffer_free(idp);
4480
4481     /* Client's mode on channel */
4482     SILC_PUT32_MSB(chl->mode, client_mode_list->data);
4483     silc_buffer_pull(client_mode_list, 4);
4484
4485     list_count++;
4486   }
4487   silc_hash_table_list_reset(&htl);
4488   silc_buffer_push(client_id_list,
4489                    client_id_list->data - client_id_list->head);
4490   silc_buffer_push(client_mode_list,
4491                    client_mode_list->data - client_mode_list->head);
4492
4493   *user_list = client_id_list;
4494   *mode_list = client_mode_list;
4495   *user_count = list_count;
4496   return TRUE;
4497 }
4498
4499 /* Saves users and their modes to the `channel'. */
4500
4501 void silc_server_save_users_on_channel(SilcServer server,
4502                                        SilcPacketStream sock,
4503                                        SilcChannelEntry channel,
4504                                        SilcClientID *noadd,
4505                                        SilcBuffer user_list,
4506                                        SilcBuffer mode_list,
4507                                        SilcUInt32 user_count)
4508 {
4509   int i;
4510   SilcUInt16 idp_len;
4511   SilcUInt32 mode;
4512   SilcID id;
4513   SilcClientEntry client;
4514   SilcIDCacheEntry cache;
4515   SilcChannelClientEntry chl;
4516
4517   SILC_LOG_DEBUG(("Saving %d users on %s channel", user_count,
4518                   channel->channel_name));
4519
4520   for (i = 0; i < user_count; i++) {
4521     /* Client ID */
4522     SILC_GET16_MSB(idp_len, user_list->data + 2);
4523     idp_len += 4;
4524     if (!silc_id_payload_parse_id(user_list->data, idp_len, &id))
4525       continue;
4526     silc_buffer_pull(user_list, idp_len);
4527
4528     /* Mode */
4529     SILC_GET32_MSB(mode, mode_list->data);
4530     silc_buffer_pull(mode_list, 4);
4531
4532     if (noadd && SILC_ID_CLIENT_COMPARE(&id.u.client_id, noadd))
4533       continue;
4534
4535     cache = NULL;
4536
4537     /* Check if we have this client cached already. */
4538     client = silc_idlist_find_client_by_id(server->local_list,
4539                                            &id.u.client_id,
4540                                            server->server_type, &cache);
4541     if (!client)
4542       client = silc_idlist_find_client_by_id(server->global_list,
4543                                              &id.u.client_id,
4544                                              server->server_type, &cache);
4545     if (!client) {
4546       /* If router did not find such Client ID in its lists then this must
4547          be bogus client or some router in the net is buggy. */
4548       if (server->server_type != SILC_SERVER)
4549         continue;
4550
4551       /* We don't have that client anywhere, add it. The client is added
4552          to global list since server didn't have it in the lists so it must be
4553          global. */
4554       client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
4555                                       silc_id_dup(&id.u.client_id,
4556                                                   SILC_ID_CLIENT),
4557                                       silc_packet_get_context(sock),
4558                                       NULL);
4559       if (!client) {
4560         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
4561         continue;
4562       }
4563
4564       client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
4565     }
4566
4567     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
4568       SILC_LOG_ERROR(("Attempting to add unregistered client to channel ",
4569                       "%s", channel->channel_name));
4570       continue;
4571     }
4572
4573     if (!silc_server_client_on_channel(client, channel, &chl)) {
4574       /* Client was not on the channel, add it. */
4575       chl = silc_calloc(1, sizeof(*chl));
4576       chl->client = client;
4577       chl->mode = mode;
4578       chl->channel = channel;
4579       silc_hash_table_add(channel->user_list, chl->client, chl);
4580       silc_hash_table_add(client->channels, chl->channel, chl);
4581       channel->user_count++;
4582     } else {
4583       /* Update mode */
4584       chl->mode = mode;
4585     }
4586   }
4587 }
4588
4589 /* Saves channels and channels user modes to the `client'.  Removes
4590    the client from those channels that are not sent in the list but
4591    it has joined. */
4592
4593 void silc_server_save_user_channels(SilcServer server,
4594                                     SilcPacketStream sock,
4595                                     SilcClientEntry client,
4596                                     SilcBuffer channels,
4597                                     SilcBuffer channels_user_modes)
4598 {
4599   SilcDList ch;
4600   SilcUInt32 *chumodes;
4601   SilcChannelPayload entry;
4602   SilcChannelEntry channel;
4603   SilcChannelID channel_id;
4604   SilcChannelClientEntry chl;
4605   SilcHashTable ht = NULL;
4606   SilcHashTableList htl;
4607   char *name;
4608   int i = 0;
4609
4610   if (!channels || !channels_user_modes ||
4611       !(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
4612     goto out;
4613
4614   ch = silc_channel_payload_parse_list(channels->data,
4615                                        silc_buffer_len(channels));
4616   if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
4617                                &chumodes)) {
4618     ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
4619                                NULL, NULL, NULL, TRUE);
4620     silc_dlist_start(ch);
4621     while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
4622       /* Check if we have this channel, and add it if we don't have it.
4623          Also add the client on the channel unless it is there already. */
4624       if (!silc_channel_get_id_parse(entry, &channel_id))
4625         continue;
4626       channel = silc_idlist_find_channel_by_id(server->local_list,
4627                                                &channel_id, NULL);
4628       if (!channel)
4629         channel = silc_idlist_find_channel_by_id(server->global_list,
4630                                                  &channel_id, NULL);
4631       if (!channel) {
4632         if (server->server_type != SILC_SERVER) {
4633           i++;
4634           continue;
4635         }
4636
4637         /* We don't have that channel anywhere, add it. */
4638         name = silc_channel_get_name(entry, NULL);
4639         channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
4640                                           silc_id_dup(&channel_id,
4641                                                       SILC_ID_CHANNEL),
4642                                           server->router, NULL, NULL, 0);
4643         if (!channel) {
4644           i++;
4645           continue;
4646         }
4647       }
4648
4649       channel->mode = silc_channel_get_mode(entry);
4650
4651       /* Add the client on the channel */
4652       if (!silc_server_client_on_channel(client, channel, &chl)) {
4653         chl = silc_calloc(1, sizeof(*chl));
4654         chl->client = client;
4655         chl->mode = chumodes[i++];
4656         chl->channel = channel;
4657         silc_hash_table_add(channel->user_list, chl->client, chl);
4658         silc_hash_table_add(client->channels, chl->channel, chl);
4659         channel->user_count++;
4660       } else {
4661         /* Update mode */
4662         chl->mode = chumodes[i++];
4663       }
4664
4665       silc_hash_table_add(ht, channel, channel);
4666     }
4667     silc_channel_payload_list_free(ch);
4668     silc_free(chumodes);
4669   }
4670
4671  out:
4672   /* Go through the list again and remove client from channels that
4673      are no part of the list. */
4674   if (ht) {
4675     silc_hash_table_list(client->channels, &htl);
4676     while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4677       if (!silc_hash_table_find(ht, chl->channel, NULL, NULL)) {
4678         silc_hash_table_del(chl->channel->user_list, chl->client);
4679         silc_hash_table_del(chl->client->channels, chl->channel);
4680         silc_free(chl);
4681       }
4682     }
4683     silc_hash_table_list_reset(&htl);
4684     silc_hash_table_free(ht);
4685   } else {
4686     silc_hash_table_list(client->channels, &htl);
4687     while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4688       silc_hash_table_del(chl->channel->user_list, chl->client);
4689       silc_hash_table_del(chl->client->channels, chl->channel);
4690       silc_free(chl);
4691     }
4692     silc_hash_table_list_reset(&htl);
4693   }
4694 }
4695
4696 /* Lookups route to the client indicated by the `id_data'. The connection
4697    object and internal data object is returned. Returns NULL if route
4698    could not be found to the client. If the `client_id' is specified then
4699    it is used and the `id_data' is ignored. */
4700
4701 SilcPacketStream
4702 silc_server_get_client_route(SilcServer server,
4703                              unsigned char *id_data,
4704                              SilcUInt32 id_len,
4705                              SilcClientID *client_id,
4706                              SilcIDListData *idata,
4707                              SilcClientEntry *client_entry)
4708 {
4709   SilcClientID *id, clid;
4710   SilcClientEntry client;
4711
4712   SILC_LOG_DEBUG(("Start"));
4713
4714   if (client_entry)
4715     *client_entry = NULL;
4716
4717   /* Decode destination Client ID */
4718   if (!client_id) {
4719     if (!silc_id_str2id(id_data, id_len, SILC_ID_CHANNEL, &clid, sizeof(clid)))
4720       return NULL;
4721     id = silc_id_dup(&clid, SILC_ID_CLIENT);
4722   } else {
4723     id = silc_id_dup(client_id, SILC_ID_CLIENT);
4724   }
4725
4726   /* If the destination belongs to our server we don't have to route
4727      the packet anywhere but to send it to the local destination. */
4728   client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
4729   if (client) {
4730     silc_free(id);
4731
4732     /* If we are router and the client has router then the client is in
4733        our cell but not directly connected to us. */
4734     if (server->server_type == SILC_ROUTER && client->router) {
4735       /* We are of course in this case the client's router thus the route
4736          to the client is the server who owns the client. So, we will send
4737          the packet to that server. */
4738       if (idata)
4739         *idata = (SilcIDListData)client->router;
4740       return client->router->connection;
4741     }
4742
4743     /* Seems that client really is directly connected to us */
4744     if (idata)
4745       *idata = (SilcIDListData)client;
4746     if (client_entry)
4747       *client_entry = client;
4748     return client->connection;
4749   }
4750
4751   /* Destination belongs to someone not in this server. If we are normal
4752      server our action is to send the packet to our router. */
4753   if (server->server_type != SILC_ROUTER && !server->standalone) {
4754     silc_free(id);
4755     if (idata)
4756       *idata = (SilcIDListData)server->router;
4757     return SILC_PRIMARY_ROUTE(server);
4758   }
4759
4760   /* We are router and we will perform route lookup for the destination
4761      and send the packet to fastest route. */
4762   if (server->server_type == SILC_ROUTER && !server->standalone) {
4763     /* Check first that the ID is valid */
4764     client = silc_idlist_find_client_by_id(server->global_list, id,
4765                                            TRUE, NULL);
4766     if (client) {
4767       SilcPacketStream dst_sock;
4768
4769       dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
4770
4771       silc_free(id);
4772       if (idata && dst_sock)
4773         *idata = silc_packet_get_context(dst_sock);
4774       return dst_sock;
4775     }
4776   }
4777
4778   silc_free(id);
4779   return NULL;
4780 }
4781
4782 /* Encodes and returns channel list of channels the `client' has joined.
4783    Secret channels are not put to the list. */
4784
4785 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
4786                                                SilcClientEntry client,
4787                                                SilcBool get_private,
4788                                                SilcBool get_secret,
4789                                                SilcBuffer *user_mode_list)
4790 {
4791   SilcBuffer buffer = NULL;
4792   SilcChannelEntry channel;
4793   SilcChannelClientEntry chl;
4794   SilcHashTableList htl;
4795   unsigned char cid[32];
4796   SilcUInt32 id_len;
4797   SilcUInt16 name_len;
4798   int len;
4799
4800   if (user_mode_list)
4801     *user_mode_list = NULL;
4802
4803   silc_hash_table_list(client->channels, &htl);
4804   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
4805     channel = chl->channel;
4806
4807     if (channel->mode & SILC_CHANNEL_MODE_SECRET && !get_secret)
4808       continue;
4809     if (channel->mode & SILC_CHANNEL_MODE_PRIVATE && !get_private)
4810       continue;
4811
4812     silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &id_len);
4813     name_len = strlen(channel->channel_name);
4814
4815     len = 4 + name_len + id_len + 4;
4816     buffer = silc_buffer_realloc(buffer,
4817                                  (buffer ?
4818                                   silc_buffer_truelen(buffer) + len : len));
4819     silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
4820     silc_buffer_format(buffer,
4821                        SILC_STR_UI_SHORT(name_len),
4822                        SILC_STR_DATA(channel->channel_name, name_len),
4823                        SILC_STR_UI_SHORT(id_len),
4824                        SILC_STR_DATA(cid, id_len),
4825                        SILC_STR_UI_INT(chl->channel->mode),
4826                        SILC_STR_END);
4827     silc_buffer_pull(buffer, len);
4828
4829     if (user_mode_list) {
4830       *user_mode_list =
4831         silc_buffer_realloc(*user_mode_list,
4832                             (*user_mode_list ?
4833                              silc_buffer_truelen((*user_mode_list)) + 4 : 4));
4834       silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
4835                                               (*user_mode_list)->data));
4836       SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
4837       silc_buffer_pull(*user_mode_list, 4);
4838     }
4839   }
4840   silc_hash_table_list_reset(&htl);
4841
4842   if (buffer)
4843     silc_buffer_push(buffer, buffer->data - buffer->head);
4844   if (user_mode_list && *user_mode_list)
4845     silc_buffer_push(*user_mode_list, ((*user_mode_list)->data -
4846                                        (*user_mode_list)->head));
4847
4848   return buffer;
4849 }
4850
4851 /* Task callback used to retrieve network statistical information from
4852    router server once in a while. */
4853
4854 SILC_TASK_CALLBACK(silc_server_get_stats)
4855 {
4856   SilcServer server = (SilcServer)context;
4857   SilcBuffer idp, packet;
4858
4859   if (!server->standalone) {
4860     SILC_LOG_DEBUG(("Retrieving stats from router"));
4861     server->stat.commands_sent++;
4862     idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
4863     packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
4864                                             ++server->cmd_ident, 1,
4865                                             1, idp->data,
4866                                             silc_buffer_len(idp));
4867     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4868                             SILC_PACKET_COMMAND, 0, packet->data,
4869                             silc_buffer_len(packet));
4870     silc_buffer_free(packet);
4871     silc_buffer_free(idp);
4872   }
4873
4874   silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats,
4875                                  server, 120, 0);
4876 }