Handle local error during resuming correctly.
[silc.git] / lib / silcclient / client.c
1 /*
2
3   client.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 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; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "silcincludes.h"
22 #include "silcclient.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_rekey_callback);
30 SILC_TASK_CALLBACK(silc_client_rekey_final);
31
32 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
33                                      void *context);
34 static void silc_client_packet_parse_type(SilcClient client, 
35                                           SilcSocketConnection sock,
36                                           SilcPacketContext *packet);
37 void silc_client_resolve_auth_method(bool success,
38                                      SilcProtocolAuthMeth auth_meth,
39                                      const unsigned char *auth_data,
40                                      SilcUInt32 auth_data_len, void *context);
41
42 /* Allocates new client object. This has to be done before client may
43    work. After calling this one must call silc_client_init to initialize
44    the client. The `application' is application specific user data pointer
45    and caller must free it. */
46
47 SilcClient silc_client_alloc(SilcClientOperations *ops, 
48                              SilcClientParams *params,
49                              void *application,
50                              const char *silc_version)
51 {
52   SilcClient new_client;
53
54   new_client = silc_calloc(1, sizeof(*new_client));
55   new_client->application = application;
56
57   new_client->internal = silc_calloc(1, sizeof(*new_client->internal));
58   new_client->internal->ops = ops;
59   new_client->internal->params = 
60     silc_calloc(1, sizeof(*new_client->internal->params));
61   new_client->internal->silc_client_version = strdup(silc_version);
62
63   if (params)
64     memcpy(new_client->internal->params, params, sizeof(*params));
65
66   if (!new_client->internal->params->task_max)
67     new_client->internal->params->task_max = 200;
68
69   if (!new_client->internal->params->rekey_secs)
70     new_client->internal->params->rekey_secs = 3600;
71
72   if (!new_client->internal->params->connauth_request_secs)
73     new_client->internal->params->connauth_request_secs = 2;
74
75   new_client->internal->params->
76     nickname_format[sizeof(new_client->internal->
77                            params->nickname_format) - 1] = 0;
78
79   return new_client;
80 }
81
82 /* Frees client object and its internals. */
83
84 void silc_client_free(SilcClient client)
85 {
86   if (client) {
87     if (client->rng)
88       silc_rng_free(client->rng);
89
90     silc_free(client->internal->params);
91     silc_free(client->internal->silc_client_version);
92     silc_free(client->internal);
93     silc_free(client);
94   }
95 }
96
97 /* Initializes the client. This makes all the necessary steps to make
98    the client ready to be run. One must call silc_client_run to run the
99    client. Returns FALSE if error occured, TRUE otherwise. */
100
101 int silc_client_init(SilcClient client)
102 {
103   SILC_LOG_DEBUG(("Initializing client"));
104
105   /* Initialize hash functions for client to use */
106   silc_hash_alloc("md5", &client->internal->md5hash);
107   silc_hash_alloc("sha1", &client->internal->sha1hash);
108
109   /* Initialize none cipher */
110   silc_cipher_alloc("none", &client->internal->none_cipher);
111
112   /* Initialize random number generator */
113   client->rng = silc_rng_alloc();
114   silc_rng_init(client->rng);
115   silc_rng_global_init(client->rng);
116
117   /* Register protocols */
118   silc_client_protocols_register();
119
120   /* Initialize the scheduler */
121   client->schedule = 
122     silc_schedule_init(client->internal->params->task_max ?
123                        client->internal->params->task_max : 200);
124   if (!client->schedule)
125     return FALSE;
126
127   /* Register commands */
128   silc_client_commands_register(client);
129
130   return TRUE;
131 }
132
133 /* Stops the client. This is called to stop the client and thus to stop
134    the program. */
135
136 void silc_client_stop(SilcClient client)
137 {
138   SILC_LOG_DEBUG(("Stopping client"));
139
140   silc_schedule_stop(client->schedule);
141   silc_schedule_uninit(client->schedule);
142
143   silc_client_protocols_unregister();
144   silc_client_commands_unregister(client);
145
146   SILC_LOG_DEBUG(("Client stopped"));
147 }
148
149 /* Runs the client. This starts the scheduler from the utility library.
150    When this functions returns the execution of the appliation is over. */
151
152 void silc_client_run(SilcClient client)
153 {
154   SILC_LOG_DEBUG(("Running client"));
155
156   /* Start the scheduler, the heart of the SILC client. When this returns
157      the program will be terminated. */
158   silc_schedule(client->schedule);
159 }
160
161 /* Runs the client and returns immeadiately. This function is used when
162    the SILC Client object indicated by the `client' is run under some
163    other scheduler, or event loop or main loop.  On GUI applications,
164    for example this may be desired to use to run the client under the
165    GUI application's main loop.  Typically the GUI application would
166    register an idle task that calls this function multiple times in
167    a second to quickly process the SILC specific data. */
168
169 void silc_client_run_one(SilcClient client)
170 {
171   /* Run the scheduler once. */
172   silc_schedule_one(client->schedule, 0);
173 }
174
175 static void silc_client_entry_destructor(SilcIDCache cache,
176                                          SilcIDCacheEntry entry)
177 {
178   silc_free(entry->name);
179 }
180
181 /* Allocates and adds new connection to the client. This adds the allocated
182    connection to the connection table and returns a pointer to it. A client
183    can have multiple connections to multiple servers. Every connection must
184    be added to the client using this function. User data `context' may
185    be sent as argument. This function is normally used only if the 
186    application performed the connecting outside the library. The library
187    however may use this internally. */
188
189 SilcClientConnection
190 silc_client_add_connection(SilcClient client,
191                            SilcClientConnectionParams *params,
192                            char *hostname, int port, void *context)
193 {
194   SilcClientConnection conn;
195   int i;
196
197   conn = silc_calloc(1, sizeof(*conn));
198
199   /* Initialize ID caches */
200   conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, 
201                                           silc_client_entry_destructor);
202   conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
203   conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
204   conn->client = client;
205   conn->remote_host = strdup(hostname);
206   conn->remote_port = port;
207   conn->context = context;
208   conn->pending_commands = silc_dlist_init();
209   conn->ftp_sessions = silc_dlist_init();
210
211   if (params) {
212     if (params->detach_data)
213       conn->params.detach_data = silc_memdup(params->detach_data,
214                                              params->detach_data_len);
215     conn->params.detach_data_len = params->detach_data_len;
216   }
217
218   /* Add the connection to connections table */
219   for (i = 0; i < client->internal->conns_count; i++)
220     if (client->internal->conns && !client->internal->conns[i]) {
221       client->internal->conns[i] = conn;
222       return conn;
223     }
224
225   client->internal->conns = 
226     silc_realloc(client->internal->conns, sizeof(*client->internal->conns)
227                  * (client->internal->conns_count + 1));
228   client->internal->conns[client->internal->conns_count] = conn;
229   client->internal->conns_count++;
230
231   return conn;
232 }
233
234 /* Removes connection from client. Frees all memory. */
235
236 void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
237 {
238   int i;
239
240   for (i = 0; i < client->internal->conns_count; i++)
241     if (client->internal->conns[i] == conn) {
242
243       silc_idcache_free(conn->client_cache);
244       silc_idcache_free(conn->channel_cache);
245       silc_idcache_free(conn->server_cache);
246       if (conn->pending_commands)
247         silc_dlist_uninit(conn->pending_commands);
248       silc_free(conn->remote_host);
249       silc_dlist_uninit(conn->ftp_sessions);
250       silc_free(conn);
251
252       client->internal->conns[i] = NULL;
253     }
254 }
255
256 /* Adds listener socket to the listener sockets table. This function is
257    used to add socket objects that are listeners to the client.  This should
258    not be used to add other connection objects. */
259
260 void silc_client_add_socket(SilcClient client, SilcSocketConnection sock)
261 {
262   int i;
263
264   if (!client->internal->sockets) {
265     client->internal->sockets = 
266       silc_calloc(1, sizeof(*client->internal->sockets));
267     client->internal->sockets[0] = silc_socket_dup(sock);
268     client->internal->sockets_count = 1;
269     return;
270   }
271
272   for (i = 0; i < client->internal->sockets_count; i++) {
273     if (client->internal->sockets[i] == NULL) {
274       client->internal->sockets[i] = silc_socket_dup(sock);
275       return;
276     }
277   }
278
279   client->internal->sockets = 
280     silc_realloc(client->internal->sockets, 
281                  sizeof(*client->internal->sockets) *
282                  (client->internal->sockets_count + 1));
283   client->internal->sockets[client->internal->sockets_count] = 
284     silc_socket_dup(sock);
285   client->internal->sockets_count++;
286 }
287
288 /* Deletes listener socket from the listener sockets table. */
289
290 void silc_client_del_socket(SilcClient client, SilcSocketConnection sock)
291 {
292   int i;
293
294   if (!client->internal->sockets)
295     return;
296
297   for (i = 0; i < client->internal->sockets_count; i++) {
298     if (client->internal->sockets[i] == sock) {
299       silc_socket_free(sock);
300       client->internal->sockets[i] = NULL;
301       return;
302     }
303   }
304 }
305
306 static int 
307 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
308 {
309   int sock;
310
311   /* XXX In the future we should give up this non-blocking connect all
312      together and use threads instead. */
313   /* Create connection to server asynchronously */
314   sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
315   if (sock < 0)
316     return -1;
317
318   /* Register task that will receive the async connect and will
319      read the result. */
320   ctx->task = silc_schedule_task_add(ctx->client->schedule, sock, 
321                                      silc_client_connect_to_server_start,
322                                      (void *)ctx, 0, 0, 
323                                      SILC_TASK_FD,
324                                      SILC_TASK_PRI_NORMAL);
325   silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
326
327   ctx->sock = sock;
328
329   return sock;
330 }
331
332 /* Connects to remote server. This is the main routine used to connect
333    to SILC server. Returns -1 on error and the created socket otherwise. 
334    The `context' is user context that is saved into the SilcClientConnection
335    that is created after the connection is created. Note that application
336    may handle the connecting process outside the library. If this is the
337    case then this function is not used at all. When the connecting is
338    done the `connect' client operation is called. */
339
340 int silc_client_connect_to_server(SilcClient client,
341                                   SilcClientConnectionParams *params,
342                                   int port, char *host, void *context)
343 {
344   SilcClientInternalConnectContext *ctx;
345   SilcClientConnection conn;
346   int sock;
347
348   SILC_LOG_DEBUG(("Connecting to port %d of server %s",
349                   port, host));
350
351   conn = silc_client_add_connection(client, params, host, port, context);
352
353   client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
354                              "Connecting to port %d of server %s", port, host);
355
356   /* Allocate internal context for connection process. This is
357      needed as we are doing async connecting. */
358   ctx = silc_calloc(1, sizeof(*ctx));
359   ctx->client = client;
360   ctx->conn = conn;
361   ctx->host = strdup(host);
362   ctx->port = port;
363   ctx->tries = 0;
364
365   /* Do the actual connecting process */
366   sock = silc_client_connect_to_server_internal(ctx);
367   if (sock == -1)
368     silc_client_del_connection(client, conn);
369   return sock;
370 }
371
372 /* Socket hostname and IP lookup callback that is called before actually
373    starting the key exchange.  The lookup is called from the function
374    silc_client_start_key_exchange. */
375
376 static void silc_client_start_key_exchange_cb(SilcSocketConnection sock,
377                                               void *context)
378 {
379   SilcClientConnection conn = (SilcClientConnection)context;
380   SilcClient client = conn->client;
381   SilcProtocol protocol;
382   SilcClientKEInternalContext *proto_ctx;
383
384   SILC_LOG_DEBUG(("Start"));
385
386   /* XXX We should most likely use the resolved host name instead of the
387      one user provided for us. */
388   silc_free(conn->sock->hostname);
389   conn->sock->hostname = strdup(conn->remote_host);
390   if (!conn->sock->ip)
391     conn->sock->ip = strdup(conn->remote_host);
392   conn->sock->port = conn->remote_port;
393
394   /* Allocate internal Key Exchange context. This is sent to the
395      protocol as context. */
396   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
397   proto_ctx->client = (void *)client;
398   proto_ctx->sock = silc_socket_dup(conn->sock);
399   proto_ctx->rng = client->rng;
400   proto_ctx->responder = FALSE;
401   proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
402   proto_ctx->verify = silc_client_protocol_ke_verify_key;
403
404   /* Perform key exchange protocol. silc_client_connect_to_server_final
405      will be called after the protocol is finished. */
406   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
407                       &protocol, (void *)proto_ctx,
408                       silc_client_connect_to_server_second);
409   if (!protocol) {
410     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
411                                "Error: Could not start key exchange protocol");
412     silc_net_close_connection(conn->sock->sock);
413     client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
414     return;
415   }
416   conn->sock->protocol = protocol;
417
418   /* Register the connection for network input and output. This sets
419      that scheduler will listen for incoming packets for this connection 
420      and sets that outgoing packets may be sent to this connection as well.
421      However, this doesn't set the scheduler for outgoing traffic, it will 
422      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
423      later when outgoing data is available. */
424   context = (void *)client;
425   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(conn->sock->sock);
426
427   /* Execute the protocol */
428   silc_protocol_execute(protocol, client->schedule, 0, 0);
429 }
430
431 /* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
432    key material between client and server.  This function can be called
433    directly if application is performing its own connecting and does not
434    use the connecting provided by this library. This function is normally
435    used only if the application performed the connecting outside the library.
436    The library however may use this internally. */
437
438 void silc_client_start_key_exchange(SilcClient client,
439                                     SilcClientConnection conn,
440                                     int fd)
441 {
442   /* Allocate new socket connection object */
443   silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
444
445   /* Sometimes when doing quick reconnects the new socket may be same as
446      the old one and there might be pending stuff for the old socket. 
447      If new one is same then those pending sutff might cause problems.
448      Make sure they do not do that. */
449   silc_schedule_task_del_by_fd(client->schedule, fd);
450
451   conn->nickname = (client->nickname ? strdup(client->nickname) :
452                     strdup(client->username));
453
454   /* Resolve the remote hostname and IP address for our socket connection */
455   silc_socket_host_lookup(conn->sock, FALSE, silc_client_start_key_exchange_cb,
456                           conn, client->schedule);
457 }
458
459 /* Callback called when error has occurred during connecting to the server.
460    The `connect' client operation will be called. */
461
462 SILC_TASK_CALLBACK(silc_client_connect_failure)
463 {
464   SilcClientKEInternalContext *ctx = 
465     (SilcClientKEInternalContext *)context;
466   SilcClient client = (SilcClient)ctx->client;
467
468   client->internal->ops->connect(client, ctx->sock->user_data, 
469                                  SILC_CLIENT_CONN_ERROR);
470   if (ctx->packet)
471     silc_packet_context_free(ctx->packet);
472   silc_free(ctx);
473 }
474
475 /* Start of the connection to the remote server. This is called after
476    succesful TCP/IP connection has been established to the remote host. */
477
478 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
479 {
480   SilcClientInternalConnectContext *ctx =
481     (SilcClientInternalConnectContext *)context;
482   SilcClient client = ctx->client;
483   SilcClientConnection conn = ctx->conn;
484   int opt, opt_len = sizeof(opt);
485
486   SILC_LOG_DEBUG(("Start"));
487
488   /* Check the socket status as it might be in error */
489   silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
490   if (opt != 0) {
491     if (ctx->tries < 2) {
492       /* Connection failed but lets try again */
493       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
494                                  "Could not connect to server %s: %s",
495                                  ctx->host, strerror(opt));
496       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
497                                  "Connecting to port %d of server %s resumed", 
498                                  ctx->port, ctx->host);
499
500       /* Unregister old connection try */
501       silc_schedule_unset_listen_fd(client->schedule, fd);
502       silc_net_close_connection(fd);
503       silc_schedule_task_del(client->schedule, ctx->task);
504
505       /* Try again */
506       silc_client_connect_to_server_internal(ctx);
507       ctx->tries++;
508     } else {
509       /* Connection failed and we won't try anymore */
510       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
511                                  "Could not connect to server %s: %s",
512                                  ctx->host, strerror(opt));
513       silc_schedule_unset_listen_fd(client->schedule, fd);
514       silc_net_close_connection(fd);
515       silc_schedule_task_del(client->schedule, ctx->task);
516       silc_free(ctx);
517
518       /* Notify application of failure */
519       client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
520       silc_client_del_connection(client, conn);
521     }
522     return;
523   }
524
525   silc_schedule_unset_listen_fd(client->schedule, fd);
526   silc_schedule_task_del(client->schedule, ctx->task);
527   silc_free(ctx);
528
529   silc_client_start_key_exchange(client, conn, fd);
530 }
531
532 /* Second part of the connecting to the server. This executed 
533    authentication protocol. */
534
535 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
536 {
537   SilcProtocol protocol = (SilcProtocol)context;
538   SilcClientKEInternalContext *ctx = 
539     (SilcClientKEInternalContext *)protocol->context;
540   SilcClient client = (SilcClient)ctx->client;
541   SilcSocketConnection sock = NULL;
542   SilcClientConnAuthInternalContext *proto_ctx;
543
544   SILC_LOG_DEBUG(("Start"));
545
546   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
547       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
548     /* Error occured during protocol */
549     SILC_LOG_DEBUG(("Error during KE protocol"));
550     silc_protocol_free(protocol);
551     silc_ske_free_key_material(ctx->keymat);
552     if (ctx->ske)
553       silc_ske_free(ctx->ske);
554     if (ctx->dest_id)
555       silc_free(ctx->dest_id);
556     ctx->sock->protocol = NULL;
557     silc_socket_free(ctx->sock);
558
559     /* Notify application of failure */
560     silc_schedule_task_add(client->schedule, ctx->sock->sock,
561                            silc_client_connect_failure, ctx,
562                            0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
563     return;
564   }
565
566   /* We now have the key material as the result of the key exchange
567      protocol. Take the key material into use. Free the raw key material
568      as soon as we've set them into use. */
569   silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
570                                    ctx->ske->prop->cipher,
571                                    ctx->ske->prop->pkcs,
572                                    ctx->ske->prop->hash,
573                                    ctx->ske->prop->hmac,
574                                    ctx->ske->prop->group,
575                                    ctx->responder);
576   silc_ske_free_key_material(ctx->keymat);
577
578   /* Allocate internal context for the authentication protocol. This
579      is sent as context for the protocol. */
580   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
581   proto_ctx->client = (void *)client;
582   proto_ctx->sock = sock = ctx->sock;
583   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
584   proto_ctx->dest_id_type = ctx->dest_id_type;
585   proto_ctx->dest_id = ctx->dest_id;
586
587   /* Free old protocol as it is finished now */
588   silc_protocol_free(protocol);
589   if (ctx->packet)
590     silc_packet_context_free(ctx->packet);
591   silc_free(ctx);
592   sock->protocol = NULL;
593
594   /* Resolve the authentication method to be used in this connection. The
595      completion callback is called after the application has resolved
596      the authentication method. */
597   client->internal->ops->get_auth_method(client, sock->user_data, 
598                                          sock->hostname,
599                                          sock->port, 
600                                          silc_client_resolve_auth_method,
601                                          proto_ctx);
602 }
603
604 /* Authentication method resolving callback. Application calls this function
605    after we've called the client->internal->ops->get_auth_method 
606    client operation to resolve the authentication method. We will continue
607    the executiong of the protocol in this function. */
608
609 void silc_client_resolve_auth_method(bool success,
610                                      SilcProtocolAuthMeth auth_meth,
611                                      const unsigned char *auth_data,
612                                      SilcUInt32 auth_data_len, void *context)
613 {
614   SilcClientConnAuthInternalContext *proto_ctx =
615     (SilcClientConnAuthInternalContext *)context;
616   SilcClient client = (SilcClient)proto_ctx->client;
617
618   if (!success)
619     auth_meth = SILC_AUTH_NONE;
620
621   proto_ctx->auth_meth = auth_meth;
622
623   if (auth_data && auth_data_len) {
624     proto_ctx->auth_data = silc_memdup(auth_data, auth_data_len);
625     proto_ctx->auth_data_len = auth_data_len;
626   }
627
628   /* Allocate the authenteication protocol and execute it. */
629   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH, 
630                       &proto_ctx->sock->protocol, (void *)proto_ctx, 
631                       silc_client_connect_to_server_final);
632
633   /* Execute the protocol */
634   silc_protocol_execute(proto_ctx->sock->protocol, client->schedule, 0, 0);
635 }
636
637 /* Finalizes the connection to the remote SILC server. This is called
638    after authentication protocol has been completed. This send our
639    user information to the server to receive our client ID from
640    server. */
641
642 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
643 {
644   SilcProtocol protocol = (SilcProtocol)context;
645   SilcClientConnAuthInternalContext *ctx = 
646     (SilcClientConnAuthInternalContext *)protocol->context;
647   SilcClient client = (SilcClient)ctx->client;
648   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
649   SilcBuffer packet;
650
651   SILC_LOG_DEBUG(("Start"));
652
653   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
654       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
655     /* Error occured during protocol */
656     SILC_LOG_DEBUG(("Error during authentication protocol"));
657     goto err;
658   }
659
660   if (conn->params.detach_data) {
661     /* Send RESUME_CLIENT packet to the server, which is used to resume
662        old detached session back. */
663     SilcBuffer auth;
664     SilcClientID *old_client_id;
665     unsigned char *old_id;
666     SilcUInt16 old_id_len;
667
668     if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len))
669       goto err;
670
671     old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT);
672     if (!old_client_id) {
673       silc_free(old_id);
674       goto err;
675     }
676
677     /* Generate authentication data that server will verify */
678     auth = silc_auth_public_key_auth_generate(client->public_key,
679                                               client->private_key,
680                                               client->rng, conn->hash,
681                                               old_client_id, SILC_ID_CLIENT);
682     if (!auth) {
683       silc_free(old_client_id);
684       silc_free(old_id);
685       goto err;
686     }
687
688     packet = silc_buffer_alloc_size(2 + old_id_len + auth->len);
689     silc_buffer_format(packet,
690                        SILC_STR_UI_SHORT(old_id_len),
691                        SILC_STR_UI_XNSTRING(old_id, old_id_len),
692                        SILC_STR_UI_XNSTRING(auth->data, auth->len),
693                        SILC_STR_END);
694
695     /* Send the packet */
696     silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT,
697                             NULL, 0, NULL, NULL, 
698                             packet->data, packet->len, TRUE);
699     silc_buffer_free(packet);
700     silc_buffer_free(auth);
701     silc_free(old_client_id);
702     silc_free(old_id);
703   } else {
704     /* Send NEW_CLIENT packet to the server. We will become registered
705        to the SILC network after sending this packet and we will receive
706        client ID from the server. */
707     packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + 
708                                strlen(client->realname));
709     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
710     silc_buffer_format(packet,
711                        SILC_STR_UI_SHORT(strlen(client->username)),
712                        SILC_STR_UI_XNSTRING(client->username,
713                                             strlen(client->username)),
714                        SILC_STR_UI_SHORT(strlen(client->realname)),
715                        SILC_STR_UI_XNSTRING(client->realname,
716                                             strlen(client->realname)),
717                        SILC_STR_END);
718
719     /* Send the packet */
720     silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
721                             NULL, 0, NULL, NULL, 
722                             packet->data, packet->len, TRUE);
723     silc_buffer_free(packet);
724   }
725
726   /* Save remote ID. */
727   conn->remote_id = ctx->dest_id;
728   conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
729   conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
730
731   /* Register re-key timeout */
732   conn->rekey->timeout = client->internal->params->rekey_secs;
733   conn->rekey->context = (void *)client;
734   silc_schedule_task_add(client->schedule, conn->sock->sock, 
735                          silc_client_rekey_callback,
736                          (void *)conn->sock, conn->rekey->timeout, 0,
737                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
738
739   silc_protocol_free(protocol);
740   silc_free(ctx->auth_data);
741   if (ctx->ske)
742     silc_ske_free(ctx->ske);
743   silc_socket_free(ctx->sock);
744   silc_free(ctx);
745   conn->sock->protocol = NULL;
746   return;
747
748  err:
749   silc_protocol_free(protocol);
750   silc_free(ctx->auth_data);
751   silc_free(ctx->dest_id);
752   if (ctx->ske)
753     silc_ske_free(ctx->ske);
754   conn->sock->protocol = NULL;
755   silc_socket_free(ctx->sock);
756
757   /* Notify application of failure */
758   silc_schedule_task_add(client->schedule, ctx->sock->sock,
759                          silc_client_connect_failure, ctx,
760                          0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
761 }
762
763 /* Internal routine that sends packet or marks packet to be sent. This
764    is used directly only in special cases. Normal cases should use
765    silc_server_packet_send. Returns < 0 on error. */
766
767 int silc_client_packet_send_real(SilcClient client,
768                                  SilcSocketConnection sock,
769                                  bool force_send)
770 {
771   int ret;
772
773   /* If rekey protocol is active we must assure that all packets are
774      sent through packet queue. */
775   if (SILC_CLIENT_IS_REKEY(sock))
776     force_send = FALSE;
777
778   /* If outbound data is already pending do not force send */
779   if (SILC_IS_OUTBUF_PENDING(sock))
780     force_send = FALSE;
781
782   /* Send the packet */
783   ret = silc_packet_send(sock, force_send);
784   if (ret != -2)
785     return ret;
786
787   /* Mark that there is some outgoing data available for this connection. 
788      This call sets the connection both for input and output (the input
789      is set always and this call keeps the input setting, actually). 
790      Actual data sending is performed by silc_client_packet_process. */
791   SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
792
793   /* Mark to socket that data is pending in outgoing buffer. This flag
794      is needed if new data is added to the buffer before the earlier
795      put data is sent to the network. */
796   SILC_SET_OUTBUF_PENDING(sock);
797
798   return 0;
799 }
800
801 /* Packet processing callback. This is used to send and receive packets
802    from network. This is generic task. */
803
804 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
805 {
806   SilcClient client = (SilcClient)context;
807   SilcSocketConnection sock = NULL;
808   SilcClientConnection conn;
809   int ret;
810
811   SILC_LOG_DEBUG(("Processing packet"));
812
813   SILC_CLIENT_GET_SOCK(client, fd, sock);
814   if (sock == NULL)
815     return;
816
817   conn = (SilcClientConnection)sock->user_data;
818
819   /* Packet sending */
820   if (type == SILC_TASK_WRITE) {
821     /* Do not send data to disconnected connection */
822     if (SILC_IS_DISCONNECTED(sock))
823       return;
824
825     ret = silc_packet_send(sock, TRUE);
826
827     /* If returned -2 could not write to connection now, will do
828        it later. */
829     if (ret == -2)
830       return;
831
832     /* Error */
833     if (ret == -1)
834       return;
835     
836     /* The packet has been sent and now it is time to set the connection
837        back to only for input. When there is again some outgoing data 
838        available for this connection it will be set for output as well. 
839        This call clears the output setting and sets it only for input. */
840     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
841     SILC_UNSET_OUTBUF_PENDING(sock);
842
843     silc_buffer_clear(sock->outbuf);
844     return;
845   }
846
847   /* Packet receiving */
848   if (type == SILC_TASK_READ) {
849     /* Read data from network */
850     ret = silc_packet_receive(sock);
851     if (ret < 0)
852       return;
853     
854     /* EOF */
855     if (ret == 0) {
856       SILC_LOG_DEBUG(("Read EOF"));
857
858       /* If connection is disconnecting already we will finally
859          close the connection */
860       if (SILC_IS_DISCONNECTING(sock)) {
861         if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
862           client->internal->ops->disconnect(client, conn);
863         silc_client_close_connection_real(client, sock, conn);
864         return;
865       }
866       
867       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
868       if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
869         client->internal->ops->disconnect(client, conn);
870       silc_client_close_connection_real(client, sock, conn);
871       return;
872     }
873
874     /* Process the packet. This will call the parser that will then
875        decrypt and parse the packet. */
876     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
877       silc_packet_receive_process(sock, FALSE, conn->receive_key, 
878                                   conn->hmac_receive, conn->psn_receive,
879                                   silc_client_packet_parse, client);
880     else
881       silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, 
882                                   silc_client_packet_parse, client);
883   }
884 }
885
886 /* Parser callback called by silc_packet_receive_process. Thie merely
887    registers timeout that will handle the actual parsing when appropriate. */
888
889 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
890                                      void *context)
891 {
892   SilcClient client = (SilcClient)context;
893   SilcSocketConnection sock = parser_context->sock;
894   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
895   SilcPacketContext *packet = parser_context->packet;
896   SilcPacketType ret;
897
898   if (conn && conn->hmac_receive && conn->sock == sock)
899     conn->psn_receive = parser_context->packet->sequence + 1;
900
901   /* Parse the packet immediately */
902   if (parser_context->normal)
903     ret = silc_packet_parse(packet, conn->receive_key);
904   else
905     ret = silc_packet_parse_special(packet, conn->receive_key);
906
907   if (ret == SILC_PACKET_NONE) {
908     silc_packet_context_free(packet);
909     silc_free(parser_context);
910     return FALSE;
911   }
912   
913   /* If protocol for this connection is key exchange or rekey then we'll
914      process all packets synchronously, since there might be packets in
915      queue that we are not able to decrypt without first processing the
916      packets before them. */
917   if ((ret == SILC_PACKET_REKEY || ret == SILC_PACKET_REKEY_DONE) ||
918       (sock->protocol && sock->protocol->protocol && 
919        (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
920         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY))) {
921
922     /* Parse the incoming packet type */
923     silc_client_packet_parse_type(client, sock, packet);
924     silc_packet_context_free(packet);
925     silc_free(parser_context);
926
927     /* Reprocess the buffer since we'll return FALSE. This is because
928        the `conn->receive_key' might have become valid by processing
929        the previous packet */
930     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
931       silc_packet_receive_process(sock, FALSE, conn->receive_key, 
932                                   conn->hmac_receive, conn->psn_receive,
933                                   silc_client_packet_parse, client);
934     else
935       silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, 
936                                   silc_client_packet_parse, client);
937     
938     return FALSE;
939   }
940
941   /* Parse the incoming packet type */
942   silc_client_packet_parse_type(client, sock, packet);
943   silc_packet_context_free(packet);
944   silc_free(parser_context);
945   return TRUE;
946 }
947
948 /* Parses the packet type and calls what ever routines the packet type
949    requires. This is done for all incoming packets. */
950
951 void silc_client_packet_parse_type(SilcClient client, 
952                                    SilcSocketConnection sock,
953                                    SilcPacketContext *packet)
954 {
955   SilcBuffer buffer = packet->buffer;
956   SilcPacketType type = packet->type;
957
958   SILC_LOG_DEBUG(("Parsing packet type %d", type));
959
960   /* Parse the packet type */
961   switch(type) {
962   case SILC_PACKET_DISCONNECT:
963     silc_client_disconnected_by_server(client, sock, buffer);
964     break;
965   case SILC_PACKET_SUCCESS:
966     /*
967      * Success received for something. For now we can have only
968      * one protocol for connection executing at once hence this
969      * success message is for whatever protocol is executing currently.
970      */
971     if (sock->protocol)
972       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
973     break;
974   case SILC_PACKET_FAILURE:
975     /*
976      * Failure received for some protocol. Set the protocol state to 
977      * error and call the protocol callback. This fill cause error on
978      * protocol and it will call the final callback.
979      */
980     silc_client_process_failure(client, sock, packet);
981     break;
982   case SILC_PACKET_REJECT:
983     break;
984
985   case SILC_PACKET_NOTIFY:
986     /*
987      * Received notify message 
988      */
989     silc_client_notify_by_server(client, sock, packet);
990     break;
991
992   case SILC_PACKET_ERROR:
993     /*
994      * Received error message
995      */
996     silc_client_error_by_server(client, sock, buffer);
997     break;
998
999   case SILC_PACKET_CHANNEL_MESSAGE:
1000     /*
1001      * Received message to (from, actually) a channel
1002      */
1003     silc_client_channel_message(client, sock, packet);
1004     break;
1005   case SILC_PACKET_CHANNEL_KEY:
1006     /*
1007      * Received key for a channel. By receiving this key the client will be
1008      * able to talk to the channel it has just joined. This can also be
1009      * a new key for existing channel as keys expire peridiocally.
1010      */
1011     silc_client_receive_channel_key(client, sock, buffer);
1012     break;
1013
1014   case SILC_PACKET_PRIVATE_MESSAGE:
1015     /*
1016      * Received private message
1017      */
1018     silc_client_private_message(client, sock, packet);
1019     break;
1020   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1021     /*
1022      * Received private message key
1023      */
1024     break;
1025
1026   case SILC_PACKET_COMMAND_REPLY:
1027     /*
1028      * Recived reply for a command
1029      */
1030     silc_client_command_reply_process(client, sock, packet);
1031     break;
1032
1033   case SILC_PACKET_KEY_EXCHANGE:
1034     if (sock->protocol && sock->protocol->protocol && 
1035         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
1036       SilcClientKEInternalContext *proto_ctx = 
1037         (SilcClientKEInternalContext *)sock->protocol->context;
1038
1039       proto_ctx->packet = silc_packet_context_dup(packet);
1040       proto_ctx->dest_id_type = packet->src_id_type;
1041       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1042                                           packet->src_id_type);
1043       if (!proto_ctx->dest_id)
1044         break;
1045
1046       /* Let the protocol handle the packet */
1047       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1048     } else {
1049       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1050                       "protocol active, packet dropped."));
1051     }
1052     break;
1053
1054   case SILC_PACKET_KEY_EXCHANGE_1:
1055     if (sock->protocol && sock->protocol->protocol && 
1056         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1057          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
1058
1059       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1060         SilcClientRekeyInternalContext *proto_ctx = 
1061           (SilcClientRekeyInternalContext *)sock->protocol->context;
1062         
1063         if (proto_ctx->packet)
1064           silc_packet_context_free(proto_ctx->packet);
1065         
1066         proto_ctx->packet = silc_packet_context_dup(packet);
1067
1068         /* Let the protocol handle the packet */
1069         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1070       } else {
1071         SilcClientKEInternalContext *proto_ctx = 
1072           (SilcClientKEInternalContext *)sock->protocol->context;
1073         
1074         if (proto_ctx->packet)
1075           silc_packet_context_free(proto_ctx->packet);
1076         
1077         proto_ctx->packet = silc_packet_context_dup(packet);
1078         proto_ctx->dest_id_type = packet->src_id_type;
1079         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1080                                             packet->src_id_type);
1081         if (!proto_ctx->dest_id)
1082           break;
1083         
1084         /* Let the protocol handle the packet */
1085         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1086       }
1087     } else {
1088       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1089                       "protocol active, packet dropped."));
1090     }
1091     break;
1092   case SILC_PACKET_KEY_EXCHANGE_2:
1093     if (sock->protocol && sock->protocol->protocol && 
1094         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1095          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
1096
1097       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1098         SilcClientRekeyInternalContext *proto_ctx = 
1099           (SilcClientRekeyInternalContext *)sock->protocol->context;
1100         
1101         if (proto_ctx->packet)
1102           silc_packet_context_free(proto_ctx->packet);
1103         
1104         proto_ctx->packet = silc_packet_context_dup(packet);
1105
1106         /* Let the protocol handle the packet */
1107         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1108       } else {
1109         SilcClientKEInternalContext *proto_ctx = 
1110           (SilcClientKEInternalContext *)sock->protocol->context;
1111         
1112         if (proto_ctx->packet)
1113           silc_packet_context_free(proto_ctx->packet);
1114         if (proto_ctx->dest_id)
1115           silc_free(proto_ctx->dest_id);
1116         proto_ctx->packet = silc_packet_context_dup(packet);
1117         proto_ctx->dest_id_type = packet->src_id_type;
1118         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1119                                             packet->src_id_type);
1120         if (!proto_ctx->dest_id)
1121           break;
1122         
1123         /* Let the protocol handle the packet */
1124         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1125       }
1126     } else {
1127       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1128                       "protocol active, packet dropped."));
1129     }
1130     break;
1131
1132   case SILC_PACKET_NEW_ID:
1133     {
1134       /*
1135        * Received new ID from server. This packet is received at
1136        * the connection to the server.  New ID is also received when 
1137        * user changes nickname but in that case the new ID is received
1138        * as command reply and not as this packet type.
1139        */
1140       SilcIDPayload idp;
1141
1142       idp = silc_id_payload_parse(buffer->data, buffer->len);
1143       if (!idp)
1144         break;
1145       if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
1146         break;
1147
1148       silc_client_receive_new_id(client, sock, idp);
1149       silc_id_payload_free(idp);
1150       break;
1151     }
1152
1153   case SILC_PACKET_HEARTBEAT:
1154     /*
1155      * Received heartbeat packet
1156      */
1157     SILC_LOG_DEBUG(("Heartbeat packet"));
1158     break;
1159
1160   case SILC_PACKET_KEY_AGREEMENT:
1161     /*
1162      * Received key agreement packet
1163      */
1164     SILC_LOG_DEBUG(("Key agreement packet"));
1165     silc_client_key_agreement(client, sock, packet);
1166     break;
1167
1168   case SILC_PACKET_REKEY:
1169     SILC_LOG_DEBUG(("Re-key packet"));
1170     /* We ignore this for now */
1171     break;
1172
1173   case SILC_PACKET_REKEY_DONE:
1174     SILC_LOG_DEBUG(("Re-key done packet"));
1175
1176     if (sock->protocol && sock->protocol->protocol && 
1177         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1178
1179       SilcClientRekeyInternalContext *proto_ctx = 
1180         (SilcClientRekeyInternalContext *)sock->protocol->context;
1181       
1182       if (proto_ctx->packet)
1183         silc_packet_context_free(proto_ctx->packet);
1184       
1185       proto_ctx->packet = silc_packet_context_dup(packet);
1186
1187       /* Let the protocol handle the packet */
1188       if (proto_ctx->responder == FALSE)
1189         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1190       else
1191         /* Let the protocol handle the packet */
1192         silc_protocol_execute(sock->protocol, client->schedule, 
1193                               0, 100000);
1194     } else {
1195       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1196                       "protocol active, packet dropped."));
1197     }
1198     break;
1199
1200   case SILC_PACKET_CONNECTION_AUTH_REQUEST:
1201     /*
1202      * Reveived reply to our connection authentication method request
1203      * packet. This is used to resolve the authentication method for the
1204      * current session from the server if the client does not know it.
1205      */
1206     silc_client_connection_auth_request(client, sock, packet);
1207     break;
1208
1209   case SILC_PACKET_FTP:
1210     /* Received file transfer packet. */
1211     silc_client_ftp(client, sock, packet);
1212     break;
1213
1214   default:
1215     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1216     break;
1217   }
1218 }
1219
1220 /* Sends packet. This doesn't actually send the packet instead it assembles
1221    it and marks it to be sent. However, if force_send is TRUE the packet
1222    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1223    will be derived from sock argument. Otherwise the valid arguments sent
1224    are used. */
1225
1226 void silc_client_packet_send(SilcClient client, 
1227                              SilcSocketConnection sock,
1228                              SilcPacketType type, 
1229                              void *dst_id,
1230                              SilcIdType dst_id_type,
1231                              SilcCipher cipher,
1232                              SilcHmac hmac,
1233                              unsigned char *data, 
1234                              SilcUInt32 data_len, 
1235                              int force_send)
1236 {
1237   SilcPacketContext packetdata;
1238   const SilcBufferStruct packet;
1239   int block_len;
1240   SilcUInt32 sequence = 0;
1241
1242   if (!sock)
1243     return;
1244
1245   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1246
1247   /* Get data used in the packet sending, keys and stuff */
1248   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1249     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1250       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1251
1252     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1253       hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1254
1255     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1256       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1257       dst_id_type = SILC_ID_SERVER;
1258     }
1259
1260     if (hmac)
1261       sequence = ((SilcClientConnection)sock->user_data)->psn_send++;
1262   }
1263
1264   block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
1265
1266   /* Set the packet context pointers */
1267   packetdata.flags = 0;
1268   packetdata.type = type;
1269   if (sock->user_data && 
1270       ((SilcClientConnection)sock->user_data)->local_id_data) {
1271     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1272     packetdata.src_id_len = 
1273       silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
1274                       SILC_ID_CLIENT);
1275   } else { 
1276     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1277     packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1278   }
1279   packetdata.src_id_type = SILC_ID_CLIENT;
1280   if (dst_id) {
1281     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1282     packetdata.dst_id_len = silc_id_get_len(dst_id, dst_id_type);
1283     packetdata.dst_id_type = dst_id_type;
1284   } else {
1285     packetdata.dst_id = NULL;
1286     packetdata.dst_id_len = 0;
1287     packetdata.dst_id_type = SILC_ID_NONE;
1288   }
1289   data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
1290                                             packetdata.src_id_len + 
1291                                             packetdata.dst_id_len));
1292   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1293     packetdata.src_id_len + packetdata.dst_id_len;
1294   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
1295
1296   /* Create the outgoing packet */
1297   if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock, 
1298                             data, data_len, (const SilcBuffer)&packet)) {
1299     SILC_LOG_ERROR(("Error assembling packet"));
1300     return;
1301   }
1302
1303   /* Encrypt the packet */
1304   if (cipher)
1305     silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet, 
1306                         packet.len);
1307
1308   SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, packet.len),
1309                    packet.data, packet.len);
1310
1311   /* Now actually send the packet */
1312   silc_client_packet_send_real(client, sock, force_send);
1313 }
1314
1315 void silc_client_packet_queue_purge(SilcClient client,
1316                                     SilcSocketConnection sock)
1317 {
1318   if (sock && SILC_IS_OUTBUF_PENDING(sock) && 
1319       (SILC_IS_DISCONNECTED(sock) == FALSE)) {
1320     silc_packet_send(sock, TRUE);
1321     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, sock->sock);
1322     SILC_UNSET_OUTBUF_PENDING(sock);
1323     silc_buffer_clear(sock->outbuf);
1324   }
1325 }
1326
1327 /* Closes connection to remote end. Free's all allocated data except
1328    for some information such as nickname etc. that are valid at all time. 
1329    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1330    provided it will be checked whether the sock and `conn->sock' are the
1331    same (they can be different, ie. a socket can use `conn' as its
1332    connection but `conn->sock' might be actually a different connection
1333    than the `sock'). */
1334
1335 void silc_client_close_connection_real(SilcClient client,
1336                                        SilcSocketConnection sock,
1337                                        SilcClientConnection conn)
1338 {
1339   int del = FALSE;
1340
1341   SILC_LOG_DEBUG(("Start"));
1342
1343   if (!sock && !conn)
1344     return;
1345
1346   if (!sock || (sock && conn->sock == sock))
1347     del = TRUE;
1348   if (!sock)
1349     sock = conn->sock;
1350
1351   /* We won't listen for this connection anymore */
1352   silc_schedule_unset_listen_fd(client->schedule, sock->sock);
1353
1354   /* Unregister all tasks */
1355   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1356
1357   /* Close the actual connection */
1358   silc_net_close_connection(sock->sock);
1359
1360   /* Cancel any active protocol */
1361   if (sock->protocol) {
1362     if (sock->protocol->protocol->type == 
1363         SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1364         sock->protocol->protocol->type == 
1365         SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
1366       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1367       silc_protocol_execute_final(sock->protocol, client->schedule);
1368       /* The application will recall this function with these protocols
1369          (the ops->connect client operation). */
1370       return;
1371     } else {
1372       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1373       silc_protocol_execute_final(sock->protocol, client->schedule);
1374       sock->protocol = NULL;
1375     }
1376   }
1377
1378   /* Free everything */
1379   if (del && sock->user_data) {
1380     /* Free all cache entries */
1381     SilcIDCacheList list;
1382     SilcIDCacheEntry entry;
1383     SilcClientCommandPending *r;
1384     bool ret;
1385
1386     if (silc_idcache_get_all(conn->client_cache, &list)) {
1387       ret = silc_idcache_list_first(list, &entry);
1388       while (ret) {
1389         silc_client_del_client(client, conn, entry->context);
1390         ret = silc_idcache_list_next(list, &entry);
1391       }
1392       silc_idcache_list_free(list);
1393     }
1394
1395     if (silc_idcache_get_all(conn->channel_cache, &list)) {
1396       ret = silc_idcache_list_first(list, &entry);
1397       while (ret) {
1398         silc_client_del_channel(client, conn, entry->context);
1399         ret = silc_idcache_list_next(list, &entry);
1400       }
1401       silc_idcache_list_free(list);
1402     }
1403
1404     if (silc_idcache_get_all(conn->server_cache, &list)) {
1405       ret = silc_idcache_list_first(list, &entry);
1406       while (ret) {
1407         silc_client_del_server(client, conn, entry->context);
1408         ret = silc_idcache_list_next(list, &entry);
1409       }
1410       silc_idcache_list_free(list);
1411     }
1412
1413     /* Clear ID caches */
1414     if (conn->client_cache)
1415       silc_idcache_free(conn->client_cache);
1416     if (conn->channel_cache)
1417       silc_idcache_free(conn->channel_cache);
1418     if (conn->server_cache)
1419       silc_idcache_free(conn->server_cache);
1420
1421     /* Free data (my ID is freed in above silc_client_del_client).
1422        conn->nickname is freed when freeing the local_entry->nickname. */
1423     if (conn->remote_host)
1424       silc_free(conn->remote_host);
1425     if (conn->local_id_data)
1426       silc_free(conn->local_id_data);
1427     if (conn->send_key)
1428       silc_cipher_free(conn->send_key);
1429     if (conn->receive_key)
1430       silc_cipher_free(conn->receive_key);
1431     if (conn->hmac_send)
1432       silc_hmac_free(conn->hmac_send);
1433     if (conn->hmac_receive)
1434       silc_hmac_free(conn->hmac_receive);
1435     if (conn->rekey)
1436       silc_free(conn->rekey);
1437
1438     if (conn->active_session) {
1439       sock->user_data = NULL;
1440       silc_client_ftp_session_free(conn->active_session);
1441       conn->active_session = NULL;
1442     }
1443
1444     silc_client_ftp_free_sessions(client, conn);
1445
1446     silc_dlist_start(conn->pending_commands);
1447     while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END)
1448       silc_dlist_del(conn->pending_commands, r);
1449     if (conn->pending_commands)
1450       silc_dlist_uninit(conn->pending_commands);
1451
1452     memset(conn, 0, sizeof(*conn));
1453     silc_client_del_connection(client, conn);
1454   }
1455
1456   silc_socket_free(sock);
1457 }
1458
1459 /* Closes the connection to the remote end */
1460
1461 void silc_client_close_connection(SilcClient client,
1462                                   SilcClientConnection conn)
1463 {
1464   silc_client_close_connection_real(client, NULL, conn);
1465 }
1466
1467 /* Called when we receive disconnection packet from server. This 
1468    closes our end properly and displays the reason of the disconnection
1469    on the screen. */
1470
1471 SILC_TASK_CALLBACK(silc_client_disconnected_by_server_later)
1472 {
1473   SilcClient client = (SilcClient)context;
1474   SilcClientConnection conn;
1475   SilcSocketConnection sock;
1476
1477   SILC_CLIENT_GET_SOCK(client, fd, sock);
1478   if (sock == NULL)
1479     return;
1480
1481   conn = (SilcClientConnection)sock->user_data;
1482   if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
1483     client->internal->ops->disconnect(client, conn);
1484
1485   silc_client_close_connection_real(client, sock, sock->user_data);
1486 }
1487
1488 /* Called when we receive disconnection packet from server. This 
1489    closes our end properly and displays the reason of the disconnection
1490    on the screen. */
1491
1492 void silc_client_disconnected_by_server(SilcClient client,
1493                                         SilcSocketConnection sock,
1494                                         SilcBuffer packet)
1495 {
1496   SilcStatus status;
1497   char *message = NULL;
1498
1499   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1500
1501   if (packet->len < 1)
1502     return;
1503
1504   status = (SilcStatus)packet->data[0];
1505
1506   if (packet->len > 1 &&
1507       silc_utf8_valid(packet->data + 1, packet->len - 1))
1508     message = silc_memdup(packet->data + 1, packet->len - 1);
1509
1510   client->internal->ops->say(client, sock->user_data, 
1511                              SILC_CLIENT_MESSAGE_AUDIT, 
1512                              "Server closed connection: %s (%d) %s",
1513                              silc_get_status_message(status), status,
1514                              message ? message : "");
1515   silc_free(message);
1516
1517   SILC_SET_DISCONNECTED(sock);
1518
1519   /* Close connection through scheduler. */
1520   silc_schedule_task_add(client->schedule, sock->sock, 
1521                          silc_client_disconnected_by_server_later,
1522                          client, 0, 1, SILC_TASK_TIMEOUT, 
1523                          SILC_TASK_PRI_NORMAL);
1524 }
1525
1526 /* Received error message from server. Display it on the screen. 
1527    We don't take any action what so ever of the error message. */
1528
1529 void silc_client_error_by_server(SilcClient client,
1530                                  SilcSocketConnection sock,
1531                                  SilcBuffer message)
1532 {
1533   char *msg;
1534
1535   msg = silc_memdup(message->data, message->len);
1536   client->internal->ops->say(client, sock->user_data, 
1537                              SILC_CLIENT_MESSAGE_AUDIT, msg);
1538   silc_free(msg);
1539 }
1540
1541 /* Auto-nicking callback to send NICK command to server. */
1542
1543 SILC_TASK_CALLBACK(silc_client_send_auto_nick)
1544 {
1545   SilcClientConnection conn = (SilcClientConnection)context;
1546   SilcClient client = conn->client;
1547
1548   silc_client_command_send(client, conn, SILC_COMMAND_NICK, 
1549                            ++conn->cmd_ident, 1, 1, 
1550                            client->nickname, strlen(client->nickname));
1551 }
1552
1553 /* Client session resuming callback.  If the session was resumed
1554    this callback is called after the resuming is completed.  This
1555    will call the `connect' client operation to the application
1556    since it has not been called yet. */
1557
1558 static void silc_client_resume_session_cb(SilcClient client,
1559                                           SilcClientConnection conn,
1560                                           bool success,
1561                                           void *context)
1562 {
1563   SilcBuffer sidp;
1564
1565   /* Notify application that connection is created to server */
1566   client->internal->ops->connect(client, conn, success ?
1567                                  SILC_CLIENT_CONN_SUCCESS_RESUME :
1568                                  SILC_CLIENT_CONN_ERROR);
1569
1570   if (success) {
1571     /* Issue INFO command to fetch the real server name and server
1572        information and other stuff. */
1573     silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
1574                                  silc_client_command_reply_info_i, 0, 
1575                                  ++conn->cmd_ident);
1576     sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1577     silc_client_command_send(client, conn, SILC_COMMAND_INFO,
1578                              conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1579     silc_buffer_free(sidp);
1580   }
1581 }
1582
1583 /* Processes the received new Client ID from server. Old Client ID is
1584    deleted from cache and new one is added. */
1585
1586 void silc_client_receive_new_id(SilcClient client,
1587                                 SilcSocketConnection sock,
1588                                 SilcIDPayload idp)
1589 {
1590   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1591   int connecting = FALSE;
1592   SilcClientID *client_id = silc_id_payload_get_id(idp);
1593
1594   if (!conn->local_entry)
1595     connecting = TRUE;
1596
1597   /* Delete old ID from ID cache */
1598   if (conn->local_id) {
1599     /* Check whether they are different */
1600     if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
1601       silc_free(client_id);
1602       return;
1603     }
1604
1605     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
1606     silc_free(conn->local_id);
1607   }
1608   
1609   /* Save the new ID */
1610
1611   if (conn->local_id_data)
1612     silc_free(conn->local_id_data);
1613
1614   conn->local_id = client_id;
1615   conn->local_id_data = silc_id_payload_get_data(idp);
1616   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1617
1618   if (!conn->local_entry)
1619     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1620
1621   conn->local_entry->nickname = conn->nickname;
1622   if (!conn->local_entry->username)
1623     conn->local_entry->username = strdup(client->username);
1624   if (!conn->local_entry->hostname)
1625     conn->local_entry->hostname = strdup(client->hostname);
1626   if (!conn->local_entry->server)
1627     conn->local_entry->server = strdup(conn->remote_host);
1628   conn->local_entry->id = conn->local_id;
1629   conn->local_entry->valid = TRUE;
1630   if (!conn->local_entry->channels)
1631     conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr, 
1632                                                         NULL, NULL,
1633                                                         NULL, NULL, NULL, 
1634                                                         TRUE);
1635
1636   /* Put it to the ID cache */
1637   silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, 
1638                    (void *)conn->local_entry, 0, NULL);
1639
1640   if (connecting) {
1641     if (!conn->params.detach_data) {
1642       SilcBuffer sidp;
1643
1644       /* Send NICK command if the nickname was set by the application (and is
1645          not same as the username). Send this with little timeout. */
1646       if (client->nickname && strcmp(client->nickname, client->username))
1647         silc_schedule_task_add(client->schedule, 0,
1648                                silc_client_send_auto_nick, conn,
1649                                1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1650
1651       /* Notify application of successful connection. We do it here now that
1652          we've received the Client ID and are allowed to send traffic. */
1653       client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_SUCCESS);
1654
1655       /* Issue INFO command to fetch the real server name and server
1656          information and other stuff. */
1657       silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
1658                                    silc_client_command_reply_info_i, 0, 
1659                                    ++conn->cmd_ident);
1660       sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1661       silc_client_command_send(client, conn, SILC_COMMAND_INFO,
1662                                conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1663       silc_buffer_free(sidp);
1664     } else {
1665       /* We are resuming session.  Start resolving informations from the
1666          server we need to set the client libary in the state before
1667          detaching the session.  The connect client operation is called
1668          after this is successfully completed */
1669       silc_client_resume_session(client, conn, silc_client_resume_session_cb,
1670                                  NULL);
1671     }
1672   }
1673 }
1674
1675 /* Removes a client entry from all channels it has joined. */
1676
1677 void silc_client_remove_from_channels(SilcClient client,
1678                                       SilcClientConnection conn,
1679                                       SilcClientEntry client_entry)
1680 {
1681   SilcHashTableList htl;
1682   SilcChannelUser chu;
1683
1684   silc_hash_table_list(client_entry->channels, &htl);
1685   while (silc_hash_table_get(&htl, NULL, (void **)&chu)) {
1686     silc_hash_table_del(chu->client->channels, chu->channel);
1687     silc_hash_table_del(chu->channel->user_list, chu->client);
1688     silc_free(chu);
1689   }
1690
1691   silc_hash_table_list_reset(&htl);
1692 }
1693
1694 /* Replaces `old' client entries from all channels to `new' client entry.
1695    This can be called for example when nickname changes and old ID entry
1696    is replaced from ID cache with the new one. If the old ID entry is only
1697    updated, then this fucntion needs not to be called. */
1698
1699 void silc_client_replace_from_channels(SilcClient client, 
1700                                        SilcClientConnection conn,
1701                                        SilcClientEntry old,
1702                                        SilcClientEntry new)
1703 {
1704   SilcHashTableList htl;
1705   SilcChannelUser chu;
1706
1707   silc_hash_table_list(old->channels, &htl);
1708   while (silc_hash_table_get(&htl, NULL, (void **)&chu)) {
1709     /* Replace client entry */
1710     silc_hash_table_del(chu->client->channels, chu->channel);
1711     silc_hash_table_del(chu->channel->user_list, chu->client);
1712     
1713     chu->client = new;
1714     silc_hash_table_add(chu->channel->user_list, chu->client, chu);
1715     silc_hash_table_add(chu->client->channels, chu->channel, chu);
1716   }
1717   silc_hash_table_list_reset(&htl);
1718 }
1719
1720 /* Registers failure timeout to process the received failure packet
1721    with timeout. */
1722
1723 void silc_client_process_failure(SilcClient client,
1724                                  SilcSocketConnection sock,
1725                                  SilcPacketContext *packet)
1726 {
1727   SilcUInt32 failure = 0;
1728
1729   if (sock->protocol) {
1730     if (packet->buffer->len >= 4)
1731       SILC_GET32_MSB(failure, packet->buffer->data);
1732
1733     /* Notify application */
1734     client->internal->ops->failure(client, sock->user_data, sock->protocol,
1735                                    (void *)failure);
1736   }
1737 }
1738
1739 /* A timeout callback for the re-key. We will be the initiator of the
1740    re-key protocol. */
1741
1742 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1743 {
1744   SilcSocketConnection sock = (SilcSocketConnection)context;
1745   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1746   SilcClient client = (SilcClient)conn->rekey->context;
1747   SilcProtocol protocol;
1748   SilcClientRekeyInternalContext *proto_ctx;
1749
1750   SILC_LOG_DEBUG(("Start"));
1751
1752   /* Allocate internal protocol context. This is sent as context
1753      to the protocol. */
1754   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1755   proto_ctx->client = (void *)client;
1756   proto_ctx->sock = silc_socket_dup(sock);
1757   proto_ctx->responder = FALSE;
1758   proto_ctx->pfs = conn->rekey->pfs;
1759       
1760   /* Perform rekey protocol. Will call the final callback after the
1761      protocol is over. */
1762   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1763                       &protocol, proto_ctx, silc_client_rekey_final);
1764   sock->protocol = protocol;
1765       
1766   /* Run the protocol */
1767   silc_protocol_execute(protocol, client->schedule, 0, 0);
1768
1769   /* Re-register re-key timeout */
1770   silc_schedule_task_add(client->schedule, sock->sock, 
1771                          silc_client_rekey_callback,
1772                          context, conn->rekey->timeout, 0,
1773                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1774 }
1775
1776 /* The final callback for the REKEY protocol. This will actually take the
1777    new key material into use. */
1778
1779 SILC_TASK_CALLBACK(silc_client_rekey_final)
1780 {
1781   SilcProtocol protocol = (SilcProtocol)context;
1782   SilcClientRekeyInternalContext *ctx =
1783     (SilcClientRekeyInternalContext *)protocol->context;
1784   SilcClient client = (SilcClient)ctx->client;
1785   SilcSocketConnection sock = ctx->sock;
1786
1787   SILC_LOG_DEBUG(("Start"));
1788
1789   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1790       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1791     /* Error occured during protocol */
1792     silc_protocol_cancel(protocol, client->schedule);
1793     silc_protocol_free(protocol);
1794     sock->protocol = NULL;
1795     if (ctx->packet)
1796       silc_packet_context_free(ctx->packet);
1797     if (ctx->ske)
1798       silc_ske_free(ctx->ske);
1799     silc_socket_free(ctx->sock);
1800     silc_free(ctx);
1801     return;
1802   }
1803
1804   /* Purge the outgoing data queue to assure that all rekey packets really
1805      go to the network before we quit the protocol. */
1806   silc_client_packet_queue_purge(client, sock);
1807
1808   /* Cleanup */
1809   silc_protocol_free(protocol);
1810   sock->protocol = NULL;
1811   if (ctx->packet)
1812     silc_packet_context_free(ctx->packet);
1813   if (ctx->ske)
1814     silc_ske_free(ctx->ske);
1815   silc_socket_free(ctx->sock);
1816   silc_free(ctx);
1817 }
1818
1819 /* Processes incoming connection authentication method request packet.
1820    It is a reply to our previously sent request. The packet can be used
1821    to resolve the authentication method for the current session if the
1822    client does not know it beforehand. */
1823
1824 void silc_client_connection_auth_request(SilcClient client,
1825                                          SilcSocketConnection sock,
1826                                          SilcPacketContext *packet)
1827 {
1828   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1829   SilcUInt16 conn_type, auth_meth;
1830   int ret;
1831
1832   /* If we haven't send our request then ignore this one. */
1833   if (!conn->connauth)
1834     return;
1835
1836   /* Parse the payload */
1837   ret = silc_buffer_unformat(packet->buffer,
1838                              SILC_STR_UI_SHORT(&conn_type),
1839                              SILC_STR_UI_SHORT(&auth_meth),
1840                              SILC_STR_END);
1841   if (ret == -1)
1842     auth_meth = SILC_AUTH_NONE;
1843
1844   /* Call the request callback to notify application for received 
1845      authentication method information. */
1846   if (conn->connauth->callback)
1847     (*conn->connauth->callback)(client, conn, auth_meth,
1848                                 conn->connauth->context);
1849
1850   silc_schedule_task_del(client->schedule, conn->connauth->timeout);
1851
1852   silc_free(conn->connauth);
1853   conn->connauth = NULL;
1854 }
1855
1856 /* Timeout task callback called if the server does not reply to our 
1857    connection authentication method request in the specified time interval. */
1858
1859 SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout)
1860 {
1861   SilcClientConnection conn = (SilcClientConnection)context;
1862   SilcClient client = conn->client;
1863
1864   if (!conn->connauth)
1865     return;
1866
1867   /* Call the request callback to notify application */
1868   if (conn->connauth->callback)
1869     (*conn->connauth->callback)(client, conn, SILC_AUTH_NONE,
1870                                 conn->connauth->context);
1871
1872   silc_free(conn->connauth);
1873   conn->connauth = NULL;
1874 }
1875
1876 /* This function can be used to request the current authentication method
1877    from the server. This may be called when connecting to the server
1878    and the client library requests the authentication data from the
1879    application. If the application does not know the current authentication
1880    method it can request it from the server using this function.
1881    The `callback' with `context' will be called after the server has
1882    replied back with the current authentication method. */
1883
1884 void 
1885 silc_client_request_authentication_method(SilcClient client,
1886                                           SilcClientConnection conn,
1887                                           SilcConnectionAuthRequest callback,
1888                                           void *context)
1889 {
1890   SilcClientConnAuthRequest connauth;
1891   SilcBuffer packet;
1892
1893   connauth = silc_calloc(1, sizeof(*connauth));
1894   connauth->callback = callback;
1895   connauth->context = context;
1896
1897   if (conn->connauth)
1898     silc_free(conn->connauth);
1899
1900   conn->connauth = connauth;
1901
1902   /* Assemble the request packet and send it to the server */
1903   packet = silc_buffer_alloc(4);
1904   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1905   silc_buffer_format(packet,
1906                      SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
1907                      SILC_STR_UI_SHORT(SILC_AUTH_NONE),
1908                      SILC_STR_END);
1909   silc_client_packet_send(client, conn->sock, 
1910                           SILC_PACKET_CONNECTION_AUTH_REQUEST,
1911                           NULL, 0, NULL, NULL, 
1912                           packet->data, packet->len, FALSE);
1913   silc_buffer_free(packet);
1914
1915   /* Register a timeout in case server does not reply anything back. */
1916   connauth->timeout =
1917     silc_schedule_task_add(client->schedule, conn->sock->sock, 
1918                            silc_client_request_authentication_method_timeout,
1919                            conn, 
1920                            client->internal->params->connauth_request_secs, 0,
1921                            SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1922 }