SilcClientConnection conn;
int i;
+ SILC_LOG_DEBUG(("Adding new connection to %s:%d", hostname, port));
+
conn = silc_calloc(1, sizeof(*conn));
/* Initialize ID caches */
if (conn->pending_commands)
silc_dlist_uninit(conn->pending_commands);
silc_free(conn->remote_host);
- silc_dlist_uninit(conn->ftp_sessions);
+ if (conn->ftp_sessions)
+ silc_dlist_uninit(conn->ftp_sessions);
silc_free(conn);
client->internal->conns[i] = NULL;
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) {
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 */
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);
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
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;
}
SILC_LOG_DEBUG(("Start"));
+ if (!sock && !conn)
+ return;
+
if (!sock || (sock && conn->sock == sock))
del = TRUE;
if (!sock)
SilcSocketConnection sock,
SilcBuffer packet)
{
+ SilcClientConnection conn;
SilcStatus status;
char *message = NULL;
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);
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;
(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))