updates.
[silc.git] / apps / silcd / server.c
1 /*
2
3   server.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2001 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * This is the actual SILC server than handles everything relating to
22  * servicing the SILC connections. This is also a SILC router as a router 
23  * is also normal server.
24  */
25 /* $Id$ */
26
27 #include "serverincludes.h"
28 #include "server_internal.h"
29
30 /* Static prototypes */
31 SILC_TASK_CALLBACK(silc_server_connect_router);
32 SILC_TASK_CALLBACK(silc_server_connect_to_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
35 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
38 SILC_TASK_CALLBACK(silc_server_packet_process);
39 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
40 SILC_TASK_CALLBACK(silc_server_timeout_remote);
41 SILC_TASK_CALLBACK(silc_server_failure_callback);
42 SILC_TASK_CALLBACK(silc_server_rekey_callback);
43
44 /* Allocates a new SILC server object. This has to be done before the server
45    can be used. After allocation one must call silc_server_init to initialize
46    the server. The new allocated server object is returned to the new_server
47    argument. */
48
49 int silc_server_alloc(SilcServer *new_server)
50 {
51   SilcServer server;
52
53   SILC_LOG_DEBUG(("Allocating new server object"));
54
55   server = silc_calloc(1, sizeof(*server));
56   server->server_type = SILC_SERVER;
57   server->standalone = TRUE;
58   server->local_list = silc_calloc(1, sizeof(*server->local_list));
59   server->global_list = silc_calloc(1, sizeof(*server->global_list));
60   server->pending_commands = silc_dlist_init();
61 #ifdef SILC_SIM
62   server->sim = silc_dlist_init();
63 #endif
64
65   *new_server = server;
66
67   return TRUE;
68 }
69
70 /* Free's the SILC server object. This is called at the very end before
71    the program ends. */
72
73 void silc_server_free(SilcServer server)
74 {
75   if (server) {
76 #ifdef SILC_SIM
77     SilcSimContext *sim;
78 #endif
79
80     silc_free(server->local_list);
81     silc_free(server->global_list);
82     if (server->rng)
83       silc_rng_free(server->rng);
84
85     if (server->pkcs)
86       silc_pkcs_free(server->pkcs);
87
88 #ifdef SILC_SIM
89     while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
90       silc_dlist_del(server->sim, sim);
91       silc_sim_free(sim);
92     }
93     silc_dlist_uninit(server->sim);
94 #endif
95
96     silc_free(server->params);
97
98     if (server->pending_commands)
99       silc_dlist_uninit(server->pending_commands);
100
101     silc_free(server);
102   }
103 }
104
105 /* Initializes the entire SILC server. This is called always before running
106    the server. This is called only once at the initialization of the program.
107    This binds the server to its listenning port. After this function returns 
108    one should call silc_server_run to start the server. This returns TRUE 
109    when everything is ok to run the server. Configuration file must be
110    read and parsed before calling this. */
111
112 int silc_server_init(SilcServer server)
113 {
114   int *sock = NULL, sock_count = 0, i;
115   SilcServerID *id;
116   SilcServerEntry id_entry;
117   SilcIDListPurge purge;
118   SilcServerConfigSectionListenPort *listen;
119
120   SILC_LOG_DEBUG(("Initializing server"));
121   assert(server);
122   assert(server->config);
123
124   /* Set public and private keys */
125   if (!server->config->server_keys ||
126       !server->config->server_keys->public_key || 
127       !server->config->server_keys->private_key) {
128     SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
129     return FALSE;
130   }
131   server->public_key = server->config->server_keys->public_key;
132   server->private_key = server->config->server_keys->private_key;
133
134   /* XXX After server is made as Silc Server Library this can be given
135      as argument, for now this is hard coded */
136   server->params = silc_calloc(1, sizeof(*server->params));
137   server->params->retry_count = SILC_SERVER_RETRY_COUNT;
138   server->params->retry_interval_min = SILC_SERVER_RETRY_INTERVAL_MIN;
139   server->params->retry_interval_max = SILC_SERVER_RETRY_INTERVAL_MAX;
140   server->params->retry_keep_trying = FALSE;
141   server->params->protocol_timeout = 60;
142   server->params->require_reverse_mapping = FALSE;
143
144   /* Set log files where log message should be saved. */
145   server->config->server = server;
146   silc_server_config_setlogfiles(server->config);
147  
148   /* Register all configured ciphers, PKCS and hash functions. */
149   if (!silc_server_config_register_ciphers(server->config))
150     silc_cipher_register_default();
151   if (!silc_server_config_register_pkcs(server->config))
152     silc_pkcs_register_default();
153   if (!silc_server_config_register_hashfuncs(server->config))
154     silc_hash_register_default();
155   if (!silc_server_config_register_hmacs(server->config))
156     silc_hmac_register_default();
157
158   /* Initialize random number generator for the server. */
159   server->rng = silc_rng_alloc();
160   silc_rng_init(server->rng);
161   silc_rng_global_init(server->rng);
162
163   /* Initialize hash functions for server to use */
164   silc_hash_alloc("md5", &server->md5hash);
165   silc_hash_alloc("sha1", &server->sha1hash);
166
167   /* Initialize none cipher */
168   silc_cipher_alloc("none", &server->none_cipher);
169
170   /* Allocate PKCS context for local public and private keys */
171   silc_pkcs_alloc(server->public_key->name, &server->pkcs);
172   silc_pkcs_public_key_set(server->pkcs, server->public_key);
173   silc_pkcs_private_key_set(server->pkcs, server->private_key);
174
175   /* Create a listening server. Note that our server can listen on multiple
176      ports. All listeners are created here and now. */
177   sock_count = 0;
178   listen = server->config->listen_port;
179   while(listen) {
180     int tmp;
181
182     tmp = silc_net_create_server(server->config->listen_port->port,
183                                  server->config->listen_port->listener_ip);
184     if (tmp < 0) {
185       SILC_LOG_ERROR(("Could not create server listener: %s on %d",
186                       server->config->listen_port->listener_ip,
187                       server->config->listen_port->port));
188       goto err0;
189     }
190
191     sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1)));
192     sock[sock_count] = tmp;
193     sock_count++;
194     listen = listen->next;
195   }
196
197   /* Initialize ID caches */
198   server->local_list->clients = 
199     silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
200   server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
201   server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
202
203   /* These are allocated for normal server as well as these hold some 
204      global information that the server has fetched from its router. For 
205      router these are used as they are supposed to be used on router. */
206   server->global_list->clients = 
207     silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
208   server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
209   server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
210
211   /* Allocate the entire socket list that is used in server. Eventually 
212      all connections will have entry in this table (it is a table of 
213      pointers to the actual object that is allocated individually 
214      later). */
215   server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS,
216                                 sizeof(*server->sockets));
217
218   for (i = 0; i < sock_count; i++) {
219     SilcSocketConnection newsocket = NULL;
220
221     /* Set socket to non-blocking mode */
222     silc_net_set_socket_nonblock(sock[i]);
223     server->sock = sock[i];
224     
225     /* Create a Server ID for the server. */
226     silc_id_create_server_id(sock[i], server->rng, &id);
227     if (!id) {
228       goto err0;
229     }
230     
231     server->id = id;
232     server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
233     server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
234     server->id_type = SILC_ID_SERVER;
235     server->server_name = server->config->server_info->server_name;
236
237     /* Add ourselves to the server list. We don't have a router yet 
238        beacuse we haven't established a route yet. It will be done later. 
239        For now, NULL is sent as router. This allocates new entry to
240        the ID list. */
241     id_entry = 
242       silc_idlist_add_server(server->local_list,
243                              server->config->server_info->server_name,
244                              server->server_type, server->id, NULL, NULL);
245     if (!id_entry) {
246       SILC_LOG_ERROR(("Could not add ourselves to cache"));
247       goto err0;
248     }
249     id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
250     
251     /* Add ourselves also to the socket table. The entry allocated above
252        is sent as argument for fast referencing in the future. */
253     silc_socket_alloc(sock[i], SILC_SOCKET_TYPE_SERVER, id_entry, 
254                       &newsocket);
255
256     server->sockets[sock[i]] = newsocket;
257     
258     /* Perform name and address lookups to resolve the listenning address
259        and port. */
260     if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname, 
261                                      &newsocket->ip)) {
262       if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
263           !newsocket->ip) {
264         SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
265                         newsocket->hostname ? newsocket->hostname :
266                         newsocket->ip ? newsocket->ip : ""));
267         server->stat.conn_failures++;
268         goto err0;
269       }
270       if (!newsocket->hostname)
271         newsocket->hostname = strdup(newsocket->ip);
272     }
273     newsocket->port = silc_net_get_local_port(sock[i]);
274
275     /* Put the allocated socket pointer also to the entry allocated above 
276        for fast back-referencing to the socket list. */
277     id_entry->connection = (void *)server->sockets[sock[i]];
278     server->id_entry = id_entry;
279   }
280
281   /* Register protocols */
282   silc_server_protocols_register();
283
284   /* Initialize the scheduler. */
285   server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
286   if (!server->schedule)
287     goto err0;
288   
289   /* Add the first task to the scheduler. This is task that is executed by
290      timeout. It expires as soon as the caller calls silc_server_run. This
291      task performs authentication protocol and key exchange with our
292      primary router. */
293   silc_schedule_task_add(server->schedule, sock[0], 
294                          silc_server_connect_to_router,
295                          (void *)server, 0, 1,
296                          SILC_TASK_TIMEOUT,
297                          SILC_TASK_PRI_NORMAL);
298
299   /* Add listener task to the scheduler. This task receives new connections
300      to the server. This task remains on the queue until the end of the 
301      program. */
302   silc_schedule_task_add(server->schedule, sock[0],
303                          silc_server_accept_new_connection,
304                          (void *)server, 0, 0, 
305                          SILC_TASK_FD,
306                          SILC_TASK_PRI_NORMAL);
307   server->listenning = TRUE;
308
309   /* If server connections has been configured then we must be router as
310      normal server cannot have server connections, only router connections. */
311   if (server->config->servers) {
312     SilcServerConfigSectionServerConnection *ptr = server->config->servers;
313
314     server->server_type = SILC_ROUTER;
315     while (ptr) {
316       if (ptr->backup_router) {
317         server->server_type = SILC_BACKUP_ROUTER;
318         server->backup_router = TRUE;
319         server->id_entry->server_type = SILC_BACKUP_ROUTER;
320         break;
321       }
322       ptr = ptr->next;
323     }
324   }
325
326   /* Register the ID Cache purge task. This periodically purges the ID cache
327      and removes the expired cache entries. */
328
329   /* Clients local list */
330   purge = silc_calloc(1, sizeof(*purge));
331   purge->cache = server->local_list->clients;
332   purge->schedule = server->schedule;
333   silc_schedule_task_add(purge->schedule, 0, 
334                          silc_idlist_purge,
335                          (void *)purge, 600, 0,
336                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
337
338   /* Clients global list */
339   purge = silc_calloc(1, sizeof(*purge));
340   purge->cache = server->global_list->clients;
341   purge->schedule = server->schedule;
342   silc_schedule_task_add(purge->schedule, 0, 
343                          silc_idlist_purge,
344                          (void *)purge, 300, 0,
345                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
346
347   SILC_LOG_DEBUG(("Server initialized"));
348
349   /* We are done here, return succesfully */
350   return TRUE;
351
352  err0:
353   for (i = 0; i < sock_count; i++)
354     silc_net_close_server(sock[i]);
355
356   return FALSE;
357 }
358
359 /* Fork server to background and set gid+uid to non-root */
360
361 void silc_server_daemonise(SilcServer server)
362 {
363   int i;
364
365   i = fork ();
366
367   if (i) {
368     if (i > 0) {
369       if (geteuid())
370         SILC_LOG_DEBUG(("Server started as user"));
371       else
372         SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
373
374       SILC_LOG_DEBUG(("Forking SILC server to background"));
375       exit(0);
376     } else {
377       SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
378       exit(1);
379     }
380   }
381   setsid();
382 }
383
384 /* Drop root privligies. If this cannot be done, die. */
385
386 void silc_server_drop(SilcServer server)
387 {
388   /* Are we executing silcd as root or a regular user? */
389   if (!geteuid()) {
390
391     struct passwd *pw;
392     struct group *gr;
393     char *user, *group;
394
395     if (!server->config->identity || !server->config->identity->user || 
396         !server->config->identity->group) {
397       fprintf(stderr, "Error:"
398        "\tSILC server must not be run as root.  For the security of your\n"
399        "\tsystem it is strongly suggested that you run SILC under dedicated\n"
400        "\tuser account.  Modify the [Identity] configuration section to run\n"
401        "\tthe server as non-root user.\n");
402       exit(1);
403     }
404
405     /* Get the values given for user and group in configuration file */
406     user=server->config->identity->user;
407     group=server->config->identity->group;
408
409     /* Check whether the user/group information is text */ 
410     if (atoi(user)!=0 || atoi(group)!=0) {
411       SILC_LOG_DEBUG(("Invalid user and/or group information"));
412       SILC_LOG_DEBUG(("User and/or group given as number"));
413       fprintf(stderr, "Invalid user and/or group information\n");
414       fprintf(stderr, "Please assign them as names, not numbers\n");
415       exit(1);
416     }
417
418     /* Catch the nasty incident of string "0" returning 0 from atoi */
419     if (strcmp("0", user)==0 || strcmp("0", group)==0) {
420       SILC_LOG_DEBUG(("User and/or group configured to 0. Unacceptable"));
421       fprintf(stderr, "User and/or group configured to 0. Exiting\n");
422       exit(1);
423     }
424
425     pw=getpwnam(user);
426     gr=getgrnam(group);
427
428     if (!pw) {
429       fprintf(stderr, "No such user %s found\n", user);
430       exit(1);
431     }
432
433     if (!gr) {
434       fprintf(stderr, "No such group %s found\n", group);
435       exit(1);
436     }
437
438     /* Check whether user and/or group is set to root. If yes, exit
439        immediately. Otherwise, setgid and setuid server to user.group */
440     if (gr->gr_gid==0 || pw->pw_uid==0) {
441       fprintf(stderr, "Error:"
442        "\tSILC server must not be run as root.  For the security of your\n"
443        "\tsystem it is strongly suggested that you run SILC under dedicated\n"
444        "\tuser account.  Modify the [Identity] configuration section to run\n"
445        "\tthe server as non-root user.\n");
446       exit(1);
447     } else {
448       SILC_LOG_DEBUG(("Changing to group %s", group));
449       if(setgid(gr->gr_gid)==0) {
450         SILC_LOG_DEBUG(("Setgid to %s", group));
451       } else {
452         SILC_LOG_DEBUG(("Setgid to %s failed", group));
453         fprintf(stderr, "Tried to setgid %s but no such group. Exiting\n",
454                 group);
455         exit(1);
456       }
457       SILC_LOG_DEBUG(("Changing to user nobody"));
458       if(setuid(pw->pw_uid)==0) {
459         SILC_LOG_DEBUG(("Setuid to %s", user));
460       } else {
461         SILC_LOG_DEBUG(("Setuid to %s failed", user));
462         fprintf(stderr, "Tried to setuid %s but no such user. Exiting\n",
463                 user);
464         exit(1);
465       }
466     }
467   }
468 }
469
470 /* The heart of the server. This runs the scheduler thus runs the server. 
471    When this returns the server has been stopped and the program will
472    be terminated. */
473
474 void silc_server_run(SilcServer server)
475 {
476   SILC_LOG_DEBUG(("Running server"));
477
478   SILC_LOG_INFO(("SILC Server started"));
479
480   /* Start the scheduler, the heart of the SILC server. When this returns
481      the program will be terminated. */
482   silc_schedule(server->schedule);
483 }
484
485 /* Stops the SILC server. This function is used to shutdown the server. 
486    This is usually called after the scheduler has returned. After stopping 
487    the server one should call silc_server_free. */
488
489 void silc_server_stop(SilcServer server)
490 {
491   SILC_LOG_DEBUG(("Stopping server"));
492
493   silc_schedule_stop(server->schedule);
494   silc_schedule_uninit(server->schedule);
495
496   silc_server_protocols_unregister();
497
498   SILC_LOG_DEBUG(("Server stopped"));
499 }
500
501 /* Function that is called when the network connection to a router has
502    been established.  This will continue with the key exchange protocol
503    with the remote router. */
504
505 void silc_server_start_key_exchange(SilcServer server,
506                                     SilcServerConnection sconn,
507                                     int sock)
508 {
509   SilcSocketConnection newsocket;
510   SilcProtocol protocol;
511   SilcServerKEInternalContext *proto_ctx;
512   void *context;
513
514   /* Set socket options */
515   silc_net_set_socket_nonblock(sock);
516   silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
517
518   /* Create socket connection for the connection. Even though we
519      know that we are connecting to a router we will mark the socket
520      to be unknown connection until we have executed authentication
521      protocol. */
522   silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
523   server->sockets[sock] = newsocket;
524   newsocket->hostname = strdup(sconn->remote_host);
525   newsocket->ip = strdup(sconn->remote_host);
526   newsocket->port = sconn->remote_port;
527   sconn->sock = newsocket;
528
529   /* Allocate internal protocol context. This is sent as context
530      to the protocol. */
531   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
532   proto_ctx->server = (void *)server;
533   proto_ctx->context = (void *)sconn;
534   proto_ctx->sock = newsocket;
535   proto_ctx->rng = server->rng;
536   proto_ctx->responder = FALSE;
537       
538   /* Perform key exchange protocol. silc_server_connect_to_router_second
539      will be called after the protocol is finished. */
540   silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
541                       &protocol, proto_ctx,
542                       silc_server_connect_to_router_second);
543   newsocket->protocol = protocol;
544       
545   /* Register a timeout task that will be executed if the protocol
546      is not executed within set limit. */
547   proto_ctx->timeout_task = 
548     silc_schedule_task_add(server->schedule, sock, 
549                        silc_server_timeout_remote,
550                        server, server->params->protocol_timeout,
551                        server->params->protocol_timeout_usec,
552                        SILC_TASK_TIMEOUT,
553                        SILC_TASK_PRI_LOW);
554
555   /* Register the connection for network input and output. This sets
556      that scheduler will listen for incoming packets for this connection 
557      and sets that outgoing packets may be sent to this connection as 
558      well. However, this doesn't set the scheduler for outgoing traffic,
559      it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
560      later when outgoing data is available. */
561   context = (void *)server;
562   SILC_REGISTER_CONNECTION_FOR_IO(sock);
563   
564   /* Run the protocol */
565   silc_protocol_execute(protocol, server->schedule, 0, 0);
566 }
567
568 /* Timeout callback that will be called to retry connecting to remote
569    router. This is used by both normal and router server. This will wait
570    before retrying the connecting. The timeout is generated by exponential
571    backoff algorithm. */
572
573 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
574 {
575   SilcServerConnection sconn = (SilcServerConnection)context;
576   SilcServer server = sconn->server;
577
578   SILC_LOG_INFO(("Retrying connecting to a router"));
579
580   /* Calculate next timeout */
581   if (sconn->retry_count >= 1) {
582     sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
583     if (sconn->retry_timeout > SILC_SERVER_RETRY_INTERVAL_MAX)
584       sconn->retry_timeout = SILC_SERVER_RETRY_INTERVAL_MAX;
585   } else {
586     sconn->retry_timeout = server->params->retry_interval_min;
587   }
588   sconn->retry_count++;
589   sconn->retry_timeout = sconn->retry_timeout +
590     silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER;
591
592   /* If we've reached max retry count, give up. */
593   if (sconn->retry_count > server->params->retry_count && 
594       server->params->retry_keep_trying == FALSE) {
595     SILC_LOG_ERROR(("Could not connect to router, giving up"));
596     return;
597   }
598
599   /* Wait one before retrying */
600   silc_schedule_task_add(server->schedule, fd, silc_server_connect_router,
601                          context, sconn->retry_timeout, 
602                          server->params->retry_interval_min_usec,
603                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
604 }
605
606 /* Generic routine to use connect to a router. */
607
608 SILC_TASK_CALLBACK(silc_server_connect_router)
609 {    
610   SilcServerConnection sconn = (SilcServerConnection)context;
611   SilcServer server = sconn->server;
612   int sock;
613
614   SILC_LOG_INFO(("Connecting to the %s %s on port %d", 
615                  (sconn->backup ? "backup router" : "router"), 
616                  sconn->remote_host, sconn->remote_port));
617
618   server->router_connect = time(0);
619
620   /* Connect to remote host */
621   sock = silc_net_create_connection(server->config->listen_port->local_ip,
622                                     sconn->remote_port, 
623                                     sconn->remote_host);
624   if (sock < 0) {
625     SILC_LOG_ERROR(("Could not connect to router"));
626     silc_schedule_task_add(server->schedule, fd, 
627                            silc_server_connect_to_router_retry,
628                            context, 0, 1, SILC_TASK_TIMEOUT, 
629                            SILC_TASK_PRI_NORMAL);
630     return;
631   }
632
633   /* Continue with key exchange protocol */
634   silc_server_start_key_exchange(server, sconn, sock);
635 }
636   
637 /* This function connects to our primary router or if we are a router this
638    establishes all our primary routes. This is called at the start of the
639    server to do authentication and key exchange with our router - called
640    from schedule. */
641
642 SILC_TASK_CALLBACK(silc_server_connect_to_router)
643 {
644   SilcServer server = (SilcServer)context;
645   SilcServerConnection sconn;
646   SilcServerConfigSectionServerConnection *ptr;
647
648   SILC_LOG_DEBUG(("Connecting to router(s)"));
649
650   if (server->server_type == SILC_SERVER) {
651     SILC_LOG_DEBUG(("We are normal server"));
652   } else if (server->server_type == SILC_ROUTER) {
653     SILC_LOG_DEBUG(("We are router"));
654   } else {
655     SILC_LOG_DEBUG(("We are backup router/normal server"));
656   }
657
658   /* Create the connections to all our routes */
659   ptr = server->config->routers;
660   while (ptr) {
661     
662     SILC_LOG_DEBUG(("%s connection [%s] %s:%d",
663                     ptr->backup_router ? "Backup router" : "Router",
664                     ptr->initiator ? "Initiator" : "Responder",
665                     ptr->host, ptr->port));
666
667     if (ptr->initiator) {
668       /* Allocate connection object for hold connection specific stuff. */
669       sconn = silc_calloc(1, sizeof(*sconn));
670       sconn->server = server;
671       sconn->remote_host = strdup(ptr->host);
672       sconn->remote_port = ptr->port;
673       sconn->backup = ptr->backup_router;
674       if (sconn->backup) {
675         sconn->backup_replace_ip = strdup(ptr->backup_replace_ip);
676         sconn->backup_replace_port = ptr->backup_replace_port;
677       }
678
679       silc_schedule_task_add(server->schedule, fd, 
680                              silc_server_connect_router,
681                              (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
682                              SILC_TASK_PRI_NORMAL);
683     }
684
685     if (!ptr->next)
686       return;
687     
688     ptr = ptr->next;
689   }
690
691   SILC_LOG_DEBUG(("No router(s), server will be standalone"));
692   
693   /* There wasn't a configured router, we will continue but we don't
694      have a connection to outside world.  We will be standalone server. */
695   server->standalone = TRUE;
696 }
697
698 /* Second part of connecting to router(s). Key exchange protocol has been
699    executed and now we will execute authentication protocol. */
700
701 SILC_TASK_CALLBACK(silc_server_connect_to_router_second)
702 {
703   SilcProtocol protocol = (SilcProtocol)context;
704   SilcServerKEInternalContext *ctx = 
705     (SilcServerKEInternalContext *)protocol->context;
706   SilcServer server = (SilcServer)ctx->server;
707   SilcServerConnection sconn = (SilcServerConnection)ctx->context;
708   SilcSocketConnection sock = ctx->sock;
709   SilcServerConnAuthInternalContext *proto_ctx;
710   SilcServerConfigSectionServerConnection *conn = NULL;
711
712   SILC_LOG_DEBUG(("Start"));
713
714   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
715       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
716     /* Error occured during protocol */
717     silc_protocol_free(protocol);
718     sock->protocol = NULL;
719     silc_ske_free_key_material(ctx->keymat);
720     if (ctx->packet)
721       silc_packet_context_free(ctx->packet);
722     if (ctx->ske)
723       silc_ske_free(ctx->ske);
724     silc_free(ctx->dest_id);
725     silc_free(ctx);
726     silc_schedule_task_del_by_callback(server->schedule,
727                                        silc_server_failure_callback);
728     silc_server_disconnect_remote(server, sock, "Server closed connection: "
729                                   "Key exchange failed");
730     return;
731   }
732   
733   /* We now have the key material as the result of the key exchange
734      protocol. Take the key material into use. Free the raw key material
735      as soon as we've set them into use. */
736   if (!silc_server_protocol_ke_set_keys(server, ctx->ske, 
737                                         ctx->sock, ctx->keymat,
738                                         ctx->ske->prop->cipher,
739                                         ctx->ske->prop->pkcs,
740                                         ctx->ske->prop->hash,
741                                         ctx->ske->prop->hmac,
742                                         ctx->ske->prop->group,
743                                         ctx->responder)) {
744     silc_protocol_free(protocol);
745     sock->protocol = NULL;
746     silc_ske_free_key_material(ctx->keymat);
747     if (ctx->packet)
748       silc_packet_context_free(ctx->packet);
749     if (ctx->ske)
750       silc_ske_free(ctx->ske);
751     silc_free(ctx->dest_id);
752     silc_free(ctx);
753     silc_schedule_task_del_by_callback(server->schedule,
754                                        silc_server_failure_callback);
755     silc_server_disconnect_remote(server, sock, "Server closed connection: "
756                                   "Key exchange failed");
757     return;
758   }    
759   silc_ske_free_key_material(ctx->keymat);
760
761   /* Allocate internal context for the authentication protocol. This
762      is sent as context for the protocol. */
763   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
764   proto_ctx->server = (void *)server;
765   proto_ctx->context = (void *)sconn;
766   proto_ctx->sock = sock;
767   proto_ctx->ske = ctx->ske;       /* Save SKE object from previous protocol */
768   proto_ctx->dest_id_type = ctx->dest_id_type;
769   proto_ctx->dest_id = ctx->dest_id;
770
771   /* Resolve the authentication method used in this connection. Check if 
772      we find a match from user configured connections */
773   conn = silc_server_config_find_router_conn(server->config,
774                                              sock->hostname,
775                                              sock->port);
776   if (conn) {
777     /* Match found. Use the configured authentication method */
778     proto_ctx->auth_meth = conn->auth_meth;
779     if (conn->auth_data) {
780       proto_ctx->auth_data = strdup(conn->auth_data);
781       proto_ctx->auth_data_len = strlen(conn->auth_data);
782     }
783   } else {
784     SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
785                     sock->hostname, sock->ip, sock->port));
786     silc_protocol_free(protocol);
787     sock->protocol = NULL;
788     if (ctx->packet)
789       silc_packet_context_free(ctx->packet);
790     if (ctx->ske)
791       silc_ske_free(ctx->ske);
792     silc_free(ctx->dest_id);
793     silc_free(ctx);
794     silc_schedule_task_del_by_callback(server->schedule,
795                                        silc_server_failure_callback);
796     silc_server_disconnect_remote(server, sock, "Server closed connection: "
797                                   "Key exchange failed");
798     return;
799   }
800
801   /* Free old protocol as it is finished now */
802   silc_protocol_free(protocol);
803   if (ctx->packet)
804     silc_packet_context_free(ctx->packet);
805   silc_free(ctx);
806   sock->protocol = NULL;
807
808   /* Allocate the authentication protocol. This is allocated here
809      but we won't start it yet. We will be receiving party of this
810      protocol thus we will wait that connecting party will make
811      their first move. */
812   silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH, 
813                       &sock->protocol, proto_ctx, 
814                       silc_server_connect_to_router_final);
815
816   /* Register timeout task. If the protocol is not executed inside
817      this timelimit the connection will be terminated. Currently
818      this is 15 seconds and is hard coded limit (XXX). */
819   proto_ctx->timeout_task = 
820     silc_schedule_task_add(server->schedule, sock->sock, 
821                        silc_server_timeout_remote,
822                        (void *)server, 15, 0,
823                        SILC_TASK_TIMEOUT,
824                        SILC_TASK_PRI_LOW);
825
826   /* Run the protocol */
827   silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
828 }
829
830 /* Finalizes the connection to router. Registers a server task to the
831    queue so that we can accept new connections. */
832
833 SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
834 {
835   SilcProtocol protocol = (SilcProtocol)context;
836   SilcServerConnAuthInternalContext *ctx = 
837     (SilcServerConnAuthInternalContext *)protocol->context;
838   SilcServer server = (SilcServer)ctx->server;
839   SilcServerConnection sconn = (SilcServerConnection)ctx->context;
840   SilcSocketConnection sock = ctx->sock;
841   SilcServerEntry id_entry;
842   SilcBuffer packet;
843   SilcServerHBContext hb_context;
844   unsigned char *id_string;
845   uint32 id_len;
846   SilcIDListData idata;
847
848   SILC_LOG_DEBUG(("Start"));
849
850   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
851       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
852     /* Error occured during protocol */
853     silc_free(ctx->dest_id);
854     silc_server_disconnect_remote(server, sock, "Server closed connection: "
855                                   "Authentication failed");
856     goto out;
857   }
858
859   /* Add a task to the queue. This task receives new connections to the 
860      server. This task remains on the queue until the end of the program. */
861   if (!server->listenning && !sconn->backup) {
862     silc_schedule_task_add(server->schedule, server->sock, 
863                            silc_server_accept_new_connection,
864                            (void *)server, 0, 0, 
865                            SILC_TASK_FD,
866                            SILC_TASK_PRI_NORMAL);
867     server->listenning = TRUE;
868   }
869
870   /* Send NEW_SERVER packet to the router. We will become registered
871      to the SILC network after sending this packet. */
872   id_string = silc_id_id2str(server->id, SILC_ID_SERVER);
873   id_len = silc_id_get_len(server->id, SILC_ID_SERVER);
874   packet = silc_buffer_alloc(2 + 2 + id_len + strlen(server->server_name));
875   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
876   silc_buffer_format(packet,
877                      SILC_STR_UI_SHORT(id_len),
878                      SILC_STR_UI_XNSTRING(id_string, id_len),
879                      SILC_STR_UI_SHORT(strlen(server->server_name)),
880                      SILC_STR_UI_XNSTRING(server->server_name,
881                                           strlen(server->server_name)),
882                      SILC_STR_END);
883
884   /* Send the packet */
885   silc_server_packet_send(server, ctx->sock, SILC_PACKET_NEW_SERVER, 0,
886                           packet->data, packet->len, TRUE);
887   silc_buffer_free(packet);
888   silc_free(id_string);
889
890   SILC_LOG_INFO(("Connected to router %s", sock->hostname));
891
892   /* Check that we do not have this ID already */
893   id_entry = silc_idlist_find_server_by_id(server->local_list, 
894                                            ctx->dest_id, TRUE, NULL);
895   if (id_entry) {
896     silc_idcache_del_by_context(server->local_list->servers, id_entry);
897   } else {
898     id_entry = silc_idlist_find_server_by_id(server->global_list, 
899                                              ctx->dest_id, TRUE, NULL);
900     if (id_entry) 
901       silc_idcache_del_by_context(server->global_list->servers, id_entry);
902   }
903
904   SILC_LOG_DEBUG(("New server id(%s)",
905                   silc_id_render(ctx->dest_id, SILC_ID_SERVER)));
906
907   /* Add the connected router to global server list */
908   id_entry = silc_idlist_add_server(server->global_list, 
909                                     strdup(sock->hostname),
910                                     SILC_ROUTER, ctx->dest_id, NULL, sock);
911   if (!id_entry) {
912     silc_free(ctx->dest_id);
913     silc_server_disconnect_remote(server, sock, "Server closed connection: "
914                                   "Authentication failed");
915     goto out;
916   }
917
918   silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
919   silc_free(sock->user_data);
920   sock->user_data = (void *)id_entry;
921   sock->type = SILC_SOCKET_TYPE_ROUTER;
922   idata = (SilcIDListData)sock->user_data;
923   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
924
925   /* Perform keepalive. The `hb_context' will be freed automatically
926      when finally calling the silc_socket_free function. XXX hardcoded 
927      timeout!! */
928   hb_context = silc_calloc(1, sizeof(*hb_context));
929   hb_context->server = server;
930   silc_socket_set_heartbeat(sock, 600, hb_context,
931                             silc_server_perform_heartbeat,
932                             server->schedule);
933
934   /* Register re-key timeout */
935   idata->rekey->timeout = 3600; /* XXX hardcoded */
936   idata->rekey->context = (void *)server;
937   silc_schedule_task_add(server->schedule, sock->sock, 
938                          silc_server_rekey_callback,
939                          (void *)sock, idata->rekey->timeout, 0,
940                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
941
942   if (!sconn->backup) {
943     /* Mark this router our primary router if we're still standalone */
944     if (server->standalone) {
945       server->id_entry->router = id_entry;
946       server->router = id_entry;
947       server->standalone = FALSE;
948     
949       /* If we are router then announce our possible servers. */
950       if (server->server_type == SILC_ROUTER)
951         silc_server_announce_servers(server, FALSE, 0, 
952                                      server->router->connection);
953
954       /* Announce our clients and channels to the router */
955       silc_server_announce_clients(server, 0, server->router->connection);
956       silc_server_announce_channels(server, 0, server->router->connection);
957     }
958   } else {
959     /* Add this server to be our backup router */
960     silc_server_backup_add(server, id_entry, sconn->backup_replace_ip,
961                            sconn->backup_replace_port, FALSE);
962   }
963
964   sock->protocol = NULL;
965
966   /* Call the completion callback to indicate that we've connected to
967      the router */
968   if (sconn->callback)
969     (*sconn->callback)(server, id_entry, sconn->callback_context);
970
971  out:
972   /* Free the temporary connection data context */
973   if (sconn) {
974     silc_free(sconn->remote_host);
975     silc_free(sconn->backup_replace_ip);
976     silc_free(sconn);
977   }
978
979   /* Free the protocol object */
980   if (sock->protocol == protocol)
981     sock->protocol = NULL;
982   silc_protocol_free(protocol);
983   if (ctx->packet)
984     silc_packet_context_free(ctx->packet);
985   if (ctx->ske)
986     silc_ske_free(ctx->ske);
987   silc_free(ctx);
988 }
989
990 /* Host lookup callbcak that is called after the incoming connection's
991    IP and FQDN lookup is performed. This will actually check the acceptance
992    of the incoming connection and will register the key exchange protocol
993    for this connection. */
994
995 static void 
996 silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
997                                          void *context)
998 {
999   SilcServer server = (SilcServer)context;
1000   SilcServerKEInternalContext *proto_ctx;
1001   void *cconfig, *sconfig, *rconfig;
1002   SilcServerConfigSectionDenyConnection *deny;
1003   int port;
1004
1005   SILC_LOG_DEBUG(("Start"));
1006
1007   /* Check whether we could resolve both IP and FQDN. */
1008   if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
1009                     server->params->require_reverse_mapping)) {
1010     SILC_LOG_ERROR(("IP/DNS lookup failed %s",
1011                     sock->hostname ? sock->hostname :
1012                     sock->ip ? sock->ip : ""));
1013     server->stat.conn_failures++;
1014     silc_server_disconnect_remote(server, sock,
1015                                   "Server closed connection: Unknown host");
1016     return;
1017   }
1018
1019   /* Register the connection for network input and output. This sets
1020      that scheduler will listen for incoming packets for this connection 
1021      and sets that outgoing packets may be sent to this connection as well.
1022      However, this doesn't set the scheduler for outgoing traffic, it
1023      will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
1024      later when outgoing data is available. */
1025   SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
1026
1027   SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
1028                  sock->ip));
1029
1030   port = server->sockets[server->sock]->port; /* Listenning port */
1031
1032   /* Check whether this connection is denied to connect to us. */
1033   deny = silc_server_config_denied_conn(server->config, sock->ip, port);
1034   if (!deny)
1035     deny = silc_server_config_denied_conn(server->config, sock->hostname,
1036                                           port);
1037   if (deny) {
1038     /* The connection is denied */
1039     SILC_LOG_INFO(("Connection %s (%s) is denied", 
1040                    sock->hostname, sock->ip));
1041     silc_server_disconnect_remote(server, sock, deny->comment ?
1042                                   deny->comment :
1043                                   "Server closed connection: "
1044                                   "Connection refused");
1045     server->stat.conn_failures++;
1046     return;
1047   }
1048
1049   /* Check whether we have configred this sort of connection at all. We
1050      have to check all configurations since we don't know what type of
1051      connection this is. */
1052   if (!(cconfig = silc_server_config_find_client_conn(server->config,
1053                                                       sock->ip, port)))
1054     cconfig = silc_server_config_find_client_conn(server->config,
1055                                                   sock->hostname, 
1056                                                   port);
1057   if (!(sconfig = silc_server_config_find_server_conn(server->config,
1058                                                      sock->ip, 
1059                                                      port)))
1060     sconfig = silc_server_config_find_server_conn(server->config,
1061                                                   sock->hostname,
1062                                                   port);
1063   if (!(rconfig = silc_server_config_find_router_conn(server->config,
1064                                                      sock->ip, port)))
1065     rconfig = silc_server_config_find_router_conn(server->config,
1066                                                   sock->hostname, 
1067                                                   port);
1068   if (!cconfig && !sconfig && !rconfig) {
1069     silc_server_disconnect_remote(server, sock, 
1070                                   "Server closed connection: "
1071                                   "Connection refused");
1072     server->stat.conn_failures++;
1073     return;
1074   }
1075
1076   /* The connection is allowed */
1077
1078   /* Allocate internal context for key exchange protocol. This is
1079      sent as context for the protocol. */
1080   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1081   proto_ctx->server = context;
1082   proto_ctx->sock = sock;
1083   proto_ctx->rng = server->rng;
1084   proto_ctx->responder = TRUE;
1085   proto_ctx->cconfig = cconfig;
1086   proto_ctx->sconfig = sconfig;
1087   proto_ctx->rconfig = rconfig;
1088
1089   /* Prepare the connection for key exchange protocol. We allocate the
1090      protocol but will not start it yet. The connector will be the
1091      initiator of the protocol thus we will wait for initiation from 
1092      there before we start the protocol. */
1093   server->stat.auth_attempts++;
1094   silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
1095                       &sock->protocol, proto_ctx, 
1096                       silc_server_accept_new_connection_second);
1097
1098   /* Register a timeout task that will be executed if the connector
1099      will not start the key exchange protocol within 60 seconds. For
1100      now, this is a hard coded limit. After 60 secs the connection will
1101      be closed if the key exchange protocol has not been started. */
1102   proto_ctx->timeout_task = 
1103     silc_schedule_task_add(server->schedule, sock->sock, 
1104                            silc_server_timeout_remote,
1105                            context, 60, 0,
1106                            SILC_TASK_TIMEOUT,
1107                            SILC_TASK_PRI_LOW);
1108 }
1109
1110 /* Accepts new connections to the server. Accepting new connections are
1111    done in three parts to make it async. */
1112
1113 SILC_TASK_CALLBACK(silc_server_accept_new_connection)
1114 {
1115   SilcServer server = (SilcServer)context;
1116   SilcSocketConnection newsocket;
1117   int sock;
1118
1119   SILC_LOG_DEBUG(("Accepting new connection"));
1120
1121   server->stat.conn_attempts++;
1122
1123   sock = silc_net_accept_connection(server->sock);
1124   if (sock < 0) {
1125     SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
1126     server->stat.conn_failures++;
1127     return;
1128   }
1129
1130   /* Check max connections */
1131   if (sock > SILC_SERVER_MAX_CONNECTIONS) {
1132     SILC_LOG_ERROR(("Refusing connection, server is full"));
1133     server->stat.conn_failures++;
1134     return;
1135   }
1136
1137   /* Set socket options */
1138   silc_net_set_socket_nonblock(sock);
1139   silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
1140
1141   /* We don't create a ID yet, since we don't know what type of connection
1142      this is yet. But, we do add the connection to the socket table. */
1143   silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
1144   server->sockets[sock] = newsocket;
1145
1146   /* Perform asynchronous host lookup. This will lookup the IP and the
1147      FQDN of the remote connection. After the lookup is done the connection
1148      is accepted further. */
1149   silc_socket_host_lookup(newsocket, TRUE, 
1150                           silc_server_accept_new_connection_lookup, context, 
1151                           server->schedule);
1152 }
1153
1154 /* Second part of accepting new connection. Key exchange protocol has been
1155    performed and now it is time to do little connection authentication
1156    protocol to figure out whether this connection is client or server
1157    and whether it has right to access this server (especially server
1158    connections needs to be authenticated). */
1159
1160 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
1161 {
1162   SilcProtocol protocol = (SilcProtocol)context;
1163   SilcServerKEInternalContext *ctx = 
1164     (SilcServerKEInternalContext *)protocol->context;
1165   SilcServer server = (SilcServer)ctx->server;
1166   SilcSocketConnection sock = ctx->sock;
1167   SilcServerConnAuthInternalContext *proto_ctx;
1168
1169   SILC_LOG_DEBUG(("Start"));
1170
1171   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1172       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1173     /* Error occured during protocol */
1174     silc_protocol_free(protocol);
1175     sock->protocol = NULL;
1176     silc_ske_free_key_material(ctx->keymat);
1177     if (ctx->packet)
1178       silc_packet_context_free(ctx->packet);
1179     if (ctx->ske)
1180       silc_ske_free(ctx->ske);
1181     silc_free(ctx->dest_id);
1182     silc_free(ctx);
1183     silc_schedule_task_del_by_callback(server->schedule,
1184                                        silc_server_failure_callback);
1185     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1186                                   "Key exchange failed");
1187     server->stat.auth_failures++;
1188     return;
1189   }
1190
1191   /* We now have the key material as the result of the key exchange
1192      protocol. Take the key material into use. Free the raw key material
1193      as soon as we've set them into use. */
1194   if (!silc_server_protocol_ke_set_keys(server, ctx->ske, 
1195                                         ctx->sock, ctx->keymat,
1196                                         ctx->ske->prop->cipher,
1197                                         ctx->ske->prop->pkcs,
1198                                         ctx->ske->prop->hash,
1199                                         ctx->ske->prop->hmac,
1200                                         ctx->ske->prop->group,
1201                                         ctx->responder)) {
1202     silc_protocol_free(protocol);
1203     sock->protocol = NULL;
1204     silc_ske_free_key_material(ctx->keymat);
1205     if (ctx->packet)
1206       silc_packet_context_free(ctx->packet);
1207     if (ctx->ske)
1208       silc_ske_free(ctx->ske);
1209     silc_free(ctx->dest_id);
1210     silc_free(ctx);
1211     silc_schedule_task_del_by_callback(server->schedule,
1212                                        silc_server_failure_callback);
1213     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1214                                   "Key exchange failed");
1215     server->stat.auth_failures++;
1216     return;
1217   }    
1218   silc_ske_free_key_material(ctx->keymat);
1219
1220   /* Allocate internal context for the authentication protocol. This
1221      is sent as context for the protocol. */
1222   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1223   proto_ctx->server = (void *)server;
1224   proto_ctx->sock = sock;
1225   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
1226   proto_ctx->responder = TRUE;
1227   proto_ctx->dest_id_type = ctx->dest_id_type;
1228   proto_ctx->dest_id = ctx->dest_id;
1229   proto_ctx->cconfig = ctx->cconfig;
1230   proto_ctx->sconfig = ctx->sconfig;
1231   proto_ctx->rconfig = ctx->rconfig;
1232
1233   /* Free old protocol as it is finished now */
1234   silc_protocol_free(protocol);
1235   if (ctx->packet)
1236     silc_packet_context_free(ctx->packet);
1237   silc_free(ctx);
1238   sock->protocol = NULL;
1239
1240   /* Allocate the authentication protocol. This is allocated here
1241      but we won't start it yet. We will be receiving party of this
1242      protocol thus we will wait that connecting party will make
1243      their first move. */
1244   silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH, 
1245                       &sock->protocol, proto_ctx, 
1246                       silc_server_accept_new_connection_final);
1247
1248   /* Register timeout task. If the protocol is not executed inside
1249      this timelimit the connection will be terminated. Currently
1250      this is 60 seconds and is hard coded limit (XXX). */
1251   proto_ctx->timeout_task = 
1252     silc_schedule_task_add(server->schedule, sock->sock, 
1253                            silc_server_timeout_remote,
1254                            (void *)server, 60, 0,
1255                            SILC_TASK_TIMEOUT,
1256                            SILC_TASK_PRI_LOW);
1257 }
1258
1259 /* Final part of accepting new connection. The connection has now
1260    been authenticated and keys has been exchanged. We also know whether
1261    this is client or server connection. */
1262
1263 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
1264 {
1265   SilcProtocol protocol = (SilcProtocol)context;
1266   SilcServerConnAuthInternalContext *ctx = 
1267     (SilcServerConnAuthInternalContext *)protocol->context;
1268   SilcServer server = (SilcServer)ctx->server;
1269   SilcSocketConnection sock = ctx->sock;
1270   SilcServerHBContext hb_context;
1271   SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
1272   void *id_entry = NULL;
1273
1274   SILC_LOG_DEBUG(("Start"));
1275
1276   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1277       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1278     /* Error occured during protocol */
1279     silc_protocol_free(protocol);
1280     sock->protocol = NULL;
1281     if (ctx->packet)
1282       silc_packet_context_free(ctx->packet);
1283     if (ctx->ske)
1284       silc_ske_free(ctx->ske);
1285     silc_free(ctx->dest_id);
1286     silc_free(ctx);
1287     silc_schedule_task_del_by_callback(server->schedule,
1288                                        silc_server_failure_callback);
1289     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1290                                   "Authentication failed");
1291     server->stat.auth_failures++;
1292     return;
1293   }
1294
1295   entry->data.last_receive = time(NULL);
1296
1297   switch (ctx->conn_type) {
1298   case SILC_SOCKET_TYPE_CLIENT:
1299     {
1300       SilcClientEntry client;
1301
1302       SILC_LOG_DEBUG(("Remote host is client"));
1303       SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname,
1304                      sock->ip));
1305
1306       /* Add the client to the client ID cache. The nickname and Client ID
1307          and other information is created after we have received NEW_CLIENT
1308          packet from client. */
1309       client = silc_idlist_add_client(server->local_list, 
1310                                       NULL, NULL, NULL, NULL, NULL, sock);
1311       if (!client) {
1312         SILC_LOG_ERROR(("Could not add new client to cache"));
1313         silc_free(sock->user_data);
1314         silc_server_disconnect_remote(server, sock, 
1315                                       "Server closed connection: "
1316                                       "Authentication failed");
1317         server->stat.auth_failures++;
1318         goto out;
1319       }
1320
1321       /* Statistics */
1322       server->stat.my_clients++;
1323       server->stat.clients++;
1324       if (server->server_type == SILC_ROUTER)
1325         server->stat.cell_clients++;
1326
1327       id_entry = (void *)client;
1328       break;
1329     }
1330   case SILC_SOCKET_TYPE_SERVER:
1331   case SILC_SOCKET_TYPE_ROUTER:
1332     {
1333       SilcServerEntry new_server;
1334       SilcServerConfigSectionServerConnection *conn = 
1335         ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? 
1336         ctx->sconfig : ctx->rconfig;
1337
1338       SILC_LOG_DEBUG(("Remote host is %s", 
1339                       ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? 
1340                       "server" : (conn->backup_router ? 
1341                                   "backup router" : "router")));
1342       SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname,
1343                      sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? 
1344                      "server" : (conn->backup_router ? 
1345                                  "backup router" : "router")));
1346
1347       /* Add the server into server cache. The server name and Server ID
1348          is updated after we have received NEW_SERVER packet from the
1349          server. We mark ourselves as router for this server if we really
1350          are router. */
1351       new_server = 
1352         silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1353                                 server->local_list : (conn->backup_router ?
1354                                                       server->local_list :
1355                                                       server->global_list)),
1356                                NULL,
1357                                (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1358                                 SILC_SERVER : SILC_ROUTER), 
1359                                NULL, 
1360                                (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
1361                                 server->id_entry : (conn->backup_router ? 
1362                                                     server->id_entry : NULL)),
1363                                sock);
1364       if (!new_server) {
1365         SILC_LOG_ERROR(("Could not add new server to cache"));
1366         silc_free(sock->user_data);
1367         silc_server_disconnect_remote(server, sock, 
1368                                       "Server closed connection: "
1369                                       "Authentication failed");
1370         server->stat.auth_failures++;
1371         goto out;
1372       }
1373
1374       /* Statistics */
1375       if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER)
1376         server->stat.my_servers++;
1377       else
1378         server->stat.my_routers++;
1379       server->stat.servers++;
1380
1381       id_entry = (void *)new_server;
1382
1383       /* If the incoming connection is router and marked as backup router
1384          then add it to be one of our backups */
1385       if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) {
1386         silc_server_backup_add(server, new_server, conn->backup_replace_ip,
1387                                conn->backup_replace_port, conn->backup_local);
1388
1389         /* Change it back to SERVER type since that's what it really is. */
1390         if (conn->backup_local)
1391           ctx->conn_type = SILC_SOCKET_TYPE_SERVER;
1392
1393         new_server->server_type = SILC_BACKUP_ROUTER;
1394       }
1395
1396       /* Check whether this connection is to be our primary router connection
1397          if we do not already have the primary route. */
1398       if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
1399         if (silc_server_config_is_primary_route(server->config) &&
1400             !conn->initiator)
1401           break;
1402
1403         SILC_LOG_DEBUG(("We are not standalone server anymore"));
1404         server->standalone = FALSE;
1405         if (!server->id_entry->router) {
1406           server->id_entry->router = id_entry;
1407           server->router = id_entry;
1408         }
1409       }
1410
1411       break;
1412     }
1413   default:
1414     break;
1415   }
1416
1417   sock->type = ctx->conn_type;
1418
1419   /* Add the common data structure to the ID entry. */
1420   if (id_entry)
1421     silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data);
1422       
1423   /* Add to sockets internal pointer for fast referencing */
1424   silc_free(sock->user_data);
1425   sock->user_data = id_entry;
1426
1427   /* Connection has been fully established now. Everything is ok. */
1428   SILC_LOG_DEBUG(("New connection authenticated"));
1429
1430   /* Perform keepalive. The `hb_context' will be freed automatically
1431      when finally calling the silc_socket_free function. XXX hardcoded 
1432      timeout!! */
1433   hb_context = silc_calloc(1, sizeof(*hb_context));
1434   hb_context->server = server;
1435   silc_socket_set_heartbeat(sock, 600, hb_context,
1436                             silc_server_perform_heartbeat,
1437                             server->schedule);
1438
1439  out:
1440   silc_schedule_task_del_by_callback(server->schedule,
1441                                      silc_server_failure_callback);
1442   silc_protocol_free(protocol);
1443   if (ctx->packet)
1444     silc_packet_context_free(ctx->packet);
1445   if (ctx->ske)
1446     silc_ske_free(ctx->ske);
1447   silc_free(ctx->dest_id);
1448   silc_free(ctx);
1449   sock->protocol = NULL;
1450 }
1451
1452 /* This function is used to read packets from network and send packets to
1453    network. This is usually a generic task. */
1454
1455 SILC_TASK_CALLBACK(silc_server_packet_process)
1456 {
1457   SilcServer server = (SilcServer)context;
1458   SilcSocketConnection sock = server->sockets[fd];
1459   SilcIDListData idata;
1460   SilcCipher cipher = NULL;
1461   SilcHmac hmac = NULL;
1462   uint32 sequence = 0;
1463   int ret;
1464
1465   if (!sock)
1466     return;
1467
1468   SILC_LOG_DEBUG(("Processing packet"));
1469
1470   /* Packet sending */
1471
1472   if (type == SILC_TASK_WRITE) {
1473     /* Do not send data to disconnected connection */
1474     if (SILC_IS_DISCONNECTED(sock))
1475       return;
1476
1477     server->stat.packets_sent++;
1478
1479     if (sock->outbuf->data - sock->outbuf->head)
1480      silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1481
1482     /* Send the packet */
1483     ret = silc_packet_send(sock, TRUE);
1484
1485     /* If returned -2 could not write to connection now, will do
1486        it later. */
1487     if (ret == -2)
1488       return;
1489
1490     if (ret == -1) {
1491       SILC_LOG_ERROR(("Error sending packet to connection "
1492                       "%s:%d [%s]", sock->hostname, sock->port,  
1493                       (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1494                        sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1495                        sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1496                        "Router")));
1497       return;
1498     }
1499     
1500     /* The packet has been sent and now it is time to set the connection
1501        back to only for input. When there is again some outgoing data 
1502        available for this connection it will be set for output as well. 
1503        This call clears the output setting and sets it only for input. */
1504     SILC_SET_CONNECTION_FOR_INPUT(server->schedule, fd);
1505     SILC_UNSET_OUTBUF_PENDING(sock);
1506
1507     silc_buffer_clear(sock->outbuf);
1508     return;
1509   }
1510
1511   /* Packet receiving */
1512
1513   /* Read some data from connection */
1514   ret = silc_packet_receive(sock);
1515   if (ret < 0) {
1516
1517     if (ret == -1)
1518       SILC_LOG_ERROR(("Error receiving packet from connection "
1519                       "%s:%d [%s] %s", sock->hostname, sock->port,  
1520                       (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
1521                        sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
1522                        sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
1523                        "Router"), strerror(errno)));
1524     return;
1525   }    
1526
1527   /* EOF */
1528   if (ret == 0) {
1529     SILC_LOG_DEBUG(("Read EOF"));
1530       
1531     /* If connection is disconnecting already we will finally
1532        close the connection */
1533     if (SILC_IS_DISCONNECTING(sock)) {
1534       if (sock->user_data)
1535         silc_server_free_sock_user_data(server, sock);
1536       silc_server_close_connection(server, sock);
1537       return;
1538     }
1539       
1540     SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1541     SILC_SET_DISCONNECTING(sock);
1542
1543     if (sock->user_data)
1544       silc_server_free_sock_user_data(server, sock);
1545     silc_server_close_connection(server, sock);
1546     return;
1547   }
1548
1549   /* If connection is disconnecting or disconnected we will ignore
1550      what we read. */
1551   if (SILC_IS_DISCONNECTING(sock) || SILC_IS_DISCONNECTED(sock)) {
1552     SILC_LOG_DEBUG(("Ignoring read data from disonnected connection"));
1553     return;
1554   }
1555
1556   server->stat.packets_received++;
1557
1558   /* Get keys and stuff from ID entry */
1559   idata = (SilcIDListData)sock->user_data;
1560   if (idata) {
1561     cipher = idata->receive_key;
1562     hmac = idata->hmac_receive;
1563     sequence = idata->psn_receive;
1564   }
1565  
1566   /* Process the packet. This will call the parser that will then
1567      decrypt and parse the packet. */
1568   silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ? 
1569                               TRUE : FALSE, cipher, hmac, sequence, 
1570                               silc_server_packet_parse, server);
1571 }
1572   
1573 /* Parses whole packet, received earlier. */
1574
1575 SILC_TASK_CALLBACK(silc_server_packet_parse_real)
1576 {
1577   SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1578   SilcServer server = (SilcServer)parse_ctx->context;
1579   SilcSocketConnection sock = parse_ctx->sock;
1580   SilcPacketContext *packet = parse_ctx->packet;
1581   SilcIDListData idata = (SilcIDListData)sock->user_data;
1582   int ret;
1583
1584   SILC_LOG_DEBUG(("Start"));
1585
1586   /* Parse the packet */
1587   if (parse_ctx->normal)
1588     ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL);
1589   else
1590     ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
1591
1592   /* If entry is disabled ignore what we got. */
1593   if (ret != SILC_PACKET_RESUME_ROUTER &&
1594       idata && idata->status & SILC_IDLIST_STATUS_DISABLED) {
1595     SILC_LOG_DEBUG(("Connection is disabled"));
1596     goto out;
1597   }
1598
1599   if (ret == SILC_PACKET_NONE)
1600     goto out;
1601
1602   /* Check that the the current client ID is same as in the client's packet. */
1603   if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
1604     SilcClientEntry client = (SilcClientEntry)sock->user_data;
1605     if (client && client->id) {
1606       void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
1607                                 packet->src_id_type);
1608       if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) {
1609         silc_free(id);
1610         goto out;
1611       }
1612       silc_free(id);
1613     }
1614   }
1615
1616   if (server->server_type == SILC_ROUTER) {
1617     /* Route the packet if it is not destined to us. Other ID types but
1618        server are handled separately after processing them. */
1619     if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
1620         packet->dst_id_type == SILC_ID_SERVER && 
1621         sock->type != SILC_SOCKET_TYPE_CLIENT &&
1622         memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1623       
1624       /* Route the packet to fastest route for the destination ID */
1625       void *id = silc_id_str2id(packet->dst_id, packet->dst_id_len, 
1626                                 packet->dst_id_type);
1627       if (!id)
1628         goto out;
1629       silc_server_packet_route(server,
1630                                silc_server_route_get(server, id,
1631                                                      packet->dst_id_type),
1632                                packet);
1633       silc_free(id);
1634       goto out;
1635     }
1636   }
1637
1638   /* Parse the incoming packet type */
1639   silc_server_packet_parse_type(server, sock, packet);
1640
1641   if (server->server_type == SILC_ROUTER) {
1642     /* Broadcast packet if it is marked as broadcast packet and it is
1643        originated from router and we are router. */
1644     if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1645         packet->flags & SILC_PACKET_FLAG_BROADCAST &&
1646         !server->standalone) {
1647       /* Broadcast to our primary route */
1648       silc_server_packet_broadcast(server, server->router->connection, packet);
1649
1650       /* If we have backup routers then we need to feed all broadcast
1651          data to those servers. */
1652       silc_server_backup_broadcast(server, sock, packet);
1653     }
1654   }
1655
1656  out:
1657   silc_packet_context_free(packet);
1658   silc_free(parse_ctx);
1659 }
1660
1661 /* Parser callback called by silc_packet_receive_process. This merely
1662    registers timeout that will handle the actual parsing when appropriate. */
1663
1664 bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
1665                               void *context)
1666 {
1667   SilcServer server = (SilcServer)context;
1668   SilcSocketConnection sock = parser_context->sock;
1669   SilcIDListData idata = (SilcIDListData)sock->user_data;
1670
1671   if (idata)
1672     idata->psn_receive = parser_context->packet->sequence + 1;
1673
1674   /* If protocol for this connection is key exchange or rekey then we'll
1675      process all packets synchronously, since there might be packets in
1676      queue that we are not able to decrypt without first processing the
1677      packets before them. */
1678   if ((parser_context->packet->type == SILC_PACKET_REKEY ||
1679        parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
1680       (sock->protocol && sock->protocol->protocol && 
1681        (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1682         sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
1683     silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1684                                   parser_context);
1685
1686     /* Reprocess data since we'll return FALSE here.  This is because
1687        the idata->receive_key might have become valid in the last packet
1688        and we want to call this processor with valid cipher. */
1689     if (idata)
1690       silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ? 
1691                                   TRUE : FALSE, idata->receive_key, 
1692                                   idata->hmac_receive, idata->psn_receive, 
1693                                   silc_server_packet_parse, server);
1694     else
1695       silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ? 
1696                                   TRUE : FALSE, NULL, NULL, 0, 
1697                                   silc_server_packet_parse, server);
1698     return FALSE;
1699   }
1700
1701   switch (sock->type) {
1702   case SILC_SOCKET_TYPE_UNKNOWN:
1703   case SILC_SOCKET_TYPE_CLIENT:
1704     /* Parse the packet with timeout */
1705     silc_schedule_task_add(server->schedule, sock->sock,
1706                            silc_server_packet_parse_real,
1707                            (void *)parser_context, 0, 100000,
1708                            SILC_TASK_TIMEOUT,
1709                            SILC_TASK_PRI_NORMAL);
1710     break;
1711   case SILC_SOCKET_TYPE_SERVER:
1712   case SILC_SOCKET_TYPE_ROUTER:
1713     /* Packets from servers are parsed immediately */
1714     silc_server_packet_parse_real(server->schedule, 0, sock->sock,
1715                                   parser_context);
1716     break;
1717   default:
1718     return TRUE;
1719   }
1720
1721   return TRUE;
1722 }
1723
1724 /* Parses the packet type and calls what ever routines the packet type
1725    requires. This is done for all incoming packets. */
1726
1727 void silc_server_packet_parse_type(SilcServer server, 
1728                                    SilcSocketConnection sock,
1729                                    SilcPacketContext *packet)
1730 {
1731   SilcPacketType type = packet->type;
1732   SilcIDListData idata = (SilcIDListData)sock->user_data;
1733
1734   SILC_LOG_DEBUG(("Parsing packet type %d", type));
1735
1736   /* Parse the packet type */
1737   switch (type) {
1738   case SILC_PACKET_DISCONNECT:
1739     SILC_LOG_DEBUG(("Disconnect packet"));
1740     if (packet->flags & SILC_PACKET_FLAG_LIST)
1741       break;
1742     break;
1743
1744   case SILC_PACKET_SUCCESS:
1745     /*
1746      * Success received for something. For now we can have only
1747      * one protocol for connection executing at once hence this
1748      * success message is for whatever protocol is executing currently.
1749      */
1750     SILC_LOG_DEBUG(("Success packet"));
1751     if (packet->flags & SILC_PACKET_FLAG_LIST)
1752       break;
1753     if (sock->protocol)
1754       silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1755     break;
1756
1757   case SILC_PACKET_FAILURE:
1758     /*
1759      * Failure received for something. For now we can have only
1760      * one protocol for connection executing at once hence this
1761      * failure message is for whatever protocol is executing currently.
1762      */
1763     SILC_LOG_DEBUG(("Failure packet"));
1764     if (packet->flags & SILC_PACKET_FLAG_LIST)
1765       break;
1766     if (sock->protocol) {
1767       SilcServerFailureContext f;
1768       f = silc_calloc(1, sizeof(*f));
1769       f->server = server;
1770       f->sock = sock;
1771       
1772       /* We will wait 5 seconds to process this failure packet */
1773       silc_schedule_task_add(server->schedule, sock->sock,
1774                          silc_server_failure_callback, (void *)f, 5, 0,
1775                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1776     }
1777     break;
1778
1779   case SILC_PACKET_REJECT:
1780     SILC_LOG_DEBUG(("Reject packet"));
1781     if (packet->flags & SILC_PACKET_FLAG_LIST)
1782       break;
1783     return;
1784     break;
1785
1786   case SILC_PACKET_NOTIFY:
1787     /*
1788      * Received notify packet. Server can receive notify packets from
1789      * router. Server then relays the notify messages to clients if needed.
1790      */
1791     SILC_LOG_DEBUG(("Notify packet"));
1792     if (packet->flags & SILC_PACKET_FLAG_LIST)
1793       silc_server_notify_list(server, sock, packet);
1794     else
1795       silc_server_notify(server, sock, packet);
1796     break;
1797
1798     /* 
1799      * Channel packets
1800      */
1801   case SILC_PACKET_CHANNEL_MESSAGE:
1802     /*
1803      * Received channel message. Channel messages are special packets
1804      * (although probably most common ones) thus they are handled
1805      * specially.
1806      */
1807     SILC_LOG_DEBUG(("Channel Message packet"));
1808     if (packet->flags & SILC_PACKET_FLAG_LIST)
1809       break;
1810     idata->last_receive = time(NULL);
1811     silc_server_channel_message(server, sock, packet);
1812     break;
1813
1814   case SILC_PACKET_CHANNEL_KEY:
1815     /*
1816      * Received key for channel. As channels are created by the router
1817      * the keys are as well. We will distribute the key to all of our
1818      * locally connected clients on the particular channel. Router
1819      * never receives this channel and thus is ignored.
1820      */
1821     SILC_LOG_DEBUG(("Channel Key packet"));
1822     if (packet->flags & SILC_PACKET_FLAG_LIST)
1823       break;
1824     silc_server_channel_key(server, sock, packet);
1825     break;
1826
1827     /*
1828      * Command packets
1829      */
1830   case SILC_PACKET_COMMAND:
1831     /*
1832      * Recived command. Processes the command request and allocates the
1833      * command context and calls the command.
1834      */
1835     SILC_LOG_DEBUG(("Command packet"));
1836     if (packet->flags & SILC_PACKET_FLAG_LIST)
1837       break;
1838     silc_server_command_process(server, sock, packet);
1839     break;
1840
1841   case SILC_PACKET_COMMAND_REPLY:
1842     /*
1843      * Received command reply packet. Received command reply to command. It
1844      * may be reply to command sent by us or reply to command sent by client
1845      * that we've routed further.
1846      */
1847     SILC_LOG_DEBUG(("Command Reply packet"));
1848     if (packet->flags & SILC_PACKET_FLAG_LIST)
1849       break;
1850     silc_server_command_reply(server, sock, packet);
1851     break;
1852
1853     /*
1854      * Private Message packets
1855      */
1856   case SILC_PACKET_PRIVATE_MESSAGE:
1857     /*
1858      * Received private message packet. The packet is coming from either
1859      * client or server.
1860      */
1861     SILC_LOG_DEBUG(("Private Message packet"));
1862     if (packet->flags & SILC_PACKET_FLAG_LIST)
1863       break;
1864     idata->last_receive = time(NULL);
1865     silc_server_private_message(server, sock, packet);
1866     break;
1867
1868   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1869     /*
1870      * Private message key packet.
1871      */
1872     if (packet->flags & SILC_PACKET_FLAG_LIST)
1873       break;
1874     silc_server_private_message_key(server, sock, packet);
1875     break;
1876
1877     /*
1878      * Key Exchange protocol packets
1879      */
1880   case SILC_PACKET_KEY_EXCHANGE:
1881     SILC_LOG_DEBUG(("KE packet"));
1882     if (packet->flags & SILC_PACKET_FLAG_LIST)
1883       break;
1884
1885     if (sock->protocol && sock->protocol->protocol &&
1886         sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
1887
1888       SilcServerKEInternalContext *proto_ctx = 
1889         (SilcServerKEInternalContext *)sock->protocol->context;
1890
1891       proto_ctx->packet = silc_packet_context_dup(packet);
1892
1893       /* Let the protocol handle the packet */
1894       silc_protocol_execute(sock->protocol, server->schedule, 0, 100000);
1895     } else {
1896       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1897                       "protocol active, packet dropped."));
1898     }
1899     break;
1900
1901   case SILC_PACKET_KEY_EXCHANGE_1:
1902     SILC_LOG_DEBUG(("KE 1 packet"));
1903     if (packet->flags & SILC_PACKET_FLAG_LIST)
1904       break;
1905
1906     if (sock->protocol && sock->protocol->protocol &&
1907         (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1908          sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1909
1910       if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1911         SilcServerRekeyInternalContext *proto_ctx = 
1912           (SilcServerRekeyInternalContext *)sock->protocol->context;
1913         
1914         if (proto_ctx->packet)
1915           silc_packet_context_free(proto_ctx->packet);
1916         
1917         proto_ctx->packet = silc_packet_context_dup(packet);
1918
1919         /* Let the protocol handle the packet */
1920         silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1921       } else {
1922         SilcServerKEInternalContext *proto_ctx = 
1923           (SilcServerKEInternalContext *)sock->protocol->context;
1924         
1925         if (proto_ctx->packet)
1926           silc_packet_context_free(proto_ctx->packet);
1927         
1928         proto_ctx->packet = silc_packet_context_dup(packet);
1929         proto_ctx->dest_id_type = packet->src_id_type;
1930         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1931                                             packet->src_id_type);
1932         if (!proto_ctx->dest_id)
1933           break;
1934
1935         /* Let the protocol handle the packet */
1936         silc_protocol_execute(sock->protocol, server->schedule, 
1937                               0, 100000);
1938       }
1939     } else {
1940       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1941                       "protocol active, packet dropped."));
1942     }
1943     break;
1944
1945   case SILC_PACKET_KEY_EXCHANGE_2:
1946     SILC_LOG_DEBUG(("KE 2 packet"));
1947     if (packet->flags & SILC_PACKET_FLAG_LIST)
1948       break;
1949
1950     if (sock->protocol && sock->protocol->protocol &&
1951         (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
1952          sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
1953
1954       if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
1955         SilcServerRekeyInternalContext *proto_ctx = 
1956           (SilcServerRekeyInternalContext *)sock->protocol->context;
1957         
1958         if (proto_ctx->packet)
1959           silc_packet_context_free(proto_ctx->packet);
1960         
1961         proto_ctx->packet = silc_packet_context_dup(packet);
1962
1963         /* Let the protocol handle the packet */
1964         silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
1965       } else {
1966         SilcServerKEInternalContext *proto_ctx = 
1967           (SilcServerKEInternalContext *)sock->protocol->context;
1968         
1969         if (proto_ctx->packet)
1970           silc_packet_context_free(proto_ctx->packet);
1971         
1972         proto_ctx->packet = silc_packet_context_dup(packet);
1973         proto_ctx->dest_id_type = packet->src_id_type;
1974         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1975                                             packet->src_id_type);
1976         if (!proto_ctx->dest_id)
1977           break;
1978
1979         /* Let the protocol handle the packet */
1980         silc_protocol_execute(sock->protocol, server->schedule, 
1981                               0, 100000);
1982       }
1983     } else {
1984       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1985                       "protocol active, packet dropped."));
1986     }
1987     break;
1988
1989   case SILC_PACKET_CONNECTION_AUTH_REQUEST:
1990     /*
1991      * Connection authentication request packet. When we receive this packet
1992      * we will send to the other end information about our mandatory
1993      * authentication method for the connection. This packet maybe received
1994      * at any time. 
1995      */
1996     SILC_LOG_DEBUG(("Connection authentication request packet"));
1997     if (packet->flags & SILC_PACKET_FLAG_LIST)
1998       break;
1999     silc_server_connection_auth_request(server, sock, packet);
2000     break;
2001
2002     /*
2003      * Connection Authentication protocol packets
2004      */
2005   case SILC_PACKET_CONNECTION_AUTH:
2006     /* Start of the authentication protocol. We receive here the 
2007        authentication data and will verify it. */
2008     SILC_LOG_DEBUG(("Connection auth packet"));
2009     if (packet->flags & SILC_PACKET_FLAG_LIST)
2010       break;
2011
2012     if (sock->protocol && sock->protocol->protocol->type 
2013         == SILC_PROTOCOL_SERVER_CONNECTION_AUTH) {
2014
2015       SilcServerConnAuthInternalContext *proto_ctx = 
2016         (SilcServerConnAuthInternalContext *)sock->protocol->context;
2017
2018       proto_ctx->packet = silc_packet_context_dup(packet);
2019
2020       /* Let the protocol handle the packet */
2021       silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2022     } else {
2023       SILC_LOG_ERROR(("Received Connection Auth packet but no authentication "
2024                       "protocol active, packet dropped."));
2025     }
2026     break;
2027
2028   case SILC_PACKET_NEW_ID:
2029     /*
2030      * Received New ID packet. This includes some new ID that has been
2031      * created. It may be for client, server or channel. This is the way
2032      * to distribute information about new registered entities in the
2033      * SILC network.
2034      */
2035     SILC_LOG_DEBUG(("New ID packet"));
2036     if (packet->flags & SILC_PACKET_FLAG_LIST)
2037       silc_server_new_id_list(server, sock, packet);
2038     else
2039       silc_server_new_id(server, sock, packet);
2040     break;
2041
2042   case SILC_PACKET_NEW_CLIENT:
2043     /*
2044      * Received new client packet. This includes client information that
2045      * we will use to create initial client ID. After creating new
2046      * ID we will send it to the client.
2047      */
2048     SILC_LOG_DEBUG(("New Client packet"));
2049     if (packet->flags & SILC_PACKET_FLAG_LIST)
2050       break;
2051     silc_server_new_client(server, sock, packet);
2052     break;
2053
2054   case SILC_PACKET_NEW_SERVER:
2055     /*
2056      * Received new server packet. This includes Server ID and some other
2057      * information that we may save. This is received after server has 
2058      * connected to us.
2059      */
2060     SILC_LOG_DEBUG(("New Server packet"));
2061     if (packet->flags & SILC_PACKET_FLAG_LIST)
2062       break;
2063     silc_server_new_server(server, sock, packet);
2064     break;
2065
2066   case SILC_PACKET_NEW_CHANNEL:
2067     /*
2068      * Received new channel packet. Information about new channel in the
2069      * network are distributed using this packet.
2070      */
2071     SILC_LOG_DEBUG(("New Channel packet"));
2072     if (packet->flags & SILC_PACKET_FLAG_LIST)
2073       silc_server_new_channel_list(server, sock, packet);
2074     else
2075       silc_server_new_channel(server, sock, packet);
2076     break;
2077
2078   case SILC_PACKET_HEARTBEAT:
2079     /*
2080      * Received heartbeat.
2081      */
2082     SILC_LOG_DEBUG(("Heartbeat packet"));
2083     if (packet->flags & SILC_PACKET_FLAG_LIST)
2084       break;
2085     break;
2086
2087   case SILC_PACKET_KEY_AGREEMENT:
2088     /*
2089      * Received heartbeat.
2090      */
2091     SILC_LOG_DEBUG(("Key agreement packet"));
2092     if (packet->flags & SILC_PACKET_FLAG_LIST)
2093       break;
2094     silc_server_key_agreement(server, sock, packet);
2095     break;
2096
2097   case SILC_PACKET_REKEY:
2098     /*
2099      * Received re-key packet. The sender wants to regenerate the session
2100      * keys.
2101      */
2102     SILC_LOG_DEBUG(("Re-key packet"));
2103     if (packet->flags & SILC_PACKET_FLAG_LIST)
2104       break;
2105     silc_server_rekey(server, sock, packet);
2106     break;
2107
2108   case SILC_PACKET_REKEY_DONE:
2109     /*
2110      * The re-key is done.
2111      */
2112     SILC_LOG_DEBUG(("Re-key done packet"));
2113     if (packet->flags & SILC_PACKET_FLAG_LIST)
2114       break;
2115
2116     if (sock->protocol && sock->protocol->protocol &&
2117         sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
2118
2119       SilcServerRekeyInternalContext *proto_ctx = 
2120         (SilcServerRekeyInternalContext *)sock->protocol->context;
2121
2122       if (proto_ctx->packet)
2123         silc_packet_context_free(proto_ctx->packet);
2124
2125       proto_ctx->packet = silc_packet_context_dup(packet);
2126
2127       /* Let the protocol handle the packet */
2128       silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
2129     } else {
2130       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
2131                       "protocol active, packet dropped."));
2132     }
2133     break;
2134
2135   case SILC_PACKET_FTP:
2136     /* FTP packet */
2137     SILC_LOG_DEBUG(("FTP packet"));
2138     if (packet->flags & SILC_PACKET_FLAG_LIST)
2139       break;
2140     silc_server_ftp(server, sock, packet);
2141     break;
2142
2143   case SILC_PACKET_RESUME_ROUTER:
2144     /* Resume router packet received. This packet is received for backup
2145        router resuming protocol. */
2146     SILC_LOG_DEBUG(("Resume router packet"));
2147     if (packet->flags & SILC_PACKET_FLAG_LIST)
2148       break;
2149     silc_server_backup_resume_router(server, sock, packet);
2150     break;
2151
2152   default:
2153     SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
2154     break;
2155   }
2156   
2157 }
2158
2159 /* Creates connection to a remote router. */
2160
2161 void silc_server_create_connection(SilcServer server,
2162                                    char *remote_host, uint32 port)
2163 {
2164   SilcServerConnection sconn;
2165
2166   /* Allocate connection object for hold connection specific stuff. */
2167   sconn = silc_calloc(1, sizeof(*sconn));
2168   sconn->server = server;
2169   sconn->remote_host = strdup(remote_host);
2170   sconn->remote_port = port;
2171
2172   silc_schedule_task_add(server->schedule, 0, 
2173                          silc_server_connect_router,
2174                          (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, 
2175                          SILC_TASK_PRI_NORMAL);
2176 }
2177
2178 SILC_TASK_CALLBACK(silc_server_close_connection_final)
2179 {
2180   silc_socket_free((SilcSocketConnection)context);
2181 }
2182
2183 /* Closes connection to socket connection */
2184
2185 void silc_server_close_connection(SilcServer server,
2186                                   SilcSocketConnection sock)
2187 {
2188   if (!server->sockets[sock->sock])
2189     return;
2190
2191   SILC_LOG_INFO(("Closing connection %s:%d [%s]", sock->hostname,
2192                   sock->port,
2193                   (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
2194                    sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
2195                    sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
2196                    "Router")));
2197
2198   /* We won't listen for this connection anymore */
2199   silc_schedule_unset_listen_fd(server->schedule, sock->sock);
2200
2201   /* Unregister all tasks */
2202   silc_schedule_task_del_by_fd(server->schedule, sock->sock);
2203
2204   /* Close the actual connection */
2205   silc_net_close_connection(sock->sock);
2206   server->sockets[sock->sock] = NULL;
2207
2208   /* If sock->user_data is NULL then we'll check for active protocols
2209      here since the silc_server_free_sock_user_data has not been called
2210      for this connection. */
2211   if (!sock->user_data) {
2212     /* If any protocol is active cancel its execution. It will call
2213        the final callback which will finalize the disconnection. */
2214     if (sock->protocol) {
2215       silc_protocol_cancel(sock->protocol, server->schedule);
2216       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2217       silc_protocol_execute_final(sock->protocol, server->schedule);
2218       sock->protocol = NULL;
2219       return;
2220     }
2221   }
2222
2223   silc_schedule_task_add(server->schedule, 0, 
2224                          silc_server_close_connection_final,
2225                          (void *)sock, 0, 1, SILC_TASK_TIMEOUT, 
2226                          SILC_TASK_PRI_NORMAL);
2227 }
2228
2229 /* Sends disconnect message to remote connection and disconnects the 
2230    connection. */
2231
2232 void silc_server_disconnect_remote(SilcServer server,
2233                                    SilcSocketConnection sock,
2234                                    const char *fmt, ...)
2235 {
2236   va_list ap;
2237   unsigned char buf[4096];
2238
2239   if (!sock)
2240     return;
2241
2242   memset(buf, 0, sizeof(buf));
2243   va_start(ap, fmt);
2244   vsprintf(buf, fmt, ap);
2245   va_end(ap);
2246
2247   SILC_LOG_DEBUG(("Disconnecting remote host"));
2248
2249   /* Notify remote end that the conversation is over. The notify message
2250      is tried to be sent immediately. */
2251   silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0,  
2252                           buf, strlen(buf), TRUE);
2253
2254   /* Mark the connection to be disconnected */
2255   SILC_SET_DISCONNECTED(sock);
2256   silc_server_close_connection(server, sock);
2257 }
2258
2259 typedef struct {
2260   SilcServer server;
2261   SilcClientEntry client;
2262 } *FreeClientInternal;
2263
2264 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout)
2265 {
2266   FreeClientInternal i = (FreeClientInternal)context;
2267
2268   silc_idlist_del_data(i->client);
2269   silc_idcache_purge_by_context(i->server->local_list->clients, i->client);
2270   silc_free(i);
2271 }
2272
2273 /* Frees client data and notifies about client's signoff. */
2274
2275 void silc_server_free_client_data(SilcServer server, 
2276                                   SilcSocketConnection sock,
2277                                   SilcClientEntry client, 
2278                                   int notify,
2279                                   char *signoff)
2280 {
2281   FreeClientInternal i = silc_calloc(1, sizeof(*i));
2282
2283   /* If there is pending outgoing data for the client then purge it
2284      to the network before removing the client entry. */
2285   silc_server_packet_queue_purge(server, sock);
2286
2287   if (!client->id)
2288     return;
2289
2290   /* Send SIGNOFF notify to routers. */
2291   if (notify && !server->standalone && server->router)
2292     silc_server_send_notify_signoff(server, server->router->connection,
2293                                     server->server_type == SILC_SERVER ?
2294                                     FALSE : TRUE, client->id, signoff);
2295     
2296   /* Remove client from all channels */
2297   if (notify)
2298     silc_server_remove_from_channels(server, NULL, client, 
2299                                      TRUE, signoff, TRUE);
2300   else
2301     silc_server_remove_from_channels(server, NULL, client, 
2302                                      FALSE, NULL, FALSE);
2303     
2304   /* We will not delete the client entry right away. We will take it
2305      into history (for WHOWAS command) for 5 minutes */
2306   i->server = server;
2307   i->client = client;
2308   silc_schedule_task_add(server->schedule, 0, 
2309                          silc_server_free_client_data_timeout,
2310                          (void *)i, 300, 0,
2311                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2312   client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
2313   client->router = NULL;
2314   client->connection = NULL;
2315
2316   /* Free the client entry and everything in it */
2317   server->stat.my_clients--;
2318   server->stat.clients--;
2319   if (server->server_type == SILC_ROUTER)
2320     server->stat.cell_clients--;
2321 }
2322
2323 /* Frees user_data pointer from socket connection object. This also sends
2324    appropriate notify packets to the network to inform about leaving
2325    entities. */
2326
2327 void silc_server_free_sock_user_data(SilcServer server, 
2328                                      SilcSocketConnection sock)
2329 {
2330   SILC_LOG_DEBUG(("Start"));
2331
2332   switch (sock->type) {
2333   case SILC_SOCKET_TYPE_CLIENT:
2334     {
2335       SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
2336       silc_server_free_client_data(server, sock, user_data, TRUE, NULL);
2337       break;
2338     }
2339   case SILC_SOCKET_TYPE_SERVER:
2340   case SILC_SOCKET_TYPE_ROUTER:
2341     {
2342       SilcServerEntry user_data = (SilcServerEntry)sock->user_data;
2343       SilcServerEntry backup_router = NULL;
2344
2345       if (user_data->id)
2346         backup_router = silc_server_backup_get(server, user_data->id);
2347
2348       /* If this was our primary router connection then we're lost to
2349          the outside world. */
2350       if (server->router == user_data) {
2351         /* Check whether we have a backup router connection */
2352         if (!backup_router || backup_router == user_data) {
2353           silc_schedule_task_add(server->schedule, 0, 
2354                                  silc_server_connect_to_router,
2355                                  server, 1, 0,
2356                                  SILC_TASK_TIMEOUT,
2357                                  SILC_TASK_PRI_NORMAL);
2358
2359           server->id_entry->router = NULL;
2360           server->router = NULL;
2361           server->standalone = TRUE;
2362           backup_router = NULL;
2363         } else {
2364           SILC_LOG_INFO(("New primary router is backup router %s",
2365                          backup_router->server_name));
2366           SILC_LOG_DEBUG(("New primary router is backup router %s",
2367                           backup_router->server_name));
2368           server->id_entry->router = backup_router;
2369           server->router = backup_router;
2370           server->router_connect = time(0);
2371           server->backup_primary = TRUE;
2372           if (server->server_type == SILC_BACKUP_ROUTER) {
2373             server->server_type = SILC_ROUTER;
2374
2375             /* We'll need to constantly try to reconnect to the primary
2376                router so that we'll see when it comes back online. */
2377             silc_server_backup_reconnect(server, sock->ip, sock->port,
2378                                          silc_server_backup_connected,
2379                                          NULL);
2380           }
2381
2382           /* Mark this connection as replaced */
2383           silc_server_backup_replaced_add(server, user_data->id, 
2384                                           backup_router);
2385         }
2386       } else if (backup_router) {
2387         SILC_LOG_INFO(("Enabling the use of backup router %s",
2388                        backup_router->server_name));
2389         SILC_LOG_DEBUG(("Enabling the use of backup router %s",
2390                         backup_router->server_name));
2391
2392         /* Mark this connection as replaced */
2393         silc_server_backup_replaced_add(server, user_data->id, 
2394                                         backup_router);
2395       }
2396
2397       if (!backup_router) {
2398         /* Free all client entries that this server owns as they will
2399            become invalid now as well. */
2400         if (user_data->id)
2401           silc_server_remove_clients_by_server(server, user_data, TRUE);
2402         if (server->server_type == SILC_SERVER)
2403           silc_server_remove_channels_by_server(server, user_data);
2404       } else {
2405         /* Update the client entries of this server to the new backup
2406            router. This also removes the clients that *really* was owned
2407            by the primary router and went down with the router.  */
2408         silc_server_update_clients_by_server(server, user_data, backup_router,
2409                                              TRUE, TRUE);
2410         silc_server_update_servers_by_server(server, user_data, backup_router);
2411         if (server->server_type == SILC_SERVER)
2412           silc_server_update_channels_by_server(server, user_data, 
2413                                                 backup_router);
2414       }
2415
2416       /* Free the server entry */
2417       silc_server_backup_del(server, user_data);
2418       silc_server_backup_replaced_del(server, user_data);
2419       silc_idlist_del_data(user_data);
2420       if (!silc_idlist_del_server(server->local_list, user_data))
2421         silc_idlist_del_server(server->global_list, user_data);
2422       server->stat.my_servers--;
2423       server->stat.servers--;
2424       if (server->server_type == SILC_ROUTER)
2425         server->stat.cell_servers--;
2426
2427       if (backup_router) {
2428         /* Announce all of our stuff that was created about 5 minutes ago.
2429            The backup router knows all the other stuff already. */
2430         if (server->server_type == SILC_ROUTER)
2431           silc_server_announce_servers(server, FALSE, time(0) - 300,
2432                                        backup_router->connection);
2433
2434         /* Announce our clients and channels to the router */
2435         silc_server_announce_clients(server, time(0) - 300,
2436                                      backup_router->connection);
2437         silc_server_announce_channels(server, time(0) - 300,
2438                                       backup_router->connection);
2439       }
2440       break;
2441     }
2442   default:
2443     {
2444       SilcUnknownEntry user_data = (SilcUnknownEntry)sock->user_data;
2445
2446       silc_idlist_del_data(user_data);
2447       silc_free(user_data);
2448       break;
2449     }
2450   }
2451
2452   /* If any protocol is active cancel its execution */
2453   if (sock->protocol) {
2454     silc_protocol_cancel(sock->protocol, server->schedule);
2455     sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2456     silc_protocol_execute_final(sock->protocol, server->schedule);
2457     sock->protocol = NULL;
2458   }
2459
2460   sock->user_data = NULL;
2461 }
2462
2463 /* Removes client from all channels it has joined. This is used when client
2464    connection is disconnected. If the client on a channel is last, the
2465    channel is removed as well. This sends the SIGNOFF notify types. */
2466
2467 void silc_server_remove_from_channels(SilcServer server, 
2468                                       SilcSocketConnection sock,
2469                                       SilcClientEntry client,
2470                                       int notify,
2471                                       char *signoff_message,
2472                                       int keygen)
2473 {
2474   SilcChannelEntry channel;
2475   SilcChannelClientEntry chl;
2476   SilcHashTableList htl;
2477   SilcBuffer clidp;
2478
2479   SILC_LOG_DEBUG(("Start"));
2480
2481   if (!client || !client->id)
2482     return;
2483
2484   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2485
2486   /* Remove the client from all channels. The client is removed from
2487      the channels' user list. */
2488   silc_hash_table_list(client->channels, &htl);
2489   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
2490     channel = chl->channel;
2491
2492     /* Remove channel from client's channel list */
2493     silc_hash_table_del(client->channels, channel);
2494
2495     /* Remove channel if there is no users anymore */
2496     if (server->server_type == SILC_ROUTER &&
2497         silc_hash_table_count(channel->user_list) < 2) {
2498       if (channel->rekey)
2499         silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2500       if (silc_idlist_del_channel(server->local_list, channel))
2501         server->stat.my_channels--;
2502       else 
2503         silc_idlist_del_channel(server->global_list, channel);
2504       continue;
2505     }
2506
2507     /* Remove client from channel's client list */
2508     silc_hash_table_del(channel->user_list, chl->client);
2509
2510     /* If there is no global users on the channel anymore mark the channel
2511        as local channel. Do not check if the removed client is local client. */
2512     if (server->server_type != SILC_ROUTER && channel->global_users && 
2513         chl->client->router && !silc_server_channel_has_global(channel))
2514       channel->global_users = FALSE;
2515
2516     silc_free(chl);
2517     server->stat.my_chanclients--;
2518
2519     /* If there is not at least one local user on the channel then we don't
2520        need the channel entry anymore, we can remove it safely. */
2521     if (server->server_type != SILC_ROUTER &&
2522         !silc_server_channel_has_local(channel)) {
2523       /* Notify about leaving client if this channel has global users. */
2524       if (notify && channel->global_users)
2525         silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2526                                            SILC_NOTIFY_TYPE_SIGNOFF, 
2527                                            signoff_message ? 2 : 1,
2528                                            clidp->data, clidp->len,
2529                                            signoff_message, signoff_message ?
2530                                            strlen(signoff_message) : 0);
2531
2532       if (channel->rekey)
2533         silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2534
2535       if (channel->founder_key) {
2536         /* The founder auth data exists, do not remove the channel entry */
2537         SilcChannelClientEntry chl2;
2538         SilcHashTableList htl2;
2539
2540         channel->disabled = TRUE;
2541
2542         silc_hash_table_list(channel->user_list, &htl2);
2543         while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2544           silc_hash_table_del(chl2->client->channels, channel);
2545           silc_hash_table_del(channel->user_list, chl2->client);
2546           silc_free(chl2);
2547         }
2548         continue;
2549       }
2550
2551       /* Remove the channel entry */
2552       if (silc_idlist_del_channel(server->local_list, channel))
2553         server->stat.my_channels--;
2554       else 
2555         silc_idlist_del_channel(server->global_list, channel);
2556       continue;
2557     }
2558
2559     /* Send notify to channel about client leaving SILC and thus
2560        the entire channel. */
2561     if (notify)
2562       silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2563                                          SILC_NOTIFY_TYPE_SIGNOFF, 
2564                                          signoff_message ? 2 : 1,
2565                                          clidp->data, clidp->len,
2566                                          signoff_message, signoff_message ?
2567                                          strlen(signoff_message) : 0);
2568
2569     if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2570       /* Re-generate channel key */
2571       if (!silc_server_create_channel_key(server, channel, 0))
2572         return;
2573       
2574       /* Send the channel key to the channel. The key of course is not sent
2575          to the client who was removed from the channel. */
2576       silc_server_send_channel_key(server, client->connection, channel, 
2577                                    server->server_type == SILC_ROUTER ? 
2578                                    FALSE : !server->standalone);
2579     }
2580   }
2581
2582   silc_buffer_free(clidp);
2583 }
2584
2585 /* Removes client from one channel. This is used for example when client
2586    calls LEAVE command to remove itself from the channel. Returns TRUE
2587    if channel still exists and FALSE if the channel is removed when
2588    last client leaves the channel. If `notify' is FALSE notify messages
2589    are not sent. */
2590
2591 int silc_server_remove_from_one_channel(SilcServer server, 
2592                                         SilcSocketConnection sock,
2593                                         SilcChannelEntry channel,
2594                                         SilcClientEntry client,
2595                                         int notify)
2596 {
2597   SilcChannelClientEntry chl;
2598   SilcBuffer clidp;
2599
2600   SILC_LOG_DEBUG(("Start"));
2601
2602   /* Get the entry to the channel, if this client is not on the channel
2603      then return Ok. */
2604   if (!silc_hash_table_find(client->channels, channel, NULL, (void *)&chl))
2605     return TRUE;
2606
2607   /* Remove the client from the channel. The client is removed from
2608      the channel's user list. */
2609
2610   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2611
2612   /* Remove channel from client's channel list */
2613   silc_hash_table_del(client->channels, chl->channel);
2614
2615   /* Remove channel if there is no users anymore */
2616   if (server->server_type == SILC_ROUTER &&
2617       silc_hash_table_count(channel->user_list) < 2) {
2618     if (channel->rekey)
2619       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2620     if (silc_idlist_del_channel(server->local_list, channel))
2621       server->stat.my_channels--;
2622     else 
2623       silc_idlist_del_channel(server->global_list, channel);
2624     silc_buffer_free(clidp);
2625     return FALSE;
2626   }
2627
2628   /* Remove client from channel's client list */
2629   silc_hash_table_del(channel->user_list, chl->client);
2630   
2631   /* If there is no global users on the channel anymore mark the channel
2632      as local channel. Do not check if the client is local client. */
2633   if (server->server_type != SILC_ROUTER && channel->global_users &&
2634       chl->client->router && !silc_server_channel_has_global(channel))
2635     channel->global_users = FALSE;
2636
2637   silc_free(chl);
2638   server->stat.my_chanclients--;
2639
2640   /* If there is not at least one local user on the channel then we don't
2641      need the channel entry anymore, we can remove it safely. */
2642   if (server->server_type != SILC_ROUTER &&
2643       !silc_server_channel_has_local(channel)) {
2644     /* Notify about leaving client if this channel has global users. */
2645     if (notify && channel->global_users)
2646       silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2647                                          SILC_NOTIFY_TYPE_LEAVE, 1,
2648                                          clidp->data, clidp->len);
2649     
2650     silc_buffer_free(clidp);
2651     
2652     if (channel->rekey)
2653       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
2654
2655     if (channel->founder_key) {
2656       /* The founder auth data exists, do not remove the channel entry */
2657       SilcChannelClientEntry chl2;
2658       SilcHashTableList htl2;
2659       
2660       channel->disabled = TRUE;
2661       
2662       silc_hash_table_list(channel->user_list, &htl2);
2663       while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
2664         silc_hash_table_del(chl2->client->channels, channel);
2665         silc_hash_table_del(channel->user_list, chl2->client);
2666         silc_free(chl2);
2667       }
2668       return FALSE;
2669     }
2670
2671     /* Remove the channel entry */
2672     if (silc_idlist_del_channel(server->local_list, channel))
2673       server->stat.my_channels--;
2674     else 
2675       silc_idlist_del_channel(server->global_list, channel);
2676     return FALSE;
2677   }
2678
2679   /* Send notify to channel about client leaving the channel */
2680   if (notify)
2681     silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2682                                        SILC_NOTIFY_TYPE_LEAVE, 1,
2683                                        clidp->data, clidp->len);
2684
2685   silc_buffer_free(clidp);
2686   return TRUE;
2687 }
2688
2689 /* Timeout callback. This is called if connection is idle or for some
2690    other reason is not responding within some period of time. This 
2691    disconnects the remote end. */
2692
2693 SILC_TASK_CALLBACK(silc_server_timeout_remote)
2694 {
2695   SilcServer server = (SilcServer)context;
2696   SilcSocketConnection sock = server->sockets[fd];
2697
2698   SILC_LOG_DEBUG(("Start"));
2699
2700   if (!sock)
2701     return;
2702
2703   /* If we have protocol active we must assure that we call the protocol's
2704      final callback so that all the memory is freed. */
2705   if (sock->protocol) {
2706     sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
2707     silc_protocol_execute_final(sock->protocol, server->schedule);
2708     return;
2709   }
2710
2711   if (sock->user_data)
2712     silc_server_free_sock_user_data(server, sock);
2713
2714   silc_server_disconnect_remote(server, sock, "Server closed connection: "
2715                                 "Connection timeout");
2716 }
2717
2718 /* Creates new channel. Sends NEW_CHANNEL packet to primary route. This
2719    function may be used only by router. In real SILC network all channels
2720    are created by routers thus this function is never used by normal
2721    server. */
2722
2723 SilcChannelEntry silc_server_create_new_channel(SilcServer server, 
2724                                                 SilcServerID *router_id,
2725                                                 char *cipher, 
2726                                                 char *hmac,
2727                                                 char *channel_name,
2728                                                 int broadcast)
2729 {
2730   SilcChannelID *channel_id;
2731   SilcChannelEntry entry;
2732   SilcCipher key;
2733   SilcHmac newhmac;
2734
2735   SILC_LOG_DEBUG(("Creating new channel"));
2736
2737   if (!cipher)
2738     cipher = SILC_DEFAULT_CIPHER;
2739   if (!hmac)
2740     hmac = SILC_DEFAULT_HMAC;
2741
2742   /* Allocate cipher */
2743   if (!silc_cipher_alloc(cipher, &key))
2744     return NULL;
2745
2746   /* Allocate hmac */
2747   if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2748     silc_cipher_free(key);
2749     return NULL;
2750   }
2751
2752   channel_name = strdup(channel_name);
2753
2754   /* Create the channel */
2755   if (!silc_id_create_channel_id(server, router_id, server->rng, 
2756                                  &channel_id)) {
2757     silc_free(channel_name);
2758     silc_cipher_free(key);
2759     silc_hmac_free(newhmac);
2760     return NULL;
2761   }
2762   entry = silc_idlist_add_channel(server->local_list, channel_name, 
2763                                   SILC_CHANNEL_MODE_NONE, channel_id, 
2764                                   NULL, key, newhmac);
2765   if (!entry) {
2766     silc_free(channel_name);
2767     silc_cipher_free(key);
2768     silc_hmac_free(newhmac);
2769     return NULL;
2770   }
2771
2772   entry->cipher = strdup(cipher);
2773   entry->hmac_name = strdup(hmac);
2774
2775   /* Now create the actual key material */
2776   if (!silc_server_create_channel_key(server, entry, 
2777                                       silc_cipher_get_key_len(key) / 8)) {
2778     silc_free(channel_name);
2779     silc_cipher_free(key);
2780     silc_hmac_free(newhmac);
2781     silc_free(entry->cipher);
2782     silc_free(entry->hmac_name);
2783     return NULL;
2784   }
2785
2786   /* Notify other routers about the new channel. We send the packet
2787      to our primary route. */
2788   if (broadcast && server->standalone == FALSE)
2789     silc_server_send_new_channel(server, server->router->connection, TRUE, 
2790                                  channel_name, entry->id, 
2791                                  silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2792                                  entry->mode);
2793
2794   server->stat.my_channels++;
2795
2796   return entry;
2797 }
2798
2799 /* Same as above but creates the channel with Channel ID `channel_id. */
2800
2801 SilcChannelEntry 
2802 silc_server_create_new_channel_with_id(SilcServer server, 
2803                                        char *cipher, 
2804                                        char *hmac,
2805                                        char *channel_name,
2806                                        SilcChannelID *channel_id,
2807                                        int broadcast)
2808 {
2809   SilcChannelEntry entry;
2810   SilcCipher key;
2811   SilcHmac newhmac;
2812
2813   SILC_LOG_DEBUG(("Creating new channel"));
2814
2815   if (!cipher)
2816     cipher = SILC_DEFAULT_CIPHER;
2817   if (!hmac)
2818     hmac = SILC_DEFAULT_HMAC;
2819
2820   /* Allocate cipher */
2821   if (!silc_cipher_alloc(cipher, &key))
2822     return NULL;
2823
2824   /* Allocate hmac */
2825   if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
2826     silc_cipher_free(key);
2827     return NULL;
2828   }
2829
2830   channel_name = strdup(channel_name);
2831
2832   /* Create the channel */
2833   entry = silc_idlist_add_channel(server->local_list, channel_name, 
2834                                   SILC_CHANNEL_MODE_NONE, channel_id, 
2835                                   NULL, key, newhmac);
2836   if (!entry) {
2837     silc_free(channel_name);
2838     return NULL;
2839   }
2840
2841   /* Now create the actual key material */
2842   if (!silc_server_create_channel_key(server, entry, 
2843                                       silc_cipher_get_key_len(key) / 8)) {
2844     silc_free(channel_name);
2845     return NULL;
2846   }
2847
2848   /* Notify other routers about the new channel. We send the packet
2849      to our primary route. */
2850   if (broadcast && server->standalone == FALSE)
2851     silc_server_send_new_channel(server, server->router->connection, TRUE, 
2852                                  channel_name, entry->id, 
2853                                  silc_id_get_len(entry->id, SILC_ID_CHANNEL),
2854                                  entry->mode);
2855
2856   server->stat.my_channels++;
2857
2858   return entry;
2859 }
2860
2861 /* Channel's key re-key timeout callback. */
2862
2863 SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
2864 {
2865   SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
2866   SilcServer server = (SilcServer)rekey->context;
2867
2868   rekey->task = NULL;
2869
2870   if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
2871     return;
2872
2873   silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
2874 }
2875
2876 /* Generates new channel key. This is used to create the initial channel key
2877    but also to re-generate new key for channel. If `key_len' is provided
2878    it is the bytes of the key length. */
2879
2880 bool silc_server_create_channel_key(SilcServer server, 
2881                                     SilcChannelEntry channel,
2882                                     uint32 key_len)
2883 {
2884   int i;
2885   unsigned char channel_key[32], hash[32];
2886   uint32 len;
2887
2888   SILC_LOG_DEBUG(("Generating channel key"));
2889
2890   if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2891     SILC_LOG_DEBUG(("Channel has private keys, will not generate new key"));
2892     return TRUE;
2893   }
2894
2895   if (!channel->channel_key)
2896     if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key)) {
2897       channel->channel_key = NULL;
2898       return FALSE;
2899     }
2900
2901   if (key_len)
2902     len = key_len;
2903   else if (channel->key_len)
2904     len = channel->key_len / 8;
2905   else
2906     len = silc_cipher_get_key_len(channel->channel_key) / 8;
2907
2908   /* Create channel key */
2909   for (i = 0; i < len; i++) channel_key[i] = silc_rng_get_byte(server->rng);
2910   
2911   /* Set the key */
2912   silc_cipher_set_key(channel->channel_key, channel_key, len * 8);
2913
2914   /* Remove old key if exists */
2915   if (channel->key) {
2916     memset(channel->key, 0, channel->key_len / 8);
2917     silc_free(channel->key);
2918   }
2919
2920   /* Save the key */
2921   channel->key_len = len * 8;
2922   channel->key = silc_calloc(len, sizeof(*channel->key));
2923   memcpy(channel->key, channel_key, len);
2924   memset(channel_key, 0, sizeof(channel_key));
2925
2926   /* Generate HMAC key from the channel key data and set it */
2927   if (!channel->hmac)
2928     silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
2929   silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash);
2930   silc_hmac_set_key(channel->hmac, hash, 
2931                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
2932   memset(hash, 0, sizeof(hash));
2933
2934   if (server->server_type == SILC_ROUTER) {
2935     if (!channel->rekey)
2936       channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
2937     channel->rekey->context = (void *)server;
2938     channel->rekey->channel = channel;
2939     channel->rekey->key_len = key_len;
2940     if (channel->rekey->task)
2941       silc_schedule_task_del(server->schedule, channel->rekey->task);
2942
2943     channel->rekey->task = 
2944       silc_schedule_task_add(server->schedule, 0, 
2945                              silc_server_channel_key_rekey,
2946                              (void *)channel->rekey, 3600, 0,
2947                              SILC_TASK_TIMEOUT,
2948                              SILC_TASK_PRI_NORMAL);
2949   }
2950
2951   return TRUE;
2952 }
2953
2954 /* Saves the channel key found in the encoded `key_payload' buffer. This 
2955    function is used when we receive Channel Key Payload and also when we're
2956    processing JOIN command reply. Returns entry to the channel. */
2957
2958 SilcChannelEntry silc_server_save_channel_key(SilcServer server,
2959                                               SilcBuffer key_payload,
2960                                               SilcChannelEntry channel)
2961 {
2962   SilcChannelKeyPayload payload = NULL;
2963   SilcChannelID *id = NULL;
2964   unsigned char *tmp, hash[32];
2965   uint32 tmp_len;
2966   char *cipher;
2967
2968   SILC_LOG_DEBUG(("Start"));
2969
2970   /* Decode channel key payload */
2971   payload = silc_channel_key_payload_parse(key_payload);
2972   if (!payload) {
2973     SILC_LOG_ERROR(("Bad channel key payload, dropped"));
2974     channel = NULL;
2975     goto out;
2976   }
2977
2978   /* Get the channel entry */
2979   if (!channel) {
2980
2981     /* Get channel ID */
2982     tmp = silc_channel_key_get_id(payload, &tmp_len);
2983     id = silc_id_str2id(tmp, tmp_len, SILC_ID_CHANNEL);
2984     if (!id) {
2985       channel = NULL;
2986       goto out;
2987     }
2988
2989     channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
2990     if (!channel) {
2991       channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
2992       if (!channel) {
2993         SILC_LOG_ERROR(("Received key for non-existent channel"));
2994         goto out;
2995       }
2996     }
2997   }
2998
2999   tmp = silc_channel_key_get_key(payload, &tmp_len);
3000   if (!tmp) {
3001     channel = NULL;
3002     goto out;
3003   }
3004
3005   cipher = silc_channel_key_get_cipher(payload, NULL);
3006   if (!cipher) {
3007     channel = NULL;
3008     goto out;
3009   }
3010
3011   /* Remove old key if exists */
3012   if (channel->key) {
3013     memset(channel->key, 0, channel->key_len / 8);
3014     silc_free(channel->key);
3015     silc_cipher_free(channel->channel_key);
3016   }
3017
3018   /* Create new cipher */
3019   if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
3020     channel->channel_key = NULL;
3021     channel = NULL;
3022     goto out;
3023   }
3024
3025   if (channel->cipher)
3026     silc_free(channel->cipher);
3027   channel->cipher = strdup(cipher);
3028
3029   /* Save the key */
3030   channel->key_len = tmp_len * 8;
3031   channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
3032   memcpy(channel->key, tmp, tmp_len);
3033   silc_cipher_set_key(channel->channel_key, tmp, channel->key_len);
3034
3035   /* Generate HMAC key from the channel key data and set it */
3036   if (!channel->hmac)
3037     silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
3038   silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
3039   silc_hmac_set_key(channel->hmac, hash, 
3040                     silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3041
3042   memset(hash, 0, sizeof(hash));
3043   memset(tmp, 0, tmp_len);
3044
3045   if (server->server_type == SILC_ROUTER) {
3046     if (!channel->rekey)
3047       channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
3048     channel->rekey->context = (void *)server;
3049     channel->rekey->channel = channel;
3050     if (channel->rekey->task)
3051       silc_schedule_task_del(server->schedule, channel->rekey->task);
3052
3053     channel->rekey->task = 
3054       silc_schedule_task_add(server->schedule, 0, 
3055                              silc_server_channel_key_rekey,
3056                              (void *)channel->rekey, 3600, 0,
3057                              SILC_TASK_TIMEOUT,
3058                              SILC_TASK_PRI_NORMAL);
3059   }
3060
3061  out:
3062   silc_free(id);
3063   if (payload)
3064     silc_channel_key_payload_free(payload);
3065
3066   return channel;
3067 }
3068
3069 /* Heartbeat callback. This function is set as argument for the
3070    silc_socket_set_heartbeat function. The library will call this function
3071    at the set time interval. */
3072
3073 void silc_server_perform_heartbeat(SilcSocketConnection sock,
3074                                    void *hb_context)
3075 {
3076   SilcServerHBContext hb = (SilcServerHBContext)hb_context;
3077
3078   SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname,
3079                   sock->ip));
3080
3081   /* Send the heartbeat */
3082   silc_server_send_heartbeat(hb->server, sock);
3083 }
3084
3085 /* Returns assembled of all servers in the given ID list. The packet's
3086    form is dictated by the New ID payload. */
3087
3088 static void silc_server_announce_get_servers(SilcServer server,
3089                                              SilcServerEntry remote,
3090                                              SilcIDList id_list,
3091                                              SilcBuffer *servers,
3092                                              unsigned long creation_time)
3093 {
3094   SilcIDCacheList list;
3095   SilcIDCacheEntry id_cache;
3096   SilcServerEntry entry;
3097   SilcBuffer idp;
3098
3099   /* Go through all clients in the list */
3100   if (silc_idcache_get_all(id_list->servers, &list)) {
3101     if (silc_idcache_list_first(list, &id_cache)) {
3102       while (id_cache) {
3103         entry = (SilcServerEntry)id_cache->context;
3104
3105         /* Do not announce the one we've sending our announcements and
3106            do not announce ourself. Also check the creation time if it's
3107            provided. */
3108         if ((entry == remote) || (entry == server->id_entry) ||
3109             (creation_time && entry->data.created < creation_time)) {
3110           if (!silc_idcache_list_next(list, &id_cache))
3111             break;
3112           continue;
3113         }
3114
3115         idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
3116
3117         *servers = silc_buffer_realloc(*servers, 
3118                                        (*servers ? 
3119                                         (*servers)->truelen + idp->len : 
3120                                         idp->len));
3121         silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data));
3122         silc_buffer_put(*servers, idp->data, idp->len);
3123         silc_buffer_pull(*servers, idp->len);
3124         silc_buffer_free(idp);
3125
3126         if (!silc_idcache_list_next(list, &id_cache))
3127           break;
3128       }
3129     }
3130
3131     silc_idcache_list_free(list);
3132   }
3133 }
3134
3135 /* This function is used by router to announce existing servers to our
3136    primary router when we've connected to it. If `creation_time' is non-zero
3137    then only the servers that has been created after the `creation_time'
3138    will be announced. */
3139
3140 void silc_server_announce_servers(SilcServer server, bool global,
3141                                   unsigned long creation_time,
3142                                   SilcSocketConnection remote)
3143 {
3144   SilcBuffer servers = NULL;
3145
3146   SILC_LOG_DEBUG(("Announcing servers"));
3147
3148   /* Get servers in local list */
3149   silc_server_announce_get_servers(server, remote->user_data,
3150                                    server->local_list, &servers,
3151                                    creation_time);
3152
3153   if (global)
3154     /* Get servers in global list */
3155     silc_server_announce_get_servers(server, remote->user_data,
3156                                      server->global_list, &servers,
3157                                      creation_time);
3158
3159   if (servers) {
3160     silc_buffer_push(servers, servers->data - servers->head);
3161     SILC_LOG_HEXDUMP(("servers"), servers->data, servers->len);
3162
3163     /* Send the packet */
3164     silc_server_packet_send(server, remote,
3165                             SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3166                             servers->data, servers->len, TRUE);
3167
3168     silc_buffer_free(servers);
3169   }
3170 }
3171
3172 /* Returns assembled packet of all clients in the given ID list. The
3173    packet's form is dictated by the New ID Payload. */
3174
3175 static void silc_server_announce_get_clients(SilcServer server,
3176                                              SilcIDList id_list,
3177                                              SilcBuffer *clients,
3178                                              unsigned long creation_time)
3179 {
3180   SilcIDCacheList list;
3181   SilcIDCacheEntry id_cache;
3182   SilcClientEntry client;
3183   SilcBuffer idp;
3184
3185   /* Go through all clients in the list */
3186   if (silc_idcache_get_all(id_list->clients, &list)) {
3187     if (silc_idcache_list_first(list, &id_cache)) {
3188       while (id_cache) {
3189         client = (SilcClientEntry)id_cache->context;
3190
3191         if (creation_time && client->data.created < creation_time) {
3192           if (!silc_idcache_list_next(list, &id_cache))
3193             break;
3194           continue;
3195         }
3196
3197         idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3198
3199         *clients = silc_buffer_realloc(*clients, 
3200                                        (*clients ? 
3201                                         (*clients)->truelen + idp->len : 
3202                                         idp->len));
3203         silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data));
3204         silc_buffer_put(*clients, idp->data, idp->len);
3205         silc_buffer_pull(*clients, idp->len);
3206         silc_buffer_free(idp);
3207
3208         if (!silc_idcache_list_next(list, &id_cache))
3209           break;
3210       }
3211     }
3212
3213     silc_idcache_list_free(list);
3214   }
3215 }
3216
3217 /* This function is used to announce our existing clients to our router
3218    when we've connected to it. If `creation_time' is non-zero then only
3219    the clients that has been created after the `creation_time' will be
3220    announced. */
3221
3222 void silc_server_announce_clients(SilcServer server,
3223                                   unsigned long creation_time,
3224                                   SilcSocketConnection remote)
3225 {
3226   SilcBuffer clients = NULL;
3227
3228   SILC_LOG_DEBUG(("Announcing clients"));
3229
3230   /* Get clients in local list */
3231   silc_server_announce_get_clients(server, server->local_list,
3232                                    &clients, creation_time);
3233
3234   /* As router we announce our global list as well */
3235   if (server->server_type == SILC_ROUTER)
3236     silc_server_announce_get_clients(server, server->global_list,
3237                                      &clients, creation_time);
3238
3239   if (clients) {
3240     silc_buffer_push(clients, clients->data - clients->head);
3241     SILC_LOG_HEXDUMP(("clients"), clients->data, clients->len);
3242
3243     /* Send the packet */
3244     silc_server_packet_send(server, remote,
3245                             SILC_PACKET_NEW_ID, SILC_PACKET_FLAG_LIST,
3246                             clients->data, clients->len, TRUE);
3247
3248     silc_buffer_free(clients);
3249   }
3250 }
3251
3252 static SilcBuffer 
3253 silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
3254 {
3255   va_list ap;
3256   SilcBuffer p;
3257
3258   va_start(ap, argc);
3259   p = silc_notify_payload_encode(notify, argc, ap);
3260   va_end(ap);
3261  
3262   return p;
3263 }
3264
3265 /* Returns assembled packets for channel users of the `channel'. */
3266
3267 void silc_server_announce_get_channel_users(SilcServer server,
3268                                             SilcChannelEntry channel,
3269                                             SilcBuffer *channel_users,
3270                                             SilcBuffer *channel_users_modes)
3271 {
3272   SilcChannelClientEntry chl;
3273   SilcHashTableList htl;
3274   SilcBuffer chidp, clidp;
3275   SilcBuffer tmp;
3276   int len;
3277   unsigned char mode[4];
3278
3279   SILC_LOG_DEBUG(("Start"));
3280
3281   /* Now find all users on the channel */
3282   chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3283   silc_hash_table_list(channel->user_list, &htl);
3284   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3285     clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3286
3287     /* JOIN Notify */
3288     tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2, 
3289                                              clidp->data, clidp->len,
3290                                              chidp->data, chidp->len);
3291     len = tmp->len;
3292     *channel_users = 
3293       silc_buffer_realloc(*channel_users, 
3294                           (*channel_users ? 
3295                            (*channel_users)->truelen + len : len));
3296     silc_buffer_pull_tail(*channel_users, 
3297                           ((*channel_users)->end - 
3298                            (*channel_users)->data));
3299     
3300     silc_buffer_put(*channel_users, tmp->data, tmp->len);
3301     silc_buffer_pull(*channel_users, len);
3302     silc_buffer_free(tmp);
3303
3304     /* CUMODE notify for mode change on the channel */
3305     SILC_PUT32_MSB(chl->mode, mode);
3306     tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE, 
3307                                              3, clidp->data, clidp->len,
3308                                              mode, 4,
3309                                              clidp->data, clidp->len);
3310     len = tmp->len;
3311     *channel_users_modes = 
3312       silc_buffer_realloc(*channel_users_modes, 
3313                           (*channel_users_modes ? 
3314                            (*channel_users_modes)->truelen + len : len));
3315     silc_buffer_pull_tail(*channel_users_modes, 
3316                           ((*channel_users_modes)->end - 
3317                            (*channel_users_modes)->data));
3318     
3319     silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
3320     silc_buffer_pull(*channel_users_modes, len);
3321     silc_buffer_free(tmp);
3322
3323     silc_buffer_free(clidp);
3324   }
3325   silc_buffer_free(chidp);
3326 }
3327
3328 /* Returns assembled packets for all channels and users on those channels
3329    from the given ID List. The packets are in the form dictated by the
3330    New Channel and New Channel User payloads. */
3331
3332 void silc_server_announce_get_channels(SilcServer server,
3333                                        SilcIDList id_list,
3334                                        SilcBuffer *channels,
3335                                        SilcBuffer *channel_users,
3336                                        SilcBuffer **channel_users_modes,
3337                                        uint32 *channel_users_modes_c,
3338                                        SilcChannelID ***channel_ids,
3339                                        unsigned long creation_time)
3340 {
3341   SilcIDCacheList list;
3342   SilcIDCacheEntry id_cache;
3343   SilcChannelEntry channel;
3344   unsigned char *cid;
3345   uint32 id_len;
3346   uint16 name_len;
3347   int len;
3348   int i = *channel_users_modes_c;
3349   bool announce;
3350
3351   SILC_LOG_DEBUG(("Start"));
3352
3353   /* Go through all channels in the list */
3354   if (silc_idcache_get_all(id_list->channels, &list)) {
3355     if (silc_idcache_list_first(list, &id_cache)) {
3356       while (id_cache) {
3357         channel = (SilcChannelEntry)id_cache->context;
3358
3359         if (creation_time && channel->created < creation_time)
3360           announce = FALSE;
3361         else
3362           announce = TRUE;
3363
3364         cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3365         id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3366         name_len = strlen(channel->channel_name);
3367
3368         if (announce) {
3369           len = 4 + name_len + id_len + 4;
3370           *channels = 
3371             silc_buffer_realloc(*channels, 
3372                                 (*channels ? (*channels)->truelen + 
3373                                  len : len));
3374           silc_buffer_pull_tail(*channels, 
3375                                 ((*channels)->end - (*channels)->data));
3376           silc_buffer_format(*channels,
3377                              SILC_STR_UI_SHORT(name_len),
3378                              SILC_STR_UI_XNSTRING(channel->channel_name, 
3379                                                   name_len),
3380                              SILC_STR_UI_SHORT(id_len),
3381                              SILC_STR_UI_XNSTRING(cid, id_len),
3382                              SILC_STR_UI_INT(channel->mode),
3383                              SILC_STR_END);
3384           silc_buffer_pull(*channels, len);
3385         }
3386
3387         *channel_users_modes = silc_realloc(*channel_users_modes,
3388                                             sizeof(**channel_users_modes) * 
3389                                             (i + 1));
3390         (*channel_users_modes)[i] = NULL;
3391         *channel_ids = silc_realloc(*channel_ids, 
3392                                     sizeof(**channel_ids) * (i + 1));
3393         (*channel_ids)[i] = NULL;
3394         silc_server_announce_get_channel_users(server, channel,
3395                                                channel_users,
3396                                                &(*channel_users_modes)[i]);
3397         (*channel_ids)[i] = channel->id;
3398         i++;
3399
3400         if (!silc_idcache_list_next(list, &id_cache))
3401           break;
3402       }
3403
3404       *channel_users_modes_c += i;
3405     }
3406
3407     silc_idcache_list_free(list);
3408   }
3409 }
3410
3411 /* This function is used to announce our existing channels to our router
3412    when we've connected to it. This also announces the users on the
3413    channels to the router. If the `creation_time' is non-zero only the
3414    channels that was created after the `creation_time' are announced.
3415    Note that the channel users are still announced even if the `creation_time'
3416    was provided. */
3417
3418 void silc_server_announce_channels(SilcServer server,
3419                                    unsigned long creation_time,
3420                                    SilcSocketConnection remote)
3421 {
3422   SilcBuffer channels = NULL, channel_users = NULL;
3423   SilcBuffer *channel_users_modes = NULL;
3424   uint32 channel_users_modes_c = 0;
3425   SilcChannelID **channel_ids = NULL;
3426
3427   SILC_LOG_DEBUG(("Announcing channels and channel users"));
3428
3429   /* Get channels and channel users in local list */
3430   silc_server_announce_get_channels(server, server->local_list,
3431                                     &channels, &channel_users,
3432                                     &channel_users_modes,
3433                                     &channel_users_modes_c,
3434                                     &channel_ids, creation_time);
3435
3436   /* Get channels and channel users in global list */
3437   if (server->server_type != SILC_SERVER)
3438     silc_server_announce_get_channels(server, server->global_list,
3439                                       &channels, &channel_users,
3440                                       &channel_users_modes,
3441                                       &channel_users_modes_c,
3442                                       &channel_ids, creation_time);
3443
3444   if (channels) {
3445     silc_buffer_push(channels, channels->data - channels->head);
3446     SILC_LOG_HEXDUMP(("channels"), channels->data, channels->len);
3447
3448     /* Send the packet */
3449     silc_server_packet_send(server, remote,
3450                             SILC_PACKET_NEW_CHANNEL, SILC_PACKET_FLAG_LIST,
3451                             channels->data, channels->len,
3452                             FALSE);
3453
3454     silc_buffer_free(channels);
3455   }
3456
3457   if (channel_users) {
3458     silc_buffer_push(channel_users, channel_users->data - channel_users->head);
3459     SILC_LOG_HEXDUMP(("channel users"), channel_users->data, 
3460                      channel_users->len);
3461
3462     /* Send the packet */
3463     silc_server_packet_send(server, remote,
3464                             SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3465                             channel_users->data, channel_users->len,
3466                             FALSE);
3467
3468     silc_buffer_free(channel_users);
3469   }
3470
3471   if (channel_users_modes) {
3472     int i;
3473
3474     for (i = 0; i < channel_users_modes_c; i++) {
3475       silc_buffer_push(channel_users_modes[i], 
3476                        channel_users_modes[i]->data - 
3477                        channel_users_modes[i]->head);
3478       SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes[i]->data, 
3479                        channel_users_modes[i]->len);
3480       silc_server_packet_send_dest(server, remote,
3481                                    SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3482                                    channel_ids[i], SILC_ID_CHANNEL,
3483                                    channel_users_modes[i]->data, 
3484                                    channel_users_modes[i]->len,
3485                                    FALSE);
3486       silc_buffer_free(channel_users_modes[i]);
3487     }
3488     silc_free(channel_users_modes);
3489     silc_free(channel_ids);
3490   }
3491 }
3492
3493 /* Failure timeout callback. If this is called then we will immediately
3494    process the received failure. We always process the failure with timeout
3495    since we do not want to blindly trust to received failure packets. 
3496    This won't be called (the timeout is cancelled) if the failure was
3497    bogus (it is bogus if remote does not close the connection after sending
3498    the failure). */
3499
3500 SILC_TASK_CALLBACK(silc_server_failure_callback)
3501 {
3502   SilcServerFailureContext f = (SilcServerFailureContext)context;
3503
3504   if (f->sock->protocol) {
3505     f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
3506     silc_protocol_execute(f->sock->protocol, f->server->schedule, 0, 0);
3507   }
3508
3509   silc_free(f);
3510 }
3511
3512 /* Assembles user list and users mode list from the `channel'. */
3513
3514 void silc_server_get_users_on_channel(SilcServer server,
3515                                       SilcChannelEntry channel,
3516                                       SilcBuffer *user_list,
3517                                       SilcBuffer *mode_list,
3518                                       uint32 *user_count)
3519 {
3520   SilcChannelClientEntry chl;
3521   SilcHashTableList htl;
3522   SilcBuffer client_id_list;
3523   SilcBuffer client_mode_list;
3524   SilcBuffer idp;
3525   uint32 list_count = 0, len = 0;
3526
3527   silc_hash_table_list(channel->user_list, &htl);
3528   while (silc_hash_table_get(&htl, NULL, (void *)&chl))
3529     len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
3530
3531   client_id_list = silc_buffer_alloc(len);
3532   client_mode_list = 
3533     silc_buffer_alloc(4 * silc_hash_table_count(channel->user_list));
3534   silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
3535   silc_buffer_pull_tail(client_mode_list, SILC_BUFFER_END(client_mode_list));
3536
3537   silc_hash_table_list(channel->user_list, &htl);
3538   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3539     /* Client ID */
3540     idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
3541     silc_buffer_put(client_id_list, idp->data, idp->len);
3542     silc_buffer_pull(client_id_list, idp->len);
3543     silc_buffer_free(idp);
3544
3545     /* Client's mode on channel */
3546     SILC_PUT32_MSB(chl->mode, client_mode_list->data);
3547     silc_buffer_pull(client_mode_list, 4);
3548
3549     list_count++;
3550   }
3551   silc_buffer_push(client_id_list, 
3552                    client_id_list->data - client_id_list->head);
3553   silc_buffer_push(client_mode_list, 
3554                    client_mode_list->data - client_mode_list->head);
3555
3556   *user_list = client_id_list;
3557   *mode_list = client_mode_list;
3558   *user_count = list_count;
3559 }
3560
3561 /* Saves users and their modes to the `channel'. */
3562
3563 void silc_server_save_users_on_channel(SilcServer server,
3564                                        SilcSocketConnection sock,
3565                                        SilcChannelEntry channel,
3566                                        SilcClientID *noadd,
3567                                        SilcBuffer user_list,
3568                                        SilcBuffer mode_list,
3569                                        uint32 user_count)
3570 {
3571   int i;
3572
3573   for (i = 0; i < user_count; i++) {
3574     uint16 idp_len;
3575     uint32 mode;
3576     SilcClientID *client_id;
3577     SilcClientEntry client;
3578
3579     /* Client ID */
3580     SILC_GET16_MSB(idp_len, user_list->data + 2);
3581     idp_len += 4;
3582     client_id = silc_id_payload_parse_id(user_list->data, idp_len);
3583     silc_buffer_pull(user_list, idp_len);
3584     if (!client_id)
3585       continue;
3586
3587     /* Mode */
3588     SILC_GET32_MSB(mode, mode_list->data);
3589     silc_buffer_pull(mode_list, 4);
3590
3591     if (noadd && SILC_ID_CLIENT_COMPARE(client_id, noadd)) {
3592       silc_free(client_id);
3593       continue;
3594     }
3595     
3596     /* Check if we have this client cached already. */
3597     client = silc_idlist_find_client_by_id(server->local_list, client_id,
3598                                            server->server_type, NULL);
3599     if (!client)
3600       client = silc_idlist_find_client_by_id(server->global_list, 
3601                                              client_id, server->server_type,
3602                                              NULL);
3603     if (!client) {
3604       /* If router did not find such Client ID in its lists then this must
3605          be bogus client or some router in the net is buggy. */
3606       if (server->server_type == SILC_ROUTER) {
3607         silc_free(client_id);
3608         continue;
3609       }
3610
3611       /* We don't have that client anywhere, add it. The client is added
3612          to global list since server didn't have it in the lists so it must be 
3613          global. */
3614       client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
3615                                       silc_id_dup(client_id, SILC_ID_CLIENT), 
3616                                       sock->user_data, NULL);
3617       if (!client) {
3618         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
3619         silc_free(client_id);
3620         continue;
3621       }
3622
3623       client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3624     }
3625
3626     silc_free(client_id);
3627
3628     if (!silc_server_client_on_channel(client, channel)) {
3629       /* Client was not on the channel, add it. */
3630       SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl));
3631       chl->client = client;
3632       chl->mode = mode;
3633       chl->channel = channel;
3634       silc_hash_table_add(channel->user_list, chl->client, chl);
3635       silc_hash_table_add(client->channels, chl->channel, chl);
3636     }
3637   }
3638 }
3639
3640 /* Lookups route to the client indicated by the `id_data'. The connection
3641    object and internal data object is returned. Returns NULL if route
3642    could not be found to the client. If the `client_id' is specified then
3643    it is used and the `id_data' is ignored. */
3644
3645 SilcSocketConnection silc_server_get_client_route(SilcServer server,
3646                                                   unsigned char *id_data,
3647                                                   uint32 id_len,
3648                                                   SilcClientID *client_id,
3649                                                   SilcIDListData *idata)
3650 {
3651   SilcClientID *id;
3652   SilcClientEntry client;
3653
3654   SILC_LOG_DEBUG(("Start"));
3655
3656   /* Decode destination Client ID */
3657   if (!client_id) {
3658     id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
3659     if (!id) {
3660       SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
3661       return NULL;
3662     }
3663   } else {
3664     id = silc_id_dup(client_id, SILC_ID_CLIENT);
3665   }
3666
3667   /* If the destination belongs to our server we don't have to route
3668      the packet anywhere but to send it to the local destination. */
3669   client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
3670   if (client) {
3671     silc_free(id);
3672
3673     /* If we are router and the client has router then the client is in
3674        our cell but not directly connected to us. */
3675     if (server->server_type == SILC_ROUTER && client->router) {
3676       /* We are of course in this case the client's router thus the route
3677          to the client is the server who owns the client. So, we will send
3678          the packet to that server. */
3679       if (idata)
3680         *idata = (SilcIDListData)client->router;
3681       return client->router->connection;
3682     }
3683
3684     /* Seems that client really is directly connected to us */
3685     if (idata)
3686       *idata = (SilcIDListData)client;
3687     return client->connection;
3688   }
3689
3690   /* Destination belongs to someone not in this server. If we are normal
3691      server our action is to send the packet to our router. */
3692   if (server->server_type != SILC_ROUTER && !server->standalone) {
3693     silc_free(id);
3694     if (idata)
3695       *idata = (SilcIDListData)server->router;
3696     return server->router->connection;
3697   }
3698
3699   /* We are router and we will perform route lookup for the destination 
3700      and send the packet to fastest route. */
3701   if (server->server_type == SILC_ROUTER && !server->standalone) {
3702     /* Check first that the ID is valid */
3703     client = silc_idlist_find_client_by_id(server->global_list, id, 
3704                                            TRUE, NULL);
3705     if (client) {
3706       SilcSocketConnection dst_sock;
3707
3708       dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
3709
3710       silc_free(id);
3711       if (idata)
3712         *idata = (SilcIDListData)dst_sock->user_data;
3713       return dst_sock;
3714     }
3715   }
3716
3717   silc_free(id);
3718   return NULL;
3719 }
3720
3721 /* Encodes and returns channel list of channels the `client' has joined.
3722    Secret channels are not put to the list. */
3723
3724 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
3725                                                SilcClientEntry client)
3726 {
3727   SilcBuffer buffer = NULL;
3728   SilcChannelEntry channel;
3729   SilcChannelClientEntry chl;
3730   SilcHashTableList htl;
3731   unsigned char *cid;
3732   uint32 id_len;
3733   uint16 name_len;
3734   int len;
3735
3736   silc_hash_table_list(client->channels, &htl);
3737   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3738     channel = chl->channel;
3739
3740     if (channel->mode & SILC_CHANNEL_MODE_SECRET ||
3741         channel->mode & SILC_CHANNEL_MODE_PRIVATE)
3742       continue;
3743
3744     cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3745     id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3746     name_len = strlen(channel->channel_name);
3747     
3748     len = 4 + name_len + id_len + 4;
3749     buffer = silc_buffer_realloc(buffer, 
3750                                  (buffer ? (buffer)->truelen + len : len));
3751     silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
3752     silc_buffer_format(buffer,
3753                        SILC_STR_UI_SHORT(name_len),
3754                        SILC_STR_UI_XNSTRING(channel->channel_name, 
3755                                             name_len),
3756                        SILC_STR_UI_SHORT(id_len),
3757                        SILC_STR_UI_XNSTRING(cid, id_len),
3758                        SILC_STR_UI_INT(chl->mode), /* Client's mode */
3759                        SILC_STR_END);
3760     silc_buffer_pull(buffer, len);
3761     silc_free(cid);
3762   }
3763
3764   if (buffer)
3765     silc_buffer_push(buffer, buffer->data - buffer->head);
3766
3767   return buffer;
3768 }
3769
3770 /* Finds client entry by Client ID and if it is not found then resolves
3771    it using WHOIS command. */
3772
3773 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
3774                                                SilcClientID *client_id)
3775 {
3776   SilcClientEntry client;
3777
3778   client = silc_idlist_find_client_by_id(server->local_list, client_id,
3779                                          TRUE, NULL);
3780   if (!client) {
3781     client = silc_idlist_find_client_by_id(server->global_list, 
3782                                            client_id, TRUE, NULL);
3783     if (!client && server->server_type == SILC_ROUTER)
3784       return NULL;
3785   }
3786
3787   if (!client && server->standalone)
3788     return NULL;
3789
3790   if (!client || !client->nickname || !client->username) {
3791     SilcBuffer buffer, idp;
3792
3793     client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
3794     client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
3795     client->resolve_cmd_ident = ++server->cmd_ident;
3796
3797     idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3798     buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
3799                                             server->cmd_ident, 1,
3800                                             3, idp->data, idp->len);
3801     silc_server_packet_send(server, client ? client->router->connection :
3802                             server->router->connection,
3803                             SILC_PACKET_COMMAND, 0,
3804                             buffer->data, buffer->len, FALSE);
3805     silc_buffer_free(idp);
3806     silc_buffer_free(buffer);
3807     return NULL;
3808   }
3809
3810   return client;
3811 }
3812
3813 /* A timeout callback for the re-key. We will be the initiator of the
3814    re-key protocol. */
3815
3816 SILC_TASK_CALLBACK(silc_server_rekey_callback)
3817 {
3818   SilcSocketConnection sock = (SilcSocketConnection)context;
3819   SilcIDListData idata = (SilcIDListData)sock->user_data;
3820   SilcServer server = (SilcServer)idata->rekey->context;
3821   SilcProtocol protocol;
3822   SilcServerRekeyInternalContext *proto_ctx;
3823
3824   SILC_LOG_DEBUG(("Start"));
3825
3826   /* Allocate internal protocol context. This is sent as context
3827      to the protocol. */
3828   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3829   proto_ctx->server = (void *)server;
3830   proto_ctx->sock = sock;
3831   proto_ctx->responder = FALSE;
3832   proto_ctx->pfs = idata->rekey->pfs;
3833       
3834   /* Perform rekey protocol. Will call the final callback after the
3835      protocol is over. */
3836   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
3837                       &protocol, proto_ctx, silc_server_rekey_final);
3838   sock->protocol = protocol;
3839       
3840   /* Run the protocol */
3841   silc_protocol_execute(protocol, server->schedule, 0, 0);
3842
3843   /* Re-register re-key timeout */
3844   silc_schedule_task_add(server->schedule, sock->sock, 
3845                          silc_server_rekey_callback,
3846                          context, idata->rekey->timeout, 0,
3847                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
3848 }
3849
3850 /* The final callback for the REKEY protocol. This will actually take the
3851    new key material into use. */
3852
3853 SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final)
3854 {
3855   SilcProtocol protocol = (SilcProtocol)context;
3856   SilcServerRekeyInternalContext *ctx =
3857     (SilcServerRekeyInternalContext *)protocol->context;
3858   SilcServer server = (SilcServer)ctx->server;
3859   SilcSocketConnection sock = ctx->sock;
3860
3861   SILC_LOG_DEBUG(("Start"));
3862
3863   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
3864       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
3865     /* Error occured during protocol */
3866     SILC_LOG_ERROR(("Error occurred during rekey protocol"));
3867     silc_protocol_cancel(protocol, server->schedule);
3868     silc_protocol_free(protocol);
3869     sock->protocol = NULL;
3870     if (ctx->packet)
3871       silc_packet_context_free(ctx->packet);
3872     if (ctx->ske)
3873       silc_ske_free(ctx->ske);
3874     silc_free(ctx);
3875     return;
3876   }
3877
3878   /* Purge the outgoing data queue to assure that all rekey packets really
3879      go to the network before we quit the protocol. */
3880   silc_server_packet_queue_purge(server, sock);
3881
3882   /* Cleanup */
3883   silc_protocol_free(protocol);
3884   sock->protocol = NULL;
3885   if (ctx->packet)
3886     silc_packet_context_free(ctx->packet);
3887   if (ctx->ske)
3888     silc_ske_free(ctx->ske);
3889   silc_free(ctx);
3890 }