[BACK]Return to nchan.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/nchan.c, Revision 1.35

1.7       markus      1: /*
1.30      markus      2:  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
1.7       markus      3:  *
                      4:  * Redistribution and use in source and binary forms, with or without
                      5:  * modification, are permitted provided that the following conditions
                      6:  * are met:
                      7:  * 1. Redistributions of source code must retain the above copyright
                      8:  *    notice, this list of conditions and the following disclaimer.
                      9:  * 2. Redistributions in binary form must reproduce the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer in the
                     11:  *    documentation and/or other materials provided with the distribution.
                     12:  *
                     13:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     15:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     16:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     17:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     18:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     19:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     20:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     21:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     22:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     23:  */
                     24:
1.1       markus     25: #include "includes.h"
1.35    ! markus     26: RCSID("$OpenBSD: nchan.c,v 1.34 2002/01/09 17:26:35 markus Exp $");
1.1       markus     27:
1.22      markus     28: #include "ssh1.h"
                     29: #include "ssh2.h"
1.1       markus     30: #include "buffer.h"
1.3       markus     31: #include "packet.h"
1.1       markus     32: #include "channels.h"
1.13      markus     33: #include "compat.h"
1.22      markus     34: #include "log.h"
1.3       markus     35:
1.28      markus     36: /*
                     37:  * SSH Protocol 1.5 aka New Channel Protocol
                     38:  * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
                     39:  * Written by Markus Friedl in October 1999
                     40:  *
                     41:  * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
                     42:  * tear down of channels:
                     43:  *
                     44:  * 1.3:        strict request-ack-protocol:
                     45:  *     CLOSE   ->
                     46:  *             <-  CLOSE_CONFIRM
                     47:  *
                     48:  * 1.5:        uses variations of:
                     49:  *     IEOF    ->
                     50:  *             <-  OCLOSE
                     51:  *             <-  IEOF
                     52:  *     OCLOSE  ->
                     53:  *     i.e. both sides have to close the channel
                     54:  *
                     55:  * 2.0: the EOF messages are optional
                     56:  *
                     57:  * See the debugging output from 'ssh -v' and 'sshd -d' of
                     58:  * ssh-1.2.27 as an example.
                     59:  *
                     60:  */
                     61:
1.13      markus     62: /* functions manipulating channel states */
1.3       markus     63: /*
1.6       markus     64:  * EVENTS update channel input/output states execute ACTIONS
1.3       markus     65:  */
1.13      markus     66: /* events concerning the INPUT from socket for channel (istate) */
                     67: chan_event_fn *chan_rcvd_oclose                        = NULL;
                     68: chan_event_fn *chan_read_failed                        = NULL;
                     69: chan_event_fn *chan_ibuf_empty                 = NULL;
                     70: /* events concerning the OUTPUT from channel for socket (ostate) */
                     71: chan_event_fn *chan_rcvd_ieof                  = NULL;
                     72: chan_event_fn *chan_write_failed               = NULL;
                     73: chan_event_fn *chan_obuf_empty                 = NULL;
                     74: /*
                     75:  * ACTIONS: should never update the channel states
                     76:  */
1.29      itojun     77: static void    chan_send_ieof1(Channel *);
                     78: static void    chan_send_oclose1(Channel *);
                     79: static void    chan_send_close2(Channel *);
                     80: static void    chan_send_eof2(Channel *);
1.13      markus     81:
                     82: /* helper */
1.29      itojun     83: static void    chan_shutdown_write(Channel *);
                     84: static void    chan_shutdown_read(Channel *);
1.13      markus     85:
                     86: /*
                     87:  * SSH1 specific implementation of event functions
                     88:  */
1.6       markus     89:
1.13      markus     90: static void
                     91: chan_rcvd_oclose1(Channel *c)
