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