void transport_free(rdpTransport* transport) { if (transport != NULL) { SetEvent(transport->stopEvent); if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); tsg_free(transport->tsg); CloseHandle(transport->ReadMutex); CloseHandle(transport->WriteMutex); free(transport); } }
void transport_free(rdpTransport* transport) { if (transport != NULL) { if (transport->ReceiveBuffer) stream_free(transport->ReceiveBuffer); stream_free(transport->ReceiveStream); stream_free(transport->SendStream); CloseHandle(transport->ReceiveEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); tsg_free(transport->tsg); Queue_Free(transport->ReceivePool); Queue_Free(transport->ReceiveQueue); free(transport); } }
void transport_free(rdpTransport* transport) { if (transport != NULL) { if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); if (transport->ReceiveStream) Stream_Release(transport->ReceiveStream); StreamPool_Free(transport->ReceivePool); Stream_Free(transport->SendStream, TRUE); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); tsg_free(transport->tsg); free(transport); } }
void rdg_free(rdpRdg* rdg) { if (!rdg) return; if (rdg->tlsOut) { tls_free(rdg->tlsOut); rdg->tlsOut = NULL; } if (rdg->tlsIn) { tls_free(rdg->tlsIn); rdg->tlsIn = NULL; } if (rdg->http) { http_context_free(rdg->http); rdg->http = NULL; } if (rdg->ntlm) { ntlm_free(rdg->ntlm); rdg->ntlm = NULL; } DeleteCriticalSection(&rdg->writeSection); free(rdg); }
static int init_https(void) { if(!SERVER_PORT_TLS) return 0; struct tls_config *config = tls_config_new(); if(!config) { alogf("TLS config error: %s\n", strerror(errno)); return -1; } int rc = tls_config_set_ciphers(config, TLS_CIPHERS); if(0 != rc) { alogf("TLS ciphers error: %s\n", strerror(errno)); tls_config_free(config); config = NULL; return -1; } tls_config_set_protocols(config, TLS_PROTOCOLS); str_t pemfile[PATH_MAX]; snprintf(pemfile, sizeof(pemfile), "%s/key.pem", path); rc = tls_config_set_key_file(config, pemfile); if(0 != rc) { alogf("TLS key file error: %s\n", strerror(errno)); tls_config_free(config); config = NULL; return -1; } snprintf(pemfile, sizeof(pemfile), "%s/crt.pem", path); rc = tls_config_set_cert_file(config, pemfile); if(0 != rc) { alogf("TLS crt file error: %s\n", strerror(errno)); tls_config_free(config); config = NULL; return -1; } struct tls *tls = tls_server(); if(!tls) { alogf("TLS engine error: %s\n", strerror(errno)); tls_config_free(config); config = NULL; return -1; } rc = tls_configure(tls, config); tls_config_free(config); config = NULL; if(0 != rc) { alogf("TLS config error: %s\n", tls_error(tls)); tls_free(tls); tls = NULL; return -1; } server_tls = HTTPServerCreate((HTTPListener)listener, blog); if(!server_tls) { alogf("HTTPS server could not be initialized\n"); tls_free(tls); tls = NULL; return -1; } rc = HTTPServerListenSecure(server_tls, SERVER_ADDRESS, SERVER_PORT_TLS, &tls); tls_free(tls); tls = NULL; if(rc < 0) { alogf("HTTPS server could not be started: %s\n", sln_strerror(rc)); return -1; } int const port = SERVER_PORT_TLS; alogf("StrongLink server running at https://localhost:%d/\n", port); return 0; }
static void worker_cb(int fd, short flags, void *arg) { struct Worker *w = arg; const char *err; char buf[128]; int res; size_t outlen; w->pending = 0; if (w->wstate == HANDSHAKE) { err = do_handshake(w, fd); add_error(w, err); } else if (w->wstate == CONNECTED) { if (flags & EV_READ) { res = tls_read(w->ctx, buf, sizeof buf, &outlen); if (res == TLS_READ_AGAIN) { wait_for_event(w, EV_READ); } else if (res == TLS_WRITE_AGAIN) { wait_for_event(w, EV_WRITE); } else if (res == 0) { if (outlen > 0 && w->is_server) { tls_write(w->ctx, "END", 3, &outlen); w->wstate = CLOSED; } else if (outlen == 0) { w->wstate = CLOSED; } else { wait_for_event(w, EV_READ); } } else { add_error(w, "bad pkt"); } } else { add_error(w, "EV_WRITE?"); } } if (w->wstate == CLOSED && w->ctx) { res = tls_close(w->ctx); if (res == 0) { tls_free(w->ctx); w->ctx = NULL; } else if (res == TLS_READ_AGAIN) { wait_for_event(w, EV_READ); } else if (res == TLS_WRITE_AGAIN) { wait_for_event(w, EV_WRITE); } else { tls_free(w->ctx); w->ctx = NULL; } } if (!w->pending && w->ctx) { errx(1, "missed event setup: %s flags=%d state=%d", w->is_server ? "S":"C", flags, w->wstate); } return; }
void transport_free(rdpTransport* transport) { if (transport) { if (transport->async) { if (transport->stopEvent) { SetEvent(transport->stopEvent); WaitForSingleObject(transport->thread, INFINITE); CloseHandle(transport->thread); CloseHandle(transport->stopEvent); transport->thread = NULL; transport->stopEvent = NULL; } } if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); free(transport); } }
static void free_worker(struct Worker *w) { if (!w) return; event_del(&w->ev); tls_config_free(w->config); tls_free(w->ctx); tls_free(w->base); memset(w, 0, sizeof *w); free(w); }
BOOL transport_connect_tls(rdpTransport* transport) { if (transport->layer == TRANSPORT_LAYER_TSG) { transport->TsgTls = tls_new(transport->settings); transport->TsgTls->methods = BIO_s_tsg(); transport->TsgTls->tsg = (void*) transport->tsg; transport->layer = TRANSPORT_LAYER_TSG_TLS; if (tls_connect(transport->TsgTls) != TRUE) { if (!connectErrorCode) connectErrorCode = TLSCONNECTERROR; tls_free(transport->TsgTls); transport->TsgTls = NULL; return FALSE; } return TRUE; } if (transport->TlsIn == NULL) transport->TlsIn = tls_new(transport->settings); if (transport->TlsOut == NULL) transport->TlsOut = transport->TlsIn; transport->layer = TRANSPORT_LAYER_TLS; transport->TlsIn->sockfd = transport->TcpIn->sockfd; if (tls_connect(transport->TlsIn) != TRUE) { if (!connectErrorCode) connectErrorCode = TLSCONNECTERROR; tls_free(transport->TlsIn); if (transport->TlsIn == transport->TlsOut) transport->TlsIn = transport->TlsOut = NULL; else transport->TlsIn = NULL; return FALSE; } return TRUE; }
static void free_worker(struct Worker *w) { if (!w) return; if (event_initialized(&w->ev)) event_del(&w->ev); tls_free(w->ctx); tls_free(w->base); tls_config_free(w->config); if (w->socket > 0) close(w->socket); memset(w, 0, sizeof *w); free(w); }
BOOL transport_connect_tls(rdpTransport* transport) { if (transport->layer == TRANSPORT_LAYER_TSG) return TRUE; if (transport->TlsIn == NULL) transport->TlsIn = tls_new(transport->settings); if (transport->TlsOut == NULL) transport->TlsOut = transport->TlsIn; transport->layer = TRANSPORT_LAYER_TLS; transport->TlsIn->sockfd = transport->TcpIn->sockfd; if (tls_connect(transport->TlsIn) != TRUE) { if (!connectErrorCode) connectErrorCode = TLSCONNECTERROR; tls_free(transport->TlsIn); if (transport->TlsIn == transport->TlsOut) transport->TlsIn = transport->TlsOut = NULL; else transport->TlsIn = NULL; return FALSE; } return TRUE; }
static void session_clear(struct session *s) { assert(s->outgoing || s->tasks.len == 0); array_clear(s->tasks); tls_free(s->tls_ctx); memset(s, 0, sizeof(*s)); }
static int _handle_proceedtls_default(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *name; name = xmpp_stanza_get_name(stanza); xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name); if (strcmp(name, "proceed") == 0) { xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS"); conn->tls = tls_new(conn->ctx, conn->sock); if (!tls_start(conn->tls)) { xmpp_debug(conn->ctx, "xmpp", "Couldn't start TLS! error %d", tls_error(conn->tls)); tls_free(conn->tls); conn->tls = NULL; conn->tls_failed = 1; /* failed tls spoils the connection, so disconnect */ xmpp_disconnect(conn); } else { conn->secured = 1; conn_prepare_reset(conn, auth_handle_open); conn_open_stream(conn); } } return 0; }
tls_t *tls_new(xmpp_ctx_t *ctx, xmpp_sock_t sock) { tls_t *tls = xmpp_alloc(ctx, sizeof(*tls)); if (tls) { int ret; memset(tls, 0, sizeof(*tls)); tls->ctx = ctx; tls->sock = sock; tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL); SSL_CTX_set_mode (tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_verify (tls->ssl_ctx, SSL_VERIFY_NONE, NULL); tls->ssl = SSL_new(tls->ssl_ctx); ret = SSL_set_fd(tls->ssl, sock); if (ret <= 0) { tls->lasterror = SSL_get_error(tls->ssl, ret); tls_error(tls); tls_free(tls); tls = NULL; } } return tls; }
void xmpp_close(void) { if (session.wfs < 0) return; /* Close stream */ { char *s; FORMAT(s, "<iq to='%s' type='get'>" "<query xmlns='urn:cryonline:k01'>" "<player_status prev_status='%u' new_status='%u' to='%s'/>" "</query>" "</iq>", session.online.jid.k01, session.online.status, STATUS_LEFT, session.online.channel ? session.online.channel : ""); stream_send_msg(session.wfs, s); free(s); } stream_send_msg(session.wfs, "</stream:stream>"); stream_flush(session.wfs); close(session.wfs); session.wfs = -1; #ifdef USE_TLS tls_close(); tls_free(); #endif }
int conn_tls_start(xmpp_conn_t * const conn) { int rc; if (conn->tls_disabled) { conn->tls = NULL; rc = -ENOSYS; } else { conn->tls = tls_new(conn->ctx, conn->sock); rc = conn->tls == NULL ? -ENOMEM : 0; } if (conn->tls != NULL) { if (tls_start(conn->tls)) { conn->secured = 1; conn_prepare_reset(conn, auth_handle_open); } else { rc = tls_error(conn->tls); conn->error = rc; tls_free(conn->tls); conn->tls = NULL; conn->tls_failed = 1; } } if (rc != 0) xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! error %d", rc); return rc; }
int conn_tls_start(xmpp_conn_t * const conn) { int rc; if (conn->tls_disabled) { conn->tls = NULL; rc = XMPP_EINVOP; } else { conn->tls = tls_new(conn); rc = conn->tls == NULL ? XMPP_EMEM : 0; } if (conn->tls != NULL) { if (tls_start(conn->tls)) { conn->secured = 1; } else { rc = XMPP_EINT; conn->error = tls_error(conn->tls); tls_free(conn->tls); conn->tls = NULL; conn->tls_failed = 1; } } if (rc != 0) { xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! " "error %d tls_error %d", rc, conn->error); } return rc; }
BOOL transport_disconnect(rdpTransport* transport) { BOOL status = TRUE; if (!transport) return FALSE; if (transport->tls) { tls_free(transport->tls); transport->tls = NULL; } else { if (transport->frontBio) BIO_free_all(transport->frontBio); } if (transport->tsg) { tsg_free(transport->tsg); transport->tsg = NULL; } if (transport->rdg) { rdg_free(transport->rdg); transport->rdg = NULL; } transport->frontBio = NULL; transport->layer = TRANSPORT_LAYER_TCP; return status; }
tls_t *tls_init_master(tls_issues_t *ti) { /* Default id in case RAND fails */ unsigned char sessionId[32] = "sofia/tls"; tls_t *tls; #if HAVE_SIGPIPE signal(SIGPIPE, SIG_IGN); /* Ignore spurios SIGPIPE from OpenSSL */ #endif tls_set_default(ti); if (!(tls = tls_create(tls_master))) return NULL; if (tls_init_context(tls, ti) < 0) { int err = errno; tls_free(tls); errno = err; return NULL; } RAND_pseudo_bytes(sessionId, sizeof(sessionId)); SSL_CTX_set_session_id_context(tls->ctx, (void*) sessionId, sizeof(sessionId)); if (ti->CAfile != NULL) SSL_CTX_set_client_CA_list(tls->ctx, SSL_load_client_CA_file(ti->CAfile)); #if 0 if (sock != -1) { tls->bio_con = BIO_new_socket(sock, BIO_NOCLOSE); if (tls->bio_con == NULL) { tls_log_errors(1, "tls_init_master", 0); tls_free(tls); errno = EIO; return NULL; } } #endif return tls; }
void transport_free(rdpTransport* transport) { if (transport) { if (transport->async) { assert(!transport->thread); assert(!transport->stopEvent); } if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; CloseHandle(transport->ReadMutex); CloseHandle(transport->WriteMutex); free(transport); } }
BOOL transport_disconnect(rdpTransport* transport) { BOOL status = TRUE; if (!transport) return FALSE; transport_stop(transport); if (transport->frontBio) { BIO_free_all(transport->frontBio); transport->frontBio = NULL; } if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->tsg) { tsg_free(transport->tsg); transport->tsg = NULL; } if (transport->TcpOut != transport->TcpIn) freerdp_tcp_free(transport->TcpOut); transport->TcpOut = NULL; if (transport->TsgTls) { tls_free(transport->TsgTls); transport->TsgTls = NULL; } transport->layer = TRANSPORT_LAYER_TCP; return status; }
/* * This is called by _thrp_exit() to deallocate the thread's TLS. * Destructors for all allocated TLS are called here. */ void tls_exit() { ulwp_t *self = curthread; tls_metadata_t *tlsm = &self->ul_uberdata->tls_metadata; tls_t *tlsent; TLS_modinfo *tlsp; long moduleid; ulong_t nmods; if (tlsm->static_tls.tls_size == 0 && self->ul_ntlsent == 0) return; /* no TLS */ /* * Call TLS destructors for all TLS allocated for this thread. */ lmutex_lock(&tlsm->tls_lock); nmods = tlsm->tls_modinfo.tls_size; for (moduleid = nmods - 1; moduleid >= 0; --moduleid) { /* * Resume where we left off in the module array. * tls_modinfo.tls_data may have changed since we * dropped and reacquired tls_lock, but TLS modules * retain their positions in the new array. */ tlsp = (TLS_modinfo *)tlsm->tls_modinfo.tls_data + moduleid; /* * Call destructors for this module if there are any * to be called and if it is part of the static TLS or * if the dynamic TLS for the module has been allocated. */ if (tlsp->tm_tlsfiniarraycnt != 0 && ((tlsp->tm_flags & TM_FLG_STATICTLS) || (moduleid < self->ul_ntlsent && (tlsent = self->ul_tlsent) != NULL && tlsent[moduleid].tls_data != NULL))) { ulong_t arraycnt = tlsp->tm_tlsfiniarraycnt; void (**finiarray)(void) = tlsp->tm_tlsfiniarray; /* * Call the destructors in descending order. * We must drop tls_lock while doing this because * we have no idea what the destructors will do. */ lmutex_unlock(&tlsm->tls_lock); finiarray += arraycnt; do { (**--finiarray)(); } while (--arraycnt != 0); lmutex_lock(&tlsm->tls_lock); } } lmutex_unlock(&tlsm->tls_lock); tls_free(self); }
int main(int argc, char *argv[]) { struct tls_config *conf; struct tls *ctx; struct tls_cert_info *cert; int res; const char *host; if (argc < 2) errx(1, "give host as arg\n"); host = argv[1]; res = tls_init(); if (res < 0) errx(1, "tls_init"); conf = tls_config_new(); if (!conf) errx(1, "tls_config_new"); tls_config_set_protocols(conf, TLS_PROTOCOLS_ALL); tls_config_set_ciphers(conf, "fast"); ctx = tls_client(); if (!ctx) errx(1, "tls_client"); res = tls_configure(ctx, conf); if (res < 0) errx(1, "tls_configure: %s", tls_error(ctx)); res = tls_connect(ctx, host, "443"); if (res < 0) errx(1, "tls_connect: %s", tls_error(ctx)); printf("connect ok\n"); res = tls_get_peer_cert(ctx, &cert); if (res < 0) errx(1, "tls_get_peer_cert: %s", tls_error(ctx)); tls_close(ctx); tls_free(ctx); tls_config_free(conf); printf(" CN='%s'\n", cert->subject.common_name); printf(" C='%s'\n", cert->subject.country_name); printf(" ST='%s'\n", cert->subject.state_or_province_name); printf(" L='%s'\n", cert->subject.locality_name); printf(" S='%s'\n", cert->subject.street_address); printf(" O='%s'\n", cert->subject.organization_name); printf(" OU='%s'\n", cert->subject.organizational_unit_name); tls_cert_free(cert); return 0; }
static const char *run_time(const char *val) { #ifdef USUAL_LIBSSL_FOR_TLS ASN1_TIME tmp; time_t t = 0; static char buf[128]; struct tm *tm, tmbuf; struct tls *ctx; int err; memset(&tmp, 0, sizeof tmp); memset(&tmbuf, 0, sizeof tmbuf); tmp.data = (unsigned char*)val+2; tmp.length = strlen(val+2); if (val[0] == 'G' && val[1] == ':') { tmp.type = V_ASN1_GENERALIZEDTIME; } else if (val[0] == 'U' && val[1] == ':') { tmp.type = V_ASN1_UTCTIME; } else { tmp.type = val[0]; } ctx = tls_client(); if (!ctx) return "NOMEM"; err = tls_asn1_parse_time(ctx, &tmp, &t); if (err) { strlcpy(buf, tls_error(ctx), sizeof buf); tls_free(ctx); return buf; } tls_free(ctx); tm = gmtime_r(&t, &tmbuf); if (!tm) return "E-GMTIME"; strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S GMT", tm); return buf; #else return "no-asn1"; #endif }
void server() { // load Config File and Settings fprintf(stdout, "Starting fidistat Server...\n"); openlog("fidistat-server", LOG_PID, LOG_DAEMON); syslog(LOG_INFO, "Started Fidistat Server"); struct pidfh *pfh = daemon_start('s'); // Handle Signals signal(SIGTERM, handleSigterm_S); signal(SIGCHLD, handleChild); // Open Socket initConf(); tls_init(); struct tls* ctx = tls_server(); int sock = initTLS_S(ctx); sckt = sock; int connfd, pid; listen(sock, 10); // Destroy Config destroyConf(); while(!term) { connfd = accept(sock, (struct sockaddr*) NULL, NULL); if (term) { break; } pid = fork(); if (pid < 0) { syslog(LOG_ERR, "forking new Worker failed"); } else if (pid == 0) { close(sock); syslog(LOG_INFO, "New incoming connection"); worker(connfd, ctx); syslog(LOG_INFO, "Closing connection"); exit(0); } else { close(connfd); } } syslog(LOG_INFO, "Shutting down Server"); close(sock); tls_close(ctx); tls_free(ctx); tls_config_free(tlsServer_conf); pidfile_remove(pfh); syslog(LOG_INFO, "Stopped Fidistat Server"); closelog(); exit(0); }
void transport_free(rdpTransport* transport) { if (!transport) return; transport_stop(transport); if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); StreamPool_Free(transport->ReceivePool); CloseHandle(transport->ReceiveEvent); CloseHandle(transport->connectedEvent); if (transport->TlsIn) tls_free(transport->TlsIn); if (transport->TlsOut != transport->TlsIn) tls_free(transport->TlsOut); transport->TlsIn = NULL; transport->TlsOut = NULL; if (transport->TcpIn) tcp_free(transport->TcpIn); if (transport->TcpOut != transport->TcpIn) tcp_free(transport->TcpOut); transport->TcpIn = NULL; transport->TcpOut = NULL; tsg_free(transport->tsg); transport->tsg = NULL; DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); free(transport); }
int net_close(net_t * net, void (*cb)(uv_handle_t*)) { int r = net->connected; if (cb == NULL) { cb = net->close_cb; } if (r == 1) { net->connected = 0; tls_free(net->tls); uv_close((uv_handle_t*)net->handle, cb); } return r; }
void SocketFree(SocketRef *const socketptr) { SocketRef socket = *socketptr; if(!socket) return; if(socket->secure) tls_close(socket->secure); tls_free(socket->secure); socket->secure = NULL; async_close((uv_handle_t *)socket->stream); FREE(&socket->rdmem); socket->rd->base = NULL; socket->rd->len = 0; FREE(&socket->wr->base); socket->wr->len = 0; socket->err = 0; assert_zeroed(socket, 1); FREE(socketptr); socket = NULL; }
void transport_free(rdpTransport* transport) { if (transport != NULL) { stream_free(transport->recv_buffer); stream_free(transport->recv_stream); stream_free(transport->send_stream); if (transport->tls) tls_free(transport->tls); tcp_free(transport->tcp); xfree(transport); } }
/** Disconnect from the XMPP server. * This function immediately disconnects from the XMPP server, and should * not be used outside of the Strophe library. * * @param conn a Strophe connection object */ void conn_disconnect(xmpp_conn_t * const conn) { xmpp_debug(conn->ctx, "xmpp", "Closing socket."); conn->state = XMPP_STATE_DISCONNECTED; if (conn->tls) { tls_stop(conn->tls); tls_free(conn->tls); conn->tls = NULL; } sock_close(conn->sock); /* fire off connection handler */ conn->conn_handler(conn, XMPP_CONN_DISCONNECT, conn->error, conn->stream_error, conn->userdata); }