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