1.6       markus     92: {
1.13      markus     93:        debug("channel %d: rcvd oclose", c->self);
1.6       markus     94:        switch (c->istate) {
1.3       markus     95:        case CHAN_INPUT_WAIT_OCLOSE:
1.13      markus     96:                debug("channel %d: input wait_oclose -> closed", c->self);
1.6       markus     97:                c->istate = CHAN_INPUT_CLOSED;
1.3       markus     98:                break;
                     99:        case CHAN_INPUT_OPEN:
1.13      markus    100:                debug("channel %d: input open -> closed", c->self);
1.3       markus    101:                chan_shutdown_read(c);
1.13      markus    102:                chan_send_ieof1(c);
1.6       markus    103:                c->istate = CHAN_INPUT_CLOSED;
1.10      markus    104:                break;
                    105:        case CHAN_INPUT_WAIT_DRAIN:
                    106:                /* both local read_failed and remote write_failed  */
1.13      markus    107:                log("channel %d: input drain -> closed", c->self);
                    108:                chan_send_ieof1(c);
1.10      markus    109:                c->istate = CHAN_INPUT_CLOSED;
1.3       markus    110:                break;
                    111:        default:
1.28      markus    112:                error("channel %d: protocol error: rcvd_oclose for istate %d",
1.13      markus    113:                    c->self, c->istate);
1.10      markus    114:                return;
1.3       markus    115:        }
1.1       markus    116: }
1.13      markus    117: static void
                    118: chan_read_failed_12(Channel *c)
1.6       markus    119: {
1.13      markus    120:        debug("channel %d: read failed", c->self);
1.6       markus    121:        switch (c->istate) {
1.3       markus    122:        case CHAN_INPUT_OPEN:
1.13      markus    123:                debug("channel %d: input open -> drain", c->self);
1.3       markus    124:                chan_shutdown_read(c);
1.6       markus    125:                c->istate = CHAN_INPUT_WAIT_DRAIN;
1.3       markus    126:                break;
                    127:        default:
1.28      markus    128:                error("channel %d: chan_read_failed for istate %d",
1.13      markus    129:                    c->self, c->istate);
1.3       markus    130:                break;
1.1       markus    131:        }
                    132: }
1.13      markus    133: static void
                    134: chan_ibuf_empty1(Channel *c)
1.6       markus    135: {
1.13      markus    136:        debug("channel %d: ibuf empty", c->self);
1.6       markus    137:        if (buffer_len(&c->input)) {
1.28      markus    138:                error("channel %d: chan_ibuf_empty for non empty buffer",
1.13      markus    139:                    c->self);
1.3       markus    140:                return;
                    141:        }
1.6       markus    142:        switch (c->istate) {
1.3       markus    143:        case CHAN_INPUT_WAIT_DRAIN:
1.13      markus    144:                debug("channel %d: input drain -> wait_oclose", c->self);
                    145:                chan_send_ieof1(c);
1.6       markus    146:                c->istate = CHAN_INPUT_WAIT_OCLOSE;
1.3       markus    147:                break;
                    148:        default:
1.28      markus    149:                error("channel %d: chan_ibuf_empty for istate %d",
1.13      markus    150:                    c->self, c->istate);
1.3       markus    151:                break;
1.1       markus    152:        }
                    153: }
1.13      markus    154: static void
                    155: chan_rcvd_ieof1(Channel *c)
1.6       markus    156: {
1.13      markus    157:        debug("channel %d: rcvd ieof", c->self);
1.16      markus    158:        if (c->type != SSH_CHANNEL_OPEN) {
                    159:                debug("channel %d: non-open", c->self);
                    160:                if (c->istate == CHAN_INPUT_OPEN) {
1.28      markus    161:                        debug("channel %d: non-open: input open -> wait_oclose",
                    162:                            c->self);
1.16      markus    163:                        chan_shutdown_read(c);
                    164:                        chan_send_ieof1(c);
                    165:                        c->istate = CHAN_INPUT_WAIT_OCLOSE;
                    166:                } else {
1.28      markus    167:                        error("channel %d: non-open: istate %d != open",
                    168:                            c->self, c->istate);
1.16      markus    169:                }
                    170:                if (c->ostate == CHAN_OUTPUT_OPEN) {
1.28      markus    171:                        debug("channel %d: non-open: output open -> closed",
                    172:                            c->self);
1.16      markus    173:                        chan_send_oclose1(c);
                    174:                        c->ostate = CHAN_OUTPUT_CLOSED;
                    175:                } else {
1.28      markus    176:                        error("channel %d: non-open: ostate %d != open",
                    177:                            c->self, c->ostate);
1.16      markus    178:                }
                    179:                return;
                    180:        }
1.6       markus    181:        switch (c->ostate) {
1.3       markus    182:        case CHAN_OUTPUT_OPEN:
1.13      markus    183:                debug("channel %d: output open -> drain", c->self);
1.6       markus    184:                c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
1.3       markus    185:                break;
                    186:        case CHAN_OUTPUT_WAIT_IEOF:
1.13      markus    187:                debug("channel %d: output wait_ieof -> closed", c->self);
1.6       markus    188:                c->ostate = CHAN_OUTPUT_CLOSED;
1.3       markus    189:                break;
                    190:        default:
1.28      markus    191:                error("channel %d: protocol error: rcvd_ieof for ostate %d",
1.13      markus    192:                    c->self, c->ostate);
1.3       markus    193:                break;
                    194:        }
                    195: }
