Resolved local info with IDENTIFY in connecting.
[silc.git] / lib / silcclient / client.c
index 59945b6ece412ab3f45141dfd179852ed4724552..b3835a150ed94e1bed4e4f9289480d0964f5ac9a 100644 (file)
@@ -194,6 +194,8 @@ silc_client_add_connection(SilcClient client,
   SilcClientConnection conn;
   int i;
 
+  SILC_LOG_DEBUG(("Adding new connection to %s:%d", hostname, port));
+
   conn = silc_calloc(1, sizeof(*conn));
 
   /* Initialize ID caches */
@@ -654,21 +656,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     SILC_LOG_DEBUG(("Error during authentication protocol"));
-    silc_protocol_free(protocol);
-    if (ctx->auth_data)
-      silc_free(ctx->auth_data);
-    if (ctx->ske)
-      silc_ske_free(ctx->ske);
-    if (ctx->dest_id)
-      silc_free(ctx->dest_id);
-    conn->sock->protocol = NULL;
-    silc_socket_free(ctx->sock);
-
-    /* Notify application of failure */
-    silc_schedule_task_add(client->schedule, ctx->sock->sock,
-                          silc_client_connect_failure, ctx,
-                          0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-    return;
+    goto err;
   }
 
   if (conn->params.detach_data) {
@@ -680,12 +668,12 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
     SilcUInt16 old_id_len;
 
     if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len))
-      return;
+      goto err;
 
     old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT);
     if (!old_client_id) {
       silc_free(old_id);
-      return;
+      goto err;
     }
 
     /* Generate authentication data that server will verify */
@@ -696,7 +684,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
     if (!auth) {
       silc_free(old_client_id);
       silc_free(old_id);
-      return;
+      goto err;
     }
 
     packet = silc_buffer_alloc_size(2 + old_id_len + auth->len);
@@ -751,13 +739,27 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
                         SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 
   silc_protocol_free(protocol);
-  if (ctx->auth_data)
-    silc_free(ctx->auth_data);
+  silc_free(ctx->auth_data);
   if (ctx->ske)
     silc_ske_free(ctx->ske);
   silc_socket_free(ctx->sock);
   silc_free(ctx);
   conn->sock->protocol = NULL;
+  return;
+
+ err:
+  silc_protocol_free(protocol);
+  silc_free(ctx->auth_data);
+  silc_free(ctx->dest_id);
+  if (ctx->ske)
+    silc_ske_free(ctx->ske);
+  conn->sock->protocol = NULL;
+  silc_socket_free(ctx->sock);
+
+  /* Notify application of failure */
+  silc_schedule_task_add(client->schedule, ctx->sock->sock,
+                        silc_client_connect_failure, ctx,
+                        0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 }
 
 /* Internal routine that sends packet or marks packet to be sent. This
@@ -859,14 +861,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
         close the connection */
       if (SILC_IS_DISCONNECTING(sock)) {
        if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
-         client->internal->ops->disconnect(client, conn);
+         client->internal->ops->disconnect(client, conn, 0, NULL);
        silc_client_close_connection_real(client, sock, conn);
        return;
       }
       
       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
       if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
-       client->internal->ops->disconnect(client, conn);
+       client->internal->ops->disconnect(client, conn, 0, NULL);
       silc_client_close_connection_real(client, sock, conn);
       return;
     }
@@ -1488,6 +1490,7 @@ void silc_client_disconnected_by_server(SilcClient client,
                                        SilcSocketConnection sock,
                                        SilcBuffer packet)
 {
+  SilcClientConnection conn;
   SilcStatus status;
   char *message = NULL;
 
@@ -1502,11 +1505,10 @@ void silc_client_disconnected_by_server(SilcClient client,
       silc_utf8_valid(packet->data + 1, packet->len - 1))
     message = silc_memdup(packet->data + 1, packet->len - 1);
 
-  client->internal->ops->say(client, sock->user_data, 
-                            SILC_CLIENT_MESSAGE_AUDIT, 
-                            "Server closed connection: %s (%d) %s",
-                            silc_get_status_message(status), status,
-                            message ? message : "");
+  conn = (SilcClientConnection)sock->user_data;
+  if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
+    client->internal->ops->disconnect(client, conn, status, message);
+
   silc_free(message);
 
   SILC_SET_DISCONNECTED(sock);
@@ -1616,8 +1618,6 @@ void silc_client_receive_new_id(SilcClient client,
   conn->local_entry->nickname = conn->nickname;
   if (!conn->local_entry->username)
     conn->local_entry->username = strdup(client->username);
-  if (!conn->local_entry->hostname)
-    conn->local_entry->hostname = strdup(client->hostname);
   if (!conn->local_entry->server)
     conn->local_entry->server = strdup(conn->remote_host);
   conn->local_entry->id = conn->local_id;
@@ -1633,9 +1633,19 @@ void silc_client_receive_new_id(SilcClient client,
                   (void *)conn->local_entry, 0, NULL);
 
   if (connecting) {
-    if (!conn->params.detach_data) {
-      SilcBuffer sidp;
+    SilcBuffer sidp;
 
+    /* Issue IDENTIFY command for itself to get resolved hostname
+       correctly from server. */
+    silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
+                                silc_client_command_reply_identify_i, 0, 
+                                ++conn->cmd_ident);
+    sidp = silc_id_payload_encode(conn->local_entry->id, SILC_ID_CLIENT);
+    silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
+                            conn->cmd_ident, 1, 5, sidp->data, sidp->len);
+    silc_buffer_free(sidp);
+
+    if (!conn->params.detach_data) {
       /* Send NICK command if the nickname was set by the application (and is
         not same as the username). Send this with little timeout. */
       if (client->nickname && strcmp(client->nickname, client->username))