/************************** Types and definitions ***************************/
-/* Public key verification context */
-typedef struct {
- SilcSKE ske;
- SilcSKEVerifyCbCompletion completion;
- void *completion_context;
-} *VerifyKeyContext;
-
-
/************************ Static utility functions **************************/
/* Callback called after connected to remote host */
SilcClientConnection conn = silc_fsm_get_context(fsm);
SilcClient client = conn->client;
+ conn->internal->op = NULL;
if (conn->internal->verbose) {
switch (status) {
case SILC_NET_OK:
SilcCipher send_key, receive_key;
SilcHmac hmac_send, hmac_receive;
+ conn->internal->op = NULL;
if (status != SILC_SKE_STATUS_OK) {
/* Key exchange failed */
SILC_LOG_DEBUG(("Error during key exchange with %s: %s (%d)",
SILC_FSM_CALL_CONTINUE(fsm);
}
+/* Connection timeout callback */
+
+SILC_TASK_CALLBACK(silc_client_connect_timeout)
+{
+ SilcClientConnection conn = context;
+ SilcClient client = conn->client;
+
+ SILC_LOG_DEBUG(("Connection timeout"));
+
+ conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_TIMEOUT, 0, NULL,
+ conn->callback_context);
+
+ silc_fsm_next(&conn->internal->event_thread, silc_client_st_connect_error);
+ silc_fsm_continue_sync(&conn->internal->event_thread);
+}
+
/*************************** Connect remote host ****************************/
/* Creates a connection to remote host */
/** Connect */
silc_fsm_next(fsm, silc_client_st_connect_set_stream);
+ /* Add connection timeout */
+ if (conn->internal->params.timeout_secs)
+ silc_schedule_task_add_timeout(conn->internal->schedule,
+ silc_client_connect_timeout, conn,
+ conn->internal->params.timeout_secs, 0);
+
if (conn->internal->params.udp) {
SilcStream stream;
}
/* Connect (UDP) */
- stream = silc_net_udp_connect(conn->internal->params.local_ip,
+ stream = silc_net_udp_connect(conn->internal->params.bind_ip ?
+ conn->internal->params.bind_ip :
+ conn->internal->params.local_ip,
conn->internal->params.local_port,
conn->remote_host, conn->remote_port,
conn->internal->schedule);
stream, fsm));
} else {
/* Connect (TCP) */
- SILC_FSM_CALL(silc_net_tcp_connect(NULL, conn->remote_host,
+ SILC_FSM_CALL(conn->internal->op = silc_net_tcp_connect(
+ NULL, conn->remote_host,
conn->remote_port,
conn->internal->schedule,
silc_client_connect_callback, fsm));
/** Run key exchange (TCP) */
silc_fsm_next(fsm, silc_client_st_connect_auth);
- SILC_FSM_CALL(silc_ske_initiator(conn->internal->ske, conn->stream,
- ¶ms, NULL));
+ SILC_FSM_CALL(conn->internal->op = silc_ske_initiator(conn->internal->ske,
+ conn->stream,
+ ¶ms, NULL));
}
/* For UDP/IP connections, set up the UDP session after successful key
/** Start connection authentication */
silc_fsm_next(fsm, silc_client_st_connected);
- SILC_FSM_CALL(silc_connauth_initiator(connauth, SILC_CONN_CLIENT,
+ SILC_FSM_CALL(conn->internal->op = silc_connauth_initiator(
+ connauth, SILC_CONN_CLIENT,
conn->internal->params.auth_method,
conn->internal->params.auth,
conn->internal->params.auth_len,
return SILC_FSM_CONTINUE;
}
+ silc_schedule_task_del_by_context(conn->internal->schedule, conn);
+
/* Call connection callback */
conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS, 0, NULL,
conn->callback_context);
SILC_FSM_STATE(silc_client_st_connect_error)
{
+ SilcClientConnection conn = fsm_context;
+
+ /* Signal to close connection */
+ if (!conn->internal->disconnected) {
+ conn->internal->disconnected = TRUE;
+ SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ }
- /* XXX */
- /* Close connection */
+ silc_schedule_task_del_by_context(conn->internal->schedule, conn);
return SILC_FSM_FINISH;
}