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