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