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