/* Destructor */ ~SilcSymbianTCPConnect() { silc_free(remote); if (op) silc_async_free(op); Cancel(); }
SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, const char *remote_ip_addr, int remote_port, SilcSchedule schedule, SilcNetCallback callback, void *context) { SilcNetConnect conn; if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) return NULL; SILC_LOG_DEBUG(("Creating connection to host %s port %d", remote_ip_addr, remote_port)); conn = silc_calloc(1, sizeof(*conn)); if (!conn) { callback(SILC_NET_NO_MEMORY, NULL, context); return NULL; } /* Start async operation */ conn->op = silc_async_alloc(silc_net_connect_abort, NULL, conn); if (!conn->op) { silc_free(conn); callback(SILC_NET_NO_MEMORY, NULL, context); return NULL; } if (local_ip_addr) conn->local_ip = strdup(local_ip_addr); conn->remote = strdup(remote_ip_addr); if (!conn->remote) { silc_async_free(conn->op); silc_free(conn->local_ip); silc_free(conn); callback(SILC_NET_NO_MEMORY, NULL, context); return NULL; } conn->port = remote_port; conn->callback = callback; conn->context = context; conn->retry = 1; conn->status = SILC_NET_ERROR; silc_fsm_init(&conn->fsm, conn, silc_net_connect_destructor, NULL, schedule); silc_fsm_start(&conn->fsm, silc_net_connect_st_start); return conn->op; }
void silc_client_del_connection(SilcClient client, SilcClientConnection conn) { SilcList list; SilcIDCacheEntry entry; SilcFSMThread thread; SILC_LOG_DEBUG(("Freeing connection %p", conn)); silc_schedule_task_del_by_context(conn->internal->schedule, conn); /* Free all cache entries */ if (conn->internal->server_cache) { if (silc_idcache_get_all(conn->internal->server_cache, &list)) { silc_list_start(list); while ((entry = silc_list_get(list))) silc_client_del_server(client, conn, entry->context); } } if (conn->internal->channel_cache) { if (silc_idcache_get_all(conn->internal->channel_cache, &list)) { silc_list_start(list); while ((entry = silc_list_get(list))) { silc_client_empty_channel(client, conn, entry->context); silc_client_del_channel(client, conn, entry->context); } } } if (conn->internal->client_cache) { if (silc_idcache_get_all(conn->internal->client_cache, &list)) { silc_list_start(list); while ((entry = silc_list_get(list))) silc_client_del_client(client, conn, entry->context); } } /* Free ID caches */ if (conn->internal->client_cache) silc_idcache_free(conn->internal->client_cache); if (conn->internal->channel_cache) silc_idcache_free(conn->internal->channel_cache); if (conn->internal->server_cache) silc_idcache_free(conn->internal->server_cache); /* Free thread pool */ silc_list_start(conn->internal->thread_pool); while ((thread = silc_list_get(conn->internal->thread_pool))) silc_fsm_free(thread); silc_free(conn->remote_host); silc_buffer_free(conn->internal->local_idp); silc_buffer_free(conn->internal->remote_idp); silc_mutex_free(conn->internal->lock); if (conn->internal->hash) silc_hash_free(conn->internal->hash); if (conn->internal->sha1hash) silc_hash_free(conn->internal->sha1hash); silc_atomic_uninit16(&conn->internal->cmd_ident); silc_free(conn->internal->away_message); if (conn->internal->rekey) silc_ske_free_rekey_material(conn->internal->rekey); if (conn->internal->cop) silc_async_free(conn->internal->cop); silc_free(conn->internal); memset(conn, 'F', sizeof(*conn)); silc_free(conn); }
SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, const char *remote_ip_addr, int remote_port, SilcSchedule schedule, SilcNetCallback callback, void *context) { SilcSymbianTCPConnect *conn; TInetAddr local, remote; SilcResult status; TInt ret; if (!schedule) { schedule = silc_schedule_get_global(); if (!schedule) { silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; } } if (!remote_ip_addr || remote_port < 1 || !callback) { silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; } SILC_LOG_DEBUG(("Creating connection to host %s port %d", remote_ip_addr, remote_port)); conn = new SilcSymbianTCPConnect; if (!conn) { callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } conn->schedule = schedule; conn->callback = callback; conn->context = context; conn->port = remote_port; conn->remote = strdup(remote_ip_addr); if (!conn->remote) { status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Allocate socket */ conn->sock = new RSocket; if (!conn->sock) { status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Allocate socket server */ conn->ss = new RSocketServ; if (!conn->ss) { status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Connect to socket server */ ret = conn->ss->Connect(); if (ret != KErrNone) { SILC_LOG_ERROR(("Error connecting to socket server, error %d", ret)); status = SILC_ERR; goto err; } #ifdef SILC_THREADS /* Make our socket shareable between threads */ conn->ss->ShareAuto(); #endif /* SILC_THREADS */ /* Start async operation */ conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn); if (!conn->op) { status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Do host lookup */ if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip, sizeof(conn->remote_ip))) { SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " "host", conn->remote)); status = SILC_ERR_UNREACHABLE; goto err; } /* Create the connection socket */ ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp); if (ret != KErrNone) { SILC_LOG_ERROR(("Cannot create socket, error %d", ret)); status = SILC_ERR; goto err; } /* Set appropriate options */ conn->sock->SetOpt(KSoTcpNoDelay, KSolInetTcp, 1); conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1); /* Bind to the local address if provided */ if (local_ip_addr) if (silc_net_set_sockaddr(&local, local_ip_addr, 0)) conn->sock->Bind(local); /* Connect to the host */ if (!silc_net_set_sockaddr(&remote, conn->remote_ip, remote_port)) { SILC_LOG_ERROR(("Cannot connect (cannot set address)")); status = SILC_ERR; goto err; } conn->Connect(remote); SILC_LOG_DEBUG(("Connection operation in progress")); return conn->op; err: if (conn->ss) { conn->ss->Close(); delete conn->ss; } if (conn->sock) delete conn->sock; if (conn->remote) silc_free(conn->remote); if (conn->op) silc_async_free(conn->op); callback(status, NULL, context); delete conn; return NULL; }