Exemplo n.º 1
0
/*
 * the same for SSH2
 */
static void
chan_rcvd_close2(Channel *c)
{
	debug("channel %d: rcvd close", c->self);
	if (c->flags & CHAN_CLOSE_RCVD)
		error("channel %d: protocol error: close rcvd twice", c->self);
	c->flags |= CHAN_CLOSE_RCVD;
	if (c->type == SSH_CHANNEL_LARVAL) {
		/* tear down larval channels immediately */
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		chan_set_istate(c, CHAN_INPUT_CLOSED);
		return;
	}
	switch (c->ostate) {
	case CHAN_OUTPUT_OPEN:
		/*
		 * wait until a data from the channel is consumed if a CLOSE
		 * is received
		 */
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
		break;
	}
	switch (c->istate) {
	case CHAN_INPUT_OPEN:
		chan_shutdown_read(c);
		chan_set_istate(c, CHAN_INPUT_CLOSED);
		break;
	case CHAN_INPUT_WAIT_DRAIN:
		chan_send_eof2(c);
		chan_set_istate(c, CHAN_INPUT_CLOSED);
		break;
	}
}
Exemplo n.º 2
0
static void
chan_rcvd_eof2(Channel *c)
{
	debug2("channel %d: rcvd eof", c->self);
	c->flags |= CHAN_EOF_RCVD;
	if (c->ostate == CHAN_OUTPUT_OPEN)
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
}
Exemplo n.º 3
0
static void
chan_rcvd_ieof1(Channel *c)
{
	debug2("channel %d: rcvd ieof", c->self);
	switch (c->ostate) {
	case CHAN_OUTPUT_OPEN:
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
		break;
	case CHAN_OUTPUT_WAIT_IEOF:
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		break;
	default:
		error("channel %d: protocol error: rcvd_ieof for ostate %d",
		    c->self, c->ostate);
		break;
	}
}
Exemplo n.º 4
0
static void
chan_write_failed1(Channel *c)
{
	debug2("channel %d: write failed", c->self);
	switch (c->ostate) {
	case CHAN_OUTPUT_OPEN:
		chan_shutdown_write(c);
		chan_send_oclose1(c);
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
		break;
	case CHAN_OUTPUT_WAIT_DRAIN:
		chan_shutdown_write(c);
		chan_send_oclose1(c);
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		break;
	default:
		error("channel %d: chan_write_failed for ostate %d",
		    c->self, c->ostate);
		break;
	}
}
Exemplo n.º 5
0
void
chan_rcvd_ieof(struct ssh *ssh, Channel *c)
{
	debug2("channel %d: rcvd eof", c->self);
	c->flags |= CHAN_EOF_RCVD;
	if (c->ostate == CHAN_OUTPUT_OPEN)
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
	if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
	    sshbuf_len(c->output) == 0 &&
	    !CHANNEL_EFD_OUTPUT_ACTIVE(c))
		chan_obuf_empty(ssh, c);
}
Exemplo n.º 6
0
static void
chan_write_failed2(Channel *c)
{
	debug2("channel %d: write failed", c->self);
	switch (c->ostate) {
	case CHAN_OUTPUT_OPEN:
	case CHAN_OUTPUT_WAIT_DRAIN:
		chan_shutdown_write(c);
		if (strcmp(c->ctype, "session") == 0)
			chan_send_eow2(c);
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		break;
	default:
		error("channel %d: chan_write_failed for ostate %d",
		    c->self, c->ostate);
		break;
	}
}
Exemplo n.º 7
0
void
chan_obuf_empty(struct ssh *ssh, Channel *c)
{
	debug2("channel %d: obuf empty", c->self);
	if (sshbuf_len(c->output)) {
		error("channel %d: chan_obuf_empty for non empty buffer",
		    c->self);
		return;
	}
	switch (c->ostate) {
	case CHAN_OUTPUT_WAIT_DRAIN:
		chan_shutdown_write(ssh, c);
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		break;
	default:
		error("channel %d: internal error: obuf_empty for ostate %d",
		    c->self, c->ostate);
		break;
	}
}
Exemplo n.º 8
0
void
chan_obuf_empty(Channel *c)
{
	debug2("channel %d: obuf empty", c->self);
	if (buffer_len(&c->output)) {
		error("channel %d: chan_obuf_empty for non empty buffer",
		    c->self);
		return;
	}
	switch (c->ostate) {
	case CHAN_OUTPUT_WAIT_DRAIN:
		chan_shutdown_write(c);
		if (!compat20)
			chan_send_oclose1(c);
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
		break;
	default:
		error("channel %d: internal error: obuf_empty for ostate %d",
		    c->self, c->ostate);
		break;
	}
}