return sock;
}
-/* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
- key material between client and server. This function can be called
- directly if application is performing its own connecting and does not
- use the connecting provided by this library. This function is normally
- used only if the application performed the connecting outside the library.
- The library however may use this internally. */
+/* Socket hostname and IP lookup callback that is called before actually
+ starting the key exchange. The lookup is called from the function
+ silc_client_start_key_exchange. */
-bool silc_client_start_key_exchange(SilcClient client,
- SilcClientConnection conn,
- int fd)
+static void silc_client_start_key_exchange_cb(SilcSocketConnection sock,
+ void *context)
{
+ SilcClientConnection conn = (SilcClientConnection)context;
+ SilcClient client = conn->client;
SilcProtocol protocol;
SilcClientKEInternalContext *proto_ctx;
- void *context;
- /* Allocate new socket connection object */
- silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
-
- /* Sometimes when doing quick reconnects the new socket may be same as
- the old one and there might be pending stuff for the old socket.
- If new one is same then those pending sutff might cause problems.
- Make sure they do not do that. */
- silc_schedule_task_del_by_fd(client->schedule, fd);
+ SILC_LOG_DEBUG(("Start"));
- conn->nickname = (client->nickname ? strdup(client->nickname) :
- strdup(client->username));
+ /* XXX We should most likely use the resolved host name instead of the
+ one user provided for us. */
+ silc_free(conn->sock->hostname);
conn->sock->hostname = strdup(conn->remote_host);
- conn->sock->ip = strdup(conn->remote_host);
+ if (!conn->sock->ip)
+ conn->sock->ip = strdup(conn->remote_host);
conn->sock->port = conn->remote_port;
/* Allocate internal Key Exchange context. This is sent to the
if (!protocol) {
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
"Error: Could not start key exchange protocol");
- return FALSE;
+ silc_net_close_connection(conn->sock->sock);
+ client->internal->ops->connect(client, conn, FALSE);
+ return;
}
conn->sock->protocol = protocol;
be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
later when outgoing data is available. */
context = (void *)client;
- SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
+ SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(conn->sock->sock);
/* Execute the protocol */
silc_protocol_execute(protocol, client->schedule, 0, 0);
- return TRUE;
+}
+
+/* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
+ key material between client and server. This function can be called
+ directly if application is performing its own connecting and does not
+ use the connecting provided by this library. This function is normally
+ used only if the application performed the connecting outside the library.
+ The library however may use this internally. */
+
+void silc_client_start_key_exchange(SilcClient client,
+ SilcClientConnection conn,
+ int fd)
+{
+ /* Allocate new socket connection object */
+ silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
+
+ /* Sometimes when doing quick reconnects the new socket may be same as
+ the old one and there might be pending stuff for the old socket.
+ If new one is same then those pending sutff might cause problems.
+ Make sure they do not do that. */
+ silc_schedule_task_del_by_fd(client->schedule, fd);
+
+ conn->nickname = (client->nickname ? strdup(client->nickname) :
+ strdup(client->username));
+
+ /* Resolve the remote hostname and IP address for our socket connection */
+ silc_socket_host_lookup(conn->sock, FALSE, silc_client_start_key_exchange_cb,
+ conn, client->schedule);
}
/* Callback called when error has occurred during connecting to the server.
SilcClient client = (SilcClient)ctx->client;
client->internal->ops->connect(client, ctx->sock->user_data, FALSE);
+ if (ctx->packet)
+ silc_packet_context_free(ctx->packet);
silc_free(ctx);
}
silc_schedule_task_del(client->schedule, ctx->task);
silc_free(ctx);
- if (!silc_client_start_key_exchange(client, conn, fd)) {
- silc_net_close_connection(fd);
- client->internal->ops->connect(client, conn, FALSE);
- }
+ silc_client_start_key_exchange(client, conn, fd);
}
/* Second part of the connecting to the server. This executed
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
-
+ if (proto_ctx->dest_id)
+ silc_free(proto_ctx->dest_id);
proto_ctx->packet = silc_packet_context_dup(packet);
proto_ctx->dest_id_type = packet->src_id_type;
proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
/* Clear ID caches */
if (conn->client_cache)
- silc_idcache_del_all(conn->client_cache);
+ silc_idcache_free(conn->client_cache);
if (conn->channel_cache)
- silc_idcache_del_all(conn->channel_cache);
+ silc_idcache_free(conn->channel_cache);
if (conn->server_cache)
- silc_idcache_del_all(conn->server_cache);
+ silc_idcache_free(conn->server_cache);
/* Free data (my ID is freed in above silc_client_del_client) */
+ if (conn->nickname)
+ silc_free(conn->nickname);
if (conn->remote_host)
silc_free(conn->remote_host);
if (conn->local_id_data)
if (!conn->local_entry)
conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
- conn->local_entry->nickname = conn->nickname;
+ conn->local_entry->nickname = strdup(conn->nickname);
if (!conn->local_entry->username)
conn->local_entry->username = strdup(client->username);
if (!conn->local_entry->hostname)