mx_channel_t * mx_channel_create (mx_sock_session_t *session, mx_sock_t *client, LIBSSH2_CHANNEL *channel) { mx_channel_t *mcp = malloc(sizeof(*mcp)); if (mcp == NULL) return NULL; bzero(mcp, sizeof(*mcp)); mcp->mc_id = ++mx_channel_id; mcp->mc_session = session; mcp->mc_channel = channel; mcp->mc_rbufp = mx_buffer_create(0); if (mx_mti(client)->mti_set_channel) mx_mti(client)->mti_set_channel(client, session, mcp); mcp->mc_client = client; TAILQ_INSERT_HEAD(&session->mss_channels, mcp, mc_link); MX_LOG("C%u: new channel, S%u, channel %p, client S%u", mcp->mc_id, mcp->mc_session->mss_base.ms_id, mcp->mc_channel, mcp->mc_client->ms_id); return mcp; }
static int mx_channel_netconf_read_hello (mx_channel_t *mcp) { mx_buffer_t *mbp = mcp->mc_rbufp; int len; for (;;) { if (mbp->mb_start + mbp->mb_len == mbp->mb_size) { mx_buffer_t *newp = mx_buffer_create(0); if (newp == NULL) { mx_log("C%u cannot extend buffer", mcp->mc_id); return TRUE; } mbp->mb_next = newp; mbp = newp; } len = mx_channel_read(mcp, mbp->mb_data + mbp->mb_start + mbp->mb_len, mbp->mb_size - (mbp->mb_start + mbp->mb_len)); if (libssh2_channel_eof(mcp->mc_channel)) { DBG_POLL("C%u eof during read_hello", mcp->mc_id); return FALSE; } if (len == LIBSSH2_ERROR_EAGAIN) { /* Nothing to read, nothing to write; move on */ DBG_POLL("C%u is drained", mcp->mc_id); #if 0 break; #else sleep(1); continue; #endif } if (len < 0) return TRUE; mbp->mb_len += len; DBG_POLL("C%u read %d", mcp->mc_id, len); if (mx_channel_netconf_has_marker(mcp)) { mx_log("C%u found end-of-frame; len %lu, discarding", mcp->mc_id, mcp->mc_rbufp->mb_len); mbp->mb_len = mbp->mb_start = 0; if (mbp->mb_next) { mx_buffer_free(mbp->mb_next); mbp->mb_next = NULL; } return TRUE; } } return FALSE; }
static mx_sock_t * mx_forwarder_spawn (MX_TYPE_SPAWN_ARGS) { mx_sock_forwarder_t *msfp = malloc(sizeof(*msfp)); if (msfp == NULL) return NULL; bzero(msfp, sizeof(*msfp)); msfp->msf_base.ms_id = ++mx_sock_id; msfp->msf_base.ms_type = MST_FORWARDER; msfp->msf_base.ms_sock = sock; msfp->msf_base.ms_sun = *sun; msfp->msf_rbufp = mx_buffer_create(0); /* XXX msl_request needs to move into the forwarder */ mslp->msl_request->mr_client = &msfp->msf_base; mx_sock_session_t *mssp = mx_session(mslp->msl_request); if (mssp == NULL) { mx_log("%s could not open session", mx_sock_title(&msfp->msf_base)); /* XXX fail nicely */ return NULL; } mx_request_t *mrp = mslp->msl_request; mx_channel_t *mcp; mcp = mx_channel_direct_tcpip(mssp, &msfp->msf_base, mrp->mr_desthost, mrp->mr_destport); if (mcp == NULL) { mx_log("%s could not open channel", mx_sock_title(&msfp->msf_base)); /* XXX close msfp */ return NULL; } return &msfp->msf_base; }