updates.
[silc.git] / lib / silcclient / client.c
1 /*
2
3   client.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21
22 #include "clientlibincludes.h"
23 #include "client_internal.h"
24
25 /* Static task callback prototypes */
26 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
27 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
28 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
29 SILC_TASK_CALLBACK(silc_client_packet_parse_real);
30 SILC_TASK_CALLBACK(silc_client_rekey_callback);
31 SILC_TASK_CALLBACK(silc_client_rekey_final);
32
33 static void silc_client_packet_parse(SilcPacketParserContext *parser_context);
34 static void silc_client_packet_parse_type(SilcClient client, 
35                                           SilcSocketConnection sock,
36                                           SilcPacketContext *packet);
37
38 /* Allocates new client object. This has to be done before client may
39    work. After calling this one must call silc_client_init to initialize
40    the client. The `application' is application specific user data pointer
41    and caller must free it. */
42
43 SilcClient silc_client_alloc(SilcClientOperations *ops, 
44                              SilcClientParams *params,
45                              void *application,
46                              const char *silc_version)
47 {
48   SilcClient new_client;
49
50   new_client = silc_calloc(1, sizeof(*new_client));
51   new_client->application = application;
52   new_client->ops = ops;
53   new_client->silc_client_version = strdup(silc_version);
54   new_client->params = silc_calloc(1, sizeof(*new_client->params));
55
56   if (params)
57     memcpy(new_client->params, params, sizeof(*params));
58
59   if (!new_client->params->rekey_secs)
60     new_client->params->rekey_secs = 3600;
61
62   return new_client;
63 }
64
65 /* Frees client object and its internals. */
66
67 void silc_client_free(SilcClient client)
68 {
69   if (client) {
70     if (client->rng)
71       silc_rng_free(client->rng);
72
73     silc_free(client->silc_client_version);
74     silc_free(client->params);
75     silc_free(client);
76   }
77 }
78
79 /* Initializes the client. This makes all the necessary steps to make
80    the client ready to be run. One must call silc_client_run to run the
81    client. Returns FALSE if error occured, TRUE otherwise. */
82
83 int silc_client_init(SilcClient client)
84 {
85   SILC_LOG_DEBUG(("Initializing client"));
86
87   /* Initialize hash functions for client to use */
88   silc_hash_alloc("md5", &client->md5hash);
89   silc_hash_alloc("sha1", &client->sha1hash);
90
91   /* Initialize none cipher */
92   silc_cipher_alloc("none", &client->none_cipher);
93
94   /* Initialize random number generator */
95   client->rng = silc_rng_alloc();
96   silc_rng_init(client->rng);
97   silc_rng_global_init(client->rng);
98
99   /* Register protocols */
100   silc_client_protocols_register();
101
102   /* Initialize the scheduler */
103   client->schedule = silc_schedule_init(client->params->task_max ?
104                                         client->params->task_max : 200);
105   if (!client->schedule)
106     return FALSE;
107
108   return TRUE;
109 }
110
111 /* Stops the client. This is called to stop the client and thus to stop
112    the program. */
113
114 void silc_client_stop(SilcClient client)
115 {
116   SILC_LOG_DEBUG(("Stopping client"));
117
118   silc_schedule_stop(client->schedule);
119   silc_schedule_uninit(client->schedule);
120
121   silc_client_protocols_unregister();
122
123   SILC_LOG_DEBUG(("Client stopped"));
124 }
125
126 /* Runs the client. This starts the scheduler from the utility library.
127    When this functions returns the execution of the appliation is over. */
128
129 void silc_client_run(SilcClient client)
130 {
131   SILC_LOG_DEBUG(("Running client"));
132
133   /* Start the scheduler, the heart of the SILC client. When this returns
134      the program will be terminated. */
135   silc_schedule(client->schedule);
136 }
137
138 /* Allocates and adds new connection to the client. This adds the allocated
139    connection to the connection table and returns a pointer to it. A client
140    can have multiple connections to multiple servers. Every connection must
141    be added to the client using this function. User data `context' may
142    be sent as argument. This function is normally used only if the 
143    application performed the connecting outside the library. The library
144    however may use this internally. */
145
146 SilcClientConnection silc_client_add_connection(SilcClient client,
147                                                 char *hostname,
148                                                 int port,
149                                                 void *context)
150 {
151   SilcClientConnection conn;
152   int i;
153
154   conn = silc_calloc(1, sizeof(*conn));
155
156   /* Initialize ID caches */
157   conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, NULL);
158   conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
159   conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
160   conn->client = client;
161   conn->remote_host = strdup(hostname);
162   conn->remote_port = port;
163   conn->context = context;
164   conn->pending_commands = silc_dlist_init();
165
166   /* Add the connection to connections table */
167   for (i = 0; i < client->conns_count; i++)
168     if (client->conns && !client->conns[i]) {
169       client->conns[i] = conn;
170       return conn;
171     }
172
173   client->conns = silc_realloc(client->conns, sizeof(*client->conns)
174                                * (client->conns_count + 1));
175   client->conns[client->conns_count] = conn;
176   client->conns_count++;
177
178   return conn;
179 }
180
181 /* Removes connection from client. Frees all memory. */
182
183 void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
184 {
185   int i;
186
187   for (i = 0; i < client->conns_count; i++)
188     if (client->conns[i] == conn) {
189       if (conn->pending_commands)
190         silc_dlist_uninit(conn->pending_commands);
191       silc_free(conn);
192       client->conns[i] = NULL;
193     }
194 }
195
196 /* Adds listener socket to the listener sockets table. This function is
197    used to add socket objects that are listeners to the client.  This should
198    not be used to add other connection objects. */
199
200 void silc_client_add_socket(SilcClient client, SilcSocketConnection sock)
201 {
202   int i;
203
204   if (!client->sockets) {
205     client->sockets = silc_calloc(1, sizeof(*client->sockets));
206     client->sockets[0] = silc_socket_dup(sock);
207     client->sockets_count = 1;
208     return;
209   }
210
211   for (i = 0; i < client->sockets_count; i++) {
212     if (client->sockets[i] == NULL) {
213       client->sockets[i] = silc_socket_dup(sock);
214       return;
215     }
216   }
217
218   client->sockets = silc_realloc(client->sockets, sizeof(*client->sockets) *
219                                  (client->sockets_count + 1));
220   client->sockets[client->sockets_count] = silc_socket_dup(sock);
221   client->sockets_count++;
222 }
223
224 /* Deletes listener socket from the listener sockets table. */
225
226 void silc_client_del_socket(SilcClient client, SilcSocketConnection sock)
227 {
228   int i;
229
230   if (!client->sockets)
231     return;
232
233   for (i = 0; i < client->sockets_count; i++) {
234     if (client->sockets[i] == sock) {
235       silc_socket_free(sock);
236       client->sockets[i] = NULL;
237       return;
238     }
239   }
240 }
241
242 static int 
243 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
244 {
245   int sock;
246
247   /* XXX In the future we should give up this non-blocking connect all
248      together and use threads instead. */
249   /* Create connection to server asynchronously */
250   sock = silc_net_create_connection_async(ctx->port, ctx->host);
251   if (sock < 0)
252     return -1;
253
254   /* Register task that will receive the async connect and will
255      read the result. */
256   ctx->task = silc_schedule_task_add(ctx->client->schedule, sock, 
257                                      silc_client_connect_to_server_start,
258                                      (void *)ctx, 0, 0, 
259                                      SILC_TASK_FD,
260                                      SILC_TASK_PRI_NORMAL);
261   silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
262
263   ctx->sock = sock;
264
265   return sock;
266 }
267
268 /* Connects to remote server. This is the main routine used to connect
269    to SILC server. Returns -1 on error and the created socket otherwise. 
270    The `context' is user context that is saved into the SilcClientConnection
271    that is created after the connection is created. Note that application
272    may handle the connecting process outside the library. If this is the
273    case then this function is not used at all. When the connecting is
274    done the `connect' client operation is called. */
275
276 int silc_client_connect_to_server(SilcClient client, int port,
277                                   char *host, void *context)
278 {
279   SilcClientInternalConnectContext *ctx;
280   SilcClientConnection conn;
281   int sock;
282
283   SILC_LOG_DEBUG(("Connecting to port %d of server %s",
284                   port, host));
285
286   conn = silc_client_add_connection(client, host, port, context);
287
288   client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
289                    "Connecting to port %d of server %s", port, host);
290
291   /* Allocate internal context for connection process. This is
292      needed as we are doing async connecting. */
293   ctx = silc_calloc(1, sizeof(*ctx));
294   ctx->client = client;
295   ctx->conn = conn;
296   ctx->host = strdup(host);
297   ctx->port = port;
298   ctx->tries = 0;
299
300   /* Do the actual connecting process */
301   sock = silc_client_connect_to_server_internal(ctx);
302   if (sock == -1)
303     silc_client_del_connection(client, conn);
304   return sock;
305 }
306
307 /* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
308    key material between client and server.  This function can be called
309    directly if application is performing its own connecting and does not
310    use the connecting provided by this library. This function is normally
311    used only if the application performed the connecting outside the library.
312    The library however may use this internally. */
313
314 int silc_client_start_key_exchange(SilcClient client,
315                                    SilcClientConnection conn,
316                                    int fd)
317 {
318   SilcProtocol protocol;
319   SilcClientKEInternalContext *proto_ctx;
320   void *context;
321
322   /* Allocate new socket connection object */
323   silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
324
325   /* Sometimes when doing quick reconnects the new socket may be same as
326      the old one and there might be pending stuff for the old socket. 
327      If new one is same then those pending sutff might cause problems.
328      Make sure they do not do that. */
329   silc_schedule_task_del_by_fd(client->schedule, fd);
330
331   conn->nickname = strdup(client->username);
332   conn->sock->hostname = conn->remote_host;
333   conn->sock->ip = strdup(conn->remote_host);
334   conn->sock->port = conn->remote_port;
335
336   /* Allocate internal Key Exchange context. This is sent to the
337      protocol as context. */
338   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
339   proto_ctx->client = (void *)client;
340   proto_ctx->sock = silc_socket_dup(conn->sock);
341   proto_ctx->rng = client->rng;
342   proto_ctx->responder = FALSE;
343   proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
344   proto_ctx->verify = silc_client_protocol_ke_verify_key;
345
346   /* Perform key exchange protocol. silc_client_connect_to_server_final
347      will be called after the protocol is finished. */
348   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
349                       &protocol, (void *)proto_ctx,
350                       silc_client_connect_to_server_second);
351   if (!protocol) {
352     client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
353                      "Error: Could not start authentication protocol");
354     return FALSE;
355   }
356   conn->sock->protocol = protocol;
357
358   /* Register the connection for network input and output. This sets
359      that scheduler will listen for incoming packets for this connection 
360      and sets that outgoing packets may be sent to this connection as well.
361      However, this doesn't set the scheduler for outgoing traffic, it will 
362      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
363      later when outgoing data is available. */
364   context = (void *)client;
365   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
366
367   /* Execute the protocol */
368   silc_protocol_execute(protocol, client->schedule, 0, 0);
369   return TRUE;
370 }
371
372 /* Start of the connection to the remote server. This is called after
373    succesful TCP/IP connection has been established to the remote host. */
374
375 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
376 {
377   SilcClientInternalConnectContext *ctx =
378     (SilcClientInternalConnectContext *)context;
379   SilcClient client = ctx->client;
380   SilcClientConnection conn = ctx->conn;
381   int opt, opt_len = sizeof(opt);
382
383   SILC_LOG_DEBUG(("Start"));
384
385   /* Check the socket status as it might be in error */
386   silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
387   if (opt != 0) {
388     if (ctx->tries < 2) {
389       /* Connection failed but lets try again */
390       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
391                        "Could not connect to server %s: %s",
392                        ctx->host, strerror(opt));
393       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
394                        "Connecting to port %d of server %s resumed", 
395                        ctx->port, ctx->host);
396
397       /* Unregister old connection try */
398       silc_schedule_unset_listen_fd(client->schedule, fd);
399       silc_net_close_connection(fd);
400       silc_schedule_task_del(client->schedule, ctx->task);
401
402       /* Try again */
403       silc_client_connect_to_server_internal(ctx);
404       ctx->tries++;
405     } else {
406       /* Connection failed and we won't try anymore */
407       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
408                        "Could not connect to server %s: %s",
409                        ctx->host, strerror(opt));
410       silc_schedule_unset_listen_fd(client->schedule, fd);
411       silc_net_close_connection(fd);
412       silc_schedule_task_del(client->schedule, ctx->task);
413       silc_free(ctx);
414
415       /* Notify application of failure */
416       client->ops->connect(client, conn, FALSE);
417       silc_client_del_connection(client, conn);
418     }
419     return;
420   }
421
422   silc_schedule_unset_listen_fd(client->schedule, fd);
423   silc_schedule_task_del(client->schedule, ctx->task);
424   silc_free(ctx);
425
426   if (!silc_client_start_key_exchange(client, conn, fd)) {
427     silc_net_close_connection(fd);
428     client->ops->connect(client, conn, FALSE);
429   }
430 }
431
432 /* Second part of the connecting to the server. This executed 
433    authentication protocol. */
434
435 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
436 {
437   SilcProtocol protocol = (SilcProtocol)context;
438   SilcClientKEInternalContext *ctx = 
439     (SilcClientKEInternalContext *)protocol->context;
440   SilcClient client = (SilcClient)ctx->client;
441   SilcSocketConnection sock = NULL;
442   SilcClientConnAuthInternalContext *proto_ctx;
443
444   SILC_LOG_DEBUG(("Start"));
445
446   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
447       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
448     /* Error occured during protocol */
449     SILC_LOG_DEBUG(("Error during KE protocol"));
450     silc_protocol_free(protocol);
451     silc_ske_free_key_material(ctx->keymat);
452     if (ctx->ske)
453       silc_ske_free(ctx->ske);
454     if (ctx->dest_id)
455       silc_free(ctx->dest_id);
456     ctx->sock->protocol = NULL;
457     silc_socket_free(ctx->sock);
458
459     /* Notify application of failure */
460     client->ops->connect(client, ctx->sock->user_data, FALSE);
461     silc_free(ctx);
462     return;
463   }
464
465   /* We now have the key material as the result of the key exchange
466      protocol. Take the key material into use. Free the raw key material
467      as soon as we've set them into use. */
468   silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
469                                    ctx->ske->prop->cipher,
470                                    ctx->ske->prop->pkcs,
471                                    ctx->ske->prop->hash,
472                                    ctx->ske->prop->hmac,
473                                    ctx->ske->prop->group);
474   silc_ske_free_key_material(ctx->keymat);
475
476   /* Allocate internal context for the authentication protocol. This
477      is sent as context for the protocol. */
478   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
479   proto_ctx->client = (void *)client;
480   proto_ctx->sock = sock = ctx->sock;
481   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
482   proto_ctx->dest_id_type = ctx->dest_id_type;
483   proto_ctx->dest_id = ctx->dest_id;
484
485   /* Resolve the authentication method to be used in this connection */
486   if (!client->ops->get_auth_method(client, sock->user_data, sock->hostname,
487                                     sock->port, &proto_ctx->auth_meth,
488                                     &proto_ctx->auth_data, 
489                                     &proto_ctx->auth_data_len))
490     proto_ctx->auth_meth = SILC_AUTH_NONE;
491
492   /* Free old protocol as it is finished now */
493   silc_protocol_free(protocol);
494   if (ctx->packet)
495     silc_packet_context_free(ctx->packet);
496   silc_free(ctx);
497   sock->protocol = NULL;
498
499   /* Allocate the authenteication protocol and execute it. */
500   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH, 
501                       &sock->protocol, (void *)proto_ctx, 
502                       silc_client_connect_to_server_final);
503
504   /* Execute the protocol */
505   silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
506 }
507
508 /* Finalizes the connection to the remote SILC server. This is called
509    after authentication protocol has been completed. This send our
510    user information to the server to receive our client ID from
511    server. */
512
513 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
514 {
515   SilcProtocol protocol = (SilcProtocol)context;
516   SilcClientConnAuthInternalContext *ctx = 
517     (SilcClientConnAuthInternalContext *)protocol->context;
518   SilcClient client = (SilcClient)ctx->client;
519   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
520   SilcBuffer packet;
521
522   SILC_LOG_DEBUG(("Start"));
523
524   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
525       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
526     /* Error occured during protocol */
527     SILC_LOG_DEBUG(("Error during authentication protocol"));
528     silc_protocol_free(protocol);
529     if (ctx->auth_data)
530       silc_free(ctx->auth_data);
531     if (ctx->ske)
532       silc_ske_free(ctx->ske);
533     if (ctx->dest_id)
534       silc_free(ctx->dest_id);
535     conn->sock->protocol = NULL;
536     silc_socket_free(ctx->sock);
537
538     /* Notify application of failure */
539     client->ops->connect(client, ctx->sock->user_data, FALSE);
540     silc_free(ctx);
541     return;
542   }
543
544   /* Send NEW_CLIENT packet to the server. We will become registered
545      to the SILC network after sending this packet and we will receive
546      client ID from the server. */
547   packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + 
548                              strlen(client->realname));
549   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
550   silc_buffer_format(packet,
551                      SILC_STR_UI_SHORT(strlen(client->username)),
552                      SILC_STR_UI_XNSTRING(client->username,
553                                           strlen(client->username)),
554                      SILC_STR_UI_SHORT(strlen(client->realname)),
555                      SILC_STR_UI_XNSTRING(client->realname,
556                                           strlen(client->realname)),
557                      SILC_STR_END);
558
559   /* Send the packet */
560   silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
561                           NULL, 0, NULL, NULL, 
562                           packet->data, packet->len, TRUE);
563   silc_buffer_free(packet);
564
565   /* Save remote ID. */
566   conn->remote_id = ctx->dest_id;
567   conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
568   conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
569
570   /* Register re-key timeout */
571   conn->rekey->timeout = client->params->rekey_secs;
572   conn->rekey->context = (void *)client;
573   silc_schedule_task_add(client->schedule, conn->sock->sock, 
574                      silc_client_rekey_callback,
575                      (void *)conn->sock, conn->rekey->timeout, 0,
576                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
577
578   silc_protocol_free(protocol);
579   if (ctx->auth_data)
580     silc_free(ctx->auth_data);
581   if (ctx->ske)
582     silc_ske_free(ctx->ske);
583   silc_socket_free(ctx->sock);
584   silc_free(ctx);
585   conn->sock->protocol = NULL;
586 }
587
588 /* Internal routine that sends packet or marks packet to be sent. This
589    is used directly only in special cases. Normal cases should use
590    silc_server_packet_send. Returns < 0 on error. */
591
592 int silc_client_packet_send_real(SilcClient client,
593                                  SilcSocketConnection sock,
594                                  bool force_send,
595                                  bool flush)
596 {
597   int ret;
598
599   /* If rekey protocol is active we must assure that all packets are
600      sent through packet queue. */
601   if (flush == FALSE && SILC_CLIENT_IS_REKEY(sock))
602     force_send = FALSE;
603
604   /* Send the packet */
605   ret = silc_packet_send(sock, force_send);
606   if (ret != -2)
607     return ret;
608
609   /* Mark that there is some outgoing data available for this connection. 
610      This call sets the connection both for input and output (the input
611      is set always and this call keeps the input setting, actually). 
612      Actual data sending is performed by silc_client_packet_process. */
613   SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
614
615   /* Mark to socket that data is pending in outgoing buffer. This flag
616      is needed if new data is added to the buffer before the earlier
617      put data is sent to the network. */
618   SILC_SET_OUTBUF_PENDING(sock);
619
620   return 0;
621 }
622
623 /* Packet processing callback. This is used to send and receive packets
624    from network. This is generic task. */
625
626 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
627 {
628   SilcClient client = (SilcClient)context;
629   SilcSocketConnection sock = NULL;
630   SilcClientConnection conn;
631   int ret;
632
633   SILC_LOG_DEBUG(("Processing packet"));
634
635   SILC_CLIENT_GET_SOCK(client, fd, sock);
636   if (sock == NULL)
637     return;
638
639   conn = (SilcClientConnection)sock->user_data;
640
641   /* Packet sending */
642   if (type == SILC_TASK_WRITE) {
643     SILC_LOG_DEBUG(("Writing data to connection"));
644
645     if (sock->outbuf->data - sock->outbuf->head)
646       silc_buffer_push(sock->outbuf, 
647                        sock->outbuf->data - sock->outbuf->head);
648
649     ret = silc_client_packet_send_real(client, sock, TRUE, TRUE);
650
651     /* If returned -2 could not write to connection now, will do
652        it later. */
653     if (ret == -2)
654       return;
655     
656     /* The packet has been sent and now it is time to set the connection
657        back to only for input. When there is again some outgoing data 
658        available for this connection it will be set for output as well. 
659        This call clears the output setting and sets it only for input. */
660     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
661     SILC_UNSET_OUTBUF_PENDING(sock);
662
663     silc_buffer_clear(sock->outbuf);
664     return;
665   }
666
667   /* Packet receiving */
668   if (type == SILC_TASK_READ) {
669     SILC_LOG_DEBUG(("Reading data from connection"));
670
671     /* Read data from network */
672     ret = silc_packet_receive(sock);
673     if (ret < 0)
674       return;
675     
676     /* EOF */
677     if (ret == 0) {
678       SILC_LOG_DEBUG(("Read EOF"));
679
680       /* If connection is disconnecting already we will finally
681          close the connection */
682       if (SILC_IS_DISCONNECTING(sock)) {
683         if (sock == conn->sock)
684           client->ops->disconnect(client, conn);
685         silc_client_close_connection(client, sock, conn);
686         return;
687       }
688       
689       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
690       if (sock == conn->sock)
691         client->ops->disconnect(client, conn);
692       silc_client_close_connection(client, sock, conn);
693       return;
694     }
695
696     /* Process the packet. This will call the parser that will then
697        decrypt and parse the packet. */
698     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
699       silc_packet_receive_process(sock, conn->receive_key, conn->hmac_receive,
700                                   silc_client_packet_parse, client);
701     else
702       silc_packet_receive_process(sock, NULL, NULL,
703                                   silc_client_packet_parse, client);
704   }
705 }
706
707 /* Callback function that the silc_packet_decrypt will call to make the
708    decision whether the packet is normal or special packet. We will 
709    return TRUE if it is normal and FALSE if it is special */
710
711 static int silc_client_packet_decrypt_check(SilcPacketType packet_type,
712                                             SilcBuffer buffer,
713                                             SilcPacketContext *packet,
714                                             void *context)
715 {
716
717   /* Packet is normal packet, if: 
718
719      1) packet is private message packet and does not have private key set
720      2) is other packet than channel message packet
721
722      all other packets are special packets 
723   */
724
725   if (packet_type == SILC_PACKET_PRIVATE_MESSAGE &&
726       (buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
727     return FALSE;
728
729   if (packet_type != SILC_PACKET_CHANNEL_MESSAGE)
730     return TRUE;
731
732   return FALSE;
733 }
734
735 /* Parses whole packet, received earlier. */
736
737 SILC_TASK_CALLBACK(silc_client_packet_parse_real)
738 {
739   SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
740   SilcClient client = (SilcClient)parse_ctx->context;
741   SilcPacketContext *packet = parse_ctx->packet;
742   SilcBuffer buffer = packet->buffer;
743   SilcSocketConnection sock = parse_ctx->sock;
744   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
745   int ret;
746
747   SILC_LOG_DEBUG(("Start"));
748
749   /* Decrypt the received packet */
750   if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
751     ret = silc_packet_decrypt(conn->receive_key, conn->hmac_receive, 
752                               buffer, packet,
753                               silc_client_packet_decrypt_check, parse_ctx);
754   else
755     ret = silc_packet_decrypt(NULL, NULL, buffer, packet,
756                               silc_client_packet_decrypt_check, parse_ctx);
757
758   if (ret < 0)
759     goto out;
760
761   if (ret == 0) {
762     /* Parse the packet. Packet type is returned. */
763     ret = silc_packet_parse(packet);
764   } else {
765     /* Parse the packet header in special way as this is "special"
766        packet type. */
767     ret = silc_packet_parse_special(packet);
768   }
769
770   if (ret == SILC_PACKET_NONE)
771     goto out;
772
773   /* Parse the incoming packet type */
774   silc_client_packet_parse_type(client, sock, packet);
775
776  out:
777   /*  silc_buffer_clear(sock->inbuf); */
778   silc_packet_context_free(packet);
779   silc_free(parse_ctx);
780 }
781
782 /* Parser callback called by silc_packet_receive_process. Thie merely
783    registers timeout that will handle the actual parsing when appropriate. */
784
785 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
786 {
787   SilcClient client = (SilcClient)parser_context->context;
788
789   /* Parse the packet */
790   silc_schedule_task_add(client->schedule, parser_context->sock->sock, 
791                      silc_client_packet_parse_real,
792                      (void *)parser_context, 0, 1, 
793                      SILC_TASK_TIMEOUT,
794                      SILC_TASK_PRI_NORMAL);
795 }
796
797 /* Parses the packet type and calls what ever routines the packet type
798    requires. This is done for all incoming packets. */
799
800 void silc_client_packet_parse_type(SilcClient client, 
801                                    SilcSocketConnection sock,
802                                    SilcPacketContext *packet)
803 {
804   SilcBuffer buffer = packet->buffer;
805   SilcPacketType type = packet->type;
806
807   SILC_LOG_DEBUG(("Parsing packet type %d", type));
808
809   /* Parse the packet type */
810   switch(type) {
811   case SILC_PACKET_DISCONNECT:
812     silc_client_disconnected_by_server(client, sock, buffer);
813     break;
814   case SILC_PACKET_SUCCESS:
815     /*
816      * Success received for something. For now we can have only
817      * one protocol for connection executing at once hence this
818      * success message is for whatever protocol is executing currently.
819      */
820     if (sock->protocol)
821       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
822     break;
823   case SILC_PACKET_FAILURE:
824     /*
825      * Failure received for some protocol. Set the protocol state to 
826      * error and call the protocol callback. This fill cause error on
827      * protocol and it will call the final callback.
828      */
829     silc_client_process_failure(client, sock, packet);
830     break;
831   case SILC_PACKET_REJECT:
832     break;
833
834   case SILC_PACKET_NOTIFY:
835     /*
836      * Received notify message 
837      */
838     silc_client_notify_by_server(client, sock, packet);
839     break;
840
841   case SILC_PACKET_ERROR:
842     /*
843      * Received error message
844      */
845     silc_client_error_by_server(client, sock, buffer);
846     break;
847
848   case SILC_PACKET_CHANNEL_MESSAGE:
849     /*
850      * Received message to (from, actually) a channel
851      */
852     silc_client_channel_message(client, sock, packet);
853     break;
854   case SILC_PACKET_CHANNEL_KEY:
855     /*
856      * Received key for a channel. By receiving this key the client will be
857      * able to talk to the channel it has just joined. This can also be
858      * a new key for existing channel as keys expire peridiocally.
859      */
860     silc_client_receive_channel_key(client, sock, buffer);
861     break;
862
863   case SILC_PACKET_PRIVATE_MESSAGE:
864     /*
865      * Received private message
866      */
867     silc_client_private_message(client, sock, packet);
868     break;
869   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
870     /*
871      * Received private message key
872      */
873     break;
874
875   case SILC_PACKET_COMMAND_REPLY:
876     /*
877      * Recived reply for a command
878      */
879     silc_client_command_reply_process(client, sock, packet);
880     break;
881
882   case SILC_PACKET_KEY_EXCHANGE:
883     if (sock->protocol && sock->protocol->protocol && 
884         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
885       SilcClientKEInternalContext *proto_ctx = 
886         (SilcClientKEInternalContext *)sock->protocol->context;
887
888       proto_ctx->packet = silc_packet_context_dup(packet);
889       proto_ctx->dest_id_type = packet->src_id_type;
890       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
891                                           packet->src_id_type);
892       if (!proto_ctx->dest_id)
893         break;
894
895       /* Let the protocol handle the packet */
896       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
897     } else {
898       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
899                       "protocol active, packet dropped."));
900     }
901     break;
902
903   case SILC_PACKET_KEY_EXCHANGE_1:
904     if (sock->protocol && sock->protocol->protocol && 
905         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
906          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
907
908       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
909         SilcClientRekeyInternalContext *proto_ctx = 
910           (SilcClientRekeyInternalContext *)sock->protocol->context;
911         
912         if (proto_ctx->packet)
913           silc_packet_context_free(proto_ctx->packet);
914         
915         proto_ctx->packet = silc_packet_context_dup(packet);
916
917         /* Let the protocol handle the packet */
918         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
919       } else {
920         SilcClientKEInternalContext *proto_ctx = 
921           (SilcClientKEInternalContext *)sock->protocol->context;
922         
923         if (proto_ctx->packet)
924           silc_packet_context_free(proto_ctx->packet);
925         
926         proto_ctx->packet = silc_packet_context_dup(packet);
927         proto_ctx->dest_id_type = packet->src_id_type;
928         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
929                                             packet->src_id_type);
930         if (!proto_ctx->dest_id)
931           break;
932         
933         /* Let the protocol handle the packet */
934         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
935       }
936     } else {
937       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
938                       "protocol active, packet dropped."));
939     }
940     break;
941   case SILC_PACKET_KEY_EXCHANGE_2:
942     if (sock->protocol && sock->protocol->protocol && 
943         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
944          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
945
946       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
947         SilcClientRekeyInternalContext *proto_ctx = 
948           (SilcClientRekeyInternalContext *)sock->protocol->context;
949         
950         if (proto_ctx->packet)
951           silc_packet_context_free(proto_ctx->packet);
952         
953         proto_ctx->packet = silc_packet_context_dup(packet);
954
955         /* Let the protocol handle the packet */
956         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
957       } else {
958         SilcClientKEInternalContext *proto_ctx = 
959           (SilcClientKEInternalContext *)sock->protocol->context;
960         
961         if (proto_ctx->packet)
962           silc_packet_context_free(proto_ctx->packet);
963         
964         proto_ctx->packet = silc_packet_context_dup(packet);
965         proto_ctx->dest_id_type = packet->src_id_type;
966         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
967                                             packet->src_id_type);
968         if (!proto_ctx->dest_id)
969           break;
970         
971         /* Let the protocol handle the packet */
972         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
973       }
974     } else {
975       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
976                       "protocol active, packet dropped."));
977     }
978     break;
979
980   case SILC_PACKET_NEW_ID:
981     {
982       /*
983        * Received new ID from server. This packet is received at
984        * the connection to the server.  New ID is also received when 
985        * user changes nickname but in that case the new ID is received
986        * as command reply and not as this packet type.
987        */
988       SilcIDPayload idp;
989
990       idp = silc_id_payload_parse(buffer);
991       if (!idp)
992         break;
993       if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
994         break;
995
996       silc_client_receive_new_id(client, sock, idp);
997       silc_id_payload_free(idp);
998       break;
999     }
1000
1001   case SILC_PACKET_HEARTBEAT:
1002     /*
1003      * Received heartbeat packet
1004      */
1005     SILC_LOG_DEBUG(("Heartbeat packet"));
1006     break;
1007
1008   case SILC_PACKET_KEY_AGREEMENT:
1009     /*
1010      * Received key agreement packet
1011      */
1012     SILC_LOG_DEBUG(("Key agreement packet"));
1013     silc_client_key_agreement(client, sock, packet);
1014     break;
1015
1016   case SILC_PACKET_REKEY:
1017     SILC_LOG_DEBUG(("Re-key packet"));
1018     /* We ignore this for now */
1019     break;
1020
1021   case SILC_PACKET_REKEY_DONE:
1022     SILC_LOG_DEBUG(("Re-key done packet"));
1023
1024     if (sock->protocol && sock->protocol->protocol && 
1025         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1026
1027       SilcClientRekeyInternalContext *proto_ctx = 
1028         (SilcClientRekeyInternalContext *)sock->protocol->context;
1029       
1030       if (proto_ctx->packet)
1031         silc_packet_context_free(proto_ctx->packet);
1032       
1033       proto_ctx->packet = silc_packet_context_dup(packet);
1034
1035       /* Let the protocol handle the packet */
1036       if (proto_ctx->responder == FALSE)
1037         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1038       else
1039         /* Let the protocol handle the packet */
1040         silc_protocol_execute(sock->protocol, client->schedule, 
1041                               0, 100000);
1042     } else {
1043       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1044                       "protocol active, packet dropped."));
1045     }
1046     break;
1047
1048   default:
1049     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1050     break;
1051   }
1052 }
1053
1054 /* Sends packet. This doesn't actually send the packet instead it assembles
1055    it and marks it to be sent. However, if force_send is TRUE the packet
1056    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1057    will be derived from sock argument. Otherwise the valid arguments sent
1058    are used. */
1059
1060 void silc_client_packet_send(SilcClient client, 
1061                              SilcSocketConnection sock,
1062                              SilcPacketType type, 
1063                              void *dst_id,
1064                              SilcIdType dst_id_type,
1065                              SilcCipher cipher,
1066                              SilcHmac hmac,
1067                              unsigned char *data, 
1068                              uint32 data_len, 
1069                              int force_send)
1070 {
1071   SilcPacketContext packetdata;
1072
1073   if (!sock)
1074     return;
1075
1076   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1077
1078   /* Get data used in the packet sending, keys and stuff */
1079   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1080     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1081       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1082
1083     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1084       hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1085
1086     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1087       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1088       dst_id_type = SILC_ID_SERVER;
1089     }
1090   }
1091
1092   /* Set the packet context pointers */
1093   packetdata.flags = 0;
1094   packetdata.type = type;
1095   if (sock->user_data && 
1096       ((SilcClientConnection)sock->user_data)->local_id_data) {
1097     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1098     packetdata.src_id_len = 
1099       silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
1100                       SILC_ID_CLIENT);
1101   } else { 
1102     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1103     packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1104   }
1105   packetdata.src_id_type = SILC_ID_CLIENT;
1106   if (dst_id) {
1107     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1108     packetdata.dst_id_len = silc_id_get_len(dst_id, dst_id_type);
1109     packetdata.dst_id_type = dst_id_type;
1110   } else {
1111     packetdata.dst_id = NULL;
1112     packetdata.dst_id_len = 0;
1113     packetdata.dst_id_type = SILC_ID_NONE;
1114   }
1115   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1116     packetdata.src_id_len + packetdata.dst_id_len;
1117   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1118
1119   /* Prepare outgoing data buffer for packet sending */
1120   silc_packet_send_prepare(sock, 
1121                            SILC_PACKET_HEADER_LEN +
1122                            packetdata.src_id_len + 
1123                            packetdata.dst_id_len,
1124                            packetdata.padlen,
1125                            data_len);
1126
1127   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1128
1129   packetdata.buffer = sock->outbuf;
1130
1131   /* Put the data to the buffer */
1132   if (data && data_len)
1133     silc_buffer_put(sock->outbuf, data, data_len);
1134
1135   /* Create the outgoing packet */
1136   silc_packet_assemble(&packetdata);
1137
1138   /* Encrypt the packet */
1139   if (cipher)
1140     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1141
1142   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1143                    sock->outbuf->data, sock->outbuf->len);
1144
1145   /* Now actually send the packet */
1146   silc_client_packet_send_real(client, sock, force_send, FALSE);
1147 }
1148
1149 /* Closes connection to remote end. Free's all allocated data except
1150    for some information such as nickname etc. that are valid at all time. 
1151    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1152    provided it will be checked whether the sock and `conn->sock' are the
1153    same (they can be different, ie. a socket can use `conn' as its
1154    connection but `conn->sock' might be actually a different connection
1155    than the `sock'). */
1156
1157 void silc_client_close_connection(SilcClient client,
1158                                   SilcSocketConnection sock,
1159                                   SilcClientConnection conn)
1160 {
1161   int del = FALSE;
1162
1163   if (!sock || (sock && conn->sock == sock))
1164     del = TRUE;
1165   if (!sock)
1166     sock = conn->sock;
1167
1168   /* We won't listen for this connection anymore */
1169   silc_schedule_unset_listen_fd(client->schedule, sock->sock);
1170
1171   /* Unregister all tasks */
1172   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1173   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1174
1175   /* Close the actual connection */
1176   silc_net_close_connection(sock->sock);
1177
1178   /* Cancel any active protocol */
1179   if (sock->protocol) {
1180     if (sock->protocol->protocol->type == 
1181         SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1182         sock->protocol->protocol->type == 
1183         SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
1184       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1185       silc_protocol_execute_final(sock->protocol, client->schedule);
1186       /* The application will recall this function with these protocols
1187          (the ops->connect client operation). */
1188       return;
1189     } else {
1190       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1191       silc_protocol_execute_final(sock->protocol, client->schedule);
1192       sock->protocol = NULL;
1193     }
1194   }
1195
1196   /* Free everything */
1197   if (del && sock->user_data) {
1198     /* Free all cache entries */
1199     SilcIDCacheList list;
1200     SilcIDCacheEntry entry;
1201     bool ret;
1202
1203     if (silc_idcache_get_all(conn->client_cache, &list)) {
1204       ret = silc_idcache_list_first(list, &entry);
1205       while (ret) {
1206         silc_client_del_client(client, conn, entry->context);
1207         ret = silc_idcache_list_next(list, &entry);
1208       }
1209       silc_idcache_list_free(list);
1210     }
1211
1212     if (silc_idcache_get_all(conn->channel_cache, &list)) {
1213       ret = silc_idcache_list_first(list, &entry);
1214       while (ret) {
1215         silc_client_del_channel(client, conn, entry->context);
1216         ret = silc_idcache_list_next(list, &entry);
1217       }
1218       silc_idcache_list_free(list);
1219     }
1220
1221     if (silc_idcache_get_all(conn->server_cache, &list)) {
1222       ret = silc_idcache_list_first(list, &entry);
1223       while (ret) {
1224         silc_client_del_server(client, conn, entry->context);
1225         ret = silc_idcache_list_next(list, &entry);
1226       }
1227       silc_idcache_list_free(list);
1228     }
1229
1230     /* Clear ID caches */
1231     if (conn->client_cache)
1232       silc_idcache_del_all(conn->client_cache);
1233     if (conn->channel_cache)
1234       silc_idcache_del_all(conn->channel_cache);
1235     if (conn->server_cache)
1236       silc_idcache_del_all(conn->server_cache);
1237
1238     /* Free data (my ID is freed in above silc_client_del_client) */
1239     if (conn->remote_host)
1240       silc_free(conn->remote_host);
1241     if (conn->local_id_data)
1242       silc_free(conn->local_id_data);
1243     if (conn->send_key)
1244       silc_cipher_free(conn->send_key);
1245     if (conn->receive_key)
1246       silc_cipher_free(conn->receive_key);
1247     if (conn->hmac_send)        /* conn->hmac_receive is same */
1248       silc_hmac_free(conn->hmac_send);
1249     if (conn->pending_commands)
1250       silc_dlist_uninit(conn->pending_commands);
1251     if (conn->rekey)
1252       silc_free(conn->rekey);
1253
1254     memset(conn, 0, sizeof(*conn));
1255     silc_client_del_connection(client, conn);
1256   }
1257
1258   silc_socket_free(sock);
1259 }
1260
1261 /* Called when we receive disconnection packet from server. This 
1262    closes our end properly and displays the reason of the disconnection
1263    on the screen. */
1264
1265 void silc_client_disconnected_by_server(SilcClient client,
1266                                         SilcSocketConnection sock,
1267                                         SilcBuffer message)
1268 {
1269   char *msg;
1270
1271   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1272
1273   msg = silc_calloc(message->len + 1, sizeof(char));
1274   memcpy(msg, message->data, message->len);
1275   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1276   silc_free(msg);
1277
1278   SILC_SET_DISCONNECTED(sock);
1279   silc_client_close_connection(client, sock, sock->user_data);
1280 }
1281
1282 /* Received error message from server. Display it on the screen. 
1283    We don't take any action what so ever of the error message. */
1284
1285 void silc_client_error_by_server(SilcClient client,
1286                                  SilcSocketConnection sock,
1287                                  SilcBuffer message)
1288 {
1289   char *msg;
1290
1291   msg = silc_calloc(message->len + 1, sizeof(char));
1292   memcpy(msg, message->data, message->len);
1293   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1294   silc_free(msg);
1295 }
1296
1297 /* Processes the received new Client ID from server. Old Client ID is
1298    deleted from cache and new one is added. */
1299
1300 void silc_client_receive_new_id(SilcClient client,
1301                                 SilcSocketConnection sock,
1302                                 SilcIDPayload idp)
1303 {
1304   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1305   int connecting = FALSE;
1306   SilcBuffer sidp;
1307
1308   if (!conn->local_entry)
1309     connecting = TRUE;
1310
1311   /* Delete old ID from ID cache */
1312   if (conn->local_id) {
1313     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
1314     silc_free(conn->local_id);
1315   }
1316   
1317   /* Save the new ID */
1318
1319   if (conn->local_id_data)
1320     silc_free(conn->local_id_data);
1321
1322   conn->local_id = silc_id_payload_get_id(idp);
1323   conn->local_id_data = silc_id_payload_get_data(idp);
1324   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1325
1326   if (!conn->local_entry)
1327     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1328
1329   conn->local_entry->nickname = conn->nickname;
1330   if (!conn->local_entry->username) {
1331     conn->local_entry->username = 
1332       silc_calloc(strlen(client->username) + strlen(client->hostname) + 1,
1333                   sizeof(conn->local_entry->username));
1334     sprintf(conn->local_entry->username, "%s@%s", client->username,
1335             client->hostname);
1336   }
1337   conn->local_entry->server = strdup(conn->remote_host);
1338   conn->local_entry->id = conn->local_id;
1339   
1340   /* Put it to the ID cache */
1341   silc_idcache_add(conn->client_cache, conn->nickname, conn->local_id, 
1342                    (void *)conn->local_entry, FALSE);
1343
1344   /* Issue INFO command to fetch the real server name and server information
1345      and other stuff. */
1346   sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1347   silc_client_send_command(client, conn, SILC_COMMAND_INFO,
1348                            ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1349   silc_buffer_free(sidp);
1350
1351   /* Notify application of successful connection. We do it here now that
1352      we've received the Client ID and are allowed to send traffic. */
1353   if (connecting)
1354     client->ops->connect(client, conn, TRUE);
1355 }
1356
1357 /* Processed received Channel ID for a channel. This is called when client
1358    joins to channel and server replies with channel ID. The ID is cached. 
1359    Returns the created channel entry. This is also called when received
1360    channel ID in for example USERS command reply that we do not have. */
1361
1362 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
1363                                             SilcSocketConnection sock,
1364                                             char *channel_name,
1365                                             uint32 mode, 
1366                                             SilcIDPayload idp)
1367 {
1368   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1369   SilcChannelEntry channel;
1370
1371   SILC_LOG_DEBUG(("New channel ID"));
1372
1373   channel = silc_calloc(1, sizeof(*channel));
1374   channel->channel_name = channel_name;
1375   channel->id = silc_id_payload_get_id(idp);
1376   channel->mode = mode;
1377   silc_list_init(channel->clients, struct SilcChannelUserStruct, next);
1378
1379   /* Put it to the ID cache */
1380   silc_idcache_add(conn->channel_cache, channel_name, (void *)channel->id, 
1381                    (void *)channel, FALSE);
1382
1383   return channel;
1384 }
1385
1386 /* Removes a client entry from all channel it has joined. This really is
1387    a performance killer (client_entry should have pointers to channel 
1388    entry list). */
1389
1390 void silc_client_remove_from_channels(SilcClient client,
1391                                       SilcClientConnection conn,
1392                                       SilcClientEntry client_entry)
1393 {
1394   SilcIDCacheEntry id_cache;
1395   SilcIDCacheList list;
1396   SilcChannelEntry channel;
1397   SilcChannelUser chu;
1398
1399   if (!silc_idcache_get_all(conn->channel_cache, &list))
1400     return;
1401
1402   silc_idcache_list_first(list, &id_cache);
1403   channel = (SilcChannelEntry)id_cache->context;
1404   
1405   while (channel) {
1406     
1407     /* Remove client from channel */
1408     silc_list_start(channel->clients);
1409     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1410       if (chu->client == client_entry) {
1411         silc_list_del(channel->clients, chu);
1412         silc_free(chu);
1413         break;
1414       }
1415     }
1416
1417     if (!silc_idcache_list_next(list, &id_cache))
1418       break;
1419     
1420     channel = (SilcChannelEntry)id_cache->context;
1421   }
1422
1423   silc_idcache_list_free(list);
1424 }
1425
1426 /* Replaces `old' client entries from all channels to `new' client entry.
1427    This can be called for example when nickname changes and old ID entry
1428    is replaced from ID cache with the new one. If the old ID entry is only
1429    updated, then this fucntion needs not to be called. */
1430
1431 void silc_client_replace_from_channels(SilcClient client, 
1432                                        SilcClientConnection conn,
1433                                        SilcClientEntry old,
1434                                        SilcClientEntry new)
1435 {
1436   SilcIDCacheEntry id_cache;
1437   SilcIDCacheList list;
1438   SilcChannelEntry channel;
1439   SilcChannelUser chu;
1440
1441   if (!silc_idcache_get_all(conn->channel_cache, &list))
1442     return;
1443
1444   silc_idcache_list_first(list, &id_cache);
1445   channel = (SilcChannelEntry)id_cache->context;
1446   
1447   while (channel) {
1448     
1449     /* Replace client entry */
1450     silc_list_start(channel->clients);
1451     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1452       if (chu->client == old) {
1453         chu->client = new;
1454         break;
1455       }
1456     }
1457
1458     if (!silc_idcache_list_next(list, &id_cache))
1459       break;
1460     
1461     channel = (SilcChannelEntry)id_cache->context;
1462   }
1463
1464   silc_idcache_list_free(list);
1465 }
1466
1467 /* Registers failure timeout to process the received failure packet
1468    with timeout. */
1469
1470 void silc_client_process_failure(SilcClient client,
1471                                  SilcSocketConnection sock,
1472                                  SilcPacketContext *packet)
1473 {
1474   uint32 failure = 0;
1475
1476   if (sock->protocol) {
1477     if (packet->buffer->len >= 4)
1478       SILC_GET32_MSB(failure, packet->buffer->data);
1479
1480     /* Notify application */
1481     client->ops->failure(client, sock->user_data, sock->protocol,
1482                          (void *)failure);
1483   }
1484 }
1485
1486 /* A timeout callback for the re-key. We will be the initiator of the
1487    re-key protocol. */
1488
1489 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1490 {
1491   SilcSocketConnection sock = (SilcSocketConnection)context;
1492   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1493   SilcClient client = (SilcClient)conn->rekey->context;
1494   SilcProtocol protocol;
1495   SilcClientRekeyInternalContext *proto_ctx;
1496
1497   SILC_LOG_DEBUG(("Start"));
1498
1499   /* Allocate internal protocol context. This is sent as context
1500      to the protocol. */
1501   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1502   proto_ctx->client = (void *)client;
1503   proto_ctx->sock = silc_socket_dup(sock);
1504   proto_ctx->responder = FALSE;
1505   proto_ctx->pfs = conn->rekey->pfs;
1506       
1507   /* Perform rekey protocol. Will call the final callback after the
1508      protocol is over. */
1509   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1510                       &protocol, proto_ctx, silc_client_rekey_final);
1511   sock->protocol = protocol;
1512       
1513   /* Run the protocol */
1514   silc_protocol_execute(protocol, client->schedule, 0, 0);
1515
1516   /* Re-register re-key timeout */
1517   silc_schedule_task_add(client->schedule, sock->sock, 
1518                      silc_client_rekey_callback,
1519                      context, conn->rekey->timeout, 0,
1520                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1521 }
1522
1523 /* The final callback for the REKEY protocol. This will actually take the
1524    new key material into use. */
1525
1526 SILC_TASK_CALLBACK(silc_client_rekey_final)
1527 {
1528   SilcProtocol protocol = (SilcProtocol)context;
1529   SilcClientRekeyInternalContext *ctx =
1530     (SilcClientRekeyInternalContext *)protocol->context;
1531   SilcClient client = (SilcClient)ctx->client;
1532   SilcSocketConnection sock = ctx->sock;
1533
1534   SILC_LOG_DEBUG(("Start"));
1535
1536   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1537       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1538     /* Error occured during protocol */
1539     silc_protocol_cancel(protocol, client->schedule);
1540     silc_protocol_free(protocol);
1541     sock->protocol = NULL;
1542     if (ctx->packet)
1543       silc_packet_context_free(ctx->packet);
1544     if (ctx->ske)
1545       silc_ske_free(ctx->ske);
1546     silc_socket_free(ctx->sock);
1547     silc_free(ctx);
1548     return;
1549   }
1550
1551   /* Cleanup */
1552   silc_protocol_free(protocol);
1553   sock->protocol = NULL;
1554   if (ctx->packet)
1555     silc_packet_context_free(ctx->packet);
1556   if (ctx->ske)
1557     silc_ske_free(ctx->ske);
1558   silc_socket_free(ctx->sock);
1559   silc_free(ctx);
1560 }