1.13      markus    196: static void
                    197: chan_write_failed1(Channel *c)
1.6       markus    198: {
1.13      markus    199:        debug("channel %d: write failed", c->self);
1.6       markus    200:        switch (c->ostate) {
1.3       markus    201:        case CHAN_OUTPUT_OPEN:
1.13      markus    202:                debug("channel %d: output open -> wait_ieof", c->self);
                    203:                chan_send_oclose1(c);
1.6       markus    204:                c->ostate = CHAN_OUTPUT_WAIT_IEOF;
1.3       markus    205:                break;
                    206:        case CHAN_OUTPUT_WAIT_DRAIN:
1.13      markus    207:                debug("channel %d: output wait_drain -> closed", c->self);
                    208:                chan_send_oclose1(c);
1.6       markus    209:                c->ostate = CHAN_OUTPUT_CLOSED;
1.3       markus    210:                break;
                    211:        default:
1.28      markus    212:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    213:                    c->self, c->ostate);
1.3       markus    214:                break;
                    215:        }
                    216: }
1.13      markus    217: static void
                    218: chan_obuf_empty1(Channel *c)
1.6       markus    219: {
1.13      markus    220:        debug("channel %d: obuf empty", c->self);
1.6       markus    221:        if (buffer_len(&c->output)) {
1.28      markus    222:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    223:                    c->self);
1.3       markus    224:                return;
                    225:        }
1.6       markus    226:        switch (c->ostate) {
1.3       markus    227:        case CHAN_OUTPUT_WAIT_DRAIN:
1.13      markus    228:                debug("channel %d: output drain -> closed", c->self);
                    229:                chan_send_oclose1(c);
1.6       markus    230:                c->ostate = CHAN_OUTPUT_CLOSED;
1.3       markus    231:                break;
                    232:        default:
1.28      markus    233:                error("channel %d: internal error: obuf_empty for ostate %d",
1.13      markus    234:                    c->self, c->ostate);
1.3       markus    235:                break;
                    236:        }
                    237: }
                    238: static void
1.13      markus    239: chan_send_ieof1(Channel *c)
1.6       markus    240: {
1.13      markus    241:        debug("channel %d: send ieof", c->self);
1.6       markus    242:        switch (c->istate) {
1.3       markus    243:        case CHAN_INPUT_OPEN:
                    244:        case CHAN_INPUT_WAIT_DRAIN:
                    245:                packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
                    246:                packet_put_int(c->remote_id);
                    247:                packet_send();
                    248:                break;
                    249:        default:
1.28      markus    250:                error("channel %d: cannot send ieof for istate %d",
1.13      markus    251:                    c->self, c->istate);
1.3       markus    252:                break;
1.1       markus    253:        }
                    254: }
1.3       markus    255: static void
1.13      markus    256: chan_send_oclose1(Channel *c)
1.6       markus    257: {
1.13      markus    258:        debug("channel %d: send oclose", c->self);
1.6       markus    259:        switch (c->ostate) {
1.3       markus    260:        case CHAN_OUTPUT_OPEN:
                    261:        case CHAN_OUTPUT_WAIT_DRAIN:
                    262:                chan_shutdown_write(c);
1.34      markus    263:                buffer_clear(&c->output);
1.3       markus    264:                packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
                    265:                packet_put_int(c->remote_id);
                    266:                packet_send();
                    267:                break;
                    268:        default:
1.28      markus    269:                error("channel %d: cannot send oclose for ostate %d",
1.33      deraadt   270:                    c->self, c->ostate);
1.3       markus    271:                break;
1.1       markus    272:        }
                    273: }
