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