diff options
Diffstat (limited to 'usr.bin/ssh/channels.c')
-rw-r--r-- | usr.bin/ssh/channels.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index e5787e3fdde..b494ba73279 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $"); +RCSID("$OpenBSD: channels.c,v 1.228 2005/12/06 22:38:27 reyk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1413,6 +1413,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) debug2("channel %d: filter stops", c->self); chan_read_failed(c); } + } else if (c->datagram) { + buffer_put_string(&c->input, buf, len); } else { buffer_append(&c->input, buf, len); } @@ -1431,6 +1433,23 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && buffer_len(&c->output) > 0) { + if (c->datagram) { + data = buffer_get_string(&c->output, &dlen); + /* ignore truncated writes, datagrams might get lost */ + c->local_consumed += dlen + 4; + len = write(c->wfd, data, dlen); + xfree(data); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) + chan_mark_dead(c); + else + chan_write_failed(c); + return -1; + } + return 1; + } data = buffer_ptr(&c->output); dlen = buffer_len(&c->output); len = write(c->wfd, data, dlen); @@ -1786,6 +1805,22 @@ channel_output_poll(void) if ((c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN) && (len = buffer_len(&c->input)) > 0) { + if (c->datagram) { + if (len > 0) { + u_char *data; + u_int dlen; + + data = buffer_get_string(&c->input, + &dlen); + packet_start(SSH2_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(data, dlen); + packet_send(); + c->remote_window -= dlen + 4; + xfree(data); + } + continue; + } /* * Send some data for the other side over the secure * connection. @@ -1908,7 +1943,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) c->local_window -= data_len; } packet_check_eom(); - buffer_append(&c->output, data, data_len); + if (c->datagram) + buffer_put_string(&c->output, data, data_len); + else + buffer_append(&c->output, data, data_len); xfree(data); } |