1.6       markus    274:
1.13      markus    275: /*
                    276:  * the same for SSH2
                    277:  */
                    278: static void
                    279: chan_rcvd_oclose2(Channel *c)
                    280: {
                    281:        debug("channel %d: rcvd close", c->self);
                    282:        if (c->flags & CHAN_CLOSE_RCVD)
                    283:                error("channel %d: protocol error: close rcvd twice", c->self);
                    284:        c->flags |= CHAN_CLOSE_RCVD;
                    285:        if (c->type == SSH_CHANNEL_LARVAL) {
                    286:                /* tear down larval channels immediately */
                    287:                c->ostate = CHAN_OUTPUT_CLOSED;
                    288:                c->istate = CHAN_INPUT_CLOSED;
                    289:                return;
                    290:        }
                    291:        switch (c->ostate) {
                    292:        case CHAN_OUTPUT_OPEN:
1.28      markus    293:                /*
                    294:                 * wait until a data from the channel is consumed if a CLOSE
                    295:                 * is received
                    296:                 */
1.13      markus    297:                debug("channel %d: output open -> drain", c->self);
                    298:                c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
                    299:                break;
                    300:        }
                    301:        switch (c->istate) {
                    302:        case CHAN_INPUT_OPEN:
                    303:                debug("channel %d: input open -> closed", c->self);
                    304:                chan_shutdown_read(c);
                    305:                break;
                    306:        case CHAN_INPUT_WAIT_DRAIN:
                    307:                debug("channel %d: input drain -> closed", c->self);
                    308:                chan_send_eof2(c);
                    309:                break;
                    310:        }
                    311:        c->istate = CHAN_INPUT_CLOSED;
                    312: }
                    313: static void
                    314: chan_ibuf_empty2(Channel *c)
                    315: {
                    316:        debug("channel %d: ibuf empty", c->self);
                    317:        if (buffer_len(&c->input)) {
1.28      markus    318:                error("channel %d: chan_ibuf_empty for non empty buffer",
1.33      deraadt   319:                    c->self);
1.13      markus    320:                return;
                    321:        }
                    322:        switch (c->istate) {
                    323:        case CHAN_INPUT_WAIT_DRAIN:
                    324:                debug("channel %d: input drain -> closed", c->self);
                    325:                if (!(c->flags & CHAN_CLOSE_SENT))
                    326:                        chan_send_eof2(c);
                    327:                c->istate = CHAN_INPUT_CLOSED;
                    328:                break;
                    329:        default:
1.28      markus    330:                error("channel %d: chan_ibuf_empty for istate %d",
1.33      deraadt   331:                    c->self, c->istate);
1.13      markus    332:                break;
                    333:        }
                    334: }
                    335: static void
                    336: chan_rcvd_ieof2(Channel *c)
                    337: {
                    338:        debug("channel %d: rcvd eof", c->self);
                    339:        if (c->ostate == CHAN_OUTPUT_OPEN) {
                    340:                debug("channel %d: output open -> drain", c->self);
                    341:                c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
                    342:        }
                    343: }
                    344: static void
                    345: chan_write_failed2(Channel *c)
                    346: {
                    347:        debug("channel %d: write failed", c->self);
                    348:        switch (c->ostate) {
                    349:        case CHAN_OUTPUT_OPEN:
                    350:                debug("channel %d: output open -> closed", c->self);
1.15      markus    351:                chan_shutdown_write(c); /* ?? */
1.13      markus    352:                c->ostate = CHAN_OUTPUT_CLOSED;
                    353:                break;
                    354:        case CHAN_OUTPUT_WAIT_DRAIN:
                    355:                debug("channel %d: output drain -> closed", c->self);
                    356:                chan_shutdown_write(c);
                    357:                c->ostate = CHAN_OUTPUT_CLOSED;
                    358:                break;
                    359:        default:
1.28      markus    360:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    361:                    c->self, c->ostate);
                    362:                break;
                    363:        }
                    364: }
                    365: static void
                    366: chan_obuf_empty2(Channel *c)
                    367: {
                    368:        debug("channel %d: obuf empty", c->self);
                    369:        if (buffer_len(&c->output)) {
1.28      markus    370:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    371:                    c->self);
                    372:                return;
                    373:        }
                    374:        switch (c->ostate) {
                    375:        case CHAN_OUTPUT_WAIT_DRAIN:
                    376:                debug("channel %d: output drain -> closed", c->self);
                    377:                chan_shutdown_write(c);
                    378:                c->ostate = CHAN_OUTPUT_CLOSED;
                    379:                break;
                    380:        default:
1.28      markus    381:                error("channel %d: chan_obuf_empty for ostate %d",
1.13      markus    382:                    c->self, c->ostate);
                    383:                break;
                    384:        }
                    385: }
