int vsx_engine_param::disconnect(vsx_engine_param* src, bool lowlevel) { if (!lowlevel) { vsx_engine_param_connection* engine_conn = get_conn_by_src(src); src->delete_conn(engine_conn); delete_conn(engine_conn); delete engine_conn; } else { // 1. disconnect the low level stuff vsx_engine_param* real_dest_param; vsx_engine_param* real_src_param; if (alias) real_dest_param = alias_owner; else { real_dest_param = this; } if (src->alias) real_src_param = src->alias_owner; else real_src_param = src; if (real_dest_param->channel->disconnect(real_src_param)) { // 2. that went well, so disconnect our connection as well //printf("disconn OK\n"); vsx_engine_param_connection* engine_conn = get_conn_by_src(src); src->delete_conn(engine_conn); delete_conn(engine_conn); delete engine_conn; channel->update_connections_order(); } else return -1; } return 1; }
/** Called after the local connection to the mush has established */ void local_connected(struct conn *c) { char *hostid; int len; #if SSL_DEBUG_LEVEL > 0 errputs(stdout, "Local connection attempt completed. Setting up pipe."); #endif bufferevent_setcb(c->local_bev, pipe_cb, NULL, ssl_event_cb, c); bufferevent_enable(c->local_bev, EV_READ | EV_WRITE); bufferevent_setcb(c->remote_bev, pipe_cb, NULL, ssl_event_cb, c); bufferevent_enable(c->remote_bev, EV_READ | EV_WRITE); c->state = C_ESTABLISHED; /* Now pass the remote host and IP to the mush as the very first line it gets */ len = strlen(c->remote_host) + strlen(c->remote_ip) + 3; hostid = malloc(len + 1); sprintf(hostid, "%s^%s\r\n", c->remote_ip, c->remote_host); if (send_with_creds(bufferevent_getfd(c->local_bev), hostid, len) < 0) { penn_perror("send_with_creds"); delete_conn(c); } free(hostid); }
/** Called on successful connections and errors */ void ssl_event_cb(struct bufferevent *bev, short e, void *data) { struct conn *c = data; uint32_t error_conditions = BEV_EVENT_EOF | BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT; #if SSL_DEBUG_LEVEL > 1 errprintf(stdout, "ssl_slave: event callback triggered with flags 0x%hx\n", e); #endif if (e & BEV_EVENT_CONNECTED) { if (c->local_bev == bev) { local_connected(c); } else { ssl_connected(c); } } else if (e & BEV_EVENT_TIMEOUT) { if (c->state == C_SSL_CONNECTING) { /* Handshake timed out. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: SSL handshake timeout.\n"); #endif bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE); bufferevent_free(c->remote_bev); c->remote_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->local_bev) { bufferevent_disable(c->local_bev, EV_READ); bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED); } delete_conn(c); } else { /* Bug in some versions of libevent cause this to trigger when it shouldn't. Ignore. */ return; } } else if (e & error_conditions) { if (c->local_bev == bev) { /* Mush side of the connection went away. Flush SSL buffer and shut down. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: Lost local connection. State: %d, reason 0x%hx.\n", c->state, e); #endif bufferevent_disable(c->local_bev, EV_READ | EV_WRITE); bufferevent_free(c->local_bev); c->local_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->remote_bev) { bufferevent_disable(c->remote_bev, EV_READ); bufferevent_flush(c->remote_bev, EV_WRITE, BEV_FINISHED); SSL_shutdown(bufferevent_openssl_get_ssl(c->remote_bev)); } delete_conn(c); } else { /* Remote side of the connection went away. Flush mush buffer and shut down. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: Lost SSL connection. State: %d, reason 0x%hx.\n", c->state, e); #endif bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE); bufferevent_free(c->remote_bev); c->remote_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->local_bev) { bufferevent_disable(c->local_bev, EV_READ); bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED); } delete_conn(c); } } }