11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h" 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h" 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "channels.h" 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h" 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH Protocol 1.5 aka New Channel Protocol 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Written by Markus Friedl in October 1999 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * tear down of channels: 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1.3: strict request-ack-protocol: 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * CLOSE -> 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * <- CLOSE_CONFIRM 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1.5: uses variations of: 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IEOF -> 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * <- OCLOSE 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * <- IEOF 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OCLOSE -> 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * i.e. both sides have to close the channel 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2.0: the EOF messages are optional 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * See the debugging output from 'ssh -v' and 'sshd -d' of 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ssh-1.2.27 as an example. 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* functions manipulating channel states */ 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * EVENTS update channel input/output states execute ACTIONS 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTIONS: should never update the channel states 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_send_ieof1(Channel *); 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_send_oclose1(Channel *); 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_send_close2(Channel *); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_send_eof2(Channel *); 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_send_eow2(Channel *); 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* helper */ 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_shutdown_write(Channel *); 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void chan_shutdown_read(Channel *); 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_set_istate(Channel *c, u_int next) 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED) 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chan_set_istate: bad state %d -> %d", c->istate, next); 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: input %s -> %s", c->self, istates[c->istate], 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood istates[next]); 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->istate = next; 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_set_ostate(Channel *c, u_int next) 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED) 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next); 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate], 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ostates[next]); 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->ostate = next; 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH1 specific implementation of event functions 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_oclose1(Channel *c) 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: rcvd oclose", c->self); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_OCLOSE: 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_OPEN: 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_read(c); 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_ieof1(c); 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_DRAIN: 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* both local read_failed and remote write_failed */ 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_ieof1(c); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: protocol error: rcvd_oclose for istate %d", 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate); 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_read_failed(Channel *c) 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: read failed", c->self); 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_OPEN: 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_read(c); 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_read_failed for istate %d", 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_ibuf_empty(Channel *c) 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: ibuf empty", c->self); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&c->input)) { 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_ibuf_empty for non empty buffer", 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_DRAIN: 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_eof2(c); 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_ieof1(c); 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_ibuf_empty for istate %d", 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate); 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_ieof1(Channel *c) 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: rcvd ieof", c->self); 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_OPEN: 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_WAIT_IEOF: 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: protocol error: rcvd_ieof for ostate %d", 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->ostate); 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_write_failed1(Channel *c) 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: write failed", c->self); 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_OPEN: 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_write(c); 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_oclose1(c); 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF); 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_WAIT_DRAIN: 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_write(c); 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_oclose1(c); 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_write_failed for ostate %d", 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->ostate); 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_obuf_empty(Channel *c) 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: obuf empty", c->self); 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&c->output)) { 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_obuf_empty for non empty buffer", 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self); 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_WAIT_DRAIN: 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_write(c); 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_oclose1(c); 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: internal error: obuf_empty for ostate %d", 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->ostate); 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_send_ieof1(Channel *c) 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: send ieof", c->self); 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_OPEN: 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_DRAIN: 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_MSG_CHANNEL_INPUT_EOF); 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: cannot send ieof for istate %d", 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate); 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_send_oclose1(Channel *c) 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: send oclose", c->self); 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_OPEN: 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_WAIT_DRAIN: 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&c->output); 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: cannot send oclose for ostate %d", 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->ostate); 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the same for SSH2 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_close2(Channel *c) 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: rcvd close", c->self); 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(c->flags & CHAN_LOCAL)) { 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->flags & CHAN_CLOSE_RCVD) 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: protocol error: close rcvd twice", 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self); 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->flags |= CHAN_CLOSE_RCVD; 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->type == SSH_CHANNEL_LARVAL) { 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* tear down larval channels immediately */ 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_OPEN: 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * wait until a data from the channel is consumed if a CLOSE 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * is received 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_OPEN: 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_read(c); 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_DRAIN: 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(c->flags & CHAN_LOCAL)) 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_eof2(c); 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_eow(Channel *c) 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: rcvd eow", c->self); 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_OPEN: 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_read(c); 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_istate(c, CHAN_INPUT_CLOSED); 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_eof2(Channel *c) 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: rcvd eof", c->self); 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->flags |= CHAN_EOF_RCVD; 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate == CHAN_OUTPUT_OPEN) 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_write_failed2(Channel *c) 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: write failed", c->self); 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->ostate) { 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_OPEN: 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_OUTPUT_WAIT_DRAIN: 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_shutdown_write(c); 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(c->ctype, "session") == 0) 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_eow2(c); 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_write_failed for ostate %d", 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->ostate); 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_send_eof2(Channel *c) 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: send eof", c->self); 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (c->istate) { 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case CHAN_INPUT_WAIT_DRAIN: 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_EOF); 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->flags |= CHAN_EOF_SENT; 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: cannot send eof for istate %d", 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate); 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_send_close2(Channel *c) 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: send close", c->self); 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate != CHAN_OUTPUT_CLOSED || 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->istate != CHAN_INPUT_CLOSED) { 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: cannot send close for istate/ostate %d/%d", 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->istate, c->ostate); 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (c->flags & CHAN_CLOSE_SENT) { 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: already sent close", c->self); 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_CLOSE); 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->flags |= CHAN_CLOSE_SENT; 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_send_eow2(Channel *c) 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: send eow", c->self); 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate == CHAN_OUTPUT_CLOSED) { 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: must not sent eow on closed output", 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self); 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(datafellows & SSH_NEW_OPENSSH)) 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_REQUEST); 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("eow@openssh.com"); 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(0); 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* shared */ 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_ieof(Channel *c) 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_rcvd_eof2(c); 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_rcvd_ieof1(c); 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&c->output) == 0 && 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_obuf_empty(c); 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_rcvd_oclose(Channel *c) 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_rcvd_close2(c); 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_rcvd_oclose1(c); 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_write_failed(Channel *c) 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_write_failed2(c); 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_write_failed1(c); 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_mark_dead(Channel *c) 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->type = SSH_CHANNEL_ZOMBIE; 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_is_dead(Channel *c, int do_send) 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->type == SSH_CHANNEL_ZOMBIE) { 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: zombie", c->self); 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) { 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: is dead", c->self); 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((datafellows & SSH_BUG_EXTEOF) && 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->extended_usage == CHAN_EXTENDED_WRITE && 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->efd != -1 && 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&c->extended) > 0) { 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: active efd: %d len %d", 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->efd, buffer_len(&c->extended)); 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->flags & CHAN_LOCAL) { 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: is dead (local)", c->self); 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(c->flags & CHAN_CLOSE_SENT)) { 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_send) { 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_send_close2(c); 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* channel would be dead if we sent a close */ 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->flags & CHAN_CLOSE_RCVD) { 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: almost dead", 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self); 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((c->flags & CHAN_CLOSE_SENT) && 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (c->flags & CHAN_CLOSE_RCVD)) { 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: is dead", c->self); 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* helper */ 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_shutdown_write(Channel *c) 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&c->output); 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20 && c->type == SSH_CHANNEL_LARVAL) 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* shutdown failure is allowed if write failed already */ 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: close_write", c->self); 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->sock != -1) { 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (shutdown(c->sock, SHUT_WR) < 0) 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: chan_shutdown_write: " 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "shutdown() failed for fd %d: %.100s", 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->sock, strerror(errno)); 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (channel_close_fd(&c->wfd) < 0) 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("channel %d: chan_shutdown_write: " 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "close() failed for fd %d: %.100s", 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->wfd, strerror(errno)); 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchan_shutdown_read(Channel *c) 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20 && c->type == SSH_CHANNEL_LARVAL) 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("channel %d: close_read", c->self); 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->sock != -1) { 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * shutdown(sock, SHUT_READ) may return ENOTCONN if the 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * write side has been closed already. (bug on Linux) 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * HP-UX may return ENOTCONN also. 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (shutdown(c->sock, SHUT_RD) < 0 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood && errno != ENOTCONN) 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("channel %d: chan_shutdown_read: " 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "shutdown() failed for fd %d [i%d o%d]: %.100s", 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->sock, c->istate, c->ostate, 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (channel_close_fd(&c->rfd) < 0) 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("channel %d: chan_shutdown_read: " 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "close() failed for fd %d: %.100s", 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, c->rfd, strerror(errno)); 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 532