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