Fixed Remove Channel User payload parsing.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * Server packet routines to handle received packets.
22  */
23 /* $Id$ */
24
25 #include "serverincludes.h"
26 #include "server_internal.h"
27
28 extern char *server_version;
29
30 /* Received private message. This resolves the destination of the message 
31    and sends the packet. This is used by both server and router.  If the
32    destination is our locally connected client this sends the packet to
33    the client. This may also send the message for further routing if
34    the destination is not in our server (or router). */
35
36 void silc_server_private_message(SilcServer server,
37                                  SilcSocketConnection sock,
38                                  SilcPacketContext *packet)
39 {
40   SilcClientID *id;
41   SilcServerEntry router;
42   SilcSocketConnection dst_sock;
43   SilcClientEntry client;
44   SilcIDListData idata;
45
46   SILC_LOG_DEBUG(("Start"));
47
48   if (!packet->dst_id)
49     goto err;
50
51   /* Decode destination Client ID */
52   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
53   if (!id) {
54     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
55     goto err;
56   }
57
58   /* If the destination belongs to our server we don't have to route
59      the message anywhere but to send it to the local destination. */
60   client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
61   if (client) {
62     /* It exists, now deliver the message to the destination */
63     dst_sock = (SilcSocketConnection)client->connection;
64
65     /* If we are router and the client has router then the client is in
66        our cell but not directly connected to us. */
67     if (server->server_type == SILC_ROUTER && client->router) {
68       /* We are of course in this case the client's router thus the real
69          "router" of the client is the server who owns the client. Thus
70          we will send the packet to that server. */
71       router = (SilcServerEntry)client->router;
72       idata = (SilcIDListData)router;
73
74       silc_server_send_private_message(server, router->connection,
75                                        idata->send_key,
76                                        idata->hmac,
77                                        packet);
78       return;
79     }
80
81     /* Seems that client really is directly connected to us */
82     idata = (SilcIDListData)client;
83     silc_server_send_private_message(server, dst_sock, 
84                                      idata->send_key,
85                                      idata->hmac, packet);
86     return;
87   }
88
89   /* Destination belongs to someone not in this server. If we are normal
90      server our action is to send the packet to our router. */
91   if (server->server_type == SILC_SERVER && !server->standalone) {
92     router = server->router;
93
94     /* Send to primary route */
95     if (router) {
96       dst_sock = (SilcSocketConnection)router->connection;
97       idata = (SilcIDListData)router;
98       silc_server_send_private_message(server, dst_sock, 
99                                        idata->send_key,
100                                        idata->hmac, packet);
101     }
102     return;
103   }
104
105   /* We are router and we will perform route lookup for the destination 
106      and send the message to fastest route. */
107   if (server->server_type == SILC_ROUTER && !server->standalone) {
108     /* Check first that the ID is valid */
109     client = silc_idlist_find_client_by_id(server->global_list, id, NULL);
110     if (client) {
111       dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
112       router = (SilcServerEntry)dst_sock->user_data;
113       idata = (SilcIDListData)router;
114
115       /* Get fastest route and send packet. */
116       if (router)
117         silc_server_send_private_message(server, dst_sock, 
118                                          idata->send_key,
119                                          idata->hmac, packet);
120       return;
121     }
122   }
123
124  err:
125   silc_server_send_error(server, sock, 
126                          "No such nickname: Private message not sent");
127 }
128
129 /* Processes incoming command reply packet. The command reply packet may
130    be destined to one of our clients or it may directly for us. We will 
131    call the command reply routine after processing the packet. */
132
133 void silc_server_command_reply(SilcServer server,
134                                SilcSocketConnection sock,
135                                SilcPacketContext *packet)
136 {
137   SilcBuffer buffer = packet->buffer;
138   SilcClientEntry client = NULL;
139   SilcSocketConnection dst_sock;
140   SilcIDListData idata;
141   SilcClientID *id = NULL;
142
143   SILC_LOG_DEBUG(("Start"));
144
145   /* Source must be server or router */
146   if (packet->src_id_type != SILC_ID_SERVER &&
147       sock->type != SILC_SOCKET_TYPE_ROUTER)
148     return;
149
150   if (packet->dst_id_type == SILC_ID_CHANNEL)
151     return;
152
153   if (packet->dst_id_type == SILC_ID_CLIENT) {
154     /* Destination must be one of ours */
155     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
156     if (!id)
157       return;
158     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
159     if (!client) {
160       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
161       silc_free(id);
162       return;
163     }
164   }
165
166   if (packet->dst_id_type == SILC_ID_SERVER) {
167     /* For now this must be for us */
168     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
169       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
170       return;
171     }
172   }
173
174   /* Execute command reply locally for the command */
175   silc_server_command_reply_process(server, sock, buffer);
176
177   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
178     /* Relay the packet to the client */
179     
180     dst_sock = (SilcSocketConnection)client->connection;
181     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
182                      + packet->dst_id_len + packet->padlen);
183     
184     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
185     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
186     
187     idata = (SilcIDListData)client;
188     
189     /* Encrypt packet */
190     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
191                         buffer->len);
192     
193     /* Send the packet */
194     silc_server_packet_send_real(server, dst_sock, TRUE);
195
196     silc_free(id);
197   }
198 }
199
200 /* Process received channel message. The message can be originated from
201    client or server. */
202
203 void silc_server_channel_message(SilcServer server,
204                                  SilcSocketConnection sock,
205                                  SilcPacketContext *packet)
206 {
207   SilcChannelEntry channel = NULL;
208   SilcChannelClientEntry chl;
209   SilcChannelID *id = NULL;
210   void *sender = NULL;
211
212   SILC_LOG_DEBUG(("Processing channel message"));
213
214   /* Sanity checks */
215   if (packet->dst_id_type != SILC_ID_CHANNEL) {
216     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
217     goto out;
218   }
219
220   /* Find channel entry */
221   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
222   if (!id)
223     goto out;
224   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
225   if (!channel) {
226     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
227     if (!channel) {
228       SILC_LOG_DEBUG(("Could not find channel"));
229       goto out;
230     }
231   }
232
233   /* See that this client is on the channel. If the message is coming
234      from router we won't do the check as the message is from client that
235      we don't know about. Also, if the original sender is not client
236      (as it can be server as well) we don't do the check. */
237   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
238                           packet->src_id_type);
239   if (!sender)
240     goto out;
241   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
242       packet->src_id_type == SILC_ID_CLIENT) {
243     silc_list_start(channel->user_list);
244     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
245       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
246         break;
247     }
248     if (chl == SILC_LIST_END)
249       goto out;
250   }
251
252   /* Distribute the packet to our local clients. This will send the
253      packet for further routing as well, if needed. */
254   silc_server_packet_relay_to_channel(server, sock, channel, sender,
255                                       packet->src_id_type,
256                                       packet->buffer->data,
257                                       packet->buffer->len, FALSE);
258
259  out:
260   if (sender)
261     silc_free(sender);
262   if (id)
263     silc_free(id);
264 }
265
266 /* Received channel key packet. We distribute the key to all of our locally
267    connected clients on the channel. */
268
269 void silc_server_channel_key(SilcServer server,
270                              SilcSocketConnection sock,
271                              SilcPacketContext *packet)
272 {
273   SilcBuffer buffer = packet->buffer;
274   SilcChannelEntry channel;
275
276   if (packet->src_id_type != SILC_ID_SERVER)
277     return;
278
279   /* Save the channel key */
280   channel = silc_server_save_channel_key(server, buffer, NULL);
281   if (!channel)
282     return;
283
284   /* Distribute the key to everybody who is on the channel. If we are router
285      we will also send it to locally connected servers. */
286   silc_server_send_channel_key(server, sock, channel, FALSE);
287 }
288
289 /* Received packet to replace a ID. This checks that the requested ID
290    exists and replaces it with the new one. */
291
292 void silc_server_replace_id(SilcServer server,
293                             SilcSocketConnection sock,
294                             SilcPacketContext *packet)
295 {
296   SilcBuffer buffer = packet->buffer;
297   unsigned char *old_id = NULL, *new_id = NULL;
298   SilcIdType old_id_type, new_id_type;
299   unsigned short old_id_len, new_id_len;
300   void *id = NULL, *id2 = NULL;
301   int ret;
302
303   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
304       packet->src_id_type == SILC_ID_CLIENT)
305     return;
306
307   SILC_LOG_DEBUG(("Replacing ID"));
308
309   ret = silc_buffer_unformat(buffer,
310                              SILC_STR_UI_SHORT(&old_id_type),
311                              SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
312                              SILC_STR_UI_SHORT(&new_id_type),
313                              SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
314                              SILC_STR_END);
315   if (ret == -1)
316     goto out;
317
318   if (old_id_type != new_id_type)
319     goto out;
320
321   if (old_id_len != silc_id_get_len(old_id_type) ||
322       new_id_len != silc_id_get_len(new_id_type))
323     goto out;
324
325   id = silc_id_str2id(old_id, old_id_len, old_id_type);
326   if (!id)
327     goto out;
328
329   id2 = silc_id_str2id(new_id, new_id_len, new_id_type);
330   if (!id2)
331     goto out;
332
333   /* If we are router and this packet is not already broadcast packet
334      we will broadcast it. The sending socket really cannot be router or
335      the router is buggy. If this packet is coming from router then it must
336      have the broadcast flag set already and we won't do anything. */
337   if (!server->standalone && server->server_type == SILC_ROUTER &&
338       sock->type == SILC_SOCKET_TYPE_SERVER &&
339       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
340     SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
341     silc_server_packet_send(server, server->router->connection, packet->type,
342                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
343                             buffer->data, buffer->len, FALSE);
344   }
345
346   /* Replace the old ID */
347   switch(old_id_type) {
348   case SILC_ID_CLIENT:
349     {
350       SilcBuffer nidp, oidp;
351       SilcClientEntry client = NULL;
352
353       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
354                       silc_id_render(id, SILC_ID_CLIENT)));
355       SILC_LOG_DEBUG(("New Client ID id(%s)", 
356                       silc_id_render(id2, SILC_ID_CLIENT)));
357
358       if ((client = silc_idlist_replace_client_id(server->local_list, 
359                                                   id, id2)) == NULL)
360         if (server->server_type == SILC_ROUTER)
361           client = silc_idlist_replace_client_id(server->global_list, id, id2);
362       
363       if (client) {
364         oidp = silc_id_payload_encode(id, SILC_ID_CLIENT);
365         nidp = silc_id_payload_encode(id2, SILC_ID_CLIENT);
366
367         /* The nickname is not valid anymore, set it NULL. This causes that
368            the nickname will be queried if someone wants to know it. */
369         if (client->nickname)
370           silc_free(client->nickname);
371         client->nickname = NULL;
372
373         /* Send the NICK_CHANGE notify type to local clients on the channels
374            this client is joined to. */
375         silc_server_send_notify_on_channels(server, client, 
376                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
377                                             oidp->data, oidp->len, 
378                                             nidp->data, nidp->len);
379         
380         silc_buffer_free(nidp);
381         silc_buffer_free(oidp);
382       }
383       break;
384     }
385
386   case SILC_ID_SERVER:
387     SILC_LOG_DEBUG(("Old Server ID id(%s)", 
388                     silc_id_render(id, SILC_ID_CLIENT)));
389     SILC_LOG_DEBUG(("New Server ID id(%s)", 
390                     silc_id_render(id2, SILC_ID_CLIENT)));
391     if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
392       if (server->server_type == SILC_ROUTER)
393         silc_idlist_replace_server_id(server->global_list, id, id2);
394     break;
395
396   case SILC_ID_CHANNEL:
397     /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
398        re-generated. */
399     silc_free(id2);
400     break;
401
402   default:
403     silc_free(id2);
404     break;
405   }
406
407  out:
408   if (id)
409     silc_free(id);
410   if (old_id)
411     silc_free(old_id);
412   if (new_id)
413     silc_free(new_id);
414 }
415
416
417 /* Received New Client packet and processes it.  Creates Client ID for the
418    client. Client becomes registered after calling this functions. */
419
420 SilcClientEntry silc_server_new_client(SilcServer server,
421                                        SilcSocketConnection sock,
422                                        SilcPacketContext *packet)
423 {
424   SilcBuffer buffer = packet->buffer;
425   SilcClientEntry client;
426   SilcIDCacheEntry cache;
427   SilcClientID *client_id;
428   SilcBuffer reply;
429   SilcIDListData idata;
430   char *username = NULL, *realname = NULL, *id_string;
431   int ret;
432
433   SILC_LOG_DEBUG(("Creating new client"));
434
435   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
436     return NULL;
437
438   /* Take client entry */
439   client = (SilcClientEntry)sock->user_data;
440   idata = (SilcIDListData)client;
441
442   /* Fetch the old client cache entry so that we can update it. */
443   if (!silc_idcache_find_by_context(server->local_list->clients,
444                                     sock->user_data, &cache)) {
445     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
446     return NULL;
447   }
448
449   /* Parse incoming packet */
450   ret = silc_buffer_unformat(buffer,
451                              SILC_STR_UI16_STRING_ALLOC(&username),
452                              SILC_STR_UI16_STRING_ALLOC(&realname),
453                              SILC_STR_END);
454   if (ret == -1) {
455     if (username)
456       silc_free(username);
457     if (realname)
458       silc_free(realname);
459     return NULL;
460   }
461
462   /* Create Client ID */
463   silc_id_create_client_id(server->id, server->rng, server->md5hash,
464                            username, &client_id);
465
466   /* Update client entry */
467   idata->registered = TRUE;
468   client->nickname = strdup(username);
469   client->username = username;
470   client->userinfo = realname;
471   client->id = client_id;
472
473   /* Update the cache entry */
474   cache->id = (void *)client_id;
475   cache->type = SILC_ID_CLIENT;
476   cache->data = username;
477   silc_idcache_sort_by_data(server->local_list->clients);
478
479   /* Notify our router about new client on the SILC network */
480   if (!server->standalone)
481     silc_server_send_new_id(server, (SilcSocketConnection) 
482                             server->router->connection, 
483                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
484                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
485   
486   /* Send the new client ID to the client. */
487   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
488   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
489   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
490   silc_buffer_format(reply,
491                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
492                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
493                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
494                      SILC_STR_END);
495   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
496                           reply->data, reply->len, FALSE);
497   silc_free(id_string);
498   silc_buffer_free(reply);
499
500   /* Send some nice info to the client */
501   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
502                           ("Welcome to the SILC Network %s@%s",
503                            username, sock->hostname));
504   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505                           ("Your host is %s, running version %s",
506                            server->config->server_info->server_name,
507                            server_version));
508   if (server->server_type == SILC_ROUTER) {
509     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
510                             ("There are %d clients on %d servers in SILC "
511                              "Network", server->stat.clients,
512                              server->stat.servers + 1));
513     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514                             ("There are %d clients on %d server in our cell",
515                              server->stat.cell_clients,
516                              server->stat.cell_servers + 1));
517     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
518                             ("I have %d clients, %d channels, %d servers and "
519                              "%d routers",
520                              server->stat.my_clients, 
521                              server->stat.my_channels,
522                              server->stat.my_servers,
523                              server->stat.my_routers));
524     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
525                             ("%d server operators and %d router operators "
526                              "online",
527                              server->stat.my_server_ops,
528                              server->stat.my_router_ops));
529   } else {
530     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
531                             ("I have %d clients and %d channels formed",
532                              server->stat.my_clients,
533                              server->stat.my_channels));
534     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
535                             ("%d operators online",
536                              server->stat.my_server_ops));
537   }
538   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
539                           ("Your connection is secured with %s cipher, "
540                            "key length %d bits",
541                            idata->send_key->cipher->name,
542                            idata->send_key->cipher->key_len));
543   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
544                           ("Your current nickname is %s",
545                            client->nickname));
546
547   /* Send motd */
548   silc_server_send_motd(server, sock);
549
550   return client;
551 }
552
553 /* Create new server. This processes received New Server packet and
554    saves the received Server ID. The server is our locally connected
555    server thus we save all the information and save it to local list. 
556    This funtion can be used by both normal server and router server.
557    If normal server uses this it means that its router has connected
558    to the server. If router uses this it means that one of the cell's
559    servers is connected to the router. */
560
561 SilcServerEntry silc_server_new_server(SilcServer server,
562                                        SilcSocketConnection sock,
563                                        SilcPacketContext *packet)
564 {
565   SilcBuffer buffer = packet->buffer;
566   SilcServerEntry new_server;
567   SilcIDCacheEntry cache;
568   SilcServerID *server_id;
569   SilcIDListData idata;
570   unsigned char *server_name, *id_string;
571   unsigned short id_len;
572   int ret;
573
574   SILC_LOG_DEBUG(("Creating new server"));
575
576   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
577       sock->type != SILC_SOCKET_TYPE_ROUTER)
578     return NULL;
579
580   /* Take server entry */
581   new_server = (SilcServerEntry)sock->user_data;
582   idata = (SilcIDListData)new_server;
583
584   /* Fetch the old server cache entry so that we can update it. */
585   if (!silc_idcache_find_by_context(server->local_list->servers,
586                                     sock->user_data, &cache)) {
587     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
588     return NULL;
589   }
590
591   /* Parse the incoming packet */
592   ret = silc_buffer_unformat(buffer,
593                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
594                              SILC_STR_UI16_STRING_ALLOC(&server_name),
595                              SILC_STR_END);
596   if (ret == -1) {
597     if (id_string)
598       silc_free(id_string);
599     if (server_name)
600       silc_free(server_name);
601     return NULL;
602   }
603
604   if (id_len > buffer->len) {
605     silc_free(id_string);
606     silc_free(server_name);
607     return NULL;
608   }
609
610   /* Get Server ID */
611   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
612   if (!server_id) {
613     silc_free(id_string);
614     silc_free(server_name);
615     return NULL;
616   }
617   silc_free(id_string);
618
619   /* Update client entry */
620   idata->registered = TRUE;
621   new_server->server_name = server_name;
622   new_server->id = server_id;
623
624   /* Update the cache entry */
625   cache->id = (void *)server_id;
626   cache->type = SILC_ID_SERVER;
627   cache->data = server_name;
628   silc_idcache_sort_by_data(server->local_list->servers);
629
630   /* Distribute the information about new server in the SILC network
631      to our router. If we are normal server we won't send anything
632      since this connection must be our router connection. */
633   if (server->server_type == SILC_ROUTER && !server->standalone &&
634       server->router->connection != sock)
635     silc_server_send_new_id(server, server->router->connection,
636                             TRUE, new_server->id, SILC_ID_SERVER, 
637                             SILC_ID_SERVER_LEN);
638
639   if (server->server_type == SILC_ROUTER)
640     server->stat.cell_servers++;
641
642   return new_server;
643 }
644
645 /* Processes incoming New ID packet. New ID Payload is used to distribute
646    information about newly registered clients and servers. */
647
648 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
649                         SilcPacketContext *packet)
650 {
651   SilcBuffer buffer = packet->buffer;
652   SilcIDList id_list;
653   SilcServerEntry router;
654   SilcSocketConnection router_sock;
655   SilcIDPayload idp;
656   SilcIdType id_type;
657   unsigned char *hash = NULL;
658   void *id;
659
660   SILC_LOG_DEBUG(("Processing new ID"));
661
662   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
663       server->server_type == SILC_SERVER ||
664       packet->src_id_type != SILC_ID_SERVER)
665     return;
666
667   idp = silc_id_payload_parse(buffer);
668   if (!idp)
669     return;
670
671   id_type = silc_id_payload_get_type(idp);
672
673   /* Normal server cannot have other normal server connections */
674   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
675     goto out;
676
677   id = silc_id_payload_get_id(idp);
678   if (!id)
679     goto out;
680
681   /* If the sender of this packet is server and we are router we need to
682      broadcast this packet to other routers in the network. */
683   if (!server->standalone && server->server_type == SILC_ROUTER &&
684       sock->type == SILC_SOCKET_TYPE_SERVER &&
685       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
686     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
687     silc_server_packet_send(server, server->router->connection,
688                             packet->type, 
689                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
690                             buffer->data, buffer->len, FALSE);
691   }
692
693   if (sock->type == SILC_SOCKET_TYPE_SERVER)
694     id_list = server->local_list;
695   else
696     id_list = server->global_list;
697
698   router_sock = sock;
699   router = sock->user_data;
700
701   switch(id_type) {
702   case SILC_ID_CLIENT:
703     {
704       SilcClientEntry entry;
705
706       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
707                       silc_id_render(id, SILC_ID_CLIENT),
708                       sock->type == SILC_SOCKET_TYPE_SERVER ?
709                       "Server" : "Router", sock->hostname));
710     
711       /* As a router we keep information of all global information in our
712          global list. Cell wide information however is kept in the local
713          list. The client is put to global list and we will take the hash
714          value of the Client ID and save it to the ID Cache system for fast
715          searching in the future. */
716       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
717                          sizeof(unsigned char));
718       memcpy(hash, ((SilcClientID *)id)->hash, 
719              sizeof(((SilcClientID *)id)->hash));
720       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
721                                      router, NULL);
722       entry->nickname = NULL;
723
724       if (sock->type == SILC_SOCKET_TYPE_SERVER)
725         server->stat.cell_clients++;
726       server->stat.clients++;
727
728 #if 0
729       /* XXX Adding two ID's with same IP number replaces the old entry thus
730          gives wrong route. Thus, now disabled until figured out a better way
731          to do this or when removed the whole thing. This could be removed
732          because entry->router->connection gives always the most optimal route
733          for the ID anyway (unless new routes (faster perhaps) are established
734          after receiving this ID, this we don't know however). */
735       /* Add route cache for this ID */
736       silc_server_route_add(silc_server_route_hash(
737                             ((SilcClientID *)id)->ip.s_addr,
738                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
739                             router);
740 #endif
741     }
742     break;
743
744   case SILC_ID_SERVER:
745     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
746                     silc_id_render(id, SILC_ID_SERVER),
747                     sock->type == SILC_SOCKET_TYPE_SERVER ?
748                     "Server" : "Router", sock->hostname));
749     
750     /* As a router we keep information of all global information in our global
751        list. Cell wide information however is kept in the local list. */
752     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
753
754     if (sock->type == SILC_SOCKET_TYPE_SERVER)
755       server->stat.cell_servers++;
756     server->stat.servers++;
757
758 #if 0
759     /* Add route cache for this ID */
760     silc_server_route_add(silc_server_route_hash(
761                           ((SilcServerID *)id)->ip.s_addr,
762                           ((SilcServerID *)id)->port), 
763                           ((SilcServerID *)id)->ip.s_addr,
764                           router);
765 #endif
766     break;
767
768   case SILC_ID_CHANNEL:
769     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
770     break;
771
772   default:
773     break;
774   }
775
776  out:
777   silc_id_payload_free(idp);
778 }
779
780 /* Received Remove Channel User packet to remove a user from a channel. 
781    Routers notify other routers that user has left a channel. Client must
782    not send this packet. Normal server may send this packet but must not
783    receive it. */
784
785 void silc_server_remove_channel_user(SilcServer server,
786                                      SilcSocketConnection sock,
787                                      SilcPacketContext *packet)
788 {
789   SilcBuffer buffer = packet->buffer;
790   unsigned char *tmp1 = NULL, *tmp2 = NULL;
791   unsigned short tmp1_len, tmp2_len;
792   SilcClientID *client_id = NULL;
793   SilcChannelID *channel_id = NULL;
794   SilcChannelEntry channel;
795   SilcClientEntry client;
796   int ret;
797
798   SILC_LOG_DEBUG(("Removing user from channel"));
799
800   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
801       server->server_type == SILC_SERVER)
802     return;
803
804   ret = silc_buffer_unformat(buffer,
805                              SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
806                              SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
807                              SILC_STR_END);
808   if (ret == -1)
809     goto out;
810
811   client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
812   channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
813   if (!client_id || !channel_id)
814     goto out;
815
816   /* If we are router and this packet is not already broadcast packet
817      we will broadcast it. The sending socket really cannot be router or
818      the router is buggy. If this packet is coming from router then it must
819      have the broadcast flag set already and we won't do anything. */
820   if (!server->standalone && server->server_type == SILC_ROUTER &&
821       sock->type == SILC_SOCKET_TYPE_SERVER &&
822       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
823     SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
824     silc_server_packet_send(server, server->router->connection, packet->type,
825                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
826                             buffer->data, buffer->len, FALSE);
827   }
828
829   /* Get channel entry */
830   channel = silc_idlist_find_channel_by_id(server->local_list, 
831                                            channel_id, NULL);
832   if (!channel) {
833     channel = silc_idlist_find_channel_by_id(server->global_list, 
834                                              channel_id, NULL);
835     if (!channel)
836       goto out;
837   }
838
839   /* Get client entry */
840   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
841   if (!client) {
842     client = silc_idlist_find_client_by_id(server->global_list, 
843                                            client_id, NULL);
844     if (!client)
845       goto out;
846   }
847
848   /* Remove user from channel */
849   silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
850
851  out:
852   if (tmp1)
853     silc_free(tmp1);
854   if (tmp2)
855     silc_free(tmp2);
856   if (client_id)
857     silc_free(client_id);
858   if (channel_id)
859     silc_free(channel_id);
860 }
861
862 /* Received New Channel packet. Information about new channels in the 
863    network are distributed using this packet. Save the information about
864    the new channel. */
865
866 void silc_server_new_channel(SilcServer server,
867                              SilcSocketConnection sock,
868                              SilcPacketContext *packet)
869 {
870   unsigned char *id;
871   SilcChannelID *channel_id;
872   unsigned short channel_id_len;
873   char *channel_name;
874   int ret;
875
876   SILC_LOG_DEBUG(("Processing New Channel"));
877
878   if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
879       server->server_type == SILC_SERVER ||
880       packet->src_id_type != SILC_ID_SERVER)
881     return;
882
883   /* Parse payload */
884   ret = silc_buffer_unformat(packet->buffer, 
885                              SILC_STR_UI16_STRING_ALLOC(&channel_name),
886                              SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
887                              SILC_STR_END);
888   if (ret == -1) {
889     if (channel_name)
890       silc_free(channel_name);
891     if (id)
892       silc_free(id);
893     return;
894   }
895     
896   /* Decode the channel ID */
897   channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
898   if (!channel_id)
899     return;
900   silc_free(id);
901
902   SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
903                   silc_id_render(channel_id, SILC_ID_CHANNEL), 
904                   sock->hostname));
905
906   /* Add the new channel. Add it always to global list since if we receive
907      this packet then it cannot be created by ourselves but some other 
908      router hence global channel. */
909   silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
910                           server->router->connection, NULL);
911
912   server->stat.channels++;
913 }
914
915 /* Received notify packet. Server can receive notify packets from router. 
916    Server then relays the notify messages to clients if needed. */
917
918 void silc_server_notify(SilcServer server,
919                         SilcSocketConnection sock,
920                         SilcPacketContext *packet)
921 {
922   SilcNotifyPayload payload;
923   SilcNotifyType type;
924   SilcArgumentPayload args;
925   SilcChannelID *channel_id;
926   SilcClientID *client_id, *client_id2;
927   SilcChannelEntry channel;
928   SilcClientEntry client;
929   unsigned char *tmp;
930   unsigned int tmp_len;
931
932   SILC_LOG_DEBUG(("Start"));
933
934   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
935       packet->src_id_type != SILC_ID_SERVER)
936     return;
937
938   /* XXX: For now we expect that the we are normal server and that the
939      sender is router. Server could send (protocol allows it) notify to
940      router but we don't support it yet. */
941   if (server->server_type != SILC_SERVER &&
942       sock->type != SILC_SOCKET_TYPE_ROUTER)
943     return;
944
945   payload = silc_notify_payload_parse(packet->buffer);
946   if (!payload)
947     return;
948
949   type = silc_notify_get_type(payload);
950   args = silc_notify_get_args(payload);
951   if (!args)
952     goto out;
953
954   switch(type) {
955   case SILC_NOTIFY_TYPE_JOIN:
956     /* 
957      * Distribute the notify to local clients on the channel
958      */
959     SILC_LOG_DEBUG(("JOIN notify"));
960
961     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
962                                 packet->dst_id_type);
963     if (!channel_id)
964       goto out;
965
966     /* Get channel entry */
967     channel = silc_idlist_find_channel_by_id(server->local_list, 
968                                              channel_id, NULL);
969     if (!channel) {
970       silc_free(channel_id);
971       goto out;
972     }
973
974     /* Get client ID */
975     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
976     if (!tmp) {
977       silc_free(channel_id);
978       goto out;
979     }
980     client_id = silc_id_payload_parse_id(tmp, tmp_len);
981     if (!client_id) {
982       silc_free(channel_id);
983       goto out;
984     }
985
986     /* Send to channel */
987     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
988                                        FALSE, packet->buffer->data, 
989                                        packet->buffer->len, FALSE);
990
991     /* If the the client is not in local list we check global list (ie. the
992        channel will be global channel) and if it does not exist then create
993        entry for the client. */
994     client = silc_idlist_find_client_by_id(server->local_list, 
995                                            client_id, NULL);
996     if (!client) {
997       SilcChannelClientEntry chl;
998
999       client = silc_idlist_find_client_by_id(server->global_list, 
1000                                              client_id, NULL);
1001       if (!client) {
1002         client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
1003                                         client_id, sock->user_data, NULL);
1004         if (!client) {
1005           silc_free(channel_id);
1006           silc_free(client_id);
1007           goto out;
1008         }
1009       }
1010
1011       /* The channel is global now */
1012       channel->global_users = TRUE;
1013
1014       /* Now actually JOIN the global client to the channel */
1015       chl = silc_calloc(1, sizeof(*chl));
1016       chl->client = client;
1017       chl->channel = channel;
1018       silc_list_add(channel->user_list, chl);
1019       silc_list_add(client->channels, chl);
1020     } else {
1021       silc_free(client_id);
1022     }
1023     break;
1024
1025   case SILC_NOTIFY_TYPE_LEAVE:
1026     /* 
1027      * Distribute the notify to local clients on the channel
1028      */
1029     SILC_LOG_DEBUG(("LEAVE notify"));
1030
1031     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1032                                 packet->dst_id_type);
1033     if (!channel_id)
1034       goto out;
1035
1036     /* Get channel entry */
1037     channel = silc_idlist_find_channel_by_id(server->local_list, 
1038                                              channel_id, NULL);
1039     if (!channel) { 
1040       silc_free(channel_id);
1041       goto out;
1042     }
1043
1044     /* Get client ID */
1045     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1046     if (!tmp) {
1047       silc_free(channel_id);
1048       goto out;
1049     }
1050     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1051     if (!client_id) {
1052       silc_free(channel_id);
1053       goto out;
1054     }
1055
1056     /* Send to channel */
1057     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1058                                        FALSE, packet->buffer->data, 
1059                                        packet->buffer->len, FALSE);
1060
1061     /* Get client entry */
1062     client = silc_idlist_find_client_by_id(server->global_list, 
1063                                            client_id, NULL);
1064     if (!client) {
1065       client = silc_idlist_find_client_by_id(server->local_list, 
1066                                              client_id, NULL);
1067       if (!client) {
1068         silc_free(client_id);
1069         silc_free(channel_id);
1070         goto out;
1071       }
1072     }
1073     silc_free(client_id);
1074
1075     /* Remove the user from channel */
1076     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1077     break;
1078
1079   case SILC_NOTIFY_TYPE_SIGNOFF:
1080     /* 
1081      * Distribute the notify to local clients on the channel
1082      */
1083     SILC_LOG_DEBUG(("SIGNOFF notify"));
1084
1085     /* Get client ID */
1086     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1087     if (!tmp)
1088       goto out;
1089     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1090     if (!client_id)
1091       goto out;
1092
1093     /* Get client entry */
1094     client = silc_idlist_find_client_by_id(server->global_list, 
1095                                            client_id, NULL);
1096     if (!client) {
1097       client = silc_idlist_find_client_by_id(server->local_list, 
1098                                              client_id, NULL);
1099       if (!client) {
1100         silc_free(client_id);
1101         goto out;
1102       }
1103     }
1104     silc_free(client_id);
1105
1106     /* Remove the client from all channels */
1107     silc_server_remove_from_channels(server, NULL, client);
1108
1109     /* Remove the client entry */
1110     silc_idlist_del_client(server->global_list, client);
1111     break;
1112
1113   case SILC_NOTIFY_TYPE_NICK_CHANGE:
1114     {
1115       /* 
1116        * Distribute the notify to local clients on the channel
1117        */
1118       unsigned char *id, *id2;
1119
1120       SILC_LOG_DEBUG(("NICK CHANGE notify"));
1121       
1122       /* Get old client ID */
1123       id = silc_argument_get_arg_type(args, 1, &tmp_len);
1124       if (!id)
1125         goto out;
1126       client_id = silc_id_payload_parse_id(id, tmp_len);
1127       if (!client_id)
1128         goto out;
1129       
1130       /* Get new client ID */
1131       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1132       if (!id2)
1133         goto out;
1134       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1135       if (!client_id2)
1136         goto out;
1137       
1138       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
1139                       silc_id_render(client_id, SILC_ID_CLIENT)));
1140       SILC_LOG_DEBUG(("New Client ID id(%s)", 
1141                       silc_id_render(client_id2, SILC_ID_CLIENT)));
1142
1143       /* Replace the Client ID */
1144       client = silc_idlist_replace_client_id(server->global_list, client_id,
1145                                              client_id2);
1146       if (!client)
1147         client = silc_idlist_replace_client_id(server->local_list, client_id, 
1148                                                client_id2);
1149
1150       if (client)
1151         /* Send the NICK_CHANGE notify type to local clients on the channels
1152            this client is joined to. */
1153         silc_server_send_notify_on_channels(server, client, 
1154                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1155                                             id, tmp_len, 
1156                                             id2, tmp_len);
1157
1158       silc_free(client_id);
1159       if (!client)
1160         silc_free(client_id2);
1161       break;
1162     }
1163   case SILC_NOTIFY_TYPE_TOPIC_SET:
1164     /* 
1165      * Distribute the notify to local clients on the channel
1166      */
1167     SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
1168     break;
1169
1170   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1171     /* 
1172      * Distribute the notify to local clients on the channel
1173      */
1174     SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
1175     break;
1176
1177   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1178     /* 
1179      * Distribute the notify to local clients on the channel
1180      */
1181     SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
1182     break;
1183
1184     /* Ignore rest notify types for now */
1185   case SILC_NOTIFY_TYPE_NONE:
1186   case SILC_NOTIFY_TYPE_INVITE:
1187   case SILC_NOTIFY_TYPE_MOTD:
1188   default:
1189     break;
1190   }
1191
1192  out:
1193   silc_notify_payload_free(payload);
1194 }
1195
1196 /* Received new channel user packet. Information about new users on a
1197    channel are distributed between routers using this packet.  The
1198    router receiving this will redistribute it and also sent JOIN notify
1199    to local clients on the same channel. Normal server sends JOIN notify
1200    to its local clients on the channel. */
1201
1202 void silc_server_new_channel_user(SilcServer server,
1203                                   SilcSocketConnection sock,
1204                                   SilcPacketContext *packet)
1205 {
1206   unsigned char *tmpid1, *tmpid2;
1207   SilcClientID *client_id = NULL;
1208   SilcChannelID *channel_id = NULL;
1209   unsigned short channel_id_len;
1210   unsigned short client_id_len;
1211   SilcClientEntry client;
1212   SilcChannelEntry channel;
1213   SilcChannelClientEntry chl;
1214   SilcBuffer clidp;
1215   int ret;
1216
1217   SILC_LOG_DEBUG(("Start"));
1218
1219   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1220       server->server_type != SILC_ROUTER ||
1221       packet->src_id_type != SILC_ID_SERVER)
1222     return;
1223
1224   /* Parse payload */
1225   ret = silc_buffer_unformat(packet->buffer, 
1226                              SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
1227                                                          &channel_id_len),
1228                              SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
1229                                                          &client_id_len),
1230                              SILC_STR_END);
1231   if (ret == -1) {
1232     if (tmpid1)
1233       silc_free(tmpid1);
1234     if (tmpid2)
1235       silc_free(tmpid2);
1236     return;
1237   }
1238
1239   /* Decode the channel ID */
1240   channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1241   if (!channel_id)
1242     goto out;
1243
1244   /* Decode the client ID */
1245   client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1246   if (!client_id)
1247     goto out;
1248
1249   /* Find the channel */
1250   channel = silc_idlist_find_channel_by_id(server->local_list, 
1251                                            channel_id, NULL);
1252   if (!channel) {
1253     channel = silc_idlist_find_channel_by_id(server->global_list, 
1254                                              channel_id, NULL);
1255     if (!channel)
1256       goto out;
1257   }
1258
1259   /* If we are router and this packet is not already broadcast packet
1260      we will broadcast it. */
1261   if (!server->standalone && server->server_type == SILC_ROUTER &&
1262       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1263     SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1264     silc_server_packet_send(server, server->router->connection, packet->type,
1265                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1266                             packet->buffer->data, packet->buffer->len, FALSE);
1267   }
1268
1269   /* Get client entry */
1270   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1271   if (!client) {
1272     client = silc_idlist_find_client_by_id(server->global_list, 
1273                                            client_id, NULL);
1274     if (!client)
1275       goto out;
1276   }
1277
1278   /* Join the client to the channel by adding it to channel's user list.
1279      Add also the channel to client entry's channels list for fast cross-
1280      referencing. */
1281   chl = silc_calloc(1, sizeof(*chl));
1282   chl->client = client;
1283   chl->channel = channel;
1284   silc_list_add(channel->user_list, chl);
1285   silc_list_add(client->channels, chl);
1286
1287   server->stat.chanclients++;
1288
1289   /* Send JOIN notify to local clients on the channel. As we are router
1290      it is assured that this is sent only to our local clients and locally
1291      connected servers if needed. */
1292   clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1293   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1294                                      SILC_NOTIFY_TYPE_JOIN, 
1295                                      1, clidp->data, clidp->len);
1296   silc_buffer_free(clidp);
1297
1298   client_id = NULL;
1299
1300  out:
1301   if (client_id)
1302     silc_free(client_id);
1303   if (channel_id)
1304     silc_free(channel_id);
1305   silc_free(tmpid1);
1306   silc_free(tmpid2);
1307 }
1308
1309 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1310    that certain ID should be removed. After that the ID will become invalid. */
1311
1312 void silc_server_remove_id(SilcServer server,
1313                            SilcSocketConnection sock,
1314                            SilcPacketContext *packet)
1315 {
1316   SilcIDList id_list;
1317   SilcIDPayload idp;
1318   SilcIdType id_type;
1319   void *id, *id_entry;
1320
1321   SILC_LOG_DEBUG(("Start"));
1322
1323   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1324       server->server_type == SILC_SERVER ||
1325       packet->src_id_type != SILC_ID_SERVER)
1326     return;
1327
1328   idp = silc_id_payload_parse(packet->buffer);
1329   if (!idp)
1330     return;
1331
1332   id_type = silc_id_payload_get_type(idp);
1333
1334   id = silc_id_payload_get_id(idp);
1335   if (!id)
1336     goto out;
1337
1338   /* If the sender of this packet is server and we are router we need to
1339      broadcast this packet to other routers in the network. */
1340   if (!server->standalone && server->server_type == SILC_ROUTER &&
1341       sock->type == SILC_SOCKET_TYPE_SERVER &&
1342       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1343     SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1344     silc_server_packet_send(server, server->router->connection,
1345                             packet->type, 
1346                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1347                             packet->buffer->data, packet->buffer->len, FALSE);
1348   }
1349
1350   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1351     id_list = server->local_list;
1352   else
1353     id_list = server->global_list;
1354
1355   /* Remove the ID */
1356   switch (id_type) {
1357   case SILC_ID_CLIENT:
1358     id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id, 
1359                                              NULL);
1360     if (id_entry) {
1361       /* Remove from channels */
1362       silc_server_remove_from_channels(server, NULL, id_entry);
1363
1364       /* Remove the client entry */
1365       silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1366       server->stat.clients--;
1367       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1368           server->server_type == SILC_ROUTER)
1369         server->stat.cell_clients--;
1370
1371       SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1372                       silc_id_render(id, SILC_ID_CLIENT),
1373                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1374                       "Server" : "Router", sock->hostname));
1375     }
1376     break;
1377
1378   case SILC_ID_SERVER:
1379     id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1380                                              NULL);
1381     if (id_entry) {
1382       silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1383       server->stat.servers--;
1384       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1385           server->server_type == SILC_ROUTER)
1386         server->stat.cell_servers--;
1387
1388       SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1389                       silc_id_render(id, SILC_ID_SERVER),
1390                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1391                       "Server" : "Router", sock->hostname));
1392     }
1393     break;
1394
1395   case SILC_ID_CHANNEL:
1396     id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1397                                               NULL);
1398     if (id_entry) {
1399       silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1400       server->stat.channels--;
1401       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1402           server->server_type == SILC_ROUTER)
1403         server->stat.cell_channels--;
1404
1405       SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1406                       silc_id_render(id, SILC_ID_CHANNEL),
1407                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1408                       "Server" : "Router", sock->hostname));
1409     }
1410     break;
1411
1412   default:
1413     break;
1414   }
1415
1416  out:
1417   silc_id_payload_free(idp);
1418 }
1419
1420 /* Processes received SET_MODE packet. The packet is used to distribute
1421    the information about changed channel's or client's channel modes. */
1422
1423 void silc_server_set_mode(SilcServer server,
1424                           SilcSocketConnection sock,
1425                           SilcPacketContext *packet)
1426 {
1427   SilcSetModePayload payload = NULL;
1428   SilcArgumentPayload args = NULL;
1429   unsigned short mode_type;
1430   unsigned int mode_mask;
1431   unsigned char *tmp, *tmp2;
1432   unsigned int tmp_len, tmp_len2;
1433   unsigned char mode[4];
1434   SilcClientID *client_id;
1435   SilcChannelID *channel_id = NULL;
1436   SilcClientEntry client;
1437   SilcChannelEntry channel;
1438   SilcChannelClientEntry chl;
1439
1440   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1441       packet->src_id_type == SILC_ID_CLIENT)
1442     return;
1443
1444   SILC_LOG_DEBUG(("Start"));
1445
1446   /* If we are router and this packet is not already broadcast packet
1447      we will broadcast it. The sending socket really cannot be router or
1448      the router is buggy. If this packet is coming from router then it must
1449      have the broadcast flag set already and we won't do anything. */
1450   if (!server->standalone && server->server_type == SILC_ROUTER &&
1451       sock->type == SILC_SOCKET_TYPE_SERVER &&
1452       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1453     SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1454     silc_server_packet_send(server, server->router->connection, packet->type,
1455                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1456                             packet->buffer->data, packet->buffer->len, FALSE);
1457   }
1458
1459   /* Parse Set Mode payload */
1460   payload = silc_set_mode_payload_parse(packet->buffer);
1461   if (!payload)
1462     return;
1463
1464   mode_type = silc_set_mode_get_type(payload);
1465   args = silc_set_mode_get_args(payload);
1466   if (!args)
1467     goto out;
1468
1469   mode_mask = silc_set_mode_get_mode(payload);
1470   SILC_PUT32_MSB(mode_mask, mode);
1471
1472   switch (mode_type) {
1473   case SILC_MODE_TYPE_CHANNEL:
1474     /* Get Channel ID */
1475     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1476     if (!tmp)
1477       goto out;
1478     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1479     if (!channel_id)
1480       goto out;
1481
1482     /* Get channel entry */
1483     channel = silc_idlist_find_channel_by_id(server->local_list, 
1484                                              channel_id, NULL);
1485     if (!channel) {
1486       channel = silc_idlist_find_channel_by_id(server->global_list, 
1487                                                channel_id, NULL);
1488       if (!channel)
1489         goto out;
1490     }
1491
1492     /* Get Client ID payload */
1493     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1494     if (!tmp)
1495       goto out;
1496
1497     /* Send CMODE_CHANGE notify to local channel */
1498     silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1499                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 
1500                                        2, tmp, tmp_len,
1501                                        mode, sizeof(mode));
1502
1503     /* Change the mode */
1504     channel->mode = mode_mask;
1505     break;
1506
1507   case SILC_MODE_TYPE_UCHANNEL:
1508     /* Get Channel ID */
1509     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1510     if (!tmp)
1511       goto out;
1512     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1513     if (!channel_id)
1514       goto out;
1515
1516     /* Get channel entry */
1517     channel = silc_idlist_find_channel_by_id(server->local_list, 
1518                                              channel_id, NULL);
1519     if (!channel) {
1520       channel = silc_idlist_find_channel_by_id(server->global_list, 
1521                                                channel_id, NULL);
1522       if (!channel)
1523         goto out;
1524     }
1525
1526     /* Get Client ID payload */
1527     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1528     if (!tmp)
1529       goto out;
1530
1531     /* Get target Client ID */
1532     tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
1533     if (!tmp2)
1534       goto out;
1535     client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
1536     if (!client_id)
1537       goto out;
1538
1539     /* Get target client entry */
1540     client = silc_idlist_find_client_by_id(server->global_list, 
1541                                            client_id, NULL);
1542     if (!client) {
1543       client = silc_idlist_find_client_by_id(server->local_list, 
1544                                              client_id, NULL);
1545       if (!client) {
1546         silc_free(client_id);
1547         goto out;
1548       }
1549     }
1550     silc_free(client_id);
1551
1552     /* Send CUMODE_CHANGE notify to local channel */
1553     silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1554                                        SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2, 
1555                                        tmp, tmp_len,
1556                                        mode, sizeof(mode),
1557                                        tmp2, tmp_len2);
1558
1559     /* Get entry to the channel user list */
1560     silc_list_start(channel->user_list);
1561     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1562       if (chl->client == client) {
1563         /* Change the mode */
1564         chl->mode = mode_mask;
1565         break;
1566       }
1567
1568     break;
1569
1570   default:
1571     break;
1572   }
1573
1574  out:
1575   if (channel_id)
1576     silc_free(channel_id);
1577   if (args)
1578     silc_argument_payload_free(args);
1579   if (payload)
1580     silc_set_mode_payload_free(payload);
1581 }