static int mx_forwarder_prep (MX_TYPE_PREP_ARGS) { mx_sock_forwarder_t *msfp = mx_sock(msp, MST_FORWARDER); mx_buffer_t *mbp = msfp->msf_rbufp; /* * If we have buffered data, we need to poll for output on * the channels' session. */ if (mbp->mb_len) { pollp->fd = mx_channel_sock(msfp->msf_channel); pollp->events = POLLOUT; DBG_POLL("%s blocking pollout for fd %d", mx_sock_title(msp), pollp->fd); } else if (mx_channel_has_buffered(msfp->msf_channel)) { pollp->fd = mx_channel_sock(msfp->msf_channel); pollp->events = POLLOUT; DBG_POLL("%s blocking pollout for fd %d (channel)", mx_sock_title(msp), pollp->fd); } else { pollp->fd = msp->ms_sock; pollp->events = POLLIN; DBG_POLL("%s blocking pollin for fd %d", mx_sock_title(msp), pollp->fd); } return TRUE; }
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 int mx_channel_write (mx_channel_t *mcp, const char *buf, unsigned long bufsiz) { int len; len = libssh2_channel_write(mcp->mc_channel, buf, bufsiz); DBG_POLL("C%u write %d", mcp->mc_id, len); if (len > 0) slaxMemDump("chwrite: ", buf, len, ">", 0); return len; }
static int mx_channel_read (mx_channel_t *mcp, char *buf, unsigned long bufsiz) { int len; len = libssh2_channel_read(mcp->mc_channel, buf, bufsiz); DBG_POLL("C%u read %d", mcp->mc_id, len); if (len > 0) { slaxMemDump("chread: ", buf, len, ">", 0); } else { if (len == LIBSSH2_ERROR_SOCKET_RECV) { if (mcp->mc_session) mcp->mc_session->mss_base.ms_state = MSS_FAILED; } } return len; }