1.3       markus    386: static void
1.13      markus    387: chan_send_eof2(Channel *c)
1.6       markus    388: {
1.13      markus    389:        debug("channel %d: send eof", c->self);
                    390:        switch (c->istate) {
                    391:        case CHAN_INPUT_WAIT_DRAIN:
                    392:                packet_start(SSH2_MSG_CHANNEL_EOF);
                    393:                packet_put_int(c->remote_id);
                    394:                packet_send();
                    395:                break;
                    396:        default:
1.28      markus    397:                error("channel %d: cannot send eof for istate %d",
1.13      markus    398:                    c->self, c->istate);
                    399:                break;
                    400:        }
1.1       markus    401: }
1.3       markus    402: static void
1.13      markus    403: chan_send_close2(Channel *c)
1.6       markus    404: {
1.13      markus    405:        debug("channel %d: send close", c->self);
                    406:        if (c->ostate != CHAN_OUTPUT_CLOSED ||
                    407:            c->istate != CHAN_INPUT_CLOSED) {
1.28      markus    408:                error("channel %d: cannot send close for istate/ostate %d/%d",
1.13      markus    409:                    c->self, c->istate, c->ostate);
                    410:        } else if (c->flags & CHAN_CLOSE_SENT) {
1.28      markus    411:                error("channel %d: already sent close", c->self);
1.13      markus    412:        } else {
                    413:                packet_start(SSH2_MSG_CHANNEL_CLOSE);
                    414:                packet_put_int(c->remote_id);
                    415:                packet_send();
                    416:                c->flags |= CHAN_CLOSE_SENT;
                    417:        }
1.1       markus    418: }
1.23      markus    419:
                    420: /* shared */
                    421:
1.24      markus    422: void
                    423: chan_mark_dead(Channel *c)
                    424: {
1.26      markus    425:        c->type = SSH_CHANNEL_ZOMBIE;
1.24      markus    426: }
                    427:
