updates, check CHANGES
[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_get_route(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. If we are normal
317      server and old key did not exist then we don't use this function
318      as the client is not in our channel user list just yet. We send the
319      key after receiveing JOIN notify from router. */
320   if (server->server_type == SILC_SERVER && exist)
321     silc_server_send_channel_key(server, channel, FALSE);
322   if (server->server_type == SILC_ROUTER)
323     silc_server_send_channel_key(server, channel, FALSE);
324
325  out:
326   if (id)
327     silc_free(id);
328   if (payload)
329     silc_channel_key_payload_free(payload);
330 }
331
332 /* Received packet to replace a ID. This checks that the requested ID
333    exists and replaces it with the new one. */
334
335 void silc_server_replace_id(SilcServer server,
336                             SilcSocketConnection sock,
337                             SilcPacketContext *packet)
338 {
339   SilcBuffer buffer = packet->buffer;
340   unsigned char *old_id = NULL, *new_id = NULL;
341   SilcIdType old_id_type, new_id_type;
342   unsigned short old_id_len, new_id_len;
343   void *id = NULL, *id2 = NULL;
344
345   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
346       packet->src_id_type == SILC_ID_CLIENT)
347     return;
348
349   SILC_LOG_DEBUG(("Replacing ID"));
350
351   silc_buffer_unformat(buffer,
352                        SILC_STR_UI_SHORT(&old_id_type),
353                        SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
354                        SILC_STR_UI_SHORT(&new_id_type),
355                        SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
356                        SILC_STR_END);
357
358   if (old_id_type != new_id_type)
359     goto out;
360
361   if (old_id_len != silc_id_get_len(old_id_type) ||
362       new_id_len != silc_id_get_len(new_id_type))
363     goto out;
364
365   id = silc_id_str2id(old_id, old_id_type);
366   if (!id)
367     goto out;
368
369   id2 = silc_id_str2id(new_id, new_id_type);
370   if (!id2)
371     goto out;
372
373   /* If we are router and this packet is not already broadcast packet
374      we will broadcast it. The sending socket really cannot be router or
375      the router is buggy. If this packet is coming from router then it must
376      have the broadcast flag set already and we won't do anything. */
377   if (server->server_type == SILC_ROUTER &&
378       sock->type == SILC_SOCKET_TYPE_SERVER &&
379       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
380     SILC_LOG_DEBUG(("Broadcasting received Replace ID packet"));
381     silc_server_packet_send(server, server->router->connection, packet->type,
382                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
383                             buffer->data, buffer->len, FALSE);
384   }
385
386   /* Replace the old ID */
387   switch(old_id_type) {
388   case SILC_ID_CLIENT:
389     if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
390       if (server->server_type == SILC_ROUTER)
391         silc_idlist_replace_client_id(server->global_list, id, id2);
392     break;
393
394   case SILC_ID_SERVER:
395     if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL)
396       if (server->server_type == SILC_ROUTER)
397         silc_idlist_replace_server_id(server->global_list, id, id2);
398     break;
399
400   case SILC_ID_CHANNEL:
401     /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be
402        re-generated. */
403     silc_free(id2);
404     break;
405
406   default:
407     silc_free(id2);
408     break;
409   }
410
411  out:
412   if (id)
413     silc_free(id);
414   if (old_id)
415     silc_free(old_id);
416   if (new_id)
417     silc_free(new_id);
418 }
419
420
421 /* Received New Client packet and processes it.  Creates Client ID for the
422    client. Client becomes registered after calling this functions. */
423
424 SilcClientEntry silc_server_new_client(SilcServer server,
425                                        SilcSocketConnection sock,
426                                        SilcPacketContext *packet)
427 {
428   SilcBuffer buffer = packet->buffer;
429   SilcClientEntry client;
430   SilcIDCacheEntry cache;
431   SilcClientID *client_id;
432   SilcBuffer reply;
433   SilcIDListData idata;
434   char *username = NULL, *realname = NULL, *id_string;
435
436   SILC_LOG_DEBUG(("Creating new client"));
437
438   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
439     return NULL;
440
441   /* Take client entry */
442   client = (SilcClientEntry)sock->user_data;
443   idata = (SilcIDListData)client;
444
445   /* Fetch the old client cache entry so that we can update it. */
446   if (!silc_idcache_find_by_context(server->local_list->clients,
447                                     sock->user_data, &cache)) {
448     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
449     return NULL;
450   }
451
452   /* Parse incoming packet */
453   silc_buffer_unformat(buffer,
454                        SILC_STR_UI16_STRING_ALLOC(&username),
455                        SILC_STR_UI16_STRING_ALLOC(&realname),
456                        SILC_STR_END);
457
458   /* Create Client ID */
459   silc_id_create_client_id(server->id, server->rng, server->md5hash,
460                            username, &client_id);
461
462   /* Update client entry */
463   idata->registered = TRUE;
464   client->nickname = strdup(username);
465   client->username = username;
466   client->userinfo = realname;
467   client->id = client_id;
468
469   /* Update the cache entry */
470   cache->id = (void *)client_id;
471   cache->type = SILC_ID_CLIENT;
472   cache->data = username;
473   silc_idcache_sort_by_data(server->local_list->clients);
474
475   /* Notify our router about new client on the SILC network */
476   if (!server->standalone)
477     silc_server_send_new_id(server, (SilcSocketConnection) 
478                             server->router->connection, 
479                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
480                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
481   
482   /* Send the new client ID to the client. */
483   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
484   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
485   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
486   silc_buffer_format(reply,
487                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
488                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
489                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
490                      SILC_STR_END);
491   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
492                           reply->data, reply->len, FALSE);
493   silc_free(id_string);
494   silc_buffer_free(reply);
495
496   /* Send some nice info to the client */
497   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
498                           ("Welcome to the SILC Network %s@%s",
499                            username, sock->hostname));
500   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
501                           ("Your host is %s, running version %s",
502                            server->config->server_info->server_name,
503                            server_version));
504   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
505                           ("Your connection is secured with %s cipher, "
506                            "key length %d bits",
507                            idata->send_key->cipher->name,
508                            idata->send_key->cipher->key_len));
509   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
510                           ("Your current nickname is %s",
511                            client->nickname));
512
513   /* Send motd */
514   silc_server_send_motd(server, sock);
515
516   return client;
517 }
518
519 /* Create new server. This processes received New Server packet and
520    saves the received Server ID. The server is our locally connected
521    server thus we save all the information and save it to local list. 
522    This funtion can be used by both normal server and router server.
523    If normal server uses this it means that its router has connected
524    to the server. If router uses this it means that one of the cell's
525    servers is connected to the router. */
526
527 SilcServerEntry silc_server_new_server(SilcServer server,
528                                        SilcSocketConnection sock,
529                                        SilcPacketContext *packet)
530 {
531   SilcBuffer buffer = packet->buffer;
532   SilcServerEntry new_server;
533   SilcIDCacheEntry cache;
534   SilcServerID *server_id;
535   SilcIDListData idata;
536   unsigned char *server_name, *id_string;
537   unsigned short id_len;
538
539   SILC_LOG_DEBUG(("Creating new server"));
540
541   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
542       sock->type != SILC_SOCKET_TYPE_ROUTER)
543     return NULL;
544
545   /* Take server entry */
546   new_server = (SilcServerEntry)sock->user_data;
547   idata = (SilcIDListData)new_server;
548
549   /* Fetch the old server cache entry so that we can update it. */
550   if (!silc_idcache_find_by_context(server->local_list->servers,
551                                     sock->user_data, &cache)) {
552     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
553     return NULL;
554   }
555
556   /* Parse the incoming packet */
557   silc_buffer_unformat(buffer,
558                        SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
559                        SILC_STR_UI16_STRING_ALLOC(&server_name),
560                        SILC_STR_END);
561
562   if (id_len > buffer->len) {
563     silc_free(id_string);
564     silc_free(server_name);
565     return NULL;
566   }
567
568   /* Get Server ID */
569   server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
570   silc_free(id_string);
571
572   /* Update client entry */
573   idata->registered = TRUE;
574   new_server->server_name = server_name;
575   new_server->id = server_id;
576
577   /* Update the cache entry */
578   cache->id = (void *)server_id;
579   cache->type = SILC_ID_SERVER;
580   cache->data = server_name;
581   silc_idcache_sort_by_data(server->local_list->servers);
582
583   /* Distribute the information about new server in the SILC network
584      to our router. If we are normal server we won't send anything
585      since this connection must be our router connection. */
586   if (server->server_type == SILC_ROUTER && !server->standalone &&
587       server->router->connection != sock)
588     silc_server_send_new_id(server, server->router->connection,
589                             TRUE, new_server->id, SILC_ID_SERVER, 
590                             SILC_ID_SERVER_LEN);
591
592   return new_server;
593 }
594
595 /* Processes incoming New ID packet. New ID Payload is used to distribute
596    information about newly registered clients and servers. */
597
598 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
599                         SilcPacketContext *packet)
600 {
601   SilcBuffer buffer = packet->buffer;
602   SilcIDList id_list;
603   SilcServerEntry tmpserver, router;
604   SilcSocketConnection router_sock;
605   SilcIDPayload idp;
606   SilcIdType id_type;
607   void *id, *tmpid;
608
609   SILC_LOG_DEBUG(("Processing new ID"));
610
611   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
612       server->server_type == SILC_SERVER ||
613       packet->src_id_type != SILC_ID_SERVER)
614     return;
615
616   idp = silc_id_payload_parse(buffer);
617   if (!idp)
618     return;
619
620   id_type = silc_id_payload_get_type(idp);
621
622   /* Normal server cannot have other normal server connections */
623   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
624     goto out;
625
626   id = silc_id_payload_get_id(idp);
627   if (!id)
628     goto out;
629
630   /* If the sender of this packet is server and we are router we need to
631      broadcast this packet to other routers in the network. */
632   if (!server->standalone && server->server_type == SILC_ROUTER &&
633       sock->type == SILC_SOCKET_TYPE_SERVER &&
634       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
635     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
636     silc_server_packet_send(server, server->router->connection,
637                             packet->type, 
638                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
639                             buffer->data, buffer->len, FALSE);
640   }
641
642   /* If the packet is originated from the one who sent it to us we know
643      that the ID belongs to our cell, unless the sender was router. */
644   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
645   tmpserver = (SilcServerEntry)sock->user_data;
646
647   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
648       sock->type == SILC_SOCKET_TYPE_SERVER) {
649     id_list = server->local_list;
650     router_sock = sock;
651     router = sock->user_data;
652     /*    router = server->id_entry; */
653   } else {
654     id_list = server->global_list;
655     router_sock = (SilcSocketConnection)server->router->connection;
656     router = server->router;
657   }
658
659   silc_free(tmpid);
660
661   switch(id_type) {
662   case SILC_ID_CLIENT:
663     {
664       SilcClientEntry idlist;
665
666       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
667                       silc_id_render(id, SILC_ID_CLIENT),
668                       sock->type == SILC_SOCKET_TYPE_SERVER ?
669                       "Server" : "Router", sock->hostname));
670
671       /* Add the client to our local list. We are router and we keep
672          cell specific local database of all clients in the cell. */
673       idlist = silc_idlist_add_client(id_list, NULL, NULL, NULL,
674                                       id, router, router_sock);
675     }
676     break;
677
678   case SILC_ID_SERVER:
679     {
680       SilcServerEntry idlist;
681
682       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
683                       silc_id_render(id, SILC_ID_SERVER),
684                       sock->type == SILC_SOCKET_TYPE_SERVER ?
685                       "Server" : "Router", sock->hostname));
686
687       /* Add the server to our local list. We are router and we keep
688          cell specific local database of all servers in the cell. */
689       idlist = silc_idlist_add_server(id_list, NULL, 0, id, router, 
690                                       router_sock);
691     }
692     break;
693
694   case SILC_ID_CHANNEL:
695     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
696 #if 0
697     SILC_LOG_DEBUG(("New channel id(%s) from [%s] %s",
698                     silc_id_render(id, SILC_ID_CHANNEL),
699                     sock->type == SILC_SOCKET_TYPE_SERVER ?
700                     "Server" : "Router", sock->hostname));
701
702     /* Add the channel to our local list. We are router and we keep
703        cell specific local database of all channels in the cell. */
704     silc_idlist_add_channel(id_list, NULL, 0, id, router, NULL);
705 #endif
706     break;
707
708   default:
709     break;
710   }
711
712  out:
713   silc_id_payload_free(idp);
714 }
715
716 /* Received Remove Channel User packet to remove a user from a channel. 
717    Routers notify other routers that user has left a channel. Client must
718    not send this packet.. Normal server may send this packet but must not
719    receive it. */
720
721 void silc_server_remove_channel_user(SilcServer server,
722                                      SilcSocketConnection sock,
723                                      SilcPacketContext *packet)
724 {
725   SilcBuffer buffer = packet->buffer;
726   unsigned char *tmp1 = NULL, *tmp2 = NULL;
727   SilcClientID *client_id = NULL;
728   SilcChannelID *channel_id = NULL;
729   SilcChannelEntry channel;
730   SilcClientEntry client;
731
732   SILC_LOG_DEBUG(("Removing user from channel"));
733
734   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
735       server->server_type == SILC_SERVER)
736     return;
737
738   silc_buffer_unformat(buffer,
739                        SILC_STR_UI16_STRING_ALLOC(&tmp1),
740                        SILC_STR_UI16_STRING_ALLOC(&tmp2),
741                        SILC_STR_END);
742
743   if (!tmp1 || !tmp2)
744     goto out;
745
746   client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
747   channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
748   if (!client_id || !channel_id)
749     goto out;
750
751   /* If we are router and this packet is not already broadcast packet
752      we will broadcast it. The sending socket really cannot be router or
753      the router is buggy. If this packet is coming from router then it must
754      have the broadcast flag set already and we won't do anything. */
755   if (!server->standalone && server->server_type == SILC_ROUTER &&
756       sock->type == SILC_SOCKET_TYPE_SERVER &&
757       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
758     SILC_LOG_DEBUG(("Broadcasting received Remove Channel User packet"));
759     silc_server_packet_send(server, server->router->connection, packet->type,
760                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
761                             buffer->data, buffer->len, FALSE);
762   }
763
764   /* XXX routers should check server->global_list as well */
765   /* Get channel entry */
766   channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
767   if (!channel)
768     goto out;
769   
770   /* XXX routers should check server->global_list as well */
771   /* Get client entry */
772   client = silc_idlist_find_client_by_id(server->local_list, client_id);
773   if (!client)
774     goto out;
775
776   /* Remove from channel */
777   silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
778
779  out:
780   if (tmp1)
781     silc_free(tmp1);
782   if (tmp2)
783     silc_free(tmp2);
784   if (client_id)
785     silc_free(client_id);
786   if (channel_id)
787     silc_free(channel_id);
788 }
789
790 /* Received New Channel packet. Information about new channels in the 
791    network are distributed using this packet. Save the information about
792    the new channel. */
793
794 void silc_server_new_channel(SilcServer server,
795                              SilcSocketConnection sock,
796                              SilcPacketContext *packet)
797 {
798   unsigned char *id;
799   SilcChannelID *channel_id;
800   unsigned short channel_id_len;
801   char *channel_name;
802
803   SILC_LOG_DEBUG(("Processing New Channel"));
804
805   if (sock->type != SILC_SOCKET_TYPE_ROUTER ||
806       server->server_type == SILC_SERVER ||
807       packet->src_id_type != SILC_ID_SERVER)
808     return;
809
810   /* Parse payload */
811   if (!silc_buffer_unformat(packet->buffer, 
812                             SILC_STR_UI16_STRING_ALLOC(&channel_name),
813                             SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
814                             SILC_STR_END))
815     return;
816     
817   if (!channel_name || !id)
818     return;
819
820   /* Decode the channel ID */
821   channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
822   if (!channel_id)
823     return;
824   silc_free(id);
825
826   SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
827                   silc_id_render(channel_id, SILC_ID_CHANNEL), 
828                   sock->hostname));
829
830   /* Add the new channel. Add it always to global list since if we receive
831      this packet then it cannot be created by ourselves but some other 
832      router hence global channel. */
833   silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
834                           server->router->connection, NULL);
835 }
836
837 /* Received notify packet. Server can receive notify packets from router. 
838    Server then relays the notify messages to clients if needed. */
839
840 void silc_server_notify(SilcServer server,
841                         SilcSocketConnection sock,
842                         SilcPacketContext *packet)
843 {
844   SilcNotifyPayload payload;
845   SilcNotifyType type;
846   SilcArgumentPayload args;
847   SilcClientID *client_id;
848   SilcChannelID *channel_id;
849   SilcClientEntry client;
850   SilcChannelEntry channel;
851   unsigned char *tmp;
852   unsigned int tmp_len;
853   int i;
854
855   SILC_LOG_DEBUG(("Start"));
856
857   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
858       packet->src_id_type != SILC_ID_SERVER)
859     return;
860
861   /* XXX: For now we expect that the we are normal server and that the
862      sender is router. Server could send (protocol allows it) notify to
863      router but we don't support it yet. */
864   if (server->server_type != SILC_SERVER &&
865       sock->type != SILC_SOCKET_TYPE_ROUTER)
866     return;
867
868   payload = silc_notify_payload_parse(packet->buffer);
869   if (!payload)
870     return;
871
872   type = silc_notify_get_type(payload);
873   args = silc_notify_get_args(payload);
874   if (!args)
875     goto out;
876
877   switch(type) {
878   case SILC_NOTIFY_TYPE_JOIN:
879     {
880       /* Get Client ID */
881       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
882       if (!tmp)
883         goto out;
884
885       client_id = silc_id_payload_parse_id(tmp, tmp_len);
886
887       /* Get client entry */
888       client = silc_idlist_find_client_by_id(server->local_list, client_id);
889       if (!client) {
890         silc_free(client_id);
891         goto out;
892       }
893
894       //      channel_id = ;
895
896       /* Get channel entry */
897       channel = silc_idlist_find_channel_by_id(server->local_list, channel_id);
898       if (!channel) {
899         silc_free(client_id);
900         goto out;
901       }
902       
903       silc_free(client_id);
904     }
905     break;
906
907   case SILC_NOTIFY_TYPE_LEAVE:
908     break;
909
910   case SILC_NOTIFY_TYPE_SIGNOFF:
911     break;
912
913     /* Ignore rest notify types for now */
914   case SILC_NOTIFY_TYPE_NONE:
915   case SILC_NOTIFY_TYPE_INVITE:
916   case SILC_NOTIFY_TYPE_TOPIC_SET:
917   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
918   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
919   case SILC_NOTIFY_TYPE_MOTD:
920   default:
921     break;
922   }
923
924  out:
925   silc_notify_payload_free(payload);
926 }
927
928 /* Received new channel user packet. Information about new users on a
929    channel are distributed between routers using this packet.  The
930    router receiving this will redistribute it and also sent JOIN notify
931    to local clients on the same channel. Normal server sends JOIN notify
932    to its local clients on the channel. */
933
934 void silc_server_new_channel_user(SilcServer server,
935                                   SilcSocketConnection sock,
936                                   SilcPacketContext *packet)
937 {
938   unsigned char *tmpid1, *tmpid2;
939   SilcClientID *client_id = NULL;
940   SilcChannelID *channel_id = NULL;
941   unsigned short channel_id_len;
942   unsigned short client_id_len;
943   SilcClientEntry client;
944   SilcChannelEntry channel;
945   SilcChannelClientEntry chl;
946   SilcIDList id_list;
947   SilcServerEntry tmpserver, router;
948   SilcSocketConnection router_sock;
949   SilcBuffer clidp;
950   void *tmpid;
951
952   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
953       server->server_type != SILC_ROUTER ||
954       packet->src_id_type != SILC_ID_SERVER)
955     return;
956
957   /* Parse payload */
958   if (!silc_buffer_unformat(packet->buffer, 
959                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
960                                                         &channel_id_len),
961                             SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
962                                                         &client_id_len),
963                             SILC_STR_END))
964     return;
965
966   if (!tmpid1 || !tmpid2)
967     return;
968
969   /* Decode the channel ID */
970   channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
971   if (!channel_id)
972     goto out;
973
974   /* Decode the client ID */
975   client_id = silc_id_str2id(tmpid1, SILC_ID_CLIENT);
976   if (!client_id)
977     goto out;
978
979   /* If the packet is originated from the one who sent it to us we know
980      that the ID belongs to our cell, unless the sender was router. */
981   tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER);
982   tmpserver = (SilcServerEntry)sock->user_data;
983
984   if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) &&
985       sock->type == SILC_SOCKET_TYPE_SERVER) {
986     id_list = server->local_list;
987     router_sock = sock;
988     router = sock->user_data;
989   } else {
990     id_list = server->global_list;
991     router_sock = (SilcSocketConnection)server->router->connection;
992     router = server->router;
993   }
994   silc_free(tmpid);
995
996   /* Find the channel */
997   channel = silc_idlist_find_channel_by_id(id_list, channel_id);
998   if (!channel) {
999     SILC_LOG_ERROR(("Received channel user for non-existent channel"));
1000     goto out;
1001   }
1002
1003   /* If we are router and this packet is not already broadcast packet
1004      we will broadcast it. */
1005   if (!server->standalone && server->server_type == SILC_ROUTER &&
1006       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1007     SILC_LOG_DEBUG(("Broadcasting received New Channel User packet"));
1008     silc_server_packet_send(server, server->router->connection, packet->type,
1009                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
1010                             packet->buffer->data, packet->buffer->len, FALSE);
1011   }
1012
1013   /* Get client entry */
1014   client = silc_idlist_find_client_by_id(id_list, client_id);
1015   if (!client) {
1016     /* This is new client to us, add entry to ID list */
1017     client = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1018                                     client_id, router, router_sock);
1019     if (!client)
1020       goto out;
1021   }
1022
1023   /* Join the client to the channel by adding it to channel's user list.
1024      Add also the channel to client entry's channels list for fast cross-
1025      referencing. */
1026   chl = silc_calloc(1, sizeof(*chl));
1027   chl->client = client;
1028   chl->channel = channel;
1029   silc_list_add(channel->user_list, chl);
1030   silc_list_add(client->channels, chl);
1031
1032   /* Send JOIN notify to local clients on the channel. As we are router
1033      it is assured that this is sent only to our local clients and locally
1034      connected servers if needed. */
1035   clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1036   silc_server_send_notify_to_channel(server, channel, TRUE,
1037                                      SILC_NOTIFY_TYPE_JOIN, 
1038                                      1, clidp->data, clidp->len);
1039   silc_buffer_free(clidp);
1040
1041   client_id = NULL;
1042
1043  out:
1044   if (client_id)
1045     silc_free(client_id);
1046   if (channel_id)
1047     silc_free(channel_id);
1048   silc_free(tmpid1);
1049   silc_free(tmpid2);
1050 }