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   conn->nickname = strdup(client->username);
326   conn->sock->hostname = conn->remote_host;
327   conn->sock->ip = strdup(conn->remote_host);
328   conn->sock->port = conn->remote_port;
329
330   /* Allocate internal Key Exchange context. This is sent to the
331      protocol as context. */
332   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
333   proto_ctx->client = (void *)client;
334   proto_ctx->sock = silc_socket_dup(conn->sock);
335   proto_ctx->rng = client->rng;
336   proto_ctx->responder = FALSE;
337   proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
338   proto_ctx->verify = silc_client_protocol_ke_verify_key;
339
340   /* Perform key exchange protocol. silc_client_connect_to_server_final
341      will be called after the protocol is finished. */
342   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
343                       &protocol, (void *)proto_ctx,
344                       silc_client_connect_to_server_second);
345   if (!protocol) {
346     client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
347                      "Error: Could not start authentication protocol");
348     return FALSE;
349   }
350   conn->sock->protocol = protocol;
351
352   /* Register the connection for network input and output. This sets
353      that scheduler will listen for incoming packets for this connection 
354      and sets that outgoing packets may be sent to this connection as well.
355      However, this doesn't set the scheduler for outgoing traffic, it will 
356      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
357      later when outgoing data is available. */
358   context = (void *)client;
359   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
360
361   /* Execute the protocol */
362   silc_protocol_execute(protocol, client->schedule, 0, 0);
363   return TRUE;
364 }
365
366 /* Start of the connection to the remote server. This is called after
367    succesful TCP/IP connection has been established to the remote host. */
368
369 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
370 {
371   SilcClientInternalConnectContext *ctx =
372     (SilcClientInternalConnectContext *)context;
373   SilcClient client = ctx->client;
374   SilcClientConnection conn = ctx->conn;
375   int opt, opt_len = sizeof(opt);
376
377   SILC_LOG_DEBUG(("Start"));
378
379   /* Check the socket status as it might be in error */
380   silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
381   if (opt != 0) {
382     if (ctx->tries < 2) {
383       /* Connection failed but lets try again */
384       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
385                        "Could not connect to server %s: %s",
386                        ctx->host, strerror(opt));
387       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
388                        "Connecting to port %d of server %s resumed", 
389                        ctx->port, ctx->host);
390
391       /* Unregister old connection try */
392       silc_schedule_unset_listen_fd(client->schedule, fd);
393       silc_net_close_connection(fd);
394       silc_schedule_task_del(client->schedule, ctx->task);
395
396       /* Try again */
397       silc_client_connect_to_server_internal(ctx);
398       ctx->tries++;
399     } else {
400       /* Connection failed and we won't try anymore */
401       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
402                        "Could not connect to server %s: %s",
403                        ctx->host, strerror(opt));
404       silc_schedule_unset_listen_fd(client->schedule, fd);
405       silc_net_close_connection(fd);
406       silc_schedule_task_del(client->schedule, ctx->task);
407       silc_free(ctx);
408
409       /* Notify application of failure */
410       client->ops->connect(client, conn, FALSE);
411       silc_client_del_connection(client, conn);
412     }
413     return;
414   }
415
416   silc_schedule_unset_listen_fd(client->schedule, fd);
417   silc_schedule_task_del(client->schedule, ctx->task);
418   silc_free(ctx);
419
420   if (!silc_client_start_key_exchange(client, conn, fd)) {
421     silc_net_close_connection(fd);
422     client->ops->connect(client, conn, FALSE);
423   }
424 }
425
426 /* Second part of the connecting to the server. This executed 
427    authentication protocol. */
428
429 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
430 {
431   SilcProtocol protocol = (SilcProtocol)context;
432   SilcClientKEInternalContext *ctx = 
433     (SilcClientKEInternalContext *)protocol->context;
434   SilcClient client = (SilcClient)ctx->client;
435   SilcSocketConnection sock = NULL;
436   SilcClientConnAuthInternalContext *proto_ctx;
437
438   SILC_LOG_DEBUG(("Start"));
439
440   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
441       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
442     /* Error occured during protocol */
443     SILC_LOG_DEBUG(("Error during KE protocol"));
444     silc_protocol_free(protocol);
445     silc_ske_free_key_material(ctx->keymat);
446     if (ctx->ske)
447       silc_ske_free(ctx->ske);
448     if (ctx->dest_id)
449       silc_free(ctx->dest_id);
450     ctx->sock->protocol = NULL;
451     silc_socket_free(ctx->sock);
452
453     /* Notify application of failure */
454     client->ops->connect(client, ctx->sock->user_data, FALSE);
455     silc_free(ctx);
456     return;
457   }
458
459   /* We now have the key material as the result of the key exchange
460      protocol. Take the key material into use. Free the raw key material
461      as soon as we've set them into use. */
462   silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
463                                    ctx->ske->prop->cipher,
464                                    ctx->ske->prop->pkcs,
465                                    ctx->ske->prop->hash,
466                                    ctx->ske->prop->hmac,
467                                    ctx->ske->prop->group);
468   silc_ske_free_key_material(ctx->keymat);
469
470   /* Allocate internal context for the authentication protocol. This
471      is sent as context for the protocol. */
472   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
473   proto_ctx->client = (void *)client;
474   proto_ctx->sock = sock = ctx->sock;
475   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
476   proto_ctx->dest_id_type = ctx->dest_id_type;
477   proto_ctx->dest_id = ctx->dest_id;
478
479   /* Resolve the authentication method to be used in this connection */
480   if (!client->ops->get_auth_method(client, sock->user_data, sock->hostname,
481                                     sock->port, &proto_ctx->auth_meth,
482                                     &proto_ctx->auth_data, 
483                                     &proto_ctx->auth_data_len))
484     proto_ctx->auth_meth = SILC_AUTH_NONE;
485
486   /* Free old protocol as it is finished now */
487   silc_protocol_free(protocol);
488   if (ctx->packet)
489     silc_packet_context_free(ctx->packet);
490   silc_free(ctx);
491   sock->protocol = NULL;
492
493   /* Allocate the authenteication protocol and execute it. */
494   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH, 
495                       &sock->protocol, (void *)proto_ctx, 
496                       silc_client_connect_to_server_final);
497
498   /* Execute the protocol */
499   silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
500 }
501
502 /* Finalizes the connection to the remote SILC server. This is called
503    after authentication protocol has been completed. This send our
504    user information to the server to receive our client ID from
505    server. */
506
507 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
508 {
509   SilcProtocol protocol = (SilcProtocol)context;
510   SilcClientConnAuthInternalContext *ctx = 
511     (SilcClientConnAuthInternalContext *)protocol->context;
512   SilcClient client = (SilcClient)ctx->client;
513   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
514   SilcBuffer packet;
515
516   SILC_LOG_DEBUG(("Start"));
517
518   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
519       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
520     /* Error occured during protocol */
521     SILC_LOG_DEBUG(("Error during authentication protocol"));
522     silc_protocol_free(protocol);
523     if (ctx->auth_data)
524       silc_free(ctx->auth_data);
525     if (ctx->ske)
526       silc_ske_free(ctx->ske);
527     if (ctx->dest_id)
528       silc_free(ctx->dest_id);
529     conn->sock->protocol = NULL;
530     silc_socket_free(ctx->sock);
531
532     /* Notify application of failure */
533     client->ops->connect(client, ctx->sock->user_data, FALSE);
534     silc_free(ctx);
535     return;
536   }
537
538   /* Send NEW_CLIENT packet to the server. We will become registered
539      to the SILC network after sending this packet and we will receive
540      client ID from the server. */
541   packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + 
542                              strlen(client->realname));
543   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
544   silc_buffer_format(packet,
545                      SILC_STR_UI_SHORT(strlen(client->username)),
546                      SILC_STR_UI_XNSTRING(client->username,
547                                           strlen(client->username)),
548                      SILC_STR_UI_SHORT(strlen(client->realname)),
549                      SILC_STR_UI_XNSTRING(client->realname,
550                                           strlen(client->realname)),
551                      SILC_STR_END);
552
553   /* Send the packet */
554   silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
555                           NULL, 0, NULL, NULL, 
556                           packet->data, packet->len, TRUE);
557   silc_buffer_free(packet);
558
559   /* Save remote ID. */
560   conn->remote_id = ctx->dest_id;
561   conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
562   conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
563
564   /* Register re-key timeout */
565   conn->rekey->timeout = client->params->rekey_secs;
566   conn->rekey->context = (void *)client;
567   silc_schedule_task_add(client->schedule, conn->sock->sock, 
568                      silc_client_rekey_callback,
569                      (void *)conn->sock, conn->rekey->timeout, 0,
570                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
571
572   silc_protocol_free(protocol);
573   if (ctx->auth_data)
574     silc_free(ctx->auth_data);
575   if (ctx->ske)
576     silc_ske_free(ctx->ske);
577   silc_socket_free(ctx->sock);
578   silc_free(ctx);
579   conn->sock->protocol = NULL;
580 }
581
582 /* Internal routine that sends packet or marks packet to be sent. This
583    is used directly only in special cases. Normal cases should use
584    silc_server_packet_send. Returns < 0 on error. */
585
586 int silc_client_packet_send_real(SilcClient client,
587                                  SilcSocketConnection sock,
588                                  bool force_send,
589                                  bool flush)
590 {
591   int ret;
592
593   /* If rekey protocol is active we must assure that all packets are
594      sent through packet queue. */
595   if (flush == FALSE && SILC_CLIENT_IS_REKEY(sock))
596     force_send = FALSE;
597
598   /* Send the packet */
599   ret = silc_packet_send(sock, force_send);
600   if (ret != -2)
601     return ret;
602
603   /* Mark that there is some outgoing data available for this connection. 
604      This call sets the connection both for input and output (the input
605      is set always and this call keeps the input setting, actually). 
606      Actual data sending is performed by silc_client_packet_process. */
607   SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
608
609   /* Mark to socket that data is pending in outgoing buffer. This flag
610      is needed if new data is added to the buffer before the earlier
611      put data is sent to the network. */
612   SILC_SET_OUTBUF_PENDING(sock);
613
614   return 0;
615 }
616
617 /* Packet processing callback. This is used to send and receive packets
618    from network. This is generic task. */
619
620 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
621 {
622   SilcClient client = (SilcClient)context;
623   SilcSocketConnection sock = NULL;
624   SilcClientConnection conn;
625   int ret;
626
627   SILC_LOG_DEBUG(("Processing packet"));
628
629   SILC_CLIENT_GET_SOCK(client, fd, sock);
630   if (sock == NULL)
631     return;
632
633   conn = (SilcClientConnection)sock->user_data;
634
635   /* Packet sending */
636   if (type == SILC_TASK_WRITE) {
637     SILC_LOG_DEBUG(("Writing data to connection"));
638
639     if (sock->outbuf->data - sock->outbuf->head)
640       silc_buffer_push(sock->outbuf, 
641                        sock->outbuf->data - sock->outbuf->head);
642
643     ret = silc_client_packet_send_real(client, sock, TRUE, TRUE);
644
645     /* If returned -2 could not write to connection now, will do
646        it later. */
647     if (ret == -2)
648       return;
649     
650     /* The packet has been sent and now it is time to set the connection
651        back to only for input. When there is again some outgoing data 
652        available for this connection it will be set for output as well. 
653        This call clears the output setting and sets it only for input. */
654     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
655     SILC_UNSET_OUTBUF_PENDING(sock);
656
657     silc_buffer_clear(sock->outbuf);
658     return;
659   }
660
661   /* Packet receiving */
662   if (type == SILC_TASK_READ) {
663     SILC_LOG_DEBUG(("Reading data from connection"));
664
665     /* Read data from network */
666     ret = silc_packet_receive(sock);
667     if (ret < 0)
668       return;
669     
670     /* EOF */
671     if (ret == 0) {
672       SILC_LOG_DEBUG(("Read EOF"));
673
674       /* If connection is disconnecting already we will finally
675          close the connection */
676       if (SILC_IS_DISCONNECTING(sock)) {
677         if (sock == conn->sock)
678           client->ops->disconnect(client, conn);
679         silc_client_close_connection(client, sock, conn);
680         return;
681       }
682       
683       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
684       if (sock == conn->sock)
685         client->ops->disconnect(client, conn);
686       silc_client_close_connection(client, sock, conn);
687       return;
688     }
689
690     /* Process the packet. This will call the parser that will then
691        decrypt and parse the packet. */
692     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
693       silc_packet_receive_process(sock, conn->receive_key, conn->hmac_receive,
694                                   silc_client_packet_parse, client);
695     else
696       silc_packet_receive_process(sock, NULL, NULL,
697                                   silc_client_packet_parse, client);
698   }
699 }
700
701 /* Callback function that the silc_packet_decrypt will call to make the
702    decision whether the packet is normal or special packet. We will 
703    return TRUE if it is normal and FALSE if it is special */
704
705 static int silc_client_packet_decrypt_check(SilcPacketType packet_type,
706                                             SilcBuffer buffer,
707                                             SilcPacketContext *packet,
708                                             void *context)
709 {
710
711   /* Packet is normal packet, if: 
712
713      1) packet is private message packet and does not have private key set
714      2) is other packet than channel message packet
715
716      all other packets are special packets 
717   */
718
719   if (packet_type == SILC_PACKET_PRIVATE_MESSAGE &&
720       (buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
721     return FALSE;
722
723   if (packet_type != SILC_PACKET_CHANNEL_MESSAGE)
724     return TRUE;
725
726   return FALSE;
727 }
728
729 /* Parses whole packet, received earlier. */
730
731 SILC_TASK_CALLBACK(silc_client_packet_parse_real)
732 {
733   SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
734   SilcClient client = (SilcClient)parse_ctx->context;
735   SilcPacketContext *packet = parse_ctx->packet;
736   SilcBuffer buffer = packet->buffer;
737   SilcSocketConnection sock = parse_ctx->sock;
738   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
739   int ret;
740
741   SILC_LOG_DEBUG(("Start"));
742
743   /* Decrypt the received packet */
744   if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
745     ret = silc_packet_decrypt(conn->receive_key, conn->hmac_receive, 
746                               buffer, packet,
747                               silc_client_packet_decrypt_check, parse_ctx);
748   else
749     ret = silc_packet_decrypt(NULL, NULL, buffer, packet,
750                               silc_client_packet_decrypt_check, parse_ctx);
751
752   if (ret < 0)
753     goto out;
754
755   if (ret == 0) {
756     /* Parse the packet. Packet type is returned. */
757     ret = silc_packet_parse(packet);
758   } else {
759     /* Parse the packet header in special way as this is "special"
760        packet type. */
761     ret = silc_packet_parse_special(packet);
762   }
763
764   if (ret == SILC_PACKET_NONE)
765     goto out;
766
767   /* Parse the incoming packet type */
768   silc_client_packet_parse_type(client, sock, packet);
769
770  out:
771   /*  silc_buffer_clear(sock->inbuf); */
772   silc_packet_context_free(packet);
773   silc_free(parse_ctx);
774 }
775
776 /* Parser callback called by silc_packet_receive_process. Thie merely
777    registers timeout that will handle the actual parsing when appropriate. */
778
779 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
780 {
781   SilcClient client = (SilcClient)parser_context->context;
782
783   /* Parse the packet */
784   silc_schedule_task_add(client->schedule, parser_context->sock->sock, 
785                      silc_client_packet_parse_real,
786                      (void *)parser_context, 0, 1, 
787                      SILC_TASK_TIMEOUT,
788                      SILC_TASK_PRI_NORMAL);
789 }
790
791 /* Parses the packet type and calls what ever routines the packet type
792    requires. This is done for all incoming packets. */
793
794 void silc_client_packet_parse_type(SilcClient client, 
795                                    SilcSocketConnection sock,
796                                    SilcPacketContext *packet)
797 {
798   SilcBuffer buffer = packet->buffer;
799   SilcPacketType type = packet->type;
800
801   SILC_LOG_DEBUG(("Parsing packet type %d", type));
802
803   /* Parse the packet type */
804   switch(type) {
805   case SILC_PACKET_DISCONNECT:
806     silc_client_disconnected_by_server(client, sock, buffer);
807     break;
808   case SILC_PACKET_SUCCESS:
809     /*
810      * Success received for something. For now we can have only
811      * one protocol for connection executing at once hence this
812      * success message is for whatever protocol is executing currently.
813      */
814     if (sock->protocol)
815       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
816     break;
817   case SILC_PACKET_FAILURE:
818     /*
819      * Failure received for some protocol. Set the protocol state to 
820      * error and call the protocol callback. This fill cause error on
821      * protocol and it will call the final callback.
822      */
823     silc_client_process_failure(client, sock, packet);
824     break;
825   case SILC_PACKET_REJECT:
826     break;
827
828   case SILC_PACKET_NOTIFY:
829     /*
830      * Received notify message 
831      */
832     silc_client_notify_by_server(client, sock, packet);
833     break;
834
835   case SILC_PACKET_ERROR:
836     /*
837      * Received error message
838      */
839     silc_client_error_by_server(client, sock, buffer);
840     break;
841
842   case SILC_PACKET_CHANNEL_MESSAGE:
843     /*
844      * Received message to (from, actually) a channel
845      */
846     silc_client_channel_message(client, sock, packet);
847     break;
848   case SILC_PACKET_CHANNEL_KEY:
849     /*
850      * Received key for a channel. By receiving this key the client will be
851      * able to talk to the channel it has just joined. This can also be
852      * a new key for existing channel as keys expire peridiocally.
853      */
854     silc_client_receive_channel_key(client, sock, buffer);
855     break;
856
857   case SILC_PACKET_PRIVATE_MESSAGE:
858     /*
859      * Received private message
860      */
861     silc_client_private_message(client, sock, packet);
862     break;
863   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
864     /*
865      * Received private message key
866      */
867     break;
868
869   case SILC_PACKET_COMMAND_REPLY:
870     /*
871      * Recived reply for a command
872      */
873     silc_client_command_reply_process(client, sock, packet);
874     break;
875
876   case SILC_PACKET_KEY_EXCHANGE:
877     if (sock->protocol && sock->protocol->protocol && 
878         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
879       SilcClientKEInternalContext *proto_ctx = 
880         (SilcClientKEInternalContext *)sock->protocol->context;
881
882       proto_ctx->packet = silc_packet_context_dup(packet);
883       proto_ctx->dest_id_type = packet->src_id_type;
884       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
885                                           packet->src_id_type);
886       if (!proto_ctx->dest_id)
887         break;
888
889       /* Let the protocol handle the packet */
890       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
891     } else {
892       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
893                       "protocol active, packet dropped."));
894     }
895     break;
896
897   case SILC_PACKET_KEY_EXCHANGE_1:
898     if (sock->protocol && sock->protocol->protocol && 
899         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
900          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
901
902       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
903         SilcClientRekeyInternalContext *proto_ctx = 
904           (SilcClientRekeyInternalContext *)sock->protocol->context;
905         
906         if (proto_ctx->packet)
907           silc_packet_context_free(proto_ctx->packet);
908         
909         proto_ctx->packet = silc_packet_context_dup(packet);
910
911         /* Let the protocol handle the packet */
912         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
913       } else {
914         SilcClientKEInternalContext *proto_ctx = 
915           (SilcClientKEInternalContext *)sock->protocol->context;
916         
917         if (proto_ctx->packet)
918           silc_packet_context_free(proto_ctx->packet);
919         
920         proto_ctx->packet = silc_packet_context_dup(packet);
921         proto_ctx->dest_id_type = packet->src_id_type;
922         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
923                                             packet->src_id_type);
924         if (!proto_ctx->dest_id)
925           break;
926         
927         /* Let the protocol handle the packet */
928         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
929       }
930     } else {
931       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
932                       "protocol active, packet dropped."));
933     }
934     break;
935   case SILC_PACKET_KEY_EXCHANGE_2:
936     if (sock->protocol && sock->protocol->protocol && 
937         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
938          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
939
940       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
941         SilcClientRekeyInternalContext *proto_ctx = 
942           (SilcClientRekeyInternalContext *)sock->protocol->context;
943         
944         if (proto_ctx->packet)
945           silc_packet_context_free(proto_ctx->packet);
946         
947         proto_ctx->packet = silc_packet_context_dup(packet);
948
949         /* Let the protocol handle the packet */
950         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
951       } else {
952         SilcClientKEInternalContext *proto_ctx = 
953           (SilcClientKEInternalContext *)sock->protocol->context;
954         
955         if (proto_ctx->packet)
956           silc_packet_context_free(proto_ctx->packet);
957         
958         proto_ctx->packet = silc_packet_context_dup(packet);
959         proto_ctx->dest_id_type = packet->src_id_type;
960         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
961                                             packet->src_id_type);
962         if (!proto_ctx->dest_id)
963           break;
964         
965         /* Let the protocol handle the packet */
966         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
967       }
968     } else {
969       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
970                       "protocol active, packet dropped."));
971     }
972     break;
973
974   case SILC_PACKET_NEW_ID:
975     {
976       /*
977        * Received new ID from server. This packet is received at
978        * the connection to the server.  New ID is also received when 
979        * user changes nickname but in that case the new ID is received
980        * as command reply and not as this packet type.
981        */
982       SilcIDPayload idp;
983
984       idp = silc_id_payload_parse(buffer);
985       if (!idp)
986         break;
987       if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
988         break;
989
990       silc_client_receive_new_id(client, sock, idp);
991       silc_id_payload_free(idp);
992       break;
993     }
994
995   case SILC_PACKET_HEARTBEAT:
996     /*
997      * Received heartbeat packet
998      */
999     SILC_LOG_DEBUG(("Heartbeat packet"));
1000     break;
1001
1002   case SILC_PACKET_KEY_AGREEMENT:
1003     /*
1004      * Received key agreement packet
1005      */
1006     SILC_LOG_DEBUG(("Key agreement packet"));
1007     silc_client_key_agreement(client, sock, packet);
1008     break;
1009
1010   case SILC_PACKET_REKEY:
1011     SILC_LOG_DEBUG(("Re-key packet"));
1012     /* We ignore this for now */
1013     break;
1014
1015   case SILC_PACKET_REKEY_DONE:
1016     SILC_LOG_DEBUG(("Re-key done packet"));
1017
1018     if (sock->protocol && sock->protocol->protocol && 
1019         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1020
1021       SilcClientRekeyInternalContext *proto_ctx = 
1022         (SilcClientRekeyInternalContext *)sock->protocol->context;
1023       
1024       if (proto_ctx->packet)
1025         silc_packet_context_free(proto_ctx->packet);
1026       
1027       proto_ctx->packet = silc_packet_context_dup(packet);
1028
1029       /* Let the protocol handle the packet */
1030       if (proto_ctx->responder == FALSE)
1031         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1032       else
1033         /* Let the protocol handle the packet */
1034         silc_protocol_execute(sock->protocol, client->schedule, 
1035                               0, 100000);
1036     } else {
1037       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1038                       "protocol active, packet dropped."));
1039     }
1040     break;
1041
1042   default:
1043     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1044     break;
1045   }
1046 }
1047
1048 /* Sends packet. This doesn't actually send the packet instead it assembles
1049    it and marks it to be sent. However, if force_send is TRUE the packet
1050    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1051    will be derived from sock argument. Otherwise the valid arguments sent
1052    are used. */
1053
1054 void silc_client_packet_send(SilcClient client, 
1055                              SilcSocketConnection sock,
1056                              SilcPacketType type, 
1057                              void *dst_id,
1058                              SilcIdType dst_id_type,
1059                              SilcCipher cipher,
1060                              SilcHmac hmac,
1061                              unsigned char *data, 
1062                              uint32 data_len, 
1063                              int force_send)
1064 {
1065   SilcPacketContext packetdata;
1066
1067   if (!sock)
1068     return;
1069
1070   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1071
1072   /* Get data used in the packet sending, keys and stuff */
1073   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1074     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1075       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1076
1077     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1078       hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1079
1080     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1081       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1082       dst_id_type = SILC_ID_SERVER;
1083     }
1084   }
1085
1086   /* Set the packet context pointers */
1087   packetdata.flags = 0;
1088   packetdata.type = type;
1089   if (sock->user_data && 
1090       ((SilcClientConnection)sock->user_data)->local_id_data) {
1091     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1092     packetdata.src_id_len = 
1093       silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
1094                       SILC_ID_CLIENT);
1095   } else { 
1096     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1097     packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1098   }
1099   packetdata.src_id_type = SILC_ID_CLIENT;
1100   if (dst_id) {
1101     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1102     packetdata.dst_id_len = silc_id_get_len(dst_id, dst_id_type);
1103     packetdata.dst_id_type = dst_id_type;
1104   } else {
1105     packetdata.dst_id = NULL;
1106     packetdata.dst_id_len = 0;
1107     packetdata.dst_id_type = SILC_ID_NONE;
1108   }
1109   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1110     packetdata.src_id_len + packetdata.dst_id_len;
1111   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1112
1113   /* Prepare outgoing data buffer for packet sending */
1114   silc_packet_send_prepare(sock, 
1115                            SILC_PACKET_HEADER_LEN +
1116                            packetdata.src_id_len + 
1117                            packetdata.dst_id_len,
1118                            packetdata.padlen,
1119                            data_len);
1120
1121   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1122
1123   packetdata.buffer = sock->outbuf;
1124
1125   /* Put the data to the buffer */
1126   if (data && data_len)
1127     silc_buffer_put(sock->outbuf, data, data_len);
1128
1129   /* Create the outgoing packet */
1130   silc_packet_assemble(&packetdata);
1131
1132   /* Encrypt the packet */
1133   if (cipher)
1134     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1135
1136   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1137                    sock->outbuf->data, sock->outbuf->len);
1138
1139   /* Now actually send the packet */
1140   silc_client_packet_send_real(client, sock, force_send, FALSE);
1141 }
1142
1143 /* Closes connection to remote end. Free's all allocated data except
1144    for some information such as nickname etc. that are valid at all time. 
1145    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1146    provided it will be checked whether the sock and `conn->sock' are the
1147    same (they can be different, ie. a socket can use `conn' as its
1148    connection but `conn->sock' might be actually a different connection
1149    than the `sock'). */
1150
1151 void silc_client_close_connection(SilcClient client,
1152                                   SilcSocketConnection sock,
1153                                   SilcClientConnection conn)
1154 {
1155   int del = FALSE;
1156
1157   if (!sock || (sock && conn->sock == sock))
1158     del = TRUE;
1159   if (!sock)
1160     sock = conn->sock;
1161
1162   /* We won't listen for this connection anymore */
1163   silc_schedule_unset_listen_fd(client->schedule, sock->sock);
1164
1165   /* Unregister all tasks */
1166   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1167   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1168
1169   /* Close the actual connection */
1170   silc_net_close_connection(sock->sock);
1171
1172   /* Cancel any active protocol */
1173   if (sock->protocol) {
1174     if (sock->protocol->protocol->type == 
1175         SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1176         sock->protocol->protocol->type == 
1177         SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
1178       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1179       silc_protocol_execute_final(sock->protocol, client->schedule);
1180       sock->protocol = NULL;
1181       /* The application will recall this function with these protocols
1182          (the ops->connect client operation). */
1183       return;
1184     } else {
1185       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1186       silc_protocol_execute_final(sock->protocol, client->schedule);
1187       sock->protocol = NULL;
1188     }
1189   }
1190
1191   /* Free everything */
1192   if (del && sock->user_data) {
1193     /* Free all cache entries */
1194     SilcIDCacheList list;
1195     SilcIDCacheEntry entry;
1196     bool ret;
1197
1198     if (silc_idcache_get_all(conn->client_cache, &list)) {
1199       ret = silc_idcache_list_first(list, &entry);
1200       while (ret) {
1201         silc_client_del_client(client, conn, entry->context);
1202         ret = silc_idcache_list_next(list, &entry);
1203       }
1204       silc_idcache_list_free(list);
1205     }
1206
1207     if (silc_idcache_get_all(conn->channel_cache, &list)) {
1208       ret = silc_idcache_list_first(list, &entry);
1209       while (ret) {
1210         silc_client_del_channel(client, conn, entry->context);
1211         ret = silc_idcache_list_next(list, &entry);
1212       }
1213       silc_idcache_list_free(list);
1214     }
1215
1216     if (silc_idcache_get_all(conn->server_cache, &list)) {
1217       ret = silc_idcache_list_first(list, &entry);
1218       while (ret) {
1219         silc_client_del_server(client, conn, entry->context);
1220         ret = silc_idcache_list_next(list, &entry);
1221       }
1222       silc_idcache_list_free(list);
1223     }
1224
1225     /* Clear ID caches */
1226     if (conn->client_cache)
1227       silc_idcache_del_all(conn->client_cache);
1228     if (conn->channel_cache)
1229       silc_idcache_del_all(conn->channel_cache);
1230     if (conn->server_cache)
1231       silc_idcache_del_all(conn->server_cache);
1232
1233     /* Free data */
1234     if (conn->remote_host)
1235       silc_free(conn->remote_host);
1236     if (conn->local_id)
1237       silc_free(conn->local_id);
1238     if (conn->local_id_data)
1239       silc_free(conn->local_id_data);
1240     if (conn->send_key)
1241       silc_cipher_free(conn->send_key);
1242     if (conn->receive_key)
1243       silc_cipher_free(conn->receive_key);
1244     if (conn->hmac_send)        /* conn->hmac_receive is same */
1245       silc_hmac_free(conn->hmac_send);
1246     if (conn->pending_commands)
1247       silc_dlist_uninit(conn->pending_commands);
1248     if (conn->rekey)
1249       silc_free(conn->rekey);
1250
1251     memset(conn, 0, sizeof(*conn));
1252     silc_client_del_connection(client, conn);
1253   }
1254
1255   silc_socket_free(sock);
1256 }
1257
1258 /* Called when we receive disconnection packet from server. This 
1259    closes our end properly and displays the reason of the disconnection
1260    on the screen. */
1261
1262 void silc_client_disconnected_by_server(SilcClient client,
1263                                         SilcSocketConnection sock,
1264                                         SilcBuffer message)
1265 {
1266   char *msg;
1267
1268   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1269
1270   msg = silc_calloc(message->len + 1, sizeof(char));
1271   memcpy(msg, message->data, message->len);
1272   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1273   silc_free(msg);
1274
1275   SILC_SET_DISCONNECTED(sock);
1276   silc_client_close_connection(client, sock, sock->user_data);
1277 }
1278
1279 /* Received error message from server. Display it on the screen. 
1280    We don't take any action what so ever of the error message. */
1281
1282 void silc_client_error_by_server(SilcClient client,
1283                                  SilcSocketConnection sock,
1284                                  SilcBuffer message)
1285 {
1286   char *msg;
1287
1288   msg = silc_calloc(message->len + 1, sizeof(char));
1289   memcpy(msg, message->data, message->len);
1290   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1291   silc_free(msg);
1292 }
1293
1294 /* Processes the received new Client ID from server. Old Client ID is
1295    deleted from cache and new one is added. */
1296
1297 void silc_client_receive_new_id(SilcClient client,
1298                                 SilcSocketConnection sock,
1299                                 SilcIDPayload idp)
1300 {
1301   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1302   int connecting = FALSE;
1303   SilcBuffer sidp;
1304
1305   if (!conn->local_entry)
1306     connecting = TRUE;
1307
1308   /* Delete old ID from ID cache */
1309   if (conn->local_id) {
1310     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
1311     silc_free(conn->local_id);
1312   }
1313   
1314   /* Save the new ID */
1315
1316   if (conn->local_id_data)
1317     silc_free(conn->local_id_data);
1318
1319   conn->local_id = silc_id_payload_get_id(idp);
1320   conn->local_id_data = silc_id_payload_get_data(idp);
1321   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1322
1323   if (!conn->local_entry)
1324     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1325
1326   conn->local_entry->nickname = conn->nickname;
1327   if (!conn->local_entry->username) {
1328     conn->local_entry->username = 
1329       silc_calloc(strlen(client->username) + strlen(client->hostname) + 1,
1330                   sizeof(conn->local_entry->username));
1331     sprintf(conn->local_entry->username, "%s@%s", client->username,
1332             client->hostname);
1333   }
1334   conn->local_entry->server = strdup(conn->remote_host);
1335   conn->local_entry->id = conn->local_id;
1336   
1337   /* Put it to the ID cache */
1338   silc_idcache_add(conn->client_cache, conn->nickname, conn->local_id, 
1339                    (void *)conn->local_entry, FALSE);
1340
1341   /* Issue INFO command to fetch the real server name and server information
1342      and other stuff. */
1343   sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1344   silc_client_send_command(client, conn, SILC_COMMAND_INFO,
1345                            ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1346   silc_buffer_free(sidp);
1347
1348   /* Notify application of successful connection. We do it here now that
1349      we've received the Client ID and are allowed to send traffic. */
1350   if (connecting)
1351     client->ops->connect(client, conn, TRUE);
1352 }
1353
1354 /* Processed received Channel ID for a channel. This is called when client
1355    joins to channel and server replies with channel ID. The ID is cached. 
1356    Returns the created channel entry. This is also called when received
1357    channel ID in for example USERS command reply that we do not have. */
1358
1359 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
1360                                             SilcSocketConnection sock,
1361                                             char *channel_name,
1362                                             uint32 mode, 
1363                                             SilcIDPayload idp)
1364 {
1365   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1366   SilcChannelEntry channel;
1367
1368   SILC_LOG_DEBUG(("New channel ID"));
1369
1370   channel = silc_calloc(1, sizeof(*channel));
1371   channel->channel_name = channel_name;
1372   channel->id = silc_id_payload_get_id(idp);
1373   channel->mode = mode;
1374   silc_list_init(channel->clients, struct SilcChannelUserStruct, next);
1375
1376   /* Put it to the ID cache */
1377   silc_idcache_add(conn->channel_cache, channel_name, (void *)channel->id, 
1378                    (void *)channel, FALSE);
1379
1380   return channel;
1381 }
1382
1383 /* Removes a client entry from all channel it has joined. This really is
1384    a performance killer (client_entry should have pointers to channel 
1385    entry list). */
1386
1387 void silc_client_remove_from_channels(SilcClient client,
1388                                       SilcClientConnection conn,
1389                                       SilcClientEntry client_entry)
1390 {
1391   SilcIDCacheEntry id_cache;
1392   SilcIDCacheList list;
1393   SilcChannelEntry channel;
1394   SilcChannelUser chu;
1395
1396   if (!silc_idcache_get_all(conn->channel_cache, &list))
1397     return;
1398
1399   silc_idcache_list_first(list, &id_cache);
1400   channel = (SilcChannelEntry)id_cache->context;
1401   
1402   while (channel) {
1403     
1404     /* Remove client from channel */
1405     silc_list_start(channel->clients);
1406     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1407       if (chu->client == client_entry) {
1408         silc_list_del(channel->clients, chu);
1409         silc_free(chu);
1410         break;
1411       }
1412     }
1413
1414     if (!silc_idcache_list_next(list, &id_cache))
1415       break;
1416     
1417     channel = (SilcChannelEntry)id_cache->context;
1418   }
1419
1420   silc_idcache_list_free(list);
1421 }
1422
1423 /* Replaces `old' client entries from all channels to `new' client entry.
1424    This can be called for example when nickname changes and old ID entry
1425    is replaced from ID cache with the new one. If the old ID entry is only
1426    updated, then this fucntion needs not to be called. */
1427
1428 void silc_client_replace_from_channels(SilcClient client, 
1429                                        SilcClientConnection conn,
1430                                        SilcClientEntry old,
1431                                        SilcClientEntry new)
1432 {
1433   SilcIDCacheEntry id_cache;
1434   SilcIDCacheList list;
1435   SilcChannelEntry channel;
1436   SilcChannelUser chu;
1437
1438   if (!silc_idcache_get_all(conn->channel_cache, &list))
1439     return;
1440
1441   silc_idcache_list_first(list, &id_cache);
1442   channel = (SilcChannelEntry)id_cache->context;
1443   
1444   while (channel) {
1445     
1446     /* Replace client entry */
1447     silc_list_start(channel->clients);
1448     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1449       if (chu->client == old) {
1450         chu->client = new;
1451         break;
1452       }
1453     }
1454
1455     if (!silc_idcache_list_next(list, &id_cache))
1456       break;
1457     
1458     channel = (SilcChannelEntry)id_cache->context;
1459   }
1460
1461   silc_idcache_list_free(list);
1462 }
1463
1464 /* Registers failure timeout to process the received failure packet
1465    with timeout. */
1466
1467 void silc_client_process_failure(SilcClient client,
1468                                  SilcSocketConnection sock,
1469                                  SilcPacketContext *packet)
1470 {
1471   uint32 failure = 0;
1472
1473   if (sock->protocol) {
1474     if (packet->buffer->len >= 4)
1475       SILC_GET32_MSB(failure, packet->buffer->data);
1476
1477     /* Notify application */
1478     client->ops->failure(client, sock->user_data, sock->protocol,
1479                          (void *)failure);
1480   }
1481 }
1482
1483 /* A timeout callback for the re-key. We will be the initiator of the
1484    re-key protocol. */
1485
1486 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1487 {
1488   SilcSocketConnection sock = (SilcSocketConnection)context;
1489   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1490   SilcClient client = (SilcClient)conn->rekey->context;
1491   SilcProtocol protocol;
1492   SilcClientRekeyInternalContext *proto_ctx;
1493
1494   SILC_LOG_DEBUG(("Start"));
1495
1496   /* Allocate internal protocol context. This is sent as context
1497      to the protocol. */
1498   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1499   proto_ctx->client = (void *)client;
1500   proto_ctx->sock = silc_socket_dup(sock);
1501   proto_ctx->responder = FALSE;
1502   proto_ctx->pfs = conn->rekey->pfs;
1503       
1504   /* Perform rekey protocol. Will call the final callback after the
1505      protocol is over. */
1506   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1507                       &protocol, proto_ctx, silc_client_rekey_final);
1508   sock->protocol = protocol;
1509       
1510   /* Run the protocol */
1511   silc_protocol_execute(protocol, client->schedule, 0, 0);
1512
1513   /* Re-register re-key timeout */
1514   silc_schedule_task_add(client->schedule, sock->sock, 
1515                      silc_client_rekey_callback,
1516                      context, conn->rekey->timeout, 0,
1517                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1518 }
1519
1520 /* The final callback for the REKEY protocol. This will actually take the
1521    new key material into use. */
1522
1523 SILC_TASK_CALLBACK(silc_client_rekey_final)
1524 {
1525   SilcProtocol protocol = (SilcProtocol)context;
1526   SilcClientRekeyInternalContext *ctx =
1527     (SilcClientRekeyInternalContext *)protocol->context;
1528   SilcClient client = (SilcClient)ctx->client;
1529   SilcSocketConnection sock = ctx->sock;
1530
1531   SILC_LOG_DEBUG(("Start"));
1532
1533   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1534       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1535     /* Error occured during protocol */
1536     silc_protocol_cancel(protocol, client->schedule);
1537     silc_protocol_free(protocol);
1538     sock->protocol = NULL;
1539     if (ctx->packet)
1540       silc_packet_context_free(ctx->packet);
1541     if (ctx->ske)
1542       silc_ske_free(ctx->ske);
1543     silc_socket_free(ctx->sock);
1544     silc_free(ctx);
1545     return;
1546   }
1547
1548   /* Cleanup */
1549   silc_protocol_free(protocol);
1550   sock->protocol = NULL;
1551   if (ctx->packet)
1552     silc_packet_context_free(ctx->packet);
1553   if (ctx->ske)
1554     silc_ske_free(ctx->ske);
1555   silc_socket_free(ctx->sock);
1556   silc_free(ctx);
1557 }