/************************** 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);
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);
SilcClientConnection conn = fsm_context;
/* Signal to close connection */
- conn->internal->disconnected = TRUE;
- SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ if (!conn->internal->disconnected) {
+ conn->internal->disconnected = TRUE;
+ SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ }
+
+ silc_schedule_task_del_by_context(conn->internal->schedule, conn);
return SILC_FSM_FINISH;
}