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