1.23      markus    428: int
1.32      markus    429: chan_is_dead(Channel *c, int send)
1.6       markus    430: {
1.26      markus    431:        if (c->type == SSH_CHANNEL_ZOMBIE) {
                    432:                debug("channel %d: zombie", c->self);
1.24      markus    433:                return 1;
1.26      markus    434:        }
1.23      markus    435:        if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
                    436:                return 0;
                    437:        if (!compat20) {
                    438:                debug("channel %d: is dead", c->self);
                    439:                return 1;
                    440:        }
                    441:        /*
                    442:         * we have to delay the close message if the efd (for stderr) is
                    443:         * still active
                    444:         */
                    445:        if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
                    446:            buffer_len(&c->extended) > 0)
                    447: #if 0
                    448:            || ((c->extended_usage == CHAN_EXTENDED_READ) &&
                    449:            c->efd != -1)
                    450: #endif
                    451:            ) {
                    452:                debug2("channel %d: active efd: %d len %d type %s",
                    453:                    c->self, c->efd, buffer_len(&c->extended),
                    454:                    c->extended_usage==CHAN_EXTENDED_READ ?
1.33      deraadt   455:                    "read": "write");
1.23      markus    456:        } else {
1.13      markus    457:                if (!(c->flags & CHAN_CLOSE_SENT)) {
1.32      markus    458:                        if (send) {
                    459:                                chan_send_close2(c);
                    460:                        } else {
                    461:                                /* channel would be dead if we sent a close */
                    462:                                if (c->flags & CHAN_CLOSE_RCVD) {
                    463:                                        debug("channel %d: almost dead",
                    464:                                            c->self);
                    465:                                        return 1;
                    466:                                }
                    467:                        }
1.13      markus    468:                }
1.14      markus    469:                if ((c->flags & CHAN_CLOSE_SENT) &&
1.13      markus    470:                    (c->flags & CHAN_CLOSE_RCVD)) {
1.23      markus    471:                        debug("channel %d: is dead", c->self);
                    472:                        return 1;
1.14      markus    473:                }
1.1       markus    474:        }
1.23      markus    475:        return 0;
1.3       markus    476: }
1.13      markus    477:
1.3       markus    478: void
1.6       markus    479: chan_init_iostates(Channel *c)
                    480: {
                    481:        c->ostate = CHAN_OUTPUT_OPEN;
                    482:        c->istate = CHAN_INPUT_OPEN;
1.13      markus    483:        c->flags = 0;
                    484: }
                    485:
                    486: /* init */
                    487: void
                    488: chan_init(void)
                    489: {
                    490:        if (compat20) {
                    491:                chan_rcvd_oclose                = chan_rcvd_oclose2;
                    492:                chan_read_failed                = chan_read_failed_12;
                    493:                chan_ibuf_empty                 = chan_ibuf_empty2;
                    494:
                    495:                chan_rcvd_ieof                  = chan_rcvd_ieof2;
                    496:                chan_write_failed               = chan_write_failed2;
                    497:                chan_obuf_empty                 = chan_obuf_empty2;
                    498:        } else {
                    499:                chan_rcvd_oclose                = chan_rcvd_oclose1;
                    500:                chan_read_failed                = chan_read_failed_12;
                    501:                chan_ibuf_empty                 = chan_ibuf_empty1;
                    502:
                    503:                chan_rcvd_ieof                  = chan_rcvd_ieof1;
                    504:                chan_write_failed               = chan_write_failed1;
                    505:                chan_obuf_empty                 = chan_obuf_empty1;
                    506:        }
                    507: }
                    508:
                    509: /* helper */
                    510: static void
                    511: chan_shutdown_write(Channel *c)
                    512: {
1.34      markus    513:        buffer_clear(&c->output);
1.13      markus    514:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    515:                return;
                    516:        /* shutdown failure is allowed if write failed already */
                    517:        debug("channel %d: close_write", c->self);
                    518:        if (c->sock != -1) {
                    519:                if (shutdown(c->sock, SHUT_WR) < 0)
1.28      markus    520:                        debug("channel %d: chan_shutdown_write: "
                    521:                            "shutdown() failed for fd%d: %.100s",
1.13      markus    522:                            c->self, c->sock, strerror(errno));
                    523:        } else {
1.31      markus    524:                if (channel_close_fd(&c->wfd) < 0)
1.28      markus    525:                        log("channel %d: chan_shutdown_write: "
                    526:                            "close() failed for fd%d: %.100s",
1.13      markus    527:                            c->self, c->wfd, strerror(errno));
                    528:        }
                    529: }
                    530: static void
                    531: chan_shutdown_read(Channel *c)
                    532: {
                    533:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    534:                return;
                    535:        debug("channel %d: close_read", c->self);
                    536:        if (c->sock != -1) {
                    537:                if (shutdown(c->sock, SHUT_RD) < 0)
1.28      markus    538:                        error("channel %d: chan_shutdown_read: "
                    539:                            "shutdown() failed for fd%d [i%d o%d]: %.100s",
                    540:                            c->self, c->sock, c->istate, c->ostate,
                    541:                            strerror(errno));
1.13      markus    542:        } else {
1.31      markus    543:                if (channel_close_fd(&c->rfd) < 0)
1.28      markus    544:                        log("channel %d: chan_shutdown_read: "
                    545:                            "close() failed for fd%d: %.100s",
1.13      markus    546:                            c->self, c->rfd, strerror(errno));
                    547:        }
1.1       markus    548: }