updates.
[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_SERVER)));
389     SILC_LOG_DEBUG(("New Server ID id(%s)", 
390                     silc_id_render(id2, SILC_ID_SERVER)));
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     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
398                     silc_id_render(id, SILC_ID_CHANNEL)));
399     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
400                     silc_id_render(id2, SILC_ID_CHANNEL)));
401     if (silc_idlist_replace_channel_id(server->local_list, id, id2) == NULL)
402       silc_idlist_replace_channel_id(server->global_list, id, id2);
403     break;
404
405   default:
406     silc_free(id2);
407     break;
408   }
409
410  out:
411   if (id)
412     silc_free(id);
413   if (old_id)
414     silc_free(old_id);
415   if (new_id)
416     silc_free(new_id);
417 }
418
419
420 /* Received New Client packet and processes it.  Creates Client ID for the
421    client. Client becomes registered after calling this functions. */
422
423 SilcClientEntry silc_server_new_client(SilcServer server,
424                                        SilcSocketConnection sock,
425                                        SilcPacketContext *packet)
426 {
427   SilcBuffer buffer = packet->buffer;
428   SilcClientEntry client;
429   SilcIDCacheEntry cache;
430   SilcClientID *client_id;
431   SilcBuffer reply;
432   SilcIDListData idata;
433   char *username = NULL, *realname = NULL, *id_string;
434   int ret;
435
436   SILC_LOG_DEBUG(("Creating new client"));
437
438   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
439     return NULL;
440
441   /* Take client entry */
442   client = (SilcClientEntry)sock->user_data;
443   idata = (SilcIDListData)client;
444
445   /* Fetch the old client cache entry so that we can update it. */
446   if (!silc_idcache_find_by_context(server->local_list->clients,
447                                     sock->user_data, &cache)) {
448     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
449     return NULL;
450   }
451
452   /* Parse incoming packet */
453   ret = silc_buffer_unformat(buffer,
454                              SILC_STR_UI16_STRING_ALLOC(&username),
455                              SILC_STR_UI16_STRING_ALLOC(&realname),
456                              SILC_STR_END);
457   if (ret == -1) {
458     if (username)
459       silc_free(username);
460     if (realname)
461       silc_free(realname);
462     return NULL;
463   }
464
465   if (!username) {
466     silc_free(username);
467     if (realname)
468       silc_free(realname);
469     silc_server_disconnect_remote(server, sock, "Server closed connection: "
470                                   "Incomplete client information");
471     return NULL;
472   }
473
474   /* Create Client ID */
475   silc_id_create_client_id(server->id, server->rng, server->md5hash,
476                            username, &client_id);
477
478   /* Update client entry */
479   idata->registered = TRUE;
480   client->nickname = strdup(username);
481   client->username = username;
482   client->userinfo = realname ? realname : strdup("");
483   client->id = client_id;
484
485   /* Update the cache entry */
486   cache->id = (void *)client_id;
487   cache->type = SILC_ID_CLIENT;
488   cache->data = username;
489   silc_idcache_sort_by_data(server->local_list->clients);
490
491   /* Notify our router about new client on the SILC network */
492   if (!server->standalone)
493     silc_server_send_new_id(server, (SilcSocketConnection) 
494                             server->router->connection, 
495                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
496                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
497   
498   /* Send the new client ID to the client. */
499   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
500   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
501   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
502   silc_buffer_format(reply,
503                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
504                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
505                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
506                      SILC_STR_END);
507   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
508                           reply->data, reply->len, FALSE);
509   silc_free(id_string);
510   silc_buffer_free(reply);
511
512   /* Send some nice info to the client */
513   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
514                           ("Welcome to the SILC Network %s@%s",
515                            username, sock->hostname));
516   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
517                           ("Your host is %s, running version %s",
518                            server->config->server_info->server_name,
519                            server_version));
520   if (server->server_type == SILC_ROUTER) {
521     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
522                             ("There are %d clients on %d servers in SILC "
523                              "Network", server->stat.clients,
524                              server->stat.servers + 1));
525     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
526                             ("There are %d clients on %d server in our cell",
527                              server->stat.cell_clients,
528                              server->stat.cell_servers + 1));
529     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
530                             ("I have %d clients, %d channels, %d servers and "
531                              "%d routers",
532                              server->stat.my_clients, 
533                              server->stat.my_channels,
534                              server->stat.my_servers,
535                              server->stat.my_routers));
536     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
537                             ("%d server operators and %d router operators "
538                              "online",
539                              server->stat.my_server_ops,
540                              server->stat.my_router_ops));
541   } else {
542     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
543                             ("I have %d clients and %d channels formed",
544                              server->stat.my_clients,
545                              server->stat.my_channels));
546     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
547                             ("%d operators online",
548                              server->stat.my_server_ops));
549   }
550   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
551                           ("Your connection is secured with %s cipher, "
552                            "key length %d bits",
553                            idata->send_key->cipher->name,
554                            idata->send_key->cipher->key_len));
555   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
556                           ("Your current nickname is %s",
557                            client->nickname));
558
559   /* Send motd */
560   silc_server_send_motd(server, sock);
561
562   return client;
563 }
564
565 /* Create new server. This processes received New Server packet and
566    saves the received Server ID. The server is our locally connected
567    server thus we save all the information and save it to local list. 
568    This funtion can be used by both normal server and router server.
569    If normal server uses this it means that its router has connected
570    to the server. If router uses this it means that one of the cell's
571    servers is connected to the router. */
572
573 SilcServerEntry silc_server_new_server(SilcServer server,
574                                        SilcSocketConnection sock,
575                                        SilcPacketContext *packet)
576 {
577   SilcBuffer buffer = packet->buffer;
578   SilcServerEntry new_server;
579   SilcIDCacheEntry cache;
580   SilcServerID *server_id;
581   SilcIDListData idata;
582   unsigned char *server_name, *id_string;
583   unsigned short id_len;
584   int ret;
585
586   SILC_LOG_DEBUG(("Creating new server"));
587
588   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
589       sock->type != SILC_SOCKET_TYPE_ROUTER)
590     return NULL;
591
592   /* Take server entry */
593   new_server = (SilcServerEntry)sock->user_data;
594   idata = (SilcIDListData)new_server;
595
596   /* Fetch the old server cache entry so that we can update it. */
597   if (!silc_idcache_find_by_context(server->local_list->servers,
598                                     sock->user_data, &cache)) {
599     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
600     return NULL;
601   }
602
603   /* Parse the incoming packet */
604   ret = silc_buffer_unformat(buffer,
605                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
606                              SILC_STR_UI16_STRING_ALLOC(&server_name),
607                              SILC_STR_END);
608   if (ret == -1) {
609     if (id_string)
610       silc_free(id_string);
611     if (server_name)
612       silc_free(server_name);
613     return NULL;
614   }
615
616   if (id_len > buffer->len) {
617     silc_free(id_string);
618     silc_free(server_name);
619     return NULL;
620   }
621
622   /* Get Server ID */
623   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
624   if (!server_id) {
625     silc_free(id_string);
626     silc_free(server_name);
627     return NULL;
628   }
629   silc_free(id_string);
630
631   /* Update client entry */
632   idata->registered = TRUE;
633   new_server->server_name = server_name;
634   new_server->id = server_id;
635
636   /* Update the cache entry */
637   cache->id = (void *)server_id;
638   cache->type = SILC_ID_SERVER;
639   cache->data = server_name;
640   silc_idcache_sort_by_data(server->local_list->servers);
641
642   /* Distribute the information about new server in the SILC network
643      to our router. If we are normal server we won't send anything
644      since this connection must be our router connection. */
645   if (server->server_type == SILC_ROUTER && !server->standalone &&
646       server->router->connection != sock)
647     silc_server_send_new_id(server, server->router->connection,
648                             TRUE, new_server->id, SILC_ID_SERVER, 
649                             SILC_ID_SERVER_LEN);
650
651   if (server->server_type == SILC_ROUTER)
652     server->stat.cell_servers++;
653
654   return new_server;
655 }
656
657 /* Processes incoming New ID packet. New ID Payload is used to distribute
658    information about newly registered clients and servers. */
659
660 static void silc_server_new_id_real(SilcServer server, 
661                                     SilcSocketConnection sock,
662                                     SilcPacketContext *packet,
663                                     int broadcast)
664 {
665   SilcBuffer buffer = packet->buffer;
666   SilcIDList id_list;
667   SilcServerEntry router;
668   SilcSocketConnection router_sock;
669   SilcIDPayload idp;
670   SilcIdType id_type;
671   unsigned char *hash = NULL;
672   void *id;
673
674   SILC_LOG_DEBUG(("Processing new ID"));
675
676   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
677       server->server_type == SILC_SERVER ||
678       packet->src_id_type != SILC_ID_SERVER)
679     return;
680
681   idp = silc_id_payload_parse(buffer);
682   if (!idp)
683     return;
684
685   id_type = silc_id_payload_get_type(idp);
686
687   /* Normal server cannot have other normal server connections */
688   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
689     goto out;
690
691   id = silc_id_payload_get_id(idp);
692   if (!id)
693     goto out;
694
695   /* If the sender of this packet is server and we are router we need to
696      broadcast this packet to other routers in the network. */
697   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
698       sock->type == SILC_SOCKET_TYPE_SERVER &&
699       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
700     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
701     silc_server_packet_send(server, server->router->connection,
702                             packet->type, 
703                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
704                             buffer->data, buffer->len, FALSE);
705   }
706
707   if (sock->type == SILC_SOCKET_TYPE_SERVER)
708     id_list = server->local_list;
709   else
710     id_list = server->global_list;
711
712   router_sock = sock;
713   router = sock->user_data;
714
715   switch(id_type) {
716   case SILC_ID_CLIENT:
717     {
718       SilcClientEntry entry;
719
720       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
721                       silc_id_render(id, SILC_ID_CLIENT),
722                       sock->type == SILC_SOCKET_TYPE_SERVER ?
723                       "Server" : "Router", sock->hostname));
724     
725       /* As a router we keep information of all global information in our
726          global list. Cell wide information however is kept in the local
727          list. The client is put to global list and we will take the hash
728          value of the Client ID and save it to the ID Cache system for fast
729          searching in the future. */
730       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
731                          sizeof(unsigned char));
732       memcpy(hash, ((SilcClientID *)id)->hash, 
733              sizeof(((SilcClientID *)id)->hash));
734       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
735                                      router, NULL);
736       entry->nickname = NULL;
737
738       if (sock->type == SILC_SOCKET_TYPE_SERVER)
739         server->stat.cell_clients++;
740       server->stat.clients++;
741
742 #if 0
743       /* XXX Adding two ID's with same IP number replaces the old entry thus
744          gives wrong route. Thus, now disabled until figured out a better way
745          to do this or when removed the whole thing. This could be removed
746          because entry->router->connection gives always the most optimal route
747          for the ID anyway (unless new routes (faster perhaps) are established
748          after receiving this ID, this we don't know however). */
749       /* Add route cache for this ID */
750       silc_server_route_add(silc_server_route_hash(
751                             ((SilcClientID *)id)->ip.s_addr,
752                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
753                             router);
754 #endif
755     }
756     break;
757
758   case SILC_ID_SERVER:
759     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
760                     silc_id_render(id, SILC_ID_SERVER),
761                     sock->type == SILC_SOCKET_TYPE_SERVER ?
762                     "Server" : "Router", sock->hostname));
763     
764     /* As a router we keep information of all global information in our global
765        list. Cell wide information however is kept in the local list. */
766     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
767
768     if (sock->type == SILC_SOCKET_TYPE_SERVER)
769       server->stat.cell_servers++;
770     server->stat.servers++;
771
772 #if 0
773     /* Add route cache for this ID */
774     silc_server_route_add(silc_server_route_hash(
775                           ((SilcServerID *)id)->ip.s_addr,
776                           ((SilcServerID *)id)->port), 
777                           ((SilcServerID *)id)->ip.s_addr,
778                           router);
779 #endif
780     break;
781
782   case SILC_ID_CHANNEL:
783     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
784     break;
785
786   default:
787     break;
788   }
789
790  out:
791   silc_id_payload_free(idp);
792 }
793
794
795 /* Processes incoming New ID packet. New ID Payload is used to distribute
796    information about newly registered clients and servers. */
797
798 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
799                         SilcPacketContext *packet)
800 {
801   silc_server_new_id_real(server, sock, packet, TRUE);
802 }
803
804 /* Receoved New Id List packet, list of New ID payloads inside one
805    packet. Process the New ID payloads one by one. */
806
807 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
808                              SilcPacketContext *packet)
809 {
810   SilcPacketContext *new_id;
811   SilcBuffer idp;
812   unsigned short id_len;
813
814   SILC_LOG_DEBUG(("Processing New ID List"));
815
816   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
817       packet->src_id_type != SILC_ID_SERVER)
818     return;
819
820   /* If the sender of this packet is server and we are router we need to
821      broadcast this packet to other routers in the network. Broadcast
822      this list packet instead of multiple New ID packets. */
823   if (!server->standalone && server->server_type == SILC_ROUTER &&
824       sock->type == SILC_SOCKET_TYPE_SERVER &&
825       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
826     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
827     silc_server_packet_send(server, server->router->connection,
828                             packet->type, 
829                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
830                             packet->buffer->data, packet->buffer->len, FALSE);
831   }
832
833   /* Make copy of the original packet context, except for the actual
834      data buffer, which we will here now fetch from the original buffer. */
835   new_id = silc_packet_context_alloc();
836   new_id->type = SILC_PACKET_NEW_ID;
837   new_id->flags = packet->flags;
838   new_id->src_id = packet->src_id;
839   new_id->src_id_len = packet->src_id_len;
840   new_id->src_id_type = packet->src_id_type;
841   new_id->dst_id = packet->dst_id;
842   new_id->dst_id_len = packet->dst_id_len;
843   new_id->dst_id_type = packet->dst_id_type;
844
845   idp = silc_buffer_alloc(256);
846   new_id->buffer = idp;
847
848   while (packet->buffer->len) {
849     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
850     if ((id_len > packet->buffer->len) ||
851         (id_len > idp->truelen))
852       break;
853
854     silc_buffer_pull_tail(idp, 4 + id_len);
855     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
856
857     /* Process the New ID */
858     silc_server_new_id_real(server, sock, new_id, FALSE);
859
860     silc_buffer_push_tail(idp, 4 + id_len);
861     silc_buffer_pull(packet->buffer, 4 + id_len);
862   }
863
864   silc_buffer_free(idp);
865   silc_free(new_id);
866 }
867
868 /* Received New Channel packet. Information about new channels in the 
869    network are distributed using this packet. Save the information about
870    the new channel. This usually comes from router but also normal server
871    can send this to notify channels it has when it connects to us. */
872
873 void silc_server_new_channel(SilcServer server,
874                              SilcSocketConnection sock,
875                              SilcPacketContext *packet)
876 {
877   unsigned char *id;
878   SilcChannelID *channel_id;
879   unsigned short channel_id_len;
880   char *channel_name;
881   int ret;
882
883   SILC_LOG_DEBUG(("Processing New Channel"));
884
885   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
886       packet->src_id_type != SILC_ID_SERVER ||
887       server->server_type == SILC_SERVER)
888     return;
889
890   /* Parse payload */
891   ret = silc_buffer_unformat(packet->buffer, 
892                              SILC_STR_UI16_STRING_ALLOC(&channel_name),
893                              SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
894                              SILC_STR_END);
895   if (ret == -1) {
896     if (channel_name)
897       silc_free(channel_name);
898     if (id)
899       silc_free(id);
900     return;
901   }
902     
903   /* Decode the channel ID */
904   channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
905   if (!channel_id)
906     return;
907
908   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
909     /* Add the server to global list as it is coming from router. It 
910        cannot be our own channel as it is coming from router. */
911
912     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
913                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
914                     sock->hostname));
915     
916     silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
917                             server->router->connection, NULL);
918
919     server->stat.channels++;
920   } else {
921     /* The channel is coming from our server, thus it is in our cell
922        we will add it to our local list. */
923     SilcChannelEntry channel;
924     SilcBuffer chk;
925
926     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
927                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
928                     sock->hostname));
929     
930     /* Check that we don't already have this channel */
931     channel = silc_idlist_find_channel_by_name(server->local_list, 
932                                                channel_name, NULL);
933     if (!channel)
934       channel = silc_idlist_find_channel_by_name(server->global_list, 
935                                                  channel_name, NULL);
936
937     /* If the channel does not exist, then create it. We create the channel
938        with the channel ID provided by the server. This creates a new
939        key to the channel as well that we will send to the server. */
940     if (!channel) {
941       channel = silc_server_create_new_channel_with_id(server, NULL,
942                                                        channel_name,
943                                                        channel_id, FALSE);
944       if (!channel)
945         return;
946
947       /* Send the new channel key to the server */
948       chk = silc_channel_key_payload_encode(channel_id_len, id,
949                                             strlen(channel->channel_key->
950                                                    cipher->name),
951                                             channel->channel_key->cipher->name,
952                                             channel->key_len / 8, 
953                                             channel->key);
954       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
955                               chk->data, chk->len, FALSE);
956       silc_buffer_free(chk);
957
958     } else {
959       /* The channel exist by that name, check whether the ID's match.
960          If they don't then we'll force the server to use the ID we have.
961          We also create a new key for the channel. */
962
963       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
964         /* They don't match, send Replace ID packet to the server to
965            force the ID change. */
966         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
967         silc_server_send_replace_id(server, sock, FALSE, 
968                                     channel_id, SILC_ID_CHANNEL,
969                                     SILC_ID_CHANNEL_LEN,
970                                     channel->id, SILC_ID_CHANNEL,
971                                     SILC_ID_CHANNEL_LEN);
972       }
973
974       /* Create new key for the channel and send it to the server and
975          everybody else possibly on the channel. */
976
977       silc_server_create_channel_key(server, channel, 0);
978
979       /* Send to the channel */
980       silc_server_send_channel_key(server, sock, channel, FALSE);
981
982       /* Send to the server */
983       chk = silc_channel_key_payload_encode(channel_id_len, id,
984                                             strlen(channel->channel_key->
985                                                    cipher->name),
986                                             channel->channel_key->cipher->name,
987                                             channel->key_len / 8, 
988                                             channel->key);
989       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
990                               chk->data, chk->len, FALSE);
991       silc_buffer_free(chk);
992
993       /* Since the channel is coming from server and we also know about it
994          then send the JOIN notify to the server so that it see's our
995          users on the channel "joining" the channel. */
996       /* XXX TODO **/
997     }
998   }
999
1000   silc_free(id);
1001 }
1002
1003 /* Received New Channel List packet, list of New Channel List payloads inside
1004    one packet. Process the New Channel payloads one by one. */
1005
1006 void silc_server_new_channel_list(SilcServer server,
1007                                   SilcSocketConnection sock,
1008                                   SilcPacketContext *packet)
1009 {
1010   SilcPacketContext *new;
1011   SilcBuffer buffer;
1012   unsigned short len1, len2;
1013
1014   SILC_LOG_DEBUG(("Processing New Channel List"));
1015
1016   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1017       packet->src_id_type != SILC_ID_SERVER ||
1018       server->server_type == SILC_SERVER)
1019     return;
1020
1021   /* If the sender of this packet is server and we are router we need to
1022      broadcast this packet to other routers in the network. Broadcast
1023      this list packet instead of multiple New Channel packets. */
1024   if (!server->standalone && server->server_type == SILC_ROUTER &&
1025       sock->type == SILC_SOCKET_TYPE_SERVER &&
1026       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1027     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1028     silc_server_packet_send(server, server->router->connection,
1029                             packet->type, 
1030                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1031                             packet->buffer->data, packet->buffer->len, FALSE);
1032   }
1033
1034   /* Make copy of the original packet context, except for the actual
1035      data buffer, which we will here now fetch from the original buffer. */
1036   new = silc_packet_context_alloc();
1037   new->type = SILC_PACKET_NEW_CHANNEL;
1038   new->flags = packet->flags;
1039   new->src_id = packet->src_id;
1040   new->src_id_len = packet->src_id_len;
1041   new->src_id_type = packet->src_id_type;
1042   new->dst_id = packet->dst_id;
1043   new->dst_id_len = packet->dst_id_len;
1044   new->dst_id_type = packet->dst_id_type;
1045
1046   buffer = silc_buffer_alloc(512);
1047   new->buffer = buffer;
1048
1049   while (packet->buffer->len) {
1050     SILC_GET16_MSB(len1, packet->buffer->data);
1051     if ((len1 > packet->buffer->len) ||
1052         (len1 > buffer->truelen))
1053       break;
1054
1055     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1056     if ((len2 > packet->buffer->len) ||
1057         (len2 > buffer->truelen))
1058       break;
1059
1060     silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1061     silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1062
1063     /* Process the New Channel */
1064     silc_server_new_channel(server, sock, new);
1065
1066     silc_buffer_push_tail(buffer, 4 + len1 + len2);
1067     silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1068   }
1069
1070   silc_buffer_free(buffer);
1071   silc_free(new);
1072 }
1073
1074 /* Received new channel user packet. Information about new users on a
1075    channel are distributed between routers using this packet.  The
1076    router receiving this will redistribute it and also sent JOIN notify
1077    to local clients on the same channel. Normal server sends JOIN notify
1078    to its local clients on the channel. */
1079
1080 static void silc_server_new_channel_user_real(SilcServer server,
1081                                               SilcSocketConnection sock,
1082                                               SilcPacketContext *packet,
1083                                               int broadcast)
1084 {
1085   unsigned char *tmpid1, *tmpid2;
1086   SilcClientID *client_id = NULL;
1087   SilcChannelID *channel_id = NULL;
1088   unsigned short channel_id_len;
1089   unsigned short client_id_len;
1090   SilcClientEntry client;
1091   SilcChannelEntry channel;
1092   SilcChannelClientEntry chl;
1093   SilcBuffer clidp;
1094   int ret;
1095
1096   SILC_LOG_DEBUG(("Start"));
1097
1098   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1099       server->server_type != SILC_ROUTER ||
1100       packet->src_id_type != SILC_ID_SERVER)
1101     return;
1102
1103   /* Parse payload */
1104   ret = silc_buffer_unformat(packet->buffer, 
1105                              SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
1106                                                          &channel_id_len),
1107                              SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
1108                                                          &client_id_len),
1109                              SILC_STR_END);
1110   if (ret == -1) {
1111     if (tmpid1)
1112       silc_free(tmpid1);
1113     if (tmpid2)
1114       silc_free(tmpid2);
1115     return;
1116   }
1117
1118   /* Decode the channel ID */
1119   channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
1120   if (!channel_id)
1121     goto out;
1122
1123   /* Decode the client ID */
1124   client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
1125   if (!client_id)
1126     goto out;
1127
1128   /* If we are router and this packet is not already broadcast packet
1129      we will broadcast it. */
1130   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1131       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1132     SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1133     silc_server_packet_send(server, server->router->connection, packet->type,
1134                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1135                             packet->buffer->data, packet->buffer->len, FALSE);
1136   }
1137
1138   /* Find the channel */
1139   channel = silc_idlist_find_channel_by_id(server->local_list, 
1140                                            channel_id, NULL);
1141   if (!channel) {
1142     channel = silc_idlist_find_channel_by_id(server->global_list, 
1143                                              channel_id, NULL);
1144     if (!channel)
1145       goto out;
1146   }
1147
1148   /* Get client entry */
1149   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1150   if (!client) {
1151     client = silc_idlist_find_client_by_id(server->global_list, 
1152                                            client_id, NULL);
1153     if (!client)
1154       goto out;
1155   }
1156
1157   /* Join the client to the channel by adding it to channel's user list.
1158      Add also the channel to client entry's channels list for fast cross-
1159      referencing. */
1160   chl = silc_calloc(1, sizeof(*chl));
1161   chl->client = client;
1162   chl->channel = channel;
1163   silc_list_add(channel->user_list, chl);
1164   silc_list_add(client->channels, chl);
1165
1166   server->stat.chanclients++;
1167
1168   /* Send JOIN notify to local clients on the channel. As we are router
1169      it is assured that this is sent only to our local clients and locally
1170      connected servers if needed. */
1171   clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1172   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1173                                      SILC_NOTIFY_TYPE_JOIN, 
1174                                      1, clidp->data, clidp->len);
1175   silc_buffer_free(clidp);
1176
1177   client_id = NULL;
1178
1179  out:
1180   if (client_id)
1181     silc_free(client_id);
1182   if (channel_id)
1183     silc_free(channel_id);
1184   silc_free(tmpid1);
1185   silc_free(tmpid2);
1186 }
1187
1188 /* Received new channel user packet. Information about new users on a
1189    channel are distributed between routers using this packet.  The
1190    router receiving this will redistribute it and also sent JOIN notify
1191    to local clients on the same channel. Normal server sends JOIN notify
1192    to its local clients on the channel. */
1193
1194 void silc_server_new_channel_user(SilcServer server,
1195                                   SilcSocketConnection sock,
1196                                   SilcPacketContext *packet)
1197 {
1198   silc_server_new_channel_user_real(server, sock, packet, TRUE);
1199 }
1200
1201 /* Received New Channel User List packet, list of New Channel User payloads
1202    inside one packet.  Process the payloads one by one. */
1203
1204 void silc_server_new_channel_user_list(SilcServer server,
1205                                        SilcSocketConnection sock,
1206                                        SilcPacketContext *packet)
1207 {
1208   SilcPacketContext *new;
1209   SilcBuffer buffer;
1210   unsigned short len1, len2;
1211
1212   SILC_LOG_DEBUG(("Processing New Channel User List"));
1213
1214   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1215       packet->src_id_type != SILC_ID_SERVER ||
1216       server->server_type == SILC_SERVER)
1217     return;
1218
1219   /* If we are router and this packet is not already broadcast packet
1220      we will broadcast it. Brodcast this list packet instead of multiple
1221      New Channel User packets. */
1222   if (!server->standalone && server->server_type == SILC_ROUTER &&
1223       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1224     SILC_LOG_DEBUG(("Broadcasting received New Channel User List packet"));
1225     silc_server_packet_send(server, server->router->connection, packet->type,
1226                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1227                             packet->buffer->data, packet->buffer->len, FALSE);
1228   }
1229
1230   /* Make copy of the original packet context, except for the actual
1231      data buffer, which we will here now fetch from the original buffer. */
1232   new = silc_packet_context_alloc();
1233   new->type = SILC_PACKET_NEW_CHANNEL_USER;
1234   new->flags = packet->flags;
1235   new->src_id = packet->src_id;
1236   new->src_id_len = packet->src_id_len;
1237   new->src_id_type = packet->src_id_type;
1238   new->dst_id = packet->dst_id;
1239   new->dst_id_len = packet->dst_id_len;
1240   new->dst_id_type = packet->dst_id_type;
1241
1242   buffer = silc_buffer_alloc(256);
1243   new->buffer = buffer;
1244
1245   while (packet->buffer->len) {
1246     SILC_GET16_MSB(len1, packet->buffer->data);
1247     if ((len1 > packet->buffer->len) ||
1248         (len1 > buffer->truelen))
1249       break;
1250
1251     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1252     if ((len2 > packet->buffer->len) ||
1253         (len2 > buffer->truelen))
1254       break;
1255
1256     silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1257     silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1258
1259     /* Process the New Channel User */
1260     silc_server_new_channel_user_real(server, sock, new, FALSE);
1261
1262     silc_buffer_push_tail(buffer, 4 + len1 + len2);
1263     silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1264   }
1265
1266   silc_buffer_free(buffer);
1267   silc_free(new);
1268 }
1269
1270 /* Received Remove Channel User packet to remove a user from a channel. 
1271    Routers notify other routers that user has left a channel. Client must
1272    not send this packet. Normal server may send this packet but must not
1273    receive it. */
1274
1275 void silc_server_remove_channel_user(SilcServer server,
1276                                      SilcSocketConnection sock,
1277                                      SilcPacketContext *packet)
1278 {
1279   SilcBuffer buffer = packet->buffer;
1280   unsigned char *tmp1 = NULL, *tmp2 = NULL;
1281   unsigned short tmp1_len, tmp2_len;
1282   SilcClientID *client_id = NULL;
1283   SilcChannelID *channel_id = NULL;
1284   SilcChannelEntry channel;
1285   SilcClientEntry client;
1286   int ret;
1287
1288   SILC_LOG_DEBUG(("Removing user from channel"));
1289
1290   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1291       packet->src_id_type != SILC_ID_SERVER ||
1292       server->server_type == SILC_SERVER)
1293     return;
1294
1295   ret = silc_buffer_unformat(buffer,
1296                              SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
1297                              SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
1298                              SILC_STR_END);
1299   if (ret == -1)
1300     goto out;
1301
1302   client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
1303   channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
1304   if (!client_id || !channel_id)
1305     goto out;
1306
1307   /* If we are router and this packet is not already broadcast packet
1308      we will broadcast it. The sending socket really cannot be router or
1309      the router is buggy. If this packet is coming from router then it must
1310      have the broadcast flag set already and we won't do anything. */
1311   if (!server->standalone && server->server_type == SILC_ROUTER &&
1312       sock->type == SILC_SOCKET_TYPE_SERVER &&
1313       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1314     SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
1315     silc_server_packet_send(server, server->router->connection, packet->type,
1316                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1317                             buffer->data, buffer->len, FALSE);
1318   }
1319
1320   /* Get channel entry */
1321   channel = silc_idlist_find_channel_by_id(server->local_list, 
1322                                            channel_id, NULL);
1323   if (!channel) {
1324     channel = silc_idlist_find_channel_by_id(server->global_list, 
1325                                              channel_id, NULL);
1326     if (!channel)
1327       goto out;
1328   }
1329
1330   /* Get client entry */
1331   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1332   if (!client) {
1333     client = silc_idlist_find_client_by_id(server->global_list, 
1334                                            client_id, NULL);
1335     if (!client)
1336       goto out;
1337   }
1338
1339   /* Remove user from channel */
1340   silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
1341
1342  out:
1343   if (tmp1)
1344     silc_free(tmp1);
1345   if (tmp2)
1346     silc_free(tmp2);
1347   if (client_id)
1348     silc_free(client_id);
1349   if (channel_id)
1350     silc_free(channel_id);
1351 }
1352
1353 /* Received notify packet. Server can receive notify packets from router. 
1354    Server then relays the notify messages to clients if needed. */
1355
1356 void silc_server_notify(SilcServer server,
1357                         SilcSocketConnection sock,
1358                         SilcPacketContext *packet)
1359 {
1360   SilcNotifyPayload payload;
1361   SilcNotifyType type;
1362   SilcArgumentPayload args;
1363   SilcChannelID *channel_id;
1364   SilcClientID *client_id, *client_id2;
1365   SilcChannelEntry channel;
1366   SilcClientEntry client;
1367   SilcChannelClientEntry chl;
1368   unsigned int mode;
1369   unsigned char *tmp;
1370   unsigned int tmp_len;
1371
1372   SILC_LOG_DEBUG(("Start"));
1373
1374   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1375       packet->src_id_type != SILC_ID_SERVER)
1376     return;
1377
1378   /* XXX: For now we expect that the we are normal server and that the
1379      sender is router. Server could send (protocol allows it) notify to
1380      router but we don't support it yet. */
1381   if (server->server_type != SILC_SERVER &&
1382       sock->type != SILC_SOCKET_TYPE_ROUTER)
1383     return;
1384
1385   payload = silc_notify_payload_parse(packet->buffer);
1386   if (!payload)
1387     return;
1388
1389   type = silc_notify_get_type(payload);
1390   args = silc_notify_get_args(payload);
1391   if (!args)
1392     goto out;
1393
1394   switch(type) {
1395   case SILC_NOTIFY_TYPE_JOIN:
1396     /* 
1397      * Distribute the notify to local clients on the channel
1398      */
1399     SILC_LOG_DEBUG(("JOIN notify"));
1400
1401     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1402                                 packet->dst_id_type);
1403     if (!channel_id)
1404       goto out;
1405
1406     /* Get channel entry */
1407     channel = silc_idlist_find_channel_by_id(server->local_list, 
1408                                              channel_id, NULL);
1409     if (!channel) {
1410       silc_free(channel_id);
1411       goto out;
1412     }
1413
1414     /* Get client ID */
1415     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1416     if (!tmp) {
1417       silc_free(channel_id);
1418       goto out;
1419     }
1420     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1421     if (!client_id) {
1422       silc_free(channel_id);
1423       goto out;
1424     }
1425
1426     /* Send to channel */
1427     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1428                                        FALSE, packet->buffer->data, 
1429                                        packet->buffer->len, FALSE);
1430
1431     /* If the the client is not in local list we check global list (ie. the
1432        channel will be global channel) and if it does not exist then create
1433        entry for the client. */
1434     client = silc_idlist_find_client_by_id(server->local_list, 
1435                                            client_id, NULL);
1436     if (!client) {
1437       SilcChannelClientEntry chl;
1438
1439       client = silc_idlist_find_client_by_id(server->global_list, 
1440                                              client_id, NULL);
1441       if (!client) {
1442         client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
1443                                         client_id, sock->user_data, NULL);
1444         if (!client) {
1445           silc_free(channel_id);
1446           silc_free(client_id);
1447           goto out;
1448         }
1449       }
1450
1451       /* The channel is global now */
1452       channel->global_users = TRUE;
1453
1454       /* Now actually JOIN the global client to the channel */
1455       chl = silc_calloc(1, sizeof(*chl));
1456       chl->client = client;
1457       chl->channel = channel;
1458       silc_list_add(channel->user_list, chl);
1459       silc_list_add(client->channels, chl);
1460     } else {
1461       silc_free(client_id);
1462     }
1463     break;
1464
1465   case SILC_NOTIFY_TYPE_LEAVE:
1466     /* 
1467      * Distribute the notify to local clients on the channel
1468      */
1469     SILC_LOG_DEBUG(("LEAVE notify"));
1470
1471     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1472                                 packet->dst_id_type);
1473     if (!channel_id)
1474       goto out;
1475
1476     /* Get channel entry */
1477     channel = silc_idlist_find_channel_by_id(server->local_list, 
1478                                              channel_id, NULL);
1479     if (!channel) { 
1480       silc_free(channel_id);
1481       goto out;
1482     }
1483
1484     /* Get client ID */
1485     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1486     if (!tmp) {
1487       silc_free(channel_id);
1488       goto out;
1489     }
1490     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1491     if (!client_id) {
1492       silc_free(channel_id);
1493       goto out;
1494     }
1495
1496     /* Send to channel */
1497     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1498                                        FALSE, packet->buffer->data, 
1499                                        packet->buffer->len, FALSE);
1500
1501     /* Get client entry */
1502     client = silc_idlist_find_client_by_id(server->global_list, 
1503                                            client_id, NULL);
1504     if (!client) {
1505       client = silc_idlist_find_client_by_id(server->local_list, 
1506                                              client_id, NULL);
1507       if (!client) {
1508         silc_free(client_id);
1509         silc_free(channel_id);
1510         goto out;
1511       }
1512     }
1513     silc_free(client_id);
1514
1515     /* Remove the user from channel */
1516     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1517     break;
1518
1519   case SILC_NOTIFY_TYPE_SIGNOFF:
1520     /* 
1521      * Distribute the notify to local clients on the channel
1522      */
1523     SILC_LOG_DEBUG(("SIGNOFF notify"));
1524
1525     /* Get client ID */
1526     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1527     if (!tmp)
1528       goto out;
1529     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1530     if (!client_id)
1531       goto out;
1532
1533     /* Get client entry */
1534     client = silc_idlist_find_client_by_id(server->global_list, 
1535                                            client_id, NULL);
1536     if (!client) {
1537       client = silc_idlist_find_client_by_id(server->local_list, 
1538                                              client_id, NULL);
1539       if (!client) {
1540         silc_free(client_id);
1541         goto out;
1542       }
1543     }
1544     silc_free(client_id);
1545
1546     /* Remove the client from all channels */
1547     silc_server_remove_from_channels(server, NULL, client);
1548
1549     /* Remove the client entry */
1550     silc_idlist_del_client(server->global_list, client);
1551     break;
1552
1553   case SILC_NOTIFY_TYPE_TOPIC_SET:
1554     /* 
1555      * Distribute the notify to local clients on the channel
1556      */
1557
1558     SILC_LOG_DEBUG(("TOPIC SET notify"));
1559
1560     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1561                                 packet->dst_id_type);
1562     if (!channel_id)
1563       goto out;
1564
1565     /* Get channel entry */
1566     channel = silc_idlist_find_channel_by_id(server->local_list, 
1567                                              channel_id, NULL);
1568     if (!channel) {
1569       channel = silc_idlist_find_channel_by_id(server->global_list, 
1570                                                channel_id, NULL);
1571       if (!channel) {
1572         silc_free(channel_id);
1573         goto out;
1574       }
1575     }
1576
1577     /* Get the topic */
1578     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1579     if (!tmp) {
1580       silc_free(channel_id);
1581       goto out;
1582     }
1583
1584     if (channel->topic)
1585       silc_free(channel->topic);
1586     channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
1587     memcpy(channel->topic, tmp, tmp_len);
1588
1589     /* Send the same notify to the channel */
1590     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1591                                        FALSE, packet->buffer->data, 
1592                                        packet->buffer->len, FALSE);
1593     silc_free(channel_id);
1594     break;
1595
1596   case SILC_NOTIFY_TYPE_NICK_CHANGE:
1597     {
1598       /* 
1599        * Distribute the notify to local clients on the channel
1600        */
1601       unsigned char *id, *id2;
1602
1603       SILC_LOG_DEBUG(("NICK CHANGE notify"));
1604       
1605       /* Get old client ID */
1606       id = silc_argument_get_arg_type(args, 1, &tmp_len);
1607       if (!id)
1608         goto out;
1609       client_id = silc_id_payload_parse_id(id, tmp_len);
1610       if (!client_id)
1611         goto out;
1612       
1613       /* Get new client ID */
1614       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
1615       if (!id2)
1616         goto out;
1617       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
1618       if (!client_id2)
1619         goto out;
1620       
1621       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
1622                       silc_id_render(client_id, SILC_ID_CLIENT)));
1623       SILC_LOG_DEBUG(("New Client ID id(%s)", 
1624                       silc_id_render(client_id2, SILC_ID_CLIENT)));
1625
1626       /* Replace the Client ID */
1627       client = silc_idlist_replace_client_id(server->global_list, client_id,
1628                                              client_id2);
1629       if (!client)
1630         client = silc_idlist_replace_client_id(server->local_list, client_id, 
1631                                                client_id2);
1632
1633       if (client)
1634         /* Send the NICK_CHANGE notify type to local clients on the channels
1635            this client is joined to. */
1636         silc_server_send_notify_on_channels(server, client, 
1637                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
1638                                             id, tmp_len, 
1639                                             id2, tmp_len);
1640
1641       silc_free(client_id);
1642       if (!client)
1643         silc_free(client_id2);
1644       break;
1645     }
1646
1647   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1648     /* 
1649      * Distribute the notify to local clients on the channel
1650      */
1651     
1652     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
1653       
1654     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1655                                 packet->dst_id_type);
1656     if (!channel_id)
1657       goto out;
1658
1659     /* Get channel entry */
1660     channel = silc_idlist_find_channel_by_id(server->local_list, 
1661                                              channel_id, NULL);
1662     if (!channel) {
1663       channel = silc_idlist_find_channel_by_id(server->global_list, 
1664                                                channel_id, NULL);
1665       if (!channel) {
1666         silc_free(channel_id);
1667         goto out;
1668       }
1669     }
1670
1671     /* Send the same notify to the channel */
1672     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1673                                        FALSE, packet->buffer->data, 
1674                                        packet->buffer->len, FALSE);
1675
1676     /* Get the mode */
1677     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1678     if (!tmp) {
1679       silc_free(channel_id);
1680       goto out;
1681     }
1682
1683     SILC_GET32_MSB(mode, tmp);
1684
1685     /* Change mode */
1686     channel->mode = mode;
1687     silc_free(channel_id);
1688     break;
1689
1690   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1691     /* 
1692      * Distribute the notify to local clients on the channel
1693      */
1694
1695     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
1696
1697     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1698                                 packet->dst_id_type);
1699     if (!channel_id)
1700       goto out;
1701
1702     /* Get channel entry */
1703     channel = silc_idlist_find_channel_by_id(server->local_list, 
1704                                              channel_id, NULL);
1705     if (!channel) {
1706       channel = silc_idlist_find_channel_by_id(server->global_list, 
1707                                                channel_id, NULL);
1708       if (!channel) {
1709         silc_free(channel_id);
1710         goto out;
1711       }
1712     }
1713
1714     /* Get the mode */
1715     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1716     if (!tmp) {
1717       silc_free(channel_id);
1718       goto out;
1719     }
1720       
1721     SILC_GET32_MSB(mode, tmp);
1722
1723     /* Get target client */
1724     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1725     if (!tmp)
1726       goto out;
1727     client_id = silc_id_payload_parse_id(tmp, tmp_len);
1728     if (!client_id)
1729       goto out;
1730     
1731     /* Get client entry */
1732     client = silc_idlist_find_client_by_id(server->global_list, 
1733                                            client_id, NULL);
1734     if (!client) {
1735       client = silc_idlist_find_client_by_id(server->local_list, 
1736                                              client_id, NULL);
1737       if (!client) {
1738         silc_free(client_id);
1739         goto out;
1740       }
1741     }
1742     silc_free(client_id);
1743
1744     /* Get entry to the channel user list */
1745     silc_list_start(channel->user_list);
1746     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
1747       if (chl->client == client) {
1748         /* Change the mode */
1749         chl->mode = mode;
1750         break;
1751       }
1752
1753     /* Send the same notify to the channel */
1754     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
1755                                        FALSE, packet->buffer->data, 
1756                                        packet->buffer->len, FALSE);
1757     silc_free(channel_id);
1758     break;
1759
1760   case SILC_NOTIFY_TYPE_INVITE:
1761     SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
1762     break;
1763
1764     /* Ignore rest notify types for now */
1765   case SILC_NOTIFY_TYPE_NONE:
1766   case SILC_NOTIFY_TYPE_MOTD:
1767     break;
1768   default:
1769     break;
1770   }
1771
1772  out:
1773   silc_notify_payload_free(payload);
1774 }
1775
1776 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1777    that certain ID should be removed. After that the ID will become invalid. */
1778
1779 void silc_server_remove_id(SilcServer server,
1780                            SilcSocketConnection sock,
1781                            SilcPacketContext *packet)
1782 {
1783   SilcIDList id_list;
1784   SilcIDPayload idp;
1785   SilcIdType id_type;
1786   void *id, *id_entry;
1787
1788   SILC_LOG_DEBUG(("Start"));
1789
1790   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1791       server->server_type == SILC_SERVER ||
1792       packet->src_id_type != SILC_ID_SERVER)
1793     return;
1794
1795   idp = silc_id_payload_parse(packet->buffer);
1796   if (!idp)
1797     return;
1798
1799   id_type = silc_id_payload_get_type(idp);
1800
1801   id = silc_id_payload_get_id(idp);
1802   if (!id)
1803     goto out;
1804
1805   /* If the sender of this packet is server and we are router we need to
1806      broadcast this packet to other routers in the network. */
1807   if (!server->standalone && server->server_type == SILC_ROUTER &&
1808       sock->type == SILC_SOCKET_TYPE_SERVER &&
1809       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1810     SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1811     silc_server_packet_send(server, server->router->connection,
1812                             packet->type, 
1813                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1814                             packet->buffer->data, packet->buffer->len, FALSE);
1815   }
1816
1817   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1818     id_list = server->local_list;
1819   else
1820     id_list = server->global_list;
1821
1822   /* Remove the ID */
1823   switch (id_type) {
1824   case SILC_ID_CLIENT:
1825     id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id, 
1826                                              NULL);
1827     if (id_entry) {
1828       /* Remove from channels */
1829       silc_server_remove_from_channels(server, NULL, id_entry);
1830
1831       /* Remove the client entry */
1832       silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1833       server->stat.clients--;
1834       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1835           server->server_type == SILC_ROUTER)
1836         server->stat.cell_clients--;
1837
1838       SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1839                       silc_id_render(id, SILC_ID_CLIENT),
1840                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1841                       "Server" : "Router", sock->hostname));
1842     }
1843     break;
1844
1845   case SILC_ID_SERVER:
1846     id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1847                                              NULL);
1848     if (id_entry) {
1849       silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1850       server->stat.servers--;
1851       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1852           server->server_type == SILC_ROUTER)
1853         server->stat.cell_servers--;
1854
1855       SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1856                       silc_id_render(id, SILC_ID_SERVER),
1857                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1858                       "Server" : "Router", sock->hostname));
1859     }
1860     break;
1861
1862   case SILC_ID_CHANNEL:
1863     id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1864                                               NULL);
1865     if (id_entry) {
1866       silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1867       server->stat.channels--;
1868       if (sock->type == SILC_SOCKET_TYPE_SERVER &&
1869           server->server_type == SILC_ROUTER)
1870         server->stat.cell_channels--;
1871
1872       SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1873                       silc_id_render(id, SILC_ID_CHANNEL),
1874                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1875                       "Server" : "Router", sock->hostname));
1876     }
1877     break;
1878
1879   default:
1880     break;
1881   }
1882
1883  out:
1884   silc_id_payload_free(idp);
1885 }
1886
1887 /* Processes received SET_MODE packet. The packet is used to distribute
1888    the information about changed channel's or client's channel modes. */
1889
1890 void silc_server_set_mode(SilcServer server,
1891                           SilcSocketConnection sock,
1892                           SilcPacketContext *packet)
1893 {
1894   SilcSetModePayload payload = NULL;
1895   SilcArgumentPayload args = NULL;
1896   unsigned short mode_type;
1897   unsigned int mode_mask;
1898   unsigned char *tmp, *tmp2;
1899   unsigned int tmp_len, tmp_len2;
1900   unsigned char mode[4];
1901   SilcClientID *client_id;
1902   SilcChannelID *channel_id = NULL;
1903   SilcClientEntry client;
1904   SilcChannelEntry channel;
1905   SilcChannelClientEntry chl;
1906
1907   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1908       packet->src_id_type == SILC_ID_CLIENT)
1909     return;
1910
1911   SILC_LOG_DEBUG(("Start"));
1912
1913   /* If we are router and this packet is not already broadcast packet
1914      we will broadcast it. The sending socket really cannot be router or
1915      the router is buggy. If this packet is coming from router then it must
1916      have the broadcast flag set already and we won't do anything. */
1917   if (!server->standalone && server->server_type == SILC_ROUTER &&
1918       sock->type == SILC_SOCKET_TYPE_SERVER &&
1919       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1920     SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
1921     silc_server_packet_send(server, server->router->connection, packet->type,
1922                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1923                             packet->buffer->data, packet->buffer->len, FALSE);
1924   }
1925
1926   /* Parse Set Mode payload */
1927   payload = silc_set_mode_payload_parse(packet->buffer);
1928   if (!payload)
1929     return;
1930
1931   mode_type = silc_set_mode_get_type(payload);
1932   args = silc_set_mode_get_args(payload);
1933   if (!args)
1934     goto out;
1935
1936   mode_mask = silc_set_mode_get_mode(payload);
1937   SILC_PUT32_MSB(mode_mask, mode);
1938
1939   switch (mode_type) {
1940   case SILC_MODE_TYPE_CHANNEL:
1941     /* Get Channel ID */
1942     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1943     if (!tmp)
1944       goto out;
1945     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1946     if (!channel_id)
1947       goto out;
1948
1949     /* Get channel entry */
1950     channel = silc_idlist_find_channel_by_id(server->local_list, 
1951                                              channel_id, NULL);
1952     if (!channel) {
1953       channel = silc_idlist_find_channel_by_id(server->global_list, 
1954                                                channel_id, NULL);
1955       if (!channel)
1956         goto out;
1957     }
1958
1959     /* Get Client ID payload */
1960     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1961     if (!tmp)
1962       goto out;
1963
1964     /* Send CMODE_CHANGE notify to local channel */
1965     silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1966                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 
1967                                        2, tmp, tmp_len,
1968                                        mode, sizeof(mode));
1969
1970     /* Change the mode */
1971     channel->mode = mode_mask;
1972     break;
1973
1974   case SILC_MODE_TYPE_UCHANNEL:
1975     /* Get Channel ID */
1976     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1977     if (!tmp)
1978       goto out;
1979     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1980     if (!channel_id)
1981       goto out;
1982
1983     /* Get channel entry */
1984     channel = silc_idlist_find_channel_by_id(server->local_list, 
1985                                              channel_id, NULL);
1986     if (!channel) {
1987       channel = silc_idlist_find_channel_by_id(server->global_list, 
1988                                                channel_id, NULL);
1989       if (!channel)
1990         goto out;
1991     }
1992
1993     /* Get Client ID payload */
1994     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1995     if (!tmp)
1996       goto out;
1997
1998     /* Get target Client ID */
1999     tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
2000     if (!tmp2)
2001       goto out;
2002     client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
2003     if (!client_id)
2004       goto out;
2005
2006     /* Get target client entry */
2007     client = silc_idlist_find_client_by_id(server->global_list, 
2008                                            client_id, NULL);
2009     if (!client) {
2010       client = silc_idlist_find_client_by_id(server->local_list, 
2011                                              client_id, NULL);
2012       if (!client) {
2013         silc_free(client_id);
2014         goto out;
2015       }
2016     }
2017     silc_free(client_id);
2018
2019     /* Send CUMODE_CHANGE notify to local channel */
2020     silc_server_send_notify_to_channel(server, sock, channel, FALSE,
2021                                        SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3, 
2022                                        tmp, tmp_len,
2023                                        mode, sizeof(mode),
2024                                        tmp2, tmp_len2);
2025
2026     /* Get entry to the channel user list */
2027     silc_list_start(channel->user_list);
2028     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
2029       if (chl->client == client) {
2030         /* Change the mode */
2031         chl->mode = mode_mask;
2032         break;
2033       }
2034
2035     break;
2036
2037   default:
2038     break;
2039   }
2040
2041  out:
2042   if (channel_id)
2043     silc_free(channel_id);
2044   if (payload)
2045     silc_set_mode_payload_free(payload);
2046 }