+ SilcNetConnect conn = fsm_context;
+ SilcSchedule schedule = silc_fsm_get_schedule(fsm);
+ int opt = EINVAL, optlen = sizeof(opt), ret;
+
+ if (conn->aborted) {
+ /** Aborted */
+ silc_fsm_next(fsm, silc_net_connect_st_finish);
+ return SILC_FSM_CONTINUE;
+ }
+
+ ret = silc_net_get_socket_opt(conn->sock, SOL_SOCKET, SO_ERROR,
+ &opt, &optlen);
+
+ silc_schedule_task_del_by_fd(schedule, conn->sock);
+ silc_schedule_unset_listen_fd(schedule, conn->sock);
+
+ if (ret != 0 || opt != 0) {
+ if (conn->retry) {
+ /** Retry connecting */
+ SILC_LOG_DEBUG(("Retry connecting"));
+ conn->retry--;
+ silc_net_close_connection(conn->sock);
+ silc_fsm_next(fsm, silc_net_connect_st_start);
+ return SILC_FSM_CONTINUE;
+ }
+
+#if defined(ECONNREFUSED)
+ if (errno == ECONNREFUSED)
+ conn->status = SILC_NET_CONNECTION_REFUSED;
+#endif /* ECONNREFUSED */
+#if defined(ETIMEDOUT)
+ if (errno == ETIMEDOUT)
+ conn->status = SILC_NET_CONNECTION_TIMEOUT;
+#endif /* ETIMEDOUT */
+#if defined(ENETUNREACH)
+ if (errno == ENETUNREACH)
+ conn->status = SILC_NET_HOST_UNREACHABLE;
+#endif /* ENETUNREACH */
+
+ /** Connecting failed */
+ SILC_LOG_DEBUG(("Connecting failed"));
+ silc_fsm_next(fsm, silc_net_connect_st_finish);
+ return SILC_FSM_CONTINUE;
+ }
+
+ /** Connection created */
+ silc_fsm_next(fsm, silc_net_connect_st_stream);
+ SILC_FSM_CALL((conn->sop = silc_socket_stream_create(
+ conn->sock, FALSE, FALSE,
+ schedule,
+ silc_net_connect_wait_stream, conn)));