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_DEBUG(("Received bad message for channel, dropped"));
216     goto out;
217   }
218
219   /* Find channel entry */
220   id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
221   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
222   if (!channel) {
223     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
224     if (!channel) {
225       SILC_LOG_DEBUG(("Could not find channel"));
226       goto out;
227     }
228   }
229
230   /* See that this client is on the channel. If the message is coming
231      from router we won't do the check as the message is from client that
232      we don't know about. Also, if the original sender is not client
233      (as it can be server as well) we don't do the check. */
234   sender = silc_id_str2id(packet->src_id, packet->src_id_type);
235   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
236       packet->src_id_type == SILC_ID_CLIENT) {
237     silc_list_start(channel->user_list);
238     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
239       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
240         break;
241     }
242     if (chl == SILC_LIST_END)
243       goto out;
244   }
245
246   /* Distribute the packet to our local clients. This will send the
247      packet for further routing as well, if needed. */
248   silc_server_packet_relay_to_channel(server, sock, channel, sender,
249                                       packet->src_id_type,
250                                       packet->buffer->data,
251                                       packet->buffer->len, FALSE);
252
253  out:
254   if (sender)
255     silc_free(sender);
256   if (id)
257     silc_free(id);
258 }
259
260 /* Received channel key packet. We distribute the key to all of our locally
261    connected clients on the channel. */
262
263 void silc_server_channel_key(SilcServer server,
264                              SilcSocketConnection sock,
265                              SilcPacketContext *packet)
266 {
267   SilcBuffer buffer = packet->buffer;
268   SilcChannelEntry channel;
269
270   if (packet->src_id_type != SILC_ID_SERVER)
271     return;
272
273   /* Save the channel key */
274   channel = silc_server_save_channel_key(server, buffer, NULL);
275   if (!channel)
276     return;
277
278   /* Distribute the key to everybody who is on the channel. If we are router
279      we will also send it to locally connected servers. */
280   silc_server_send_channel_key(server, channel, FALSE);
281 }
282
283 /* Received packet to replace a ID. This checks that the requested ID
284    exists and replaces it with the new one. */
285
286 void silc_server_replace_id(SilcServer server,
287                             SilcSocketConnection sock,
288                             SilcPacketContext *packet)
289 {
290   SilcBuffer buffer = packet->buffer;
291   unsigned char *old_id = NULL, *new_id = NULL;
292   SilcIdType old_id_type, new_id_type;
293   unsigned short old_id_len, new_id_len;
294   void *id = NULL, *id2 = NULL;
295
296   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
297       packet->src_id_type == SILC_ID_CLIENT)
298     return;
299
300   SILC_LOG_DEBUG(("Replacing ID"));
301
302   silc_buffer_unformat(buffer,
303                        SILC_STR_UI_SHORT(&old_id_type),
304                        SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
305                        SILC_STR_UI_SHORT(&new_id_type),
306                        SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
307                        SILC_STR_END);
308
309   if (old_id_type != new_id_type)
310     goto out;
311
312   if (old_id_len != silc_id_get_len(old_id_type) ||
313       new_id_len != silc_id_get_len(new_id_type))
314     goto out;
315
316   id = silc_id_str2id(old_id, old_id_type);
317   if (!id)
318     goto out;
319
320   id2 = silc_id_str2id(new_id, new_id_type);
321   if (!id2)
322     goto out;
323
324   /* If we are router and this packet is not already broadcast packet
325      we will broadcast it. The sending socket really cannot be router or
326      the router is buggy. If this packet is coming from router then it must
327      have the broadcast flag set already and we won't do anything. */
328   if (server->server_type == SILC_ROUTER &&
329       sock->type == SILC_SOCKET_TYPE_SERVER &&
330       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
331     SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
332     silc_server_packet_send(server, server->router->connection, packet->type,
333                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
334                             buffer->data, buffer->len, FALSE);
335   }
336
337   /* Replace the old ID */
338   switch(old_id_type) {
339   case SILC_ID_CLIENT:
340     SILC_LOG_DEBUG(("Old Client ID id(%s)", 
341                     silc_id_render(id, SILC_ID_CLIENT)));
342     SILC_LOG_DEBUG(("New Client ID id(%s)", 
343                     silc_id_render(id2, SILC_ID_CLIENT)));
344     if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
345       if (server->server_type == SILC_ROUTER)
346         silc_idlist_replace_client_id(server->global_list, id, id2);
347     break;
348
349   case SILC_ID_SERVER:
350     SILC_LOG_DEBUG(("Old Server ID id(%s)", 
351                     silc_id_render(id, SILC_ID_CLIENT)));
352     SILC_LOG_DEBUG(("New Server ID id(%s)", 
353                     silc_id_render(id2, SILC_ID_CLIENT)));
354     if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
355       if (server->server_type == SILC_ROUTER)
356         silc_idlist_replace_server_id(server->global_list, id, id2);
357     break;
358
359   case SILC_ID_CHANNEL:
360     /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
361        re-generated. */
362     silc_free(id2);
363     break;
364
365   default:
366     silc_free(id2);
367     break;
368   }
369
370  out:
371   if (id)
372     silc_free(id);
373   if (old_id)
374     silc_free(old_id);
375   if (new_id)
376     silc_free(new_id);
377 }
378
379
380 /* Received New Client packet and processes it.  Creates Client ID for the
381    client. Client becomes registered after calling this functions. */
382
383 SilcClientEntry silc_server_new_client(SilcServer server,
384                                        SilcSocketConnection sock,
385                                        SilcPacketContext *packet)
386 {
387   SilcBuffer buffer = packet->buffer;
388   SilcClientEntry client;
389   SilcIDCacheEntry cache;
390   SilcClientID *client_id;
391   SilcBuffer reply;
392   SilcIDListData idata;
393   char *username = NULL, *realname = NULL, *id_string;
394
395   SILC_LOG_DEBUG(("Creating new client"));
396
397   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
398     return NULL;
399
400   /* Take client entry */
401   client = (SilcClientEntry)sock->user_data;
402   idata = (SilcIDListData)client;
403
404   /* Fetch the old client cache entry so that we can update it. */
405   if (!silc_idcache_find_by_context(server->local_list->clients,
406                                     sock->user_data, &cache)) {
407     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
408     return NULL;
409   }
410
411   /* Parse incoming packet */
412   silc_buffer_unformat(buffer,
413                        SILC_STR_UI16_STRING_ALLOC(&username),
414                        SILC_STR_UI16_STRING_ALLOC(&realname),
415                        SILC_STR_END);
416
417   /* Create Client ID */
418   silc_id_create_client_id(server->id, server->rng, server->md5hash,
419                            username, &client_id);
420
421   /* Update client entry */
422   idata->registered = TRUE;
423   client->nickname = strdup(username);
424   client->username = username;
425   client->userinfo = realname;
426   client->id = client_id;
427
428   /* Update the cache entry */
429   cache->id = (void *)client_id;
430   cache->type = SILC_ID_CLIENT;
431   cache->data = username;
432   silc_idcache_sort_by_data(server->local_list->clients);
433
434   /* Notify our router about new client on the SILC network */
435   if (!server->standalone)
436     silc_server_send_new_id(server, (SilcSocketConnection) 
437                             server->router->connection, 
438                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
439                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
440   
441   /* Send the new client ID to the client. */
442   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
443   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
444   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
445   silc_buffer_format(reply,
446                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
447                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
448                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
449                      SILC_STR_END);
450   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
451                           reply->data, reply->len, FALSE);
452   silc_free(id_string);
453   silc_buffer_free(reply);
454
455   /* Send some nice info to the client */
456   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
457                           ("Welcome to the SILC Network %s@%s",
458                            username, sock->hostname));
459   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
460                           ("Your host is %s, running version %s",
461                            server->config->server_info->server_name,
462                            server_version));
463   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
464                           ("Your connection is secured with %s cipher, "
465                            "key length %d bits",
466                            idata->send_key->cipher->name,
467                            idata->send_key->cipher->key_len));
468   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
469                           ("Your current nickname is %s",
470                            client->nickname));
471
472   /* Send motd */
473   silc_server_send_motd(server, sock);
474
475   return client;
476 }
477
478 /* Create new server. This processes received New Server packet and
479    saves the received Server ID. The server is our locally connected
480    server thus we save all the information and save it to local list. 
481    This funtion can be used by both normal server and router server.
482    If normal server uses this it means that its router has connected
483    to the server. If router uses this it means that one of the cell's
484    servers is connected to the router. */
485
486 SilcServerEntry silc_server_new_server(SilcServer server,
487                                        SilcSocketConnection sock,
488                                        SilcPacketContext *packet)
489 {
490   SilcBuffer buffer = packet->buffer;
491   SilcServerEntry new_server;
492   SilcIDCacheEntry cache;
493   SilcServerID *server_id;
494   SilcIDListData idata;
495   unsigned char *server_name, *id_string;
496   unsigned short id_len;
497
498   SILC_LOG_DEBUG(("Creating new server"));
499
500   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
501       sock->type != SILC_SOCKET_TYPE_ROUTER)
502     return NULL;
503
504   /* Take server entry */
505   new_server = (SilcServerEntry)sock->user_data;
506   idata = (SilcIDListData)new_server;
507
508   /* Fetch the old server cache entry so that we can update it. */
509   if (!silc_idcache_find_by_context(server->local_list->servers,
510                                     sock->user_data, &cache)) {
511     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
512     return NULL;
513   }
514
515   /* Parse the incoming packet */
516   silc_buffer_unformat(buffer,
517                        SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
518                        SILC_STR_UI16_STRING_ALLOC(&server_name),
519                        SILC_STR_END);
520
521   if (id_len > buffer->len) {
522     silc_free(id_string);
523     silc_free(server_name);
524     return NULL;
525   }
526
527   /* Get Server ID */
528   server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
529   silc_free(id_string);
530
531   /* Update client entry */
532   idata->registered = TRUE;
533   new_server->server_name = server_name;
534   new_server->id = server_id;
535
536   /* Update the cache entry */
537   cache->id = (void *)server_id;
538   cache->type = SILC_ID_SERVER;
539   cache->data = server_name;
540   silc_idcache_sort_by_data(server->local_list->servers);
541
542   /* Distribute the information about new server in the SILC network
543      to our router. If we are normal server we won't send anything
544      since this connection must be our router connection. */
545   if (server->server_type == SILC_ROUTER && !server->standalone &&
546       server->router->connection != sock)
547     silc_server_send_new_id(server, server->router->connection,
548                             TRUE, new_server->id, SILC_ID_SERVER, 
549                             SILC_ID_SERVER_LEN);
550
551   return new_server;
552 }
553
554 /* Processes incoming New ID packet. New ID Payload is used to distribute
555    information about newly registered clients and servers. */
556
557 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
558                         SilcPacketContext *packet)
559 {
560   SilcBuffer buffer = packet->buffer;
561   SilcIDList id_list;
562   SilcServerEntry router;
563   SilcSocketConnection router_sock;
564   SilcIDPayload idp;
565   SilcIdType id_type;
566   unsigned char *hash = NULL;
567   void *id;
568
569   SILC_LOG_DEBUG(("Processing new ID"));
570
571   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
572       server->server_type == SILC_SERVER ||
573       packet->src_id_type != SILC_ID_SERVER)
574     return;
575
576   idp = silc_id_payload_parse(buffer);
577   if (!idp)
578     return;
579
580   id_type = silc_id_payload_get_type(idp);
581
582   /* Normal server cannot have other normal server connections */
583   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
584     goto out;
585
586   id = silc_id_payload_get_id(idp);
587   if (!id)
588     goto out;
589
590   /* If the sender of this packet is server and we are router we need to
591      broadcast this packet to other routers in the network. */
592   if (!server->standalone && server->server_type == SILC_ROUTER &&
593       sock->type == SILC_SOCKET_TYPE_SERVER &&
594       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
595     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
596     silc_server_packet_send(server, server->router->connection,
597                             packet->type, 
598                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
599                             buffer->data, buffer->len, FALSE);
600   }
601
602 #if 0
603   /* If the packet is originated from the one who sent it to us we know
604      that the ID belongs to our cell, unless the sender was router. */
605   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
606   tmpserver = (SilcServerEntry)sock->user_data;
607
608   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
609       sock->type == SILC_SOCKET_TYPE_SERVER) {
610     id_list = server->local_list;
611     router_sock = sock;
612     router = sock->user_data;
613     /*    router = server->id_entry; */
614   } else {
615     id_list = server->global_list;
616     router_sock = (SilcSocketConnection)server->router->connection;
617     router = server->router;
618   }
619
620   silc_free(tmpid);
621 #endif
622
623   if (sock->type == SILC_SOCKET_TYPE_SERVER)
624     id_list = server->local_list;
625   else
626     id_list = server->global_list;
627
628   router_sock = sock;
629   router = sock->user_data;
630
631   switch(id_type) {
632   case SILC_ID_CLIENT:
633     {
634       SilcClientEntry entry;
635
636       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
637                       silc_id_render(id, SILC_ID_CLIENT),
638                       sock->type == SILC_SOCKET_TYPE_SERVER ?
639                       "Server" : "Router", sock->hostname));
640     
641       /* As a router we keep information of all global information in our
642          global list. Cell wide information however is kept in the local
643          list. The client is put to global list and we will take the hash
644          value of the Client ID and save it to the ID Cache system for fast
645          searching in the future. */
646       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
647                          sizeof(unsigned char));
648       memcpy(hash, ((SilcClientID *)id)->hash, 
649              sizeof(((SilcClientID *)id)->hash));
650       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
651                                      router, router_sock);
652       entry->nickname = NULL;
653
654 #if 0
655       /* XXX Adding two ID's with same IP number replaces the old entry thus
656          gives wrong route. Thus, now disabled until figured out a better way
657          to do this or when removed the whole thing. This could be removed
658          because entry->router->connection gives always the most optimal route
659          for the ID anyway (unless new routes (faster perhaps) are established
660          after receiving this ID, this we don't know however). */
661       /* Add route cache for this ID */
662       silc_server_route_add(silc_server_route_hash(
663                             ((SilcClientID *)id)->ip.s_addr,
664                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
665                             router);
666 #endif
667     }
668     break;
669
670   case SILC_ID_SERVER:
671     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
672                     silc_id_render(id, SILC_ID_SERVER),
673                     sock->type == SILC_SOCKET_TYPE_SERVER ?
674                     "Server" : "Router", sock->hostname));
675     
676     /* As a router we keep information of all global information in our global
677        list. Cell wide information however is kept in the local list. */
678     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
679
680 #if 0
681     /* Add route cache for this ID */
682     silc_server_route_add(silc_server_route_hash(
683                           ((SilcServerID *)id)->ip.s_addr,
684                           ((SilcServerID *)id)->port), 
685                           ((SilcServerID *)id)->ip.s_addr,
686                           router);
687 #endif
688     break;
689
690   case SILC_ID_CHANNEL:
691     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
692     break;
693
694   default:
695     break;
696   }
697
698  out:
699   silc_id_payload_free(idp);
700 }
701
702 /* Received Remove Channel User packet to remove a user from a channel. 
703    Routers notify other routers that user has left a channel. Client must
704    not send this packet. Normal server may send this packet but must not
705    receive it. */
706
707 void silc_server_remove_channel_user(SilcServer server,
708                                      SilcSocketConnection sock,
709                                      SilcPacketContext *packet)
710 {
711   SilcBuffer buffer = packet->buffer;
712   unsigned char *tmp1 = NULL, *tmp2 = NULL;
713   SilcClientID *client_id = NULL;
714   SilcChannelID *channel_id = NULL;
715   SilcChannelEntry channel;
716   SilcClientEntry client;
717
718   SILC_LOG_DEBUG(("Removing user from channel"));
719
720   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
721       server->server_type == SILC_SERVER)
722     return;
723
724   silc_buffer_unformat(buffer,
725                        SILC_STR_UI16_STRING_ALLOC(&tmp1),
726                        SILC_STR_UI16_STRING_ALLOC(&tmp2),
727                        SILC_STR_END);
728
729   if (!tmp1 || !tmp2)
730     goto out;
731
732   client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
733   channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
734   if (!client_id || !channel_id)
735     goto out;
736
737   /* If we are router and this packet is not already broadcast packet
738      we will broadcast it. The sending socket really cannot be router or
739      the router is buggy. If this packet is coming from router then it must
740      have the broadcast flag set already and we won't do anything. */
741   if (!server->standalone && server->server_type == SILC_ROUTER &&
742       sock->type == SILC_SOCKET_TYPE_SERVER &&
743       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
744     SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
745     silc_server_packet_send(server, server->router->connection, packet->type,
746                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
747                             buffer->data, buffer->len, FALSE);
748   }
749
750   /* Get channel entry */
751   channel = silc_idlist_find_channel_by_id(server->local_list, 
752                                            channel_id, NULL);
753   if (!channel) {
754     channel = silc_idlist_find_channel_by_id(server->global_list, 
755                                              channel_id, NULL);
756     if (!channel)
757       goto out;
758   }
759
760   /* Get client entry */
761   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
762   if (!client) {
763     client = silc_idlist_find_client_by_id(server->global_list, 
764                                            client_id, NULL);
765     if (!client)
766       goto out;
767   }
768
769   /* Remove user from channel */
770   silc_server_remove_from_one_channel(server, sock, channel, client, TRUE);
771
772  out:
773   if (tmp1)
774     silc_free(tmp1);
775   if (tmp2)
776     silc_free(tmp2);
777   if (client_id)
778     silc_free(client_id);
779   if (channel_id)
780     silc_free(channel_id);
781 }
782
783 /* Received New Channel packet. Information about new channels in the 
784    network are distributed using this packet. Save the information about
785    the new channel. */
786
787 void silc_server_new_channel(SilcServer server,
788                              SilcSocketConnection sock,
789                              SilcPacketContext *packet)
790 {
791   unsigned char *id;
792   SilcChannelID *channel_id;
793   unsigned short channel_id_len;
794   char *channel_name;
795
796   SILC_LOG_DEBUG(("Processing New Channel"));
797
798   if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
799       server->server_type == SILC_SERVER ||
800       packet->src_id_type != SILC_ID_SERVER)
801     return;
802
803   /* Parse payload */
804   if (!silc_buffer_unformat(packet->buffer, 
805                             SILC_STR_UI16_STRING_ALLOC(&channel_name),
806                             SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
807                             SILC_STR_END))
808     return;
809     
810   if (!channel_name || !id)
811     return;
812
813   /* Decode the channel ID */
814   channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
815   if (!channel_id)
816     return;
817   silc_free(id);
818
819   SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
820                   silc_id_render(channel_id, SILC_ID_CHANNEL), 
821                   sock->hostname));
822
823   /* Add the new channel. Add it always to global list since if we receive
824      this packet then it cannot be created by ourselves but some other 
825      router hence global channel. */
826   silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
827                           server->router->connection, NULL);
828 }
829
830 /* Received notify packet. Server can receive notify packets from router. 
831    Server then relays the notify messages to clients if needed. */
832
833 void silc_server_notify(SilcServer server,
834                         SilcSocketConnection sock,
835                         SilcPacketContext *packet)
836 {
837   SilcNotifyPayload payload;
838   SilcNotifyType type;
839   SilcArgumentPayload args;
840   SilcChannelID *channel_id;
841   SilcClientID *client_id;
842   SilcChannelEntry channel;
843   SilcClientEntry client;
844   unsigned char *tmp;
845   unsigned int tmp_len;
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     SILC_LOG_DEBUG(("JOIN notify"));
875
876     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
877     if (!channel_id)
878       goto out;
879
880     /* Get channel entry */
881     channel = silc_idlist_find_channel_by_id(server->local_list, 
882                                              channel_id, NULL);
883     if (!channel) {
884       silc_free(channel_id);
885       goto out;
886     }
887
888     /* Get client ID */
889     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
890     if (!tmp) {
891       silc_free(channel_id);
892       goto out;
893     }
894     client_id = silc_id_payload_parse_id(tmp, tmp_len);
895
896     /* Send to channel */
897     silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
898                                        packet->buffer->data, 
899                                        packet->buffer->len, FALSE);
900
901     /* If the the client is not in local list we check global list (ie. the
902        channel will be global channel) and if it does not exist then create
903        entry for the client. */
904     client = silc_idlist_find_client_by_id(server->local_list, 
905                                            client_id, NULL);
906     if (!client) {
907       SilcChannelClientEntry chl;
908
909       client = silc_idlist_find_client_by_id(server->global_list, 
910                                              client_id, NULL);
911       if (!client)
912         client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
913                                         client_id, sock->user_data, sock);
914
915       /* The channel is global now */
916       channel->global_users = TRUE;
917
918       /* Now actually JOIN the global client to the channel */
919       chl = silc_calloc(1, sizeof(*chl));
920       chl->client = client;
921       chl->channel = channel;
922       silc_list_add(channel->user_list, chl);
923       silc_list_add(client->channels, chl);
924     } else {
925       silc_free(client_id);
926     }
927     break;
928
929   case SILC_NOTIFY_TYPE_LEAVE:
930     /* 
931      * Distribute the notify to local clients on the channel
932      */
933     SILC_LOG_DEBUG(("LEAVE notify"));
934
935     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
936     if (!channel_id)
937       goto out;
938
939     /* Get channel entry */
940     channel = silc_idlist_find_channel_by_id(server->local_list, 
941                                              channel_id, NULL);
942     if (!channel) { 
943       silc_free(channel_id);
944       goto out;
945     }
946
947     /* Get client ID */
948     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
949     if (!tmp) {
950       silc_free(channel_id);
951       goto out;
952     }
953     client_id = silc_id_payload_parse_id(tmp, tmp_len);
954
955     /* Send to channel */
956     silc_server_packet_send_to_channel(server, channel, packet->type, FALSE,
957                                        packet->buffer->data, 
958                                        packet->buffer->len, FALSE);
959
960     /* Get client entry */
961     client = silc_idlist_find_client_by_id(server->global_list, 
962                                            client_id, NULL);
963     if (!client) {
964       client = silc_idlist_find_client_by_id(server->local_list, 
965                                              client_id, NULL);
966       if (!client) {
967         silc_free(channel_id);
968         goto out;
969       }
970     }
971     silc_free(client_id);
972
973     /* Remove the user from channel */
974     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
975     break;
976
977   case SILC_NOTIFY_TYPE_SIGNOFF:
978     /* 
979      * Distribute the notify to local clients on the channel
980      */
981     SILC_LOG_DEBUG(("SIGNOFF notify"));
982
983     /* Get client ID */
984     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
985     if (!tmp)
986       goto out;
987     client_id = silc_id_payload_parse_id(tmp, tmp_len);
988
989     /* Get client entry */
990     client = silc_idlist_find_client_by_id(server->global_list, 
991                                            client_id, NULL);
992     if (!client) {
993       client = silc_idlist_find_client_by_id(server->local_list, 
994                                              client_id, NULL);
995       if (!client)
996         goto out;
997     }
998     silc_free(client_id);
999
1000     /* Remove the client from all channels */
1001     silc_server_remove_from_channels(server, NULL, client);
1002
1003     /* Remove the client entry */
1004     silc_idlist_del_client(server->global_list, client);
1005     break;
1006
1007     /* Ignore rest notify types for now */
1008   case SILC_NOTIFY_TYPE_NONE:
1009   case SILC_NOTIFY_TYPE_INVITE:
1010   case SILC_NOTIFY_TYPE_TOPIC_SET:
1011   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
1012   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
1013   case SILC_NOTIFY_TYPE_MOTD:
1014   default:
1015     break;
1016   }
1017
1018  out:
1019   silc_notify_payload_free(payload);
1020 }
1021
1022 /* Received new channel user packet. Information about new users on a
1023    channel are distributed between routers using this packet.  The
1024    router receiving this will redistribute it and also sent JOIN notify
1025    to local clients on the same channel. Normal server sends JOIN notify
1026    to its local clients on the channel. */
1027
1028 void silc_server_new_channel_user(SilcServer server,
1029                                   SilcSocketConnection sock,
1030                                   SilcPacketContext *packet)
1031 {
1032   unsigned char *tmpid1, *tmpid2;
1033   SilcClientID *client_id = NULL;
1034   SilcChannelID *channel_id = NULL;
1035   unsigned short channel_id_len;
1036   unsigned short client_id_len;
1037   SilcClientEntry client;
1038   SilcChannelEntry channel;
1039   SilcChannelClientEntry chl;
1040   SilcIDList id_list;
1041   SilcServerEntry tmpserver, router;
1042   SilcSocketConnection router_sock;
1043   SilcBuffer clidp;
1044   void *tmpid;
1045
1046   SILC_LOG_DEBUG(("Start"));
1047
1048   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1049       server->server_type != SILC_ROUTER ||
1050       packet->src_id_type != SILC_ID_SERVER)
1051     return;
1052
1053   /* Parse payload */
1054   if (!silc_buffer_unformat(packet->buffer, 
1055                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
1056                                                         &channel_id_len),
1057                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
1058                                                         &client_id_len),
1059                             SILC_STR_END))
1060     return;
1061
1062   if (!tmpid1 || !tmpid2)
1063     return;
1064
1065   /* Decode the channel ID */
1066   channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
1067   if (!channel_id)
1068     goto out;
1069
1070   /* Decode the client ID */
1071   client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
1072   if (!client_id)
1073     goto out;
1074
1075 #if 0
1076   /* If the packet is originated from the one who sent it to us we know
1077      that the ID belongs to our cell, unless the sender was router. */
1078   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
1079   tmpserver = (SilcServerEntry)sock->user_data;
1080
1081   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
1082       sock->type == SILC_SOCKET_TYPE_SERVER) {
1083     id_list = server->local_list;
1084     router_sock = sock;
1085     router = sock->user_data;
1086   } else {
1087     id_list = server->global_list;
1088     router_sock = (SilcSocketConnection)server->router->connection;
1089     router = server->router;
1090   }
1091   silc_free(tmpid);
1092 #endif
1093
1094   router_sock = sock;
1095   router = sock->user_data;
1096
1097   /* Find the channel */
1098   channel = silc_idlist_find_channel_by_id(server->local_list, 
1099                                            channel_id, NULL);
1100   if (!channel) {
1101     channel = silc_idlist_find_channel_by_id(server->global_list, 
1102                                              channel_id, NULL);
1103     if (!channel)
1104       goto out;
1105   }
1106
1107   /* If we are router and this packet is not already broadcast packet
1108      we will broadcast it. */
1109   if (!server->standalone && server->server_type == SILC_ROUTER &&
1110       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1111     SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1112     silc_server_packet_send(server, server->router->connection, packet->type,
1113                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1114                             packet->buffer->data, packet->buffer->len, FALSE);
1115   }
1116
1117   /* Get client entry */
1118   client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
1119   if (!client) {
1120     client = silc_idlist_find_client_by_id(server->global_list, 
1121                                            client_id, NULL);
1122     if (!client)
1123       goto out;
1124   }
1125
1126   /* Join the client to the channel by adding it to channel's user list.
1127      Add also the channel to client entry's channels list for fast cross-
1128      referencing. */
1129   chl = silc_calloc(1, sizeof(*chl));
1130   chl->client = client;
1131   chl->channel = channel;
1132   silc_list_add(channel->user_list, chl);
1133   silc_list_add(client->channels, chl);
1134
1135   /* Send JOIN notify to local clients on the channel. As we are router
1136      it is assured that this is sent only to our local clients and locally
1137      connected servers if needed. */
1138   clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1139   silc_server_send_notify_to_channel(server, channel, FALSE,
1140                                      SILC_NOTIFY_TYPE_JOIN, 
1141                                      1, clidp->data, clidp->len);
1142   silc_buffer_free(clidp);
1143
1144   client_id = NULL;
1145
1146  out:
1147   if (client_id)
1148     silc_free(client_id);
1149   if (channel_id)
1150     silc_free(channel_id);
1151   silc_free(tmpid1);
1152   silc_free(tmpid2);
1153 }
1154
1155 /* Processes incoming REMOVE_ID packet. The packet is used to notify routers
1156    that certain ID should be removed. After that the ID will become invalid. */
1157
1158 void silc_server_remove_id(SilcServer server,
1159                            SilcSocketConnection sock,
1160                            SilcPacketContext *packet)
1161 {
1162   SilcIDList id_list;
1163   SilcIDPayload idp;
1164   SilcIdType id_type;
1165   void *id, *id_entry;
1166
1167   SILC_LOG_DEBUG(("Start"));
1168
1169   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1170       server->server_type == SILC_SERVER ||
1171       packet->src_id_type != SILC_ID_SERVER)
1172     return;
1173
1174   idp = silc_id_payload_parse(packet->buffer);
1175   if (!idp)
1176     return;
1177
1178   id_type = silc_id_payload_get_type(idp);
1179
1180   id = silc_id_payload_get_id(idp);
1181   if (!id)
1182     goto out;
1183
1184   /* If the sender of this packet is server and we are router we need to
1185      broadcast this packet to other routers in the network. */
1186   if (!server->standalone && server->server_type == SILC_ROUTER &&
1187       sock->type == SILC_SOCKET_TYPE_SERVER &&
1188       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1189     SILC_LOG_DEBUG(("Broadcasting received Remove ID packet"));
1190     silc_server_packet_send(server, server->router->connection,
1191                             packet->type, 
1192                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1193                             packet->buffer->data, packet->buffer->len, FALSE);
1194   }
1195
1196   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1197     id_list = server->local_list;
1198   else
1199     id_list = server->global_list;
1200
1201   /* Remove the ID */
1202   switch (id_type) {
1203   case SILC_ID_CLIENT:
1204     id_entry = silc_idlist_find_client_by_id(id_list, (SilcClientID *)id, 
1205                                              NULL);
1206     if (id_entry) {
1207       /* Remove from channels */
1208       silc_server_remove_from_channels(server, NULL, id_entry);
1209
1210       /* Remove the client entry */
1211       silc_idlist_del_client(id_list, (SilcClientEntry)id_entry);
1212
1213       SILC_LOG_DEBUG(("Removed client id(%s) from [%s] %s",
1214                       silc_id_render(id, SILC_ID_CLIENT),
1215                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1216                       "Server" : "Router", sock->hostname));
1217     }
1218     break;
1219
1220   case SILC_ID_SERVER:
1221     id_entry = silc_idlist_find_server_by_id(id_list, (SilcServerID *)id,
1222                                              NULL);
1223     if (id_entry) {
1224       silc_idlist_del_server(id_list, (SilcServerEntry)id_entry);
1225
1226       SILC_LOG_DEBUG(("Removed server id(%s) from [%s] %s",
1227                       silc_id_render(id, SILC_ID_SERVER),
1228                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1229                       "Server" : "Router", sock->hostname));
1230     }
1231     break;
1232
1233   case SILC_ID_CHANNEL:
1234     id_entry = silc_idlist_find_channel_by_id(id_list, (SilcChannelID *)id,
1235                                               NULL);
1236     if (id_entry) {
1237       silc_idlist_del_channel(id_list, (SilcChannelEntry)id_entry);
1238
1239       SILC_LOG_DEBUG(("Removed channel id(%s) from [%s] %s",
1240                       silc_id_render(id, SILC_ID_CHANNEL),
1241                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1242                       "Server" : "Router", sock->hostname));
1243     }
1244     break;
1245
1246   default:
1247     break;
1248   }
1249
1250  out:
1251   silc_id_payload_free(idp);
1252 }