summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/nchan.c
diff options
context:
space:
mode:
authormarkus <markus@openbsd.org>1999-10-16 20:47:13 +0000
committermarkus <markus@openbsd.org>1999-10-16 20:47:13 +0000
commitf28787b15b36e70e00447c345eb045871f7e10a4 (patch)
tree8eeb3253cab6c5a3ff2936702b87531f464aab8f /usr.bin/ssh/nchan.c
parentFormatting fix. (diff)
downloadwireguard-openbsd-f28787b15b36e70e00447c345eb045871f7e10a4.tar.xz
wireguard-openbsd-f28787b15b36e70e00447c345eb045871f7e10a4.zip
support for SSH protocol 1.5 which is poorly documented, the RFC.troff lies.
interops (x11,agent,etc) with 1.2.27 and protocol 1.3
Diffstat (limited to 'usr.bin/ssh/nchan.c')
-rw-r--r--usr.bin/ssh/nchan.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/usr.bin/ssh/nchan.c b/usr.bin/ssh/nchan.c
new file mode 100644
index 00000000000..1ee66e111bb
--- /dev/null
+++ b/usr.bin/ssh/nchan.c
@@ -0,0 +1,98 @@
+#include "includes.h"
+#include "ssh.h"
+
+#include "buffer.h"
+#include "channels.h"
+#include "packet.h"
+#include "nchan.h"
+
+
+void
+dump_chan(Channel *c){
+ debug("chan %d type %d flags 0x%x", c->self, c->type, c->flags);
+}
+void
+chan_rcvd_ieof(Channel *c){
+ dump_chan(c);
+ if(c->flags & CHAN_IEOF_RCVD){
+ debug("chan_rcvd_ieof twice: %d",c->self);
+ return;
+ }
+ debug("rcvd_CHAN_IEOF %d",c->self);
+ c->flags |= CHAN_IEOF_RCVD;
+ /* cannot clear input buffer. remaining data has to be sent to client */
+ chan_del_if_dead(c);
+}
+void
+chan_rcvd_oclose(Channel *c){
+ dump_chan(c);
+ if(c->flags & CHAN_OCLOSE_RCVD){
+ debug("chan_rcvd_oclose twice: %d",c->self);
+ return;
+ }
+ debug("rcvd_CHAN_OCLOSE %d",c->self);
+ c->flags |= CHAN_OCLOSE_RCVD;
+ /* our peer can no longer consume, so there is not need to read */
+ chan_shutdown_read(c);
+ buffer_consume(&c->output, buffer_len(&c->output));
+ /* Note: for type==OPEN IEOF is sent by channel_output_poll() */
+ chan_del_if_dead(c);
+}
+void
+chan_send_ieof(Channel *c){
+ if(c->flags & CHAN_IEOF_SENT){
+ debug("send_chan_ieof twice %d", c->self);
+ return;
+ }
+ debug("send_CHAN_IEOF %d", c->self);
+ packet_start(CHAN_IEOF);
+ packet_put_int(c->remote_id);
+ packet_send();
+ c->flags |= CHAN_IEOF_SENT;
+ dump_chan(c);
+}
+void
+chan_send_oclose(Channel *c){
+ if(c->flags & CHAN_OCLOSE_SENT){
+ debug("send_chan_oclose twice %d", c->self);
+ return;
+ }
+ debug("send_CHAN_OCLOSE %d", c->self);
+ packet_start(CHAN_OCLOSE);
+ packet_put_int(c->remote_id);
+ packet_send();
+ c->flags |= CHAN_OCLOSE_SENT;
+ dump_chan(c);
+}
+void
+chan_shutdown_write(Channel *c){
+ if(c->flags & CHAN_SHUT_WR){
+ debug("chan_shutdown_write twice %d",c->self);
+ return;
+ }
+ debug("chan_shutdown_write %d", c->self);
+ if(shutdown(c->sock, SHUT_WR)<0)
+ error("chan_shutdown_write failed %.100s", strerror(errno));
+ c->flags |= CHAN_SHUT_WR;
+ /* clear output buffer, since there is noone going to read the data
+ we just closed the output-socket */
+ // buffer_consume(&c->output, buffer_len(&c->output));
+}
+void
+chan_shutdown_read(Channel *c){
+ if(c->flags & CHAN_SHUT_RD){
+ debug("chan_shutdown_read twice %d",c->self);
+ return;
+ }
+ debug("chan_shutdown_read %d", c->self);
+ if(shutdown(c->sock, SHUT_RD)<0)
+ error("chan_shutdown_read failed %.100s", strerror(errno));
+ c->flags |= CHAN_SHUT_RD;
+}
+void
+chan_del_if_dead(Channel *c){
+ if(c->flags == CHAN_CLOSED){
+ debug("channel %d closing",c->self);
+ channel_free(c->self);
+ }
+}