Cleaned up WHOIS command.
[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 - 2000 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     SILC_LOG_ERROR(("Bad Client ID in private message packet, dropped"));
50     goto err;
51   }
52
53   /* Decode destination Client ID */
54   id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
55   if (!id) {
56     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
57     goto err;
58   }
59
60   /* If the destination belongs to our server we don't have to route
61      the message anywhere but to send it to the local destination. */
62   client = silc_idlist_find_client_by_id(server->local_list, id);
63   if (client) {
64     /* It exists, now deliver the message to the destination */
65     dst_sock = (SilcSocketConnection)client->connection;
66
67     /* If we are router and the client has router then the client is in
68        our cell but not directly connected to us. */
69     if (server->server_type == SILC_ROUTER && client->router) {
70       /* We are of course in this case the client's router thus the real
71          "router" of the client is the server who owns the client. Thus
72          we will send the packet to that server. */
73       router = (SilcServerEntry)dst_sock->user_data;
74       idata = (SilcIDListData)router;
75       //      assert(client->router == server->id_entry);
76
77       silc_server_send_private_message(server, dst_sock,
78                                        idata->send_key,
79                                        idata->hmac,
80                                        packet);
81       return;
82     }
83
84     /* Seems that client really is directly connected to us */
85     idata = (SilcIDListData)client;
86     silc_server_send_private_message(server, dst_sock, 
87                                      idata->send_key,
88                                      idata->hmac, packet);
89     return;
90   }
91
92   /* Destination belongs to someone not in this server. If we are normal
93      server our action is to send the packet to our router. */
94   if (server->server_type == SILC_SERVER && !server->standalone) {
95     router = server->router;
96
97     /* Send to primary route */
98     if (router) {
99       dst_sock = (SilcSocketConnection)router->connection;
100       idata = (SilcIDListData)router;
101       silc_server_send_private_message(server, dst_sock, 
102                                        idata->send_key,
103                                        idata->hmac, packet);
104     }
105     return;
106   }
107
108   /* We are router and we will perform route lookup for the destination 
109      and send the message to fastest route. */
110   if (server->server_type == SILC_ROUTER && !server->standalone) {
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  err:
124   silc_server_send_error(server, sock, 
125                          "No such nickname: Private message not sent");
126 }
127
128 /* Relays received command reply packet to the correct destination. The
129    destination must be one of our locally connected client or the packet
130    will be ignored. This is called when server has forwarded one of
131    client's command request to router and router has now replied to the 
132    command. */
133
134 void silc_server_packet_relay_command_reply(SilcServer server,
135                                             SilcSocketConnection sock,
136                                             SilcPacketContext *packet)
137 {
138   SilcBuffer buffer = packet->buffer;
139   SilcClientEntry client;
140   SilcClientID *id;
141   SilcSocketConnection dst_sock;
142   SilcIDListData idata;
143
144   SILC_LOG_DEBUG(("Start"));
145
146   /* Source must be server or router */
147   if (packet->src_id_type != SILC_ID_SERVER &&
148       sock->type != SILC_SOCKET_TYPE_ROUTER)
149     return;
150
151   /* Destination must be client */
152   if (packet->dst_id_type != SILC_ID_CLIENT)
153     return;
154
155   /* Execute command reply locally for the command */
156   silc_server_command_reply_process(server, sock, buffer);
157
158   id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
159
160   /* Destination must be one of ours */
161   client = silc_idlist_find_client_by_id(server->local_list, id);
162   if (!client) {
163     SILC_LOG_ERROR(("Cannot relay command reply to unknown client"));
164     silc_free(id);
165     return;
166   }
167
168   /* Relay the packet to the client */
169
170   dst_sock = (SilcSocketConnection)client->connection;
171   silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
172                    + packet->dst_id_len + packet->padlen);
173
174   silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
175   silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
176
177   idata = (SilcIDListData)client;
178
179   /* Encrypt packet */
180   silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
181                       buffer->len);
182     
183   /* Send the packet */
184   silc_server_packet_send_real(server, dst_sock, TRUE);
185
186   silc_free(id);
187 }
188
189 /* Process received channel message. The message can be originated from
190    client or server. */
191
192 void silc_server_channel_message(SilcServer server,
193                                  SilcSocketConnection sock,
194                                  SilcPacketContext *packet)
195 {
196   SilcChannelEntry channel = NULL;
197   SilcChannelClientEntry chl;
198   SilcChannelID *id = NULL;
199   void *sender = NULL;
200
201   SILC_LOG_DEBUG(("Processing channel message"));
202
203   /* Sanity checks */
204   if (packet->dst_id_type != SILC_ID_CHANNEL) {
205     SILC_LOG_ERROR(("Received bad message for channel, dropped"));
206     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
207     goto out;
208   }
209
210   /* Find channel entry */
211   id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
212   channel = silc_idlist_find_channel_by_id(server->local_list, id);
213   if (!channel) {
214     SILC_LOG_DEBUG(("Could not find channel"));
215     goto out;
216   }
217
218   /* See that this client is on the channel. If the message is coming
219      from router we won't do the check as the message is from client that
220      we don't know about. Also, if the original sender is not client
221      (as it can be server as well) we don't do the check. */
222   sender = silc_id_str2id(packet->src_id, packet->src_id_type);
223   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
224       packet->src_id_type == SILC_ID_CLIENT) {
225     silc_list_start(channel->user_list);
226     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
227       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
228         break;
229     }
230     if (chl == SILC_LIST_END)
231       goto out;
232   }
233
234   /* Distribute the packet to our local clients. This will send the
235      packet for further routing as well, if needed. */
236   silc_server_packet_relay_to_channel(server, sock, channel, sender,
237                                       packet->src_id_type,
238                                       packet->buffer->data,
239                                       packet->buffer->len, FALSE);
240
241  out:
242   if (sender)
243     silc_free(sender);
244   if (id)
245     silc_free(id);
246 }
247
248 /* Received channel key packet. We distribute the key to all of our locally
249    connected clients on the channel. */
250
251 void silc_server_channel_key(SilcServer server,
252                              SilcSocketConnection sock,
253                              SilcPacketContext *packet)
254 {
255   SilcBuffer buffer = packet->buffer;
256   SilcChannelKeyPayload payload = NULL;
257   SilcChannelID *id = NULL;
258   SilcChannelEntry channel;
259   SilcChannelClientEntry chl;
260   unsigned char *tmp;
261   unsigned int tmp_len;
262   char *cipher;
263   int exist = FALSE;
264
265   if (packet->src_id_type != SILC_ID_SERVER)
266     goto out;
267
268   /* Decode channel key payload */
269   payload = silc_channel_key_payload_parse(buffer);
270   if (!payload) {
271     SILC_LOG_ERROR(("Bad channel key payload, dropped"));
272     goto out;
273   }
274
275   /* Get channel ID */
276   tmp = silc_channel_key_get_id(payload, &tmp_len);
277   id = silc_id_payload_parse_id(tmp, tmp_len);
278   if (!id)
279     goto out;
280
281   /* Get the channel entry */
282   channel = silc_idlist_find_channel_by_id(server->local_list, id);
283   if (!channel) {
284     SILC_LOG_ERROR(("Received key for non-existent channel"));
285     goto out;
286   }
287
288   tmp = silc_channel_key_get_key(payload, &tmp_len);
289   if (!tmp)
290     goto out;
291
292   cipher = silc_channel_key_get_cipher(payload, NULL);;
293   if (!cipher)
294     goto out;
295
296   /* Remove old key if exists */
297   if (channel->key) {
298     memset(channel->key, 0, channel->key_len);
299     silc_free(channel->key);
300     silc_cipher_free(channel->channel_key);
301     exist = TRUE;
302   }
303
304   /* Create new cipher */
305   if (!silc_cipher_alloc(cipher, &channel->channel_key))
306     goto out;
307
308   /* Save the key */
309   channel->key_len = tmp_len * 8;
310   channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
311   memcpy(channel->key, tmp, tmp_len);
312   channel->channel_key->cipher->set_key(channel->channel_key->context, 
313                                         tmp, tmp_len);
314
315   /* Distribute the key to everybody who is on the channel. If we are router
316      we will also send it to locally connected servers. */
317   silc_server_send_channel_key(server, channel, FALSE);
318
319  out:
320   if (id)
321     silc_free(id);
322   if (payload)
323     silc_channel_key_payload_free(payload);
324 }
325
326 /* Received packet to replace a ID. This checks that the requested ID
327    exists and replaces it with the new one. */
328
329 void silc_server_replace_id(SilcServer server,
330                             SilcSocketConnection sock,
331                             SilcPacketContext *packet)
332 {
333   SilcBuffer buffer = packet->buffer;
334   unsigned char *old_id = NULL, *new_id = NULL;
335   SilcIdType old_id_type, new_id_type;
336   unsigned short old_id_len, new_id_len;
337   void *id = NULL, *id2 = NULL;
338
339   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
340       packet->src_id_type == SILC_ID_CLIENT)
341     return;
342
343   SILC_LOG_DEBUG(("Replacing ID"));
344
345   silc_buffer_unformat(buffer,
346                        SILC_STR_UI_SHORT(&old_id_type),
347                        SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
348                        SILC_STR_UI_SHORT(&new_id_type),
349                        SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
350                        SILC_STR_END);
351
352   if (old_id_type != new_id_type)
353     goto out;
354
355   if (old_id_len != silc_id_get_len(old_id_type) ||
356       new_id_len != silc_id_get_len(new_id_type))
357     goto out;
358
359   id = silc_id_str2id(old_id, old_id_type);
360   if (!id)
361     goto out;
362
363   id2 = silc_id_str2id(new_id, new_id_type);
364   if (!id2)
365     goto out;
366
367   /* If we are router and this packet is not already broadcast packet
368      we will broadcast it. The sending socket really cannot be router or
369      the router is buggy. If this packet is coming from router then it must
370      have the broadcast flag set already and we won't do anything. */
371   if (server->server_type == SILC_ROUTER &&
372       sock->type == SILC_SOCKET_TYPE_SERVER &&
373       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
374     SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
375     silc_server_packet_send(server, server->router->connection, packet->type,
376                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
377                             buffer->data, buffer->len, FALSE);
378   }
379
380   /* Replace the old ID */
381   switch(old_id_type) {
382   case SILC_ID_CLIENT:
383     if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
384       if (server->server_type == SILC_ROUTER)
385         silc_idlist_replace_client_id(server->global_list, id, id2);
386     break;
387
388   case SILC_ID_SERVER:
389     if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
390       if (server->server_type == SILC_ROUTER)
391         silc_idlist_replace_server_id(server->global_list, id, id2);
392     break;
393
394   case SILC_ID_CHANNEL:
395     /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
396        re-generated. */
397     silc_free(id2);
398     break;
399
400   default:
401     silc_free(id2);
402     break;
403   }
404
405  out:
406   if (id)
407     silc_free(id);
408   if (old_id)
409     silc_free(old_id);
410   if (new_id)
411     silc_free(new_id);
412 }
413
414
415 /* Received New Client packet and processes it.  Creates Client ID for the
416    client. Client becomes registered after calling this functions. */
417
418 SilcClientEntry silc_server_new_client(SilcServer server,
419                                        SilcSocketConnection sock,
420                                        SilcPacketContext *packet)
421 {
422   SilcBuffer buffer = packet->buffer;
423   SilcClientEntry client;
424   SilcIDCacheEntry cache;
425   SilcClientID *client_id;
426   SilcBuffer reply;
427   SilcIDListData idata;
428   char *username = NULL, *realname = NULL, *id_string;
429
430   SILC_LOG_DEBUG(("Creating new client"));
431
432   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
433     return NULL;
434
435   /* Take client entry */
436   client = (SilcClientEntry)sock->user_data;
437   idata = (SilcIDListData)client;
438
439   /* Fetch the old client cache entry so that we can update it. */
440   if (!silc_idcache_find_by_context(server->local_list->clients,
441                                     sock->user_data, &cache)) {
442     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
443     return NULL;
444   }
445
446   /* Parse incoming packet */
447   silc_buffer_unformat(buffer,
448                        SILC_STR_UI16_STRING_ALLOC(&username),
449                        SILC_STR_UI16_STRING_ALLOC(&realname),
450                        SILC_STR_END);
451
452   /* Create Client ID */
453   silc_id_create_client_id(server->id, server->rng, server->md5hash,
454                            username, &client_id);
455
456   /* Update client entry */
457   idata->registered = TRUE;
458   client->nickname = strdup(username);
459   client->username = username;
460   client->userinfo = realname;
461   client->id = client_id;
462
463   /* Update the cache entry */
464   cache->id = (void *)client_id;
465   cache->type = SILC_ID_CLIENT;
466   cache->data = username;
467   silc_idcache_sort_by_data(server->local_list->clients);
468
469   /* Notify our router about new client on the SILC network */
470   if (!server->standalone)
471     silc_server_send_new_id(server, (SilcSocketConnection) 
472                             server->router->connection, 
473                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
474                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
475   
476   /* Send the new client ID to the client. */
477   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
478   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
479   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
480   silc_buffer_format(reply,
481                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
482                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
483                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
484                      SILC_STR_END);
485   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
486                           reply->data, reply->len, FALSE);
487   silc_free(id_string);
488   silc_buffer_free(reply);
489
490   /* Send some nice info to the client */
491   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
492                           ("Welcome to the SILC Network %s@%s",
493                            username, sock->hostname));
494   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
495                           ("Your host is %s, running version %s",
496                            server->config->server_info->server_name,
497                            server_version));
498   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
499                           ("Your connection is secured with %s cipher, "
500                            "key length %d bits",
501                            idata->send_key->cipher->name,
502                            idata->send_key->cipher->key_len));
503   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
504                           ("Your current nickname is %s",
505                            client->nickname));
506
507   /* Send motd */
508   silc_server_send_motd(server, sock);
509
510   return client;
511 }
512
513 /* Create new server. This processes received New Server packet and
514    saves the received Server ID. The server is our locally connected
515    server thus we save all the information and save it to local list. 
516    This funtion can be used by both normal server and router server.
517    If normal server uses this it means that its router has connected
518    to the server. If router uses this it means that one of the cell's
519    servers is connected to the router. */
520
521 SilcServerEntry silc_server_new_server(SilcServer server,
522                                        SilcSocketConnection sock,
523                                        SilcPacketContext *packet)
524 {
525   SilcBuffer buffer = packet->buffer;
526   SilcServerEntry new_server;
527   SilcIDCacheEntry cache;
528   SilcServerID *server_id;
529   SilcIDListData idata;
530   unsigned char *server_name, *id_string;
531   unsigned short id_len;
532
533   SILC_LOG_DEBUG(("Creating new server"));
534
535   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
536       sock->type != SILC_SOCKET_TYPE_ROUTER)
537     return NULL;
538
539   /* Take server entry */
540   new_server = (SilcServerEntry)sock->user_data;
541   idata = (SilcIDListData)new_server;
542
543   /* Fetch the old server cache entry so that we can update it. */
544   if (!silc_idcache_find_by_context(server->local_list->servers,
545                                     sock->user_data, &cache)) {
546     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
547     return NULL;
548   }
549
550   /* Parse the incoming packet */
551   silc_buffer_unformat(buffer,
552                        SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
553                        SILC_STR_UI16_STRING_ALLOC(&server_name),
554                        SILC_STR_END);
555
556   if (id_len > buffer->len) {
557     silc_free(id_string);
558     silc_free(server_name);
559     return NULL;
560   }
561
562   /* Get Server ID */
563   server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
564   silc_free(id_string);
565
566   /* Update client entry */
567   idata->registered = TRUE;
568   new_server->server_name = server_name;
569   new_server->id = server_id;
570
571   /* Update the cache entry */
572   cache->id = (void *)server_id;
573   cache->type = SILC_ID_SERVER;
574   cache->data = server_name;
575   silc_idcache_sort_by_data(server->local_list->servers);
576
577   /* Distribute the information about new server in the SILC network
578      to our router. If we are normal server we won't send anything
579      since this connection must be our router connection. */
580   if (server->server_type == SILC_ROUTER && !server->standalone &&
581       server->router->connection != sock)
582     silc_server_send_new_id(server, server->router->connection,
583                             TRUE, new_server->id, SILC_ID_SERVER, 
584                             SILC_ID_SERVER_LEN);
585
586   return new_server;
587 }
588
589 /* Processes incoming New ID packet. New ID Payload is used to distribute
590    information about newly registered clients and servers. */
591
592 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
593                         SilcPacketContext *packet)
594 {
595   SilcBuffer buffer = packet->buffer;
596   SilcIDList id_list;
597   SilcServerEntry tmpserver, router;
598   SilcSocketConnection router_sock;
599   SilcIDPayload idp;
600   SilcIdType id_type;
601   void *id, *tmpid;
602
603   SILC_LOG_DEBUG(("Processing new ID"));
604
605   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
606       server->server_type == SILC_SERVER ||
607       packet->src_id_type != SILC_ID_SERVER)
608     return;
609
610   idp = silc_id_payload_parse(buffer);
611   if (!idp)
612     return;
613
614   id_type = silc_id_payload_get_type(idp);
615
616   /* Normal server cannot have other normal server connections */
617   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
618     goto out;
619
620   id = silc_id_payload_get_id(idp);
621   if (!id)
622     goto out;
623
624   /* If the sender of this packet is server and we are router we need to
625      broadcast this packet to other routers in the network. */
626   if (!server->standalone && server->server_type == SILC_ROUTER &&
627       sock->type == SILC_SOCKET_TYPE_SERVER &&
628       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
629     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
630     silc_server_packet_send(server, server->router->connection,
631                             packet->type, 
632                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
633                             buffer->data, buffer->len, FALSE);
634   }
635
636 #if 0
637   /* If the packet is originated from the one who sent it to us we know
638      that the ID belongs to our cell, unless the sender was router. */
639   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
640   tmpserver = (SilcServerEntry)sock->user_data;
641
642   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
643       sock->type == SILC_SOCKET_TYPE_SERVER) {
644     id_list = server->local_list;
645     router_sock = sock;
646     router = sock->user_data;
647     /*    router = server->id_entry; */
648   } else {
649     id_list = server->global_list;
650     router_sock = (SilcSocketConnection)server->router->connection;
651     router = server->router;
652   }
653
654   silc_free(tmpid);
655 #endif
656
657   if (sock->type == SILC_SOCKET_TYPE_SERVER)
658     id_list = server->local_list;
659   else
660     id_list = server->global_list;
661
662   router_sock = sock;
663   router = sock->user_data;
664
665   switch(id_type) {
666   case SILC_ID_CLIENT:
667     SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
668                     silc_id_render(id, SILC_ID_CLIENT),
669                     sock->type == SILC_SOCKET_TYPE_SERVER ?
670                     "Server" : "Router", sock->hostname));
671     
672     /* Add the client to our local list. We are router and we keep
673        cell specific local database of all clients in the cell. */
674     silc_idlist_add_client(id_list, NULL, NULL, NULL, id, router, router_sock);
675
676     /* Add route cache for this ID */
677     silc_server_route_add(silc_server_route_hash(
678                           ((SilcClientID *)id)->ip.s_addr,
679                           server->id->port), ((SilcClientID *)id)->ip.s_addr,
680                           router);
681     break;
682
683   case SILC_ID_SERVER:
684     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
685                     silc_id_render(id, SILC_ID_SERVER),
686                     sock->type == SILC_SOCKET_TYPE_SERVER ?
687                     "Server" : "Router", sock->hostname));
688     
689     /* Add the server to our local list. We are router and we keep
690        cell specific local database of all servers in the cell. */
691     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
692
693     /* Add route cache for this ID */
694     silc_server_route_add(silc_server_route_hash(
695                           ((SilcServerID *)id)->ip.s_addr,
696                           ((SilcServerID *)id)->port), 
697                           ((SilcServerID *)id)->ip.s_addr,
698                           router);
699     break;
700
701   case SILC_ID_CHANNEL:
702     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
703     break;
704
705   default:
706     break;
707   }
708
709  out:
710   silc_id_payload_free(idp);
711 }
712
713 /* Received Remove Channel User packet to remove a user from a channel. 
714    Routers notify other routers that user has left a channel. Client must
715    not send this packet.. Normal server may send this packet but must not
716    receive it. */
717
718 void silc_server_remove_channel_user(SilcServer server,
719                                      SilcSocketConnection sock,
720                                      SilcPacketContext *packet)
721 {
722   SilcBuffer buffer = packet->buffer;
723   unsigned char *tmp1 = NULL, *tmp2 = NULL;
724   SilcClientID *client_id = NULL;
725   SilcChannelID *channel_id = NULL;
726   SilcChannelEntry channel;
727   SilcClientEntry client;
728
729   SILC_LOG_DEBUG(("Removing user from channel"));
730
731   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
732       server->server_type == SILC_SERVER)
733     return;
734
735   silc_buffer_unformat(buffer,
736                        SILC_STR_UI16_STRING_ALLOC(&tmp1),
737                        SILC_STR_UI16_STRING_ALLOC(&tmp2),
738                        SILC_STR_END);
739
740   if (!tmp1 || !tmp2)
741     goto out;
742
743   client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
744   channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
745   if (!client_id || !channel_id)
746     goto out;
747
748   /* If we are router and this packet is not already broadcast packet
749      we will broadcast it. The sending socket really cannot be router or
750      the router is buggy. If this packet is coming from router then it must
751      have the broadcast flag set already and we won't do anything. */
752   if (!server->standalone && server->server_type == SILC_ROUTER &&
753       sock->type == SILC_SOCKET_TYPE_SERVER &&
754       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
755     SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
756     silc_server_packet_send(server, server->router->connection, packet->type,
757                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
758                             buffer->data, buffer->len, FALSE);
759   }
760
761   /* XXX routers should check server->global_list as well */
762   /* Get channel entry */
763   channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
764   if (!channel)
765     goto out;
766   
767   /* XXX routers should check server->global_list as well */
768   /* Get client entry */
769   client = silc_idlist_find_client_by_id(server->local_list, client_id);
770   if (!client)
771     goto out;
772
773   /* Remove from channel */
774   silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
775
776  out:
777   if (tmp1)
778     silc_free(tmp1);
779   if (tmp2)
780     silc_free(tmp2);
781   if (client_id)
782     silc_free(client_id);
783   if (channel_id)
784     silc_free(channel_id);
785 }
786
787 /* Received New Channel packet. Information about new channels in the 
788    network are distributed using this packet. Save the information about
789    the new channel. */
790
791 void silc_server_new_channel(SilcServer server,
792                              SilcSocketConnection sock,
793                              SilcPacketContext *packet)
794 {
795   unsigned char *id;
796   SilcChannelID *channel_id;
797   unsigned short channel_id_len;
798   char *channel_name;
799
800   SILC_LOG_DEBUG(("Processing New Channel"));
801
802   if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
803       server->server_type == SILC_SERVER ||
804       packet->src_id_type != SILC_ID_SERVER)
805     return;
806
807   /* Parse payload */
808   if (!silc_buffer_unformat(packet->buffer, 
809                             SILC_STR_UI16_STRING_ALLOC(&channel_name),
810                             SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
811                             SILC_STR_END))
812     return;
813     
814   if (!channel_name || !id)
815     return;
816
817   /* Decode the channel ID */
818   channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
819   if (!channel_id)
820     return;
821   silc_free(id);
822
823   SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
824                   silc_id_render(channel_id, SILC_ID_CHANNEL), 
825                   sock->hostname));
826
827   /* Add the new channel. Add it always to global list since if we receive
828      this packet then it cannot be created by ourselves but some other 
829      router hence global channel. */
830   silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
831                           server->router->connection, NULL);
832 }
833
834 /* Received notify packet. Server can receive notify packets from router. 
835    Server then relays the notify messages to clients if needed. */
836
837 void silc_server_notify(SilcServer server,
838                         SilcSocketConnection sock,
839                         SilcPacketContext *packet)
840 {
841   SilcNotifyPayload payload;
842   SilcNotifyType type;
843   SilcArgumentPayload args;
844   SilcChannelID *channel_id;
845   SilcChannelEntry channel;
846
847   SILC_LOG_DEBUG(("Start"));
848
849   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
850       packet->src_id_type != SILC_ID_SERVER)
851     return;
852
853   /* XXX: For now we expect that the we are normal server and that the
854      sender is router. Server could send (protocol allows it) notify to
855      router but we don't support it yet. */
856   if (server->server_type != SILC_SERVER &&
857       sock->type != SILC_SOCKET_TYPE_ROUTER)
858     return;
859
860   payload = silc_notify_payload_parse(packet->buffer);
861   if (!payload)
862     return;
863
864   type = silc_notify_get_type(payload);
865   args = silc_notify_get_args(payload);
866   if (!args)
867     goto out;
868
869   switch(type) {
870   case SILC_NOTIFY_TYPE_JOIN:
871     /* 
872      * Distribute the notify to local clients on the channel
873      */
874
875     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
876     if (!channel_id)
877       goto out;
878
879     /* Get channel entry */
880     channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
881     if (!channel) {
882       silc_free(channel_id);
883       goto out;
884     }
885
886     /* Send to channel */
887     silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
888                                        packet->buffer->data, 
889                                        packet->buffer->len, FALSE);
890     break;
891
892   case SILC_NOTIFY_TYPE_LEAVE:
893     break;
894
895   case SILC_NOTIFY_TYPE_SIGNOFF:
896     break;
897
898     /* Ignore rest notify types for now */
899   case SILC_NOTIFY_TYPE_NONE:
900   case SILC_NOTIFY_TYPE_INVITE:
901   case SILC_NOTIFY_TYPE_TOPIC_SET:
902   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
903   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
904   case SILC_NOTIFY_TYPE_MOTD:
905   default:
906     break;
907   }
908
909  out:
910   silc_notify_payload_free(payload);
911 }
912
913 /* Received new channel user packet. Information about new users on a
914    channel are distributed between routers using this packet.  The
915    router receiving this will redistribute it and also sent JOIN notify
916    to local clients on the same channel. Normal server sends JOIN notify
917    to its local clients on the channel. */
918
919 void silc_server_new_channel_user(SilcServer server,
920                                   SilcSocketConnection sock,
921                                   SilcPacketContext *packet)
922 {
923   unsigned char *tmpid1, *tmpid2;
924   SilcClientID *client_id = NULL;
925   SilcChannelID *channel_id = NULL;
926   unsigned short channel_id_len;
927   unsigned short client_id_len;
928   SilcClientEntry client;
929   SilcChannelEntry channel;
930   SilcChannelClientEntry chl;
931   SilcIDList id_list;
932   SilcServerEntry tmpserver, router;
933   SilcSocketConnection router_sock;
934   SilcBuffer clidp;
935   void *tmpid;
936
937   SILC_LOG_DEBUG(("Start"));
938
939   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
940       server->server_type != SILC_ROUTER ||
941       packet->src_id_type != SILC_ID_SERVER)
942     return;
943
944   /* Parse payload */
945   if (!silc_buffer_unformat(packet->buffer, 
946                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
947                                                         &channel_id_len),
948                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
949                                                         &client_id_len),
950                             SILC_STR_END))
951     return;
952
953   if (!tmpid1 || !tmpid2)
954     return;
955
956   /* Decode the channel ID */
957   channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
958   if (!channel_id)
959     goto out;
960
961   /* Decode the client ID */
962   client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
963   if (!client_id)
964     goto out;
965
966   /* If the packet is originated from the one who sent it to us we know
967      that the ID belongs to our cell, unless the sender was router. */
968   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
969   tmpserver = (SilcServerEntry)sock->user_data;
970
971   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
972       sock->type == SILC_SOCKET_TYPE_SERVER) {
973     id_list = server->local_list;
974     router_sock = sock;
975     router = sock->user_data;
976   } else {
977     id_list = server->global_list;
978     router_sock = (SilcSocketConnection)server->router->connection;
979     router = server->router;
980   }
981   silc_free(tmpid);
982
983   /* Find the channel */
984   channel = silc_idlist_find_channel_by_id(id_list, channel_id);
985   if (!channel) {
986     SILC_LOG_ERROR(("Received channel user for non-existent channel"));
987     goto out;
988   }
989
990   /* If we are router and this packet is not already broadcast packet
991      we will broadcast it. */
992   if (!server->standalone && server->server_type == SILC_ROUTER &&
993       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
994     SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
995     silc_server_packet_send(server, server->router->connection, packet->type,
996                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
997                             packet->buffer->data, packet->buffer->len, FALSE);
998   }
999
1000   /* Get client entry */
1001   client = silc_idlist_find_client_by_id(id_list, client_id);
1002   if (!client) {
1003     /* This is new client to us, add entry to ID list */
1004     client = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1005                                     client_id, router, router_sock);
1006     if (!client)
1007       goto out;
1008   }
1009
1010   /* Join the client to the channel by adding it to channel's user list.
1011      Add also the channel to client entry's channels list for fast cross-
1012      referencing. */
1013   chl = silc_calloc(1, sizeof(*chl));
1014   chl->client = client;
1015   chl->channel = channel;
1016   silc_list_add(channel->user_list, chl);
1017   silc_list_add(client->channels, chl);
1018
1019   /* Send JOIN notify to local clients on the channel. As we are router
1020      it is assured that this is sent only to our local clients and locally
1021      connected servers if needed. */
1022   clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1023   silc_server_send_notify_to_channel(server, channel, FALSE,
1024                                      SILC_NOTIFY_TYPE_JOIN, 
1025                                      1, clidp->data, clidp->len);
1026   silc_buffer_free(clidp);
1027
1028   client_id = NULL;
1029
1030  out:
1031   if (client_id)
1032     silc_free(client_id);
1033   if (channel_id)
1034     silc_free(channel_id);
1035   silc_free(tmpid1);
1036   silc_free(tmpid2);
1037 }