Completed the backup router support for standalone routers.
[silc.git] / apps / silcd / server_util.c
1 /*
2
3   server_util.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 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 /* $Id$ */
20
21 #include "serverincludes.h"
22 #include "server_internal.h"
23
24 extern char *server_version;
25
26 /* Removes the client from channels and possibly removes the channels
27    as well.  After removing those channels that exist, their channel
28    keys are regnerated. This is called only by the function
29    silc_server_remove_clients_by_server. */
30
31 static void
32 silc_server_remove_clients_channels(SilcServer server,
33                                     SilcServerEntry server_entry,
34                                     SilcHashTable clients,
35                                     SilcClientEntry client,
36                                     SilcHashTable channels)
37 {
38   SilcChannelEntry channel;
39   SilcChannelClientEntry chl, chl2;
40   SilcHashTableList htl, htl2;
41
42   if (!client)
43     return;
44
45   SILC_LOG_DEBUG(("Remove client from all channels"));
46
47   if (silc_hash_table_find(clients, client, NULL, NULL))
48     silc_hash_table_del(clients, client);
49
50   /* Remove the client from all channels. The client is removed from
51      the channels' user list. */
52   silc_hash_table_list(client->channels, &htl);
53   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
54     channel = chl->channel;
55
56     /* Remove channel if this is last client leaving the channel, unless
57        the channel is permanent. */
58     if (server->server_type == SILC_ROUTER &&
59         silc_hash_table_count(channel->user_list) < 2) {
60       if (silc_hash_table_find(channels, channel, NULL, NULL))
61         silc_hash_table_del(channels, channel);
62       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
63       silc_server_channel_delete(server, channel);
64       continue;
65     }
66
67     silc_hash_table_del(client->channels, channel);
68     silc_hash_table_del(channel->user_list, chl->client);
69     channel->user_count--;
70
71     /* If there is no global users on the channel anymore mark the channel
72        as local channel. Do not check if the removed client is local client. */
73     if (server->server_type != SILC_ROUTER && channel->global_users && 
74         chl->client->router && !silc_server_channel_has_global(channel))
75       channel->global_users = FALSE;
76
77     silc_free(chl);
78
79     /* Update statistics */
80     if (SILC_IS_LOCAL(client))
81       server->stat.my_chanclients--;
82     if (server->server_type == SILC_ROUTER) {
83       server->stat.cell_chanclients--;
84       server->stat.chanclients--;
85     }
86
87     /* If there is not at least one local user on the channel then we don't
88        need the channel entry anymore, we can remove it safely, unless the
89        channel is permanent channel */
90     if (server->server_type != SILC_ROUTER &&
91         !silc_server_channel_has_local(channel)) {
92       if (silc_hash_table_find(channels, channel, NULL, NULL))
93         silc_hash_table_del(channels, channel);
94       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
95       silc_server_channel_delete(server, channel);
96       continue;
97     }
98
99     /* Mark other local clients to the table of clients whom will receive
100        the SERVER_SIGNOFF notify. */
101     silc_hash_table_list(channel->user_list, &htl2);
102     while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
103       SilcClientEntry c = chl2->client;
104       if (!c)
105         continue;
106
107       /* Add client to table, if it's not from the signoff server */
108       if (c->router != server_entry &&
109           !silc_hash_table_find(clients, c, NULL, NULL))
110         silc_hash_table_add(clients, c, c);
111     }
112     silc_hash_table_list_reset(&htl2);
113
114     /* Add the channel to the the channels list to regenerate the 
115        channel key */
116     if (!silc_hash_table_find(channels, channel, NULL, NULL))
117       silc_hash_table_add(channels, channel, channel);
118   }
119   silc_hash_table_list_reset(&htl);
120 }
121
122 /* This function removes all client entries that are originated from
123    `router' and are owned by `entry'.  `router' and `entry' can be same
124    too.  If `server_signoff' is TRUE then SERVER_SIGNOFF notify is 
125    distributed to our local clients. */
126
127 bool silc_server_remove_clients_by_server(SilcServer server,
128                                           SilcServerEntry router,
129                                           SilcServerEntry entry,
130                                           bool server_signoff)
131 {
132   SilcIDCacheList list = NULL;
133   SilcIDCacheEntry id_cache = NULL;
134   SilcClientEntry client = NULL;
135   SilcBuffer idp;
136   unsigned char **argv = NULL;
137   SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
138   SilcHashTableList htl;
139   SilcChannelEntry channel;
140   SilcHashTable channels, clients;
141   int i;
142
143   if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
144     return FALSE;
145
146   SILC_LOG_DEBUG(("Removing clients by %s",
147                   entry->server_name ? entry->server_name : "server"));
148
149   if (!router)
150     router = entry;
151
152   /* Allocate the hash table that holds the channels that require
153      channel key re-generation after we've removed this server's clients
154      from the channels. */
155   channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
156                                    NULL, NULL, TRUE);
157   clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
158                                   NULL, NULL, TRUE);
159
160   if (server_signoff) {
161     idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
162     argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
163     argv_lens = silc_realloc(argv_lens,  sizeof(*argv_lens) * (argc + 1));
164     argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
165     argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
166     memcpy(argv[argc], idp->data, idp->len);
167     argv_lens[argc] = idp->len;
168     argv_types[argc] = argc + 1;
169     argc++;
170     silc_buffer_free(idp);
171   }
172
173   if (silc_idcache_get_all(server->local_list->clients, &list)) {
174     if (silc_idcache_list_first(list, &id_cache)) {
175       while (id_cache) {
176         client = (SilcClientEntry)id_cache->context;
177
178         /* If client is not registered, is not originated from `router'
179            or is not owned by `entry', skip it. */
180         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
181             client->router != router ||
182             (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
183                                                  client->id->ip.data_len))) {
184           if (!silc_idcache_list_next(list, &id_cache))
185             break;
186           else
187             continue;
188         }
189
190         if (server_signoff) {
191           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
192           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
193           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
194                                    (argc + 1));
195           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
196                                     (argc + 1));
197           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
198           memcpy(argv[argc], idp->data, idp->len);
199           argv_lens[argc] = idp->len;
200           argv_types[argc] = argc + 1;
201           argc++;
202           silc_buffer_free(idp);
203         }
204
205         /* Update statistics */
206         server->stat.clients--;
207         if (server->stat.cell_clients)
208           server->stat.cell_clients--;
209         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
210         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
211
212         silc_server_remove_clients_channels(server, entry, clients,
213                                             client, channels);
214         silc_server_del_from_watcher_list(server, client);
215
216         /* Remove the client entry */
217         if (!server_signoff) {
218           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
219           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
220         } else {
221           silc_idlist_del_client(server->local_list, client);
222         }
223
224         if (!silc_idcache_list_next(list, &id_cache))
225           break;
226       }
227     }
228     silc_idcache_list_free(list);
229   }
230   
231   if (silc_idcache_get_all(server->global_list->clients, &list)) {
232
233     if (silc_idcache_list_first(list, &id_cache)) {
234       while (id_cache) {
235         client = (SilcClientEntry)id_cache->context;
236
237         /* If client is not registered, is not originated from `router'
238            or is not owned by `entry', skip it. */
239         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
240             client->router != router ||
241             (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
242                                                  client->id->ip.data_len))) {
243           if (!silc_idcache_list_next(list, &id_cache))
244             break;
245           else
246             continue;
247         }
248
249         if (server_signoff) {
250           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
251           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
252           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
253                                    (argc + 1));
254           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
255                                     (argc + 1));
256           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
257           memcpy(argv[argc], idp->data, idp->len);
258           argv_lens[argc] = idp->len;
259           argv_types[argc] = argc + 1;
260           argc++;
261           silc_buffer_free(idp);
262         }
263
264         /* Update statistics */
265         server->stat.clients--;
266         if (server->stat.cell_clients)
267           server->stat.cell_clients--;
268         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
269         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
270
271         silc_server_remove_clients_channels(server, entry, clients,
272                                             client, channels);
273         silc_server_del_from_watcher_list(server, client);
274
275         /* Remove the client entry */
276         if (!server_signoff) {
277           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
278           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
279         } else {
280           silc_idlist_del_client(server->global_list, client);
281         }
282
283         if (!silc_idcache_list_next(list, &id_cache))
284           break;
285       }
286     }
287     silc_idcache_list_free(list);
288   }
289
290   /* Send the SERVER_SIGNOFF notify */
291   if (server_signoff) {
292     SilcBuffer args, not;
293
294     SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
295                     silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
296
297     /* Send SERVER_SIGNOFF notify to our primary router */
298     if (server->router != entry) {
299       args = silc_argument_payload_encode(1, argv, argv_lens,
300                                           argv_types);
301       silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
302                                    SILC_BROADCAST(server),
303                                    SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
304                                    argc, args);
305       silc_buffer_free(args);
306     }
307
308     /* Send to local clients. We also send the list of client ID's that
309        is to be removed for those servers that would like to use that list. */
310     args = silc_argument_payload_encode(argc, argv, argv_lens,
311                                         argv_types);
312     not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF, 
313                                           argc, args);
314     silc_server_packet_send_clients(server, clients,
315                                     SILC_PACKET_NOTIFY, 0, FALSE,
316                                     not->data, not->len, FALSE);
317
318     silc_buffer_free(args);
319     silc_buffer_free(not);
320     for (i = 0; i < argc; i++)
321       silc_free(argv[i]);
322     silc_free(argv);
323     silc_free(argv_lens);
324     silc_free(argv_types);
325     silc_hash_table_free(clients);
326   }
327
328   /* We must now re-generate the channel key for all channels that had
329      this server's client(s) on the channel. As they left the channel we
330      must re-generate the channel key. */
331   silc_hash_table_list(channels, &htl);
332   while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
333     if (!silc_server_create_channel_key(server, channel, 0)) {
334       silc_hash_table_list_reset(&htl);
335       silc_hash_table_free(channels);
336       return FALSE;
337     }
338
339     /* Do not send the channel key if private channel key mode is set */
340     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
341       continue;
342
343     silc_server_send_channel_key(server, NULL, channel, 
344                                  server->server_type == SILC_ROUTER ? 
345                                  FALSE : !server->standalone);
346   }
347   silc_hash_table_list_reset(&htl);
348   silc_hash_table_free(channels);
349
350   return TRUE;
351 }
352
353 static SilcServerEntry
354 silc_server_update_clients_by_real_server(SilcServer server,
355                                           SilcServerEntry from,
356                                           SilcClientEntry client,
357                                           bool local,
358                                           SilcIDCacheEntry client_cache)
359 {
360   SilcServerEntry server_entry;
361   SilcIDCacheEntry id_cache = NULL;
362   SilcIDCacheList list;
363
364   if (!silc_idcache_get_all(server->local_list->servers, &list))
365     return NULL;
366
367   if (silc_idcache_list_first(list, &id_cache)) {
368     while (id_cache) {
369       server_entry = (SilcServerEntry)id_cache->context;
370       if (server_entry != from &&
371           SILC_ID_COMPARE(server_entry->id, client->id, 
372                           client->id->ip.data_len)) {
373         SILC_LOG_DEBUG(("Found (local) %s",
374                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
375
376         if (!server_entry->data.send_key && server_entry->router) {
377           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
378           /* If the client is not marked as local then move it to local list
379              since the server is local. */
380           if (!local) {
381             SILC_LOG_DEBUG(("Moving client to local list"));
382             silc_idcache_add(server->local_list->clients, client_cache->name,
383                              client_cache->id, client_cache->context,
384                              client_cache->expire, NULL);
385             silc_idcache_del_by_context(server->global_list->clients, client);
386           }
387           server_entry = server_entry->router;
388         } else {
389           /* If the client is not marked as local then move it to local list
390              since the server is local. */
391           if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
392             SILC_LOG_DEBUG(("Moving client to local list"));
393             silc_idcache_add(server->local_list->clients, client_cache->name,
394                              client_cache->id, client_cache->context,
395                              client_cache->expire, NULL);
396             silc_idcache_del_by_context(server->global_list->clients, client);
397           }
398         }
399
400         silc_idcache_list_free(list);
401         return server_entry;
402       }
403
404       if (!silc_idcache_list_next(list, &id_cache))
405         break;
406     }
407   }
408
409   silc_idcache_list_free(list);
410
411   if (!silc_idcache_get_all(server->global_list->servers, &list))
412     return NULL;
413
414   if (silc_idcache_list_first(list, &id_cache)) {
415     while (id_cache) {
416       server_entry = (SilcServerEntry)id_cache->context;
417       if (server_entry != from &&
418           SILC_ID_COMPARE(server_entry->id, client->id, 
419                           client->id->ip.data_len)) {
420         SILC_LOG_DEBUG(("Found (global) %s",
421                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
422
423         if (!server_entry->data.send_key && server_entry->router) {
424           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
425           /* If the client is marked as local then move it to global list
426              since the server is global. */
427           if (local) {
428             SILC_LOG_DEBUG(("Moving client to global list"));
429             silc_idcache_add(server->global_list->clients, client_cache->name,
430                              client_cache->id, client_cache->context,
431                              client_cache->expire, NULL);
432             silc_idcache_del_by_context(server->local_list->clients, client);
433           }
434           server_entry = server_entry->router;
435         } else {
436           /* If the client is marked as local then move it to global list
437              since the server is global. */
438           if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
439             SILC_LOG_DEBUG(("Moving client to global list"));
440             silc_idcache_add(server->global_list->clients, client_cache->name,
441                              client_cache->id, client_cache->context,
442                              client_cache->expire, NULL);
443             silc_idcache_del_by_context(server->local_list->clients, client);
444           }
445         }
446
447         silc_idcache_list_free(list);
448         return server_entry;
449       }
450
451       if (!silc_idcache_list_next(list, &id_cache))
452         break;
453     }
454   }
455
456   silc_idcache_list_free(list);
457
458   return NULL;
459 }
460
461 /* Updates the clients that are originated from the `from' to be originated
462    from the `to'. If the `resolve_real_server' is TRUE then this will
463    attempt to figure out which clients really are originated from the
464    `from' and which are originated from a server that we have connection
465    to, when we've acting as backup router. If it is FALSE the `to' will
466    be the new source. */
467
468 void silc_server_update_clients_by_server(SilcServer server, 
469                                           SilcServerEntry from,
470                                           SilcServerEntry to,
471                                           bool resolve_real_server)
472 {
473   SilcIDCacheList list = NULL;
474   SilcIDCacheEntry id_cache = NULL;
475   SilcClientEntry client = NULL;
476   bool local;
477
478   local = FALSE;
479   if (silc_idcache_get_all(server->global_list->clients, &list)) {
480     if (silc_idcache_list_first(list, &id_cache)) {
481       while (id_cache) {
482         client = (SilcClientEntry)id_cache->context;
483
484         /* If entry is disabled skip it.  If entry is local to us, do not
485            switch it to anyone else, it is ours so skip it. */
486         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
487             SILC_IS_LOCAL(client)) {
488           if (!silc_idcache_list_next(list, &id_cache))
489             break;
490           else
491             continue;
492         }
493
494         SILC_LOG_DEBUG(("Client %s", 
495                         silc_id_render(client->id, SILC_ID_CLIENT)));
496         if (client->router)
497           SILC_LOG_DEBUG(("Client->router %s", 
498                           silc_id_render(client->router->id, SILC_ID_SERVER)));
499
500         if (from) {
501           if (client->router == from) {
502             if (resolve_real_server) {
503               client->router = 
504                 silc_server_update_clients_by_real_server(server, from, client,
505                                                           local, id_cache);
506               if (!client->router) {
507                 if (server->server_type == SILC_ROUTER)
508                   client->router = from;
509                 else
510                   client->router = to;
511               }
512             } else {
513               client->router = to;
514             }
515           }
516         } else {
517           /* All are changed */
518           client->router = to;
519         }
520
521         if (client->router)
522           SILC_LOG_DEBUG(("Client changed to %s", 
523                           silc_id_render(client->router->id, SILC_ID_CLIENT)));
524
525         if (!silc_idcache_list_next(list, &id_cache))
526           break;
527       }
528     }
529     silc_idcache_list_free(list);
530   }
531
532   local = TRUE;
533   if (silc_idcache_get_all(server->local_list->clients, &list)) {
534     if (silc_idcache_list_first(list, &id_cache)) {
535       while (id_cache) {
536         client = (SilcClientEntry)id_cache->context;
537
538         /* If entry is disabled skip it.  If entry is local to us, do not
539            switch it to anyone else, it is ours so skip it. */
540         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
541             SILC_IS_LOCAL(client)) {
542           if (!silc_idcache_list_next(list, &id_cache))
543             break;
544           else
545             continue;
546         }
547
548         SILC_LOG_DEBUG(("Client %s", 
549                         silc_id_render(client->id, SILC_ID_CLIENT)));
550         if (client->router)
551           SILC_LOG_DEBUG(("Client->router %s", 
552                           silc_id_render(client->router->id, SILC_ID_SERVER)));
553
554         if (from) {
555           if (client->router == from) {
556             if (resolve_real_server) {
557               client->router = 
558                 silc_server_update_clients_by_real_server(server, from, client,
559                                                           local, id_cache);
560               if (!client->router)
561                 client->router = from;
562             } else {
563               client->router = to;
564             }
565           }
566         } else {
567           /* All are changed */
568           client->router = to;
569         }
570
571         if (client->router)
572           SILC_LOG_DEBUG(("Client changed to %s", 
573                           silc_id_render(client->router->id, SILC_ID_CLIENT)));
574
575         if (!silc_idcache_list_next(list, &id_cache))
576           break;
577       }
578     }
579     silc_idcache_list_free(list);
580   }
581 }
582
583 /* Updates servers that are from `from' to be originated from `to'.  This
584    will also update the server's connection to `to's connection. */
585
586 void silc_server_update_servers_by_server(SilcServer server, 
587                                           SilcServerEntry from,
588                                           SilcServerEntry to)
589 {
590   SilcIDCacheList list = NULL;
591   SilcIDCacheEntry id_cache = NULL;
592   SilcServerEntry server_entry = NULL;
593
594   SILC_LOG_DEBUG(("Updating servers"));
595
596   if (silc_idcache_get_all(server->local_list->servers, &list)) {
597     if (silc_idcache_list_first(list, &id_cache)) {
598       while (id_cache) {
599         server_entry = (SilcServerEntry)id_cache->context;
600
601         /* If entry is local to us, do not switch it to any anyone else,
602            it is ours. */
603         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
604             server_entry == from) {
605           if (!silc_idcache_list_next(list, &id_cache))
606             break;
607           else
608             continue;
609         }
610
611         /* If we are standalone router, any server that is not directly
612            connected to cannot exist anymore.  If we are not standalone
613            we update it correctly. */
614         if (server->server_type == SILC_ROUTER && server->standalone) {
615           silc_server_backup_del(server, server_entry);
616           silc_server_backup_replaced_del(server, server_entry);
617           silc_idlist_del_data(server_entry);
618           silc_idlist_del_server(server->local_list, server_entry);
619           server->stat.servers--;
620           server->stat.cell_servers--;
621         } else {
622           /* XXX if we are not standalone, do a check from local config
623              whether this server is in our cell, but not connected to
624              us (in which case we must remove it). */
625
626           if (server_entry->router == from) {
627             SILC_LOG_DEBUG(("Updating server (local) %s",
628                             server_entry->server_name ? 
629                             server_entry->server_name : ""));
630             server_entry->router = to;
631             server_entry->connection = to->connection;
632           }
633         }
634
635         if (!silc_idcache_list_next(list, &id_cache))
636           break;
637       }
638     }
639     silc_idcache_list_free(list);
640   }
641
642   if (silc_idcache_get_all(server->global_list->servers, &list)) {
643     if (silc_idcache_list_first(list, &id_cache)) {
644       while (id_cache) {
645         server_entry = (SilcServerEntry)id_cache->context;
646
647         /* If entry is local to us, do not switch it to anyone else,
648            it is ours. */
649         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
650             server_entry == from) {
651           if (!silc_idcache_list_next(list, &id_cache))
652             break;
653           else
654             continue;
655         }
656
657         /* If we are standalone router, any server that is not directly
658            connected to cannot exist anymore.  If we are not standalone
659            we update it correctly. */
660         if (server->server_type == SILC_ROUTER && server->standalone) {
661           silc_server_backup_del(server, server_entry);
662           silc_server_backup_replaced_del(server, server_entry);
663           silc_idlist_del_data(server_entry);
664           silc_idlist_del_server(server->global_list, server_entry);
665           server->stat.servers--;
666           server->stat.cell_servers--;
667         } else {
668           /* XXX if we are not standalone, do a check from local config
669              whether this server is in our cell, but not connected to
670              us (in which case we must remove it). */
671
672           if (server_entry->router == from) {
673             SILC_LOG_DEBUG(("Updating server (global) %s",
674                             server_entry->server_name ? 
675                             server_entry->server_name : ""));
676             server_entry->router = to;
677             server_entry->connection = to->connection;
678           }
679         }
680
681         if (!silc_idcache_list_next(list, &id_cache))
682           break;
683       }
684     }
685     silc_idcache_list_free(list);
686   }
687 }
688
689
690 /* Toggles the enabled/disabled status of local server connections.  Packets
691    can be sent to the servers when `toggle_enabled' is TRUE and will be
692    dropped if `toggle_enabled' is FALSE, after this function is called. */
693
694 void silc_server_local_servers_toggle_enabled(SilcServer server,
695                                               bool toggle_enabled)
696 {
697   SilcIDCacheList list = NULL;
698   SilcIDCacheEntry id_cache = NULL;
699   SilcServerEntry server_entry = NULL;
700
701   if (silc_idcache_get_all(server->local_list->servers, &list)) {
702     if (silc_idcache_list_first(list, &id_cache)) {
703       while (id_cache) {
704         server_entry = (SilcServerEntry)id_cache->context;
705         if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
706           if (!silc_idcache_list_next(list, &id_cache))
707             break;
708           else
709             continue;
710         }
711
712         if (toggle_enabled)
713           server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
714         else
715           server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
716
717         if (!silc_idcache_list_next(list, &id_cache))
718           break;
719       }
720     }
721     silc_idcache_list_free(list);
722   }
723
724   if (silc_idcache_get_all(server->global_list->servers, &list)) {
725     if (silc_idcache_list_first(list, &id_cache)) {
726       while (id_cache) {
727         server_entry = (SilcServerEntry)id_cache->context;
728         if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
729           if (!silc_idcache_list_next(list, &id_cache))
730             break;
731           else
732             continue;
733         }
734
735         if (toggle_enabled)
736           server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
737         else
738           server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
739
740         if (!silc_idcache_list_next(list, &id_cache))
741           break;
742       }
743     }
744     silc_idcache_list_free(list);
745   }
746 }
747
748 /* Removes servers that are originated from the `from'.  The server
749    entry is deleted in this function.  If `remove_clients' is TRUE then
750    all clients originated from the server are removed too, and server
751    signoff is sent.  Note that this does not remove the `from'.  This
752    also does not remove locally connected servers. */
753
754 void silc_server_remove_servers_by_server(SilcServer server,
755                                           SilcServerEntry from,
756                                           bool remove_clients)
757 {
758   SilcIDCacheList list = NULL;
759   SilcIDCacheEntry id_cache = NULL;
760   SilcServerEntry server_entry = NULL;
761
762   SILC_LOG_DEBUG(("Removing servers by %s",
763                   from->server_name ? from->server_name : "server"));
764
765   if (silc_idcache_get_all(server->local_list->servers, &list)) {
766     if (silc_idcache_list_first(list, &id_cache)) {
767       while (id_cache) {
768         server_entry = (SilcServerEntry)id_cache->context;
769         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
770           server_entry->router != from || server_entry == from) {
771           if (!silc_idcache_list_next(list, &id_cache))
772             break;
773           else
774             continue;
775         }
776
777         /* Remove clients owned by this server */
778         if (remove_clients)
779           silc_server_remove_clients_by_server(server, from, server_entry,
780                                                TRUE);
781
782         /* Remove the server */
783         silc_idlist_del_server(server->local_list, server_entry);
784
785         if (!silc_idcache_list_next(list, &id_cache))
786           break;
787       }
788     }
789     silc_idcache_list_free(list);
790   }
791
792   if (silc_idcache_get_all(server->global_list->servers, &list)) {
793     if (silc_idcache_list_first(list, &id_cache)) {
794       while (id_cache) {
795         server_entry = (SilcServerEntry)id_cache->context;
796         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
797           server_entry->router != from || server_entry == from) {
798           if (!silc_idcache_list_next(list, &id_cache))
799             break;
800           else
801             continue;
802         }
803
804         /* Remove clients owned by this server */
805         if (remove_clients)
806           silc_server_remove_clients_by_server(server, from, server_entry,
807                                                TRUE);
808
809         /* Remove the server */
810         silc_idlist_del_server(server->global_list, server_entry);
811
812         if (!silc_idcache_list_next(list, &id_cache))
813           break;
814       }
815     }
816     silc_idcache_list_free(list);
817   }
818 }
819
820 /* Removes channels that are from `from. */
821
822 void silc_server_remove_channels_by_server(SilcServer server, 
823                                            SilcServerEntry from)
824 {
825   SilcIDCacheList list = NULL;
826   SilcIDCacheEntry id_cache = NULL;
827   SilcChannelEntry channel = NULL;
828
829   SILC_LOG_DEBUG(("Removing channels by server"));
830
831   if (silc_idcache_get_all(server->global_list->channels, &list)) {
832     if (silc_idcache_list_first(list, &id_cache)) {
833       while (id_cache) {
834         channel = (SilcChannelEntry)id_cache->context;
835         if (channel->router == from)
836           silc_idlist_del_channel(server->global_list, channel);
837         if (!silc_idcache_list_next(list, &id_cache))
838           break;
839       }
840     }
841     silc_idcache_list_free(list);
842   }
843 }
844
845 /* Updates channels that are from `from' to be originated from `to'.  */
846
847 void silc_server_update_channels_by_server(SilcServer server, 
848                                            SilcServerEntry from,
849                                            SilcServerEntry to)
850 {
851   SilcIDCacheList list = NULL;
852   SilcIDCacheEntry id_cache = NULL;
853   SilcChannelEntry channel = NULL;
854
855   SILC_LOG_DEBUG(("Updating channels by server"));
856
857   if (silc_idcache_get_all(server->global_list->channels, &list)) {
858     if (silc_idcache_list_first(list, &id_cache)) {
859       while (id_cache) {
860         channel = (SilcChannelEntry)id_cache->context;
861         if (channel->router == from)
862           channel->router = to;
863         if (!silc_idcache_list_next(list, &id_cache))
864           break;
865       }
866     }
867     silc_idcache_list_free(list);
868   }
869 }
870
871 /* Checks whether given channel has global users.  If it does this returns
872    TRUE and FALSE if there is only locally connected clients on the channel. */
873
874 bool silc_server_channel_has_global(SilcChannelEntry channel)
875 {
876   SilcChannelClientEntry chl;
877   SilcHashTableList htl;
878
879   silc_hash_table_list(channel->user_list, &htl);
880   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
881     if (chl->client->router) {
882       silc_hash_table_list_reset(&htl);
883       return TRUE;
884     }
885   }
886   silc_hash_table_list_reset(&htl);
887
888   return FALSE;
889 }
890
891 /* Checks whether given channel has locally connected users.  If it does this
892    returns TRUE and FALSE if there is not one locally connected client. */
893
894 bool silc_server_channel_has_local(SilcChannelEntry channel)
895 {
896   SilcChannelClientEntry chl;
897   SilcHashTableList htl;
898
899   silc_hash_table_list(channel->user_list, &htl);
900   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
901     if (!chl->client->router) {
902       silc_hash_table_list_reset(&htl);
903       return TRUE;
904     }
905   }
906   silc_hash_table_list_reset(&htl);
907
908   return FALSE;
909 }
910
911 /* This function removes the channel and all users on the channel, unless
912    the channel is permanent.  In this case the channel is disabled but all
913    users are removed from the channel.  Returns TRUE if the channel is
914    destroyed totally, and FALSE if it is permanent and remains. */
915
916 bool silc_server_channel_delete(SilcServer server,
917                                 SilcChannelEntry channel)
918 {
919   SilcChannelClientEntry chl;
920   SilcHashTableList htl;
921   bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
922
923   if (delchan) {
924     /* Update statistics */
925     if (server->server_type == SILC_ROUTER)
926       server->stat.chanclients -= channel->user_count;
927
928     /* Totally delete the channel and all users on the channel. The
929        users are deleted automatically in silc_idlist_del_channel. */
930     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
931     if (silc_idlist_del_channel(server->local_list, channel)) {
932       server->stat.my_channels--;
933       if (server->server_type == SILC_ROUTER) {
934         server->stat.channels--;
935         server->stat.cell_channels--;
936       }
937     } else {
938       if (silc_idlist_del_channel(server->global_list, channel))
939         if (server->server_type == SILC_ROUTER)
940           server->stat.channels--;
941     }
942
943     return FALSE;
944   }
945
946   /* Channel is permanent, do not remove it, remove only users */
947   channel->disabled = TRUE;
948   silc_hash_table_list(channel->user_list, &htl);
949   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
950     silc_hash_table_del(chl->client->channels, channel);
951     silc_hash_table_del(channel->user_list, chl->client);
952     channel->user_count--;
953
954     /* Update statistics */
955     if (SILC_IS_LOCAL(chl->client))
956       server->stat.my_chanclients--;
957     if (server->server_type == SILC_ROUTER) {
958       server->stat.cell_chanclients--;
959       server->stat.chanclients--;
960     }
961
962     silc_free(chl);
963   }
964   silc_hash_table_list_reset(&htl);
965
966   SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
967
968   return TRUE;
969 }
970
971 /* Returns TRUE if the given client is on the channel.  FALSE if not. 
972    This works because we assure that the user list on the channel is
973    always in up to date thus we can only check the channel list from 
974    `client' which is faster than checking the user list from `channel'. */
975
976 bool silc_server_client_on_channel(SilcClientEntry client,
977                                    SilcChannelEntry channel,
978                                    SilcChannelClientEntry *chl)
979 {
980   if (!client || !channel)
981     return FALSE;
982
983   return silc_hash_table_find(client->channels, channel, NULL, 
984                               (void **)chl);
985 }
986
987 /* Checks string for bad characters and returns TRUE if they are found. */
988
989 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
990 {
991   int i;
992
993   for (i = 0; i < name_len; i++) {
994     if (!isascii(name[i]))
995       return TRUE;
996     if (name[i] <= 32) return TRUE;
997     if (name[i] == ' ') return TRUE;
998     if (name[i] == '*') return TRUE;
999     if (name[i] == '?') return TRUE;
1000     if (name[i] == ',') return TRUE;
1001   }
1002
1003   return FALSE;
1004 }
1005
1006 /* Modifies the `name' if it includes bad characters and returns new
1007    allocated name that does not include bad characters. */
1008
1009 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
1010 {
1011   int i;
1012   char *newname = strdup(name);
1013
1014   for (i = 0; i < name_len; i++) {
1015     if (!isascii(newname[i])) newname[i] = '_';
1016     if (newname[i] <= 32) newname[i] = '_';
1017     if (newname[i] == ' ') newname[i] = '_';
1018     if (newname[i] == '*') newname[i] = '_';
1019     if (newname[i] == '?') newname[i] = '_';
1020     if (newname[i] == ',') newname[i] = '_';
1021   }
1022
1023   return newname;
1024 }
1025
1026 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
1027    socket connections with the IP address does not exist. */
1028
1029 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1030                                          SilcSocketType type)
1031 {
1032   int i, count;
1033
1034   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1035     if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
1036         server->sockets[i]->type == type)
1037       count++;
1038   }
1039
1040   return count;
1041 }
1042
1043 /* Find number of sockets by IP address indicated by remote host, indicatd
1044    by `ip' or `hostname', `port', and `type'.  Returns 0 if socket connections
1045    does not exist. If `ip' is provided then `hostname' is ignored. */
1046
1047 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server, 
1048                                              const char *ip,
1049                                              const char *hostname,
1050                                              SilcUInt16 port,
1051                                              SilcSocketType type)
1052 {
1053   int i, count;
1054
1055   if (!ip && !hostname)
1056     return 0;
1057
1058   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1059     if (server->sockets[i] && 
1060         ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
1061          (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
1062         server->sockets[i]->port == port &&
1063         server->sockets[i]->type == type)
1064       count++;
1065   }
1066
1067   return count;
1068 }
1069
1070 /* Finds locally cached public key by the public key received in the SKE. 
1071    If we have it locally cached then we trust it and will use it in the
1072    authentication protocol.  Returns the locally cached public key or NULL
1073    if we do not find the public key.  */
1074
1075 SilcPublicKey silc_server_find_public_key(SilcServer server, 
1076                                           SilcHashTable local_public_keys,
1077                                           SilcPublicKey remote_public_key)
1078 {
1079   SilcPublicKey cached_key;
1080
1081   SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
1082                   silc_hash_table_count(local_public_keys)));
1083
1084   if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
1085                                 (void **)&cached_key, NULL, 
1086                                 silc_hash_public_key, NULL,
1087                                 silc_hash_public_key_compare, NULL)) {
1088     SILC_LOG_ERROR(("Public key not found"));
1089     return NULL;
1090   }
1091
1092   SILC_LOG_DEBUG(("Found public key"));
1093
1094   return cached_key;
1095 }
1096
1097 /* This returns the first public key from the table of public keys.  This
1098    is used only in cases where single public key exists in the table and
1099    we want to get a pointer to it.  For public key tables that has multiple
1100    keys in it the silc_server_find_public_key must be used. */
1101
1102 SilcPublicKey silc_server_get_public_key(SilcServer server,
1103                                          SilcHashTable local_public_keys)
1104 {
1105   SilcPublicKey cached_key;
1106   SilcHashTableList htl;
1107
1108   SILC_LOG_DEBUG(("Start"));
1109
1110   assert(silc_hash_table_count(local_public_keys) < 2);
1111
1112   silc_hash_table_list(local_public_keys, &htl);
1113   if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
1114     return NULL;
1115   silc_hash_table_list_reset(&htl);
1116
1117   return cached_key;
1118 }
1119
1120 /* Check whether the connection `sock' is allowed to connect to us.  This
1121    checks for example whether there is too much connections for this host,
1122    and required version for the host etc. */
1123
1124 bool silc_server_connection_allowed(SilcServer server, 
1125                                     SilcSocketConnection sock,
1126                                     SilcSocketType type,
1127                                     SilcServerConfigConnParams *global,
1128                                     SilcServerConfigConnParams *params,
1129                                     SilcSKE ske)
1130 {
1131   SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
1132                             server->stat.my_clients :
1133                             type == SILC_SOCKET_TYPE_SERVER ?
1134                             server->stat.my_servers :
1135                             server->stat.my_routers);
1136   SilcUInt32 num_sockets, max_hosts, max_per_host;
1137   SilcUInt32 r_protocol_version, l_protocol_version;
1138   SilcUInt32 r_software_version, l_software_version;
1139   char *r_vendor_version = NULL, *l_vendor_version;
1140
1141   SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1142
1143   /* Check version */
1144
1145   l_protocol_version = 
1146     silc_version_to_num(params && params->version_protocol ? 
1147                         params->version_protocol : 
1148                         global->version_protocol);
1149   l_software_version = 
1150     silc_version_to_num(params && params->version_software ? 
1151                         params->version_software : 
1152                         global->version_software);
1153   l_vendor_version = (params && params->version_software_vendor ? 
1154                       params->version_software_vendor : 
1155                       global->version_software_vendor);
1156   
1157   if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1158                                     &r_software_version, NULL,
1159                                     &r_vendor_version)) {
1160     sock->version = r_protocol_version;
1161
1162     /* Match protocol version */
1163     if (l_protocol_version && r_protocol_version &&
1164         r_protocol_version < l_protocol_version) {
1165       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1166                      sock->hostname, sock->ip));
1167       silc_server_disconnect_remote(server, sock, 
1168                                     SILC_STATUS_ERR_BAD_VERSION,
1169                                     "You support too old protocol version");
1170       return FALSE;
1171     }
1172
1173     /* Math software version */
1174     if (l_software_version && r_software_version &&
1175         r_software_version < l_software_version) {
1176       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1177                      sock->hostname, sock->ip));
1178       silc_server_disconnect_remote(server, sock, 
1179                                     SILC_STATUS_ERR_BAD_VERSION,
1180                                     "You support too old software version");
1181       return FALSE;
1182     }
1183
1184     /* Regex match vendor version */
1185     if (l_vendor_version && r_vendor_version && 
1186         !silc_string_match(l_vendor_version, r_vendor_version)) {
1187       SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1188                      sock->hostname, sock->ip));
1189       silc_server_disconnect_remote(server, sock, 
1190                                     SILC_STATUS_ERR_BAD_VERSION,
1191                                     "Your software is not supported");
1192       return FALSE;
1193     }
1194   }
1195   silc_free(r_vendor_version);
1196
1197   /* Check for maximum connections limit */
1198
1199   num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1200   max_hosts = (params ? params->connections_max : global->connections_max);
1201   max_per_host = (params ? params->connections_max_per_host :
1202                   global->connections_max_per_host);
1203
1204   if (max_hosts && conn_number >= max_hosts) {
1205     SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1206                    sock->hostname, sock->ip));
1207     silc_server_disconnect_remote(server, sock, 
1208                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1209                                   "Server is full, try again later");
1210     return FALSE;
1211   }
1212
1213   if (num_sockets >= max_per_host) {
1214     SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1215                    sock->hostname, sock->ip));
1216     silc_server_disconnect_remote(server, sock, 
1217                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1218                                   "Too many connections from your host");
1219     return FALSE;
1220   }
1221
1222   return TRUE;
1223 }
1224
1225 /* Checks that client has rights to add or remove channel modes. If any
1226    of the checks fails FALSE is returned. */
1227
1228 bool silc_server_check_cmode_rights(SilcServer server,
1229                                     SilcChannelEntry channel,
1230                                     SilcChannelClientEntry client,
1231                                     SilcUInt32 mode)
1232 {
1233   bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1234   bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1235
1236   /* Check whether has rights to change anything */
1237   if (!is_op && !is_fo)
1238     return FALSE;
1239
1240   /* Check whether has rights to change everything */
1241   if (is_op && is_fo)
1242     return TRUE;
1243
1244   /* Founder implies operator */
1245   if (is_fo)
1246     is_op = TRUE;
1247
1248   /* We know that client is channel operator, check that they are not
1249      changing anything that requires channel founder rights. Rest of the
1250      modes are available automatically for channel operator. */
1251
1252   if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1253     if (is_op && !is_fo)
1254       return FALSE;
1255   } else {
1256     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1257       if (is_op && !is_fo)
1258         return FALSE;
1259     }
1260   }
1261   
1262   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1263     if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1264       if (is_op && !is_fo)
1265         return FALSE;
1266     }
1267   } else {
1268     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1269       if (is_op && !is_fo)
1270         return FALSE;
1271     }
1272   }
1273
1274   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1275     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1276       if (is_op && !is_fo)
1277         return FALSE;
1278     }
1279   } else {
1280     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1281       if (is_op && !is_fo)
1282         return FALSE;
1283     }
1284   }
1285   
1286   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1287     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1288       if (is_op && !is_fo)
1289         return FALSE;
1290     }
1291   } else {
1292     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1293       if (is_op && !is_fo)
1294         return FALSE;
1295     }
1296   }
1297   
1298   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1299     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1300       if (is_op && !is_fo)
1301         return FALSE;
1302     }
1303   } else {
1304     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1305       if (is_op && !is_fo)
1306         return FALSE;
1307     }
1308   }
1309   
1310   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1311     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1312       if (is_op && !is_fo)
1313         return FALSE;
1314     }
1315   } else {
1316     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1317       if (is_op && !is_fo)
1318         return FALSE;
1319     }
1320   }
1321   
1322   return TRUE;
1323 }
1324
1325 /* Check that the client has rights to change its user mode.  Returns
1326    FALSE if setting some mode is not allowed. */
1327
1328 bool silc_server_check_umode_rights(SilcServer server,
1329                                     SilcClientEntry client,
1330                                     SilcUInt32 mode)
1331 {
1332   bool server_op = FALSE, router_op = FALSE;
1333
1334   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1335     /* Cannot set server operator mode (must use OPER command) */
1336     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1337       return FALSE;
1338   } else {
1339     /* Remove the server operator rights */
1340     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1341       server_op = TRUE;
1342   }
1343
1344   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1345     /* Cannot set router operator mode (must use SILCOPER command) */
1346     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1347       return FALSE;
1348   } else {
1349     /* Remove the router operator rights */
1350     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1351       router_op = TRUE;
1352   }
1353
1354   if (server_op)
1355     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1356   if (router_op)
1357     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1358
1359   return TRUE;
1360 }
1361
1362 /* This function is used to send the notify packets and motd to the
1363    incoming client connection. */
1364
1365 void silc_server_send_connect_notifys(SilcServer server,
1366                                       SilcSocketConnection sock,
1367                                       SilcClientEntry client)
1368 {
1369   SilcIDListData idata = (SilcIDListData)client;
1370
1371   SILC_LOG_DEBUG(("Send welcome notifys"));
1372
1373   /* Send some nice info to the client */
1374   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1375                           ("Welcome to the SILC Network %s",
1376                            client->username));
1377   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1378                           ("Your host is %s, running version %s",
1379                            server->server_name, server_version));
1380
1381   if (server->server_type == SILC_ROUTER) {
1382     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1383                             ("There are %d clients, %d servers and %d "
1384                              "routers in SILC Network",
1385                              server->stat.clients, server->stat.servers + 1,
1386                              server->stat.routers));
1387   } else {
1388     if (server->stat.clients && server->stat.servers + 1)
1389       SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1390                               ("There are %d clients, %d servers and %d "
1391                                "routers in SILC Network",
1392                                server->stat.clients, server->stat.servers + 1,
1393                                (server->standalone ? 0 :
1394                                 !server->stat.routers ? 1 :
1395                                 server->stat.routers)));
1396   }
1397
1398   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1399     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1400                             ("There are %d clients on %d server in our cell",
1401                              server->stat.cell_clients,
1402                              server->stat.cell_servers + 1));
1403   if (server->server_type == SILC_ROUTER) {
1404     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1405                             ("I have %d clients, %d channels, %d servers and "
1406                              "%d routers",
1407                              server->stat.my_clients, 
1408                              server->stat.my_channels,
1409                              server->stat.my_servers,
1410                              server->stat.my_routers));
1411   } else {
1412     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1413                             ("I have %d clients and %d channels formed",
1414                              server->stat.my_clients,
1415                              server->stat.my_channels));
1416   }
1417
1418   if (server->stat.server_ops || server->stat.router_ops)
1419     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1420                             ("There are %d server operators and %d router "
1421                              "operators online",
1422                              server->stat.server_ops,
1423                              server->stat.router_ops));
1424   if (server->stat.my_router_ops + server->stat.my_server_ops)
1425     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1426                             ("I have %d operators online",
1427                              server->stat.my_router_ops +
1428                              server->stat.my_server_ops));
1429
1430   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1431                           ("Your connection is secured with %s cipher, "
1432                            "key length %d bits",
1433                            idata->send_key->cipher->name,
1434                            idata->send_key->cipher->key_len));
1435   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1436                           ("Your current nickname is %s",
1437                            client->nickname));
1438
1439   /* Send motd */
1440   silc_server_send_motd(server, sock);
1441 }
1442
1443 /* Kill the client indicated by `remote_client' sending KILLED notify
1444    to the client, to all channels client has joined and to primary
1445    router if needed.  The killed client is also removed from all channels. */
1446
1447 void silc_server_kill_client(SilcServer server,
1448                              SilcClientEntry remote_client,
1449                              const char *comment,
1450                              void *killer_id,
1451                              SilcIdType killer_id_type)
1452 {
1453   SilcBuffer killed, killer;
1454
1455   SILC_LOG_DEBUG(("Killing client %s", 
1456                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1457
1458   /* Send the KILL notify packets. First send it to the channel, then
1459      to our primary router and then directly to the client who is being
1460      killed right now. */
1461
1462   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1463   killer = silc_id_payload_encode(killer_id, killer_id_type);
1464
1465   /* Send KILLED notify to the channels. It is not sent to the client
1466      as it will be sent differently destined directly to the client and not
1467      to the channel. */
1468   silc_server_send_notify_on_channels(server, remote_client, 
1469                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1470                                       3, killed->data, killed->len,
1471                                       comment, comment ? strlen(comment) : 0,
1472                                       killer->data, killer->len);
1473
1474   /* Send KILLED notify to primary route */
1475   silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1476                                  SILC_BROADCAST(server), remote_client->id,
1477                                  comment, killer_id, killer_id_type);
1478
1479   /* Send KILLED notify to the client directly */
1480   if (remote_client->connection || remote_client->router)
1481     silc_server_send_notify_killed(server, remote_client->connection ? 
1482                                    remote_client->connection : 
1483                                    remote_client->router->connection, FALSE,
1484                                    remote_client->id, comment, 
1485                                    killer_id, killer_id_type);
1486
1487   /* Remove the client from all channels. This generates new keys to the
1488      channels as well. */
1489   silc_server_remove_from_channels(server, NULL, remote_client, FALSE, 
1490                                    NULL, TRUE);
1491
1492   /* Remove the client entry, If it is locally connected then we will also
1493      disconnect the client here */
1494   if (remote_client->connection) {
1495     /* Remove locally conneted client */
1496     SilcSocketConnection sock = remote_client->connection;
1497     silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1498     silc_server_close_connection(server, sock);
1499   } else {
1500     /* Update statistics */
1501     server->stat.clients--;
1502     if (server->stat.cell_clients)
1503       server->stat.cell_clients--;
1504     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1505     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1506
1507     if (SILC_IS_LOCAL(remote_client)) {
1508       server->stat.my_clients--;
1509       silc_schedule_task_del_by_context(server->schedule, remote_client);
1510       silc_idlist_del_data(remote_client);
1511     }
1512
1513     /* Remove remote client */
1514     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1515       /* Remove this client from watcher list if it is */
1516       silc_server_del_from_watcher_list(server, remote_client);
1517       silc_idlist_del_client(server->local_list, remote_client);  
1518     }
1519   }
1520
1521   silc_buffer_free(killer);
1522   silc_buffer_free(killed);
1523 }
1524
1525 typedef struct {
1526   SilcServer server;
1527   SilcClientEntry client;
1528   SilcNotifyType notify;
1529   const char *new_nick;
1530 } WatcherNotifyContext;
1531
1532 static void 
1533 silc_server_check_watcher_list_foreach(void *key, void *context, 
1534                                        void *user_context)
1535 {
1536   WatcherNotifyContext *notify = user_context;
1537   SilcClientEntry entry = context;
1538   SilcSocketConnection sock;
1539
1540   if (entry == notify->client)
1541     return;
1542
1543   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1544                                       NULL, NULL);
1545   if (sock) {
1546     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1547                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1548
1549     /* Send the WATCH notify */
1550     silc_server_send_notify_watch(notify->server, sock, entry, 
1551                                   notify->client, 
1552                                   notify->new_nick ? notify->new_nick :
1553                                   (const char *)notify->client->nickname, 
1554                                   notify->notify);
1555   }
1556 }
1557
1558 /* This function checks whether the `client' nickname is being watched
1559    by someone, and notifies the watcher of the notify change of notify
1560    type indicated by `notify'. */
1561
1562 bool silc_server_check_watcher_list(SilcServer server,
1563                                     SilcClientEntry client,
1564                                     const char *new_nick,
1565                                     SilcNotifyType notify)
1566 {
1567   unsigned char hash[16];
1568   WatcherNotifyContext n;
1569
1570   SILC_LOG_DEBUG(("Checking watcher list %s",
1571                   client->nickname ? client->nickname : (unsigned char *)""));
1572
1573   /* If the watching is rejected by the client do nothing */
1574   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1575     return FALSE;
1576
1577   /* Make hash from the nick, or take it from Client ID */
1578   if (client->nickname) {
1579     char nick[128 + 1];
1580     memset(nick, 0, sizeof(nick));
1581     silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1582     silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1583   } else {
1584     memset(hash, 0, sizeof(hash));
1585     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1586   }
1587
1588   n.server = server;
1589   n.client = client;
1590   n.new_nick = new_nick;
1591   n.notify = notify;
1592
1593   /* Send notify to all watchers */
1594   silc_hash_table_find_foreach(server->watcher_list, hash,
1595                                silc_server_check_watcher_list_foreach, &n);
1596
1597   return TRUE;
1598 }
1599
1600 /* Remove the `client' from watcher list. After calling this the `client'
1601    is not watching any nicknames. */
1602
1603 bool silc_server_del_from_watcher_list(SilcServer server,
1604                                        SilcClientEntry client)
1605 {
1606   SilcHashTableList htl;
1607   void *key;
1608   SilcClientEntry entry;
1609   bool found = FALSE;
1610
1611   silc_hash_table_list(server->watcher_list, &htl);
1612   while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1613     if (entry == client) {
1614       silc_hash_table_del_by_context(server->watcher_list, key, client);
1615
1616       if (client->id)
1617         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1618                         silc_id_render(client->id, SILC_ID_CLIENT)));
1619
1620       /* Now check whether there still exists entries with this key, if not
1621          then free the key to not leak memory. */
1622       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1623         silc_free(key);
1624
1625       found = TRUE;
1626     }
1627   }
1628   silc_hash_table_list_reset(&htl);
1629
1630   return found;
1631 }
1632
1633 /* Force the client indicated by `chl' to change the channel user mode
1634    on channel indicated by `channel' to `forced_mode'. */
1635
1636 bool silc_server_force_cumode_change(SilcServer server,
1637                                      SilcSocketConnection sock,
1638                                      SilcChannelEntry channel,
1639                                      SilcChannelClientEntry chl,
1640                                      SilcUInt32 forced_mode)
1641 {
1642   SilcBuffer idp1, idp2;
1643   unsigned char cumode[4];
1644
1645   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1646
1647   if (sock)
1648     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1649                                    server->id, SILC_ID_SERVER,
1650                                    chl->client->id, NULL);
1651
1652   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1653   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1654   SILC_PUT32_MSB(forced_mode, cumode);
1655   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1656                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1657                                      3, idp1->data, idp1->len,
1658                                      cumode, sizeof(cumode),
1659                                      idp2->data, idp2->len);
1660   silc_buffer_free(idp1);
1661   silc_buffer_free(idp2);
1662
1663   return TRUE;
1664 }
1665
1666 /* Find active socket connection by the IP address and port indicated by
1667    `ip' and `port', and socket connection type of `type'. */
1668
1669 SilcSocketConnection
1670 silc_server_find_socket_by_host(SilcServer server,
1671                                 SilcSocketType type,
1672                                 const char *ip, SilcUInt16 port)
1673 {
1674   int i;
1675
1676   for (i = 0; i < server->config->param.connections_max; i++) {
1677     if (!server->sockets[i])
1678       continue;
1679     if (!strcmp(server->sockets[i]->ip, ip) &&
1680         (!port || server->sockets[i]->port == port) &&
1681         server->sockets[i]->type == type)
1682       return server->sockets[i];
1683   }
1684
1685   return NULL;
1686 }