[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.37

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.37    ! markus     26: RCSID("$OpenBSD: nchan.c,v 1.36 2002/01/10 12:47:59 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:
1.37    ! markus     86: static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
        !            87: static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
        !            88:
        !            89: static void
        !            90: chan_set_istate(Channel *c, u_int next)
        !            91: {
        !            92:        if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
        !            93:                fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
        !            94:        debug("channel %d: input %s -> %s", c->self, istates[c->istate],
        !            95:            istates[next]);
        !            96:        c->istate = next;
        !            97: }
        !            98: static void
        !            99: chan_set_ostate(Channel *c, u_int next)
        !           100: {
        !           101:        if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
        !           102:                fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
        !           103:        debug("channel %d: output %s -> %s", c->self, ostates[c->ostate],
        !           104:            ostates[next]);
        !           105:        c->ostate = next;
        !           106: }
        !           107:
1.13      markus    108: /*
                    109:  * SSH1 specific implementation of event functions
                    110:  */
1.6       markus    111:
1.13      markus    112: static void
                    113: chan_rcvd_oclose1(Channel *c)
1.6       markus    114: {
1.13      markus    115:        debug("channel %d: rcvd oclose", c->self);
1.6       markus    116:        switch (c->istate) {
1.3       markus    117:        case CHAN_INPUT_WAIT_OCLOSE:
1.37    ! markus    118:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.3       markus    119:                break;
                    120:        case CHAN_INPUT_OPEN:
                    121:                chan_shutdown_read(c);
1.13      markus    122:                chan_send_ieof1(c);
1.37    ! markus    123:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.10      markus    124:                break;
                    125:        case CHAN_INPUT_WAIT_DRAIN:
                    126:                /* both local read_failed and remote write_failed  */
1.13      markus    127:                chan_send_ieof1(c);
1.37    ! markus    128:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.3       markus    129:                break;
                    130:        default:
1.28      markus    131:                error("channel %d: protocol error: rcvd_oclose for istate %d",
1.13      markus    132:                    c->self, c->istate);
1.10      markus    133:                return;
1.3       markus    134:        }
1.1       markus    135: }
1.13      markus    136: static void
                    137: chan_read_failed_12(Channel *c)
1.6       markus    138: {
1.13      markus    139:        debug("channel %d: read failed", c->self);
1.6       markus    140:        switch (c->istate) {
1.3       markus    141:        case CHAN_INPUT_OPEN:
                    142:                chan_shutdown_read(c);
1.37    ! markus    143:                chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
1.3       markus    144:                break;
                    145:        default:
1.28      markus    146:                error("channel %d: chan_read_failed for istate %d",
1.13      markus    147:                    c->self, c->istate);
1.3       markus    148:                break;
1.1       markus    149:        }
                    150: }
1.13      markus    151: static void
                    152: chan_ibuf_empty1(Channel *c)
1.6       markus    153: {
1.13      markus    154:        debug("channel %d: ibuf empty", c->self);
1.6       markus    155:        if (buffer_len(&c->input)) {
1.28      markus    156:                error("channel %d: chan_ibuf_empty for non empty buffer",
1.13      markus    157:                    c->self);
1.3       markus    158:                return;
                    159:        }
1.6       markus    160:        switch (c->istate) {
1.3       markus    161:        case CHAN_INPUT_WAIT_DRAIN:
1.13      markus    162:                chan_send_ieof1(c);
1.37    ! markus    163:                chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
1.3       markus    164:                break;
                    165:        default:
1.28      markus    166:                error("channel %d: chan_ibuf_empty for istate %d",
1.13      markus    167:                    c->self, c->istate);
1.3       markus    168:                break;
1.1       markus    169:        }
                    170: }
1.13      markus    171: static void
                    172: chan_rcvd_ieof1(Channel *c)
1.6       markus    173: {
1.13      markus    174:        debug("channel %d: rcvd ieof", c->self);
1.6       markus    175:        switch (c->ostate) {
1.3       markus    176:        case CHAN_OUTPUT_OPEN:
1.37    ! markus    177:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.3       markus    178:                break;
                    179:        case CHAN_OUTPUT_WAIT_IEOF:
1.37    ! markus    180:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3       markus    181:                break;
                    182:        default:
1.28      markus    183:                error("channel %d: protocol error: rcvd_ieof for ostate %d",
1.13      markus    184:                    c->self, c->ostate);
1.3       markus    185:                break;
                    186:        }
                    187: }
1.13      markus    188: static void
                    189: chan_write_failed1(Channel *c)
1.6       markus    190: {
1.13      markus    191:        debug("channel %d: write failed", c->self);
1.6       markus    192:        switch (c->ostate) {
1.3       markus    193:        case CHAN_OUTPUT_OPEN:
1.13      markus    194:                chan_send_oclose1(c);
1.37    ! markus    195:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
1.3       markus    196:                break;
                    197:        case CHAN_OUTPUT_WAIT_DRAIN:
1.13      markus    198:                chan_send_oclose1(c);
1.37    ! markus    199:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3       markus    200:                break;
                    201:        default:
1.28      markus    202:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    203:                    c->self, c->ostate);
1.3       markus    204:                break;
                    205:        }
                    206: }
1.13      markus    207: static void
                    208: chan_obuf_empty1(Channel *c)
1.6       markus    209: {
1.13      markus    210:        debug("channel %d: obuf empty", c->self);
1.6       markus    211:        if (buffer_len(&c->output)) {
1.28      markus    212:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    213:                    c->self);
1.3       markus    214:                return;
                    215:        }
1.6       markus    216:        switch (c->ostate) {
1.3       markus    217:        case CHAN_OUTPUT_WAIT_DRAIN:
1.13      markus    218:                chan_send_oclose1(c);
1.37    ! markus    219:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3       markus    220:                break;
                    221:        default:
1.28      markus    222:                error("channel %d: internal error: obuf_empty for ostate %d",
1.13      markus    223:                    c->self, c->ostate);
1.3       markus    224:                break;
                    225:        }
                    226: }
                    227: static void
1.13      markus    228: chan_send_ieof1(Channel *c)
1.6       markus    229: {
1.13      markus    230:        debug("channel %d: send ieof", c->self);
1.6       markus    231:        switch (c->istate) {
1.3       markus    232:        case CHAN_INPUT_OPEN:
                    233:        case CHAN_INPUT_WAIT_DRAIN:
                    234:                packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
                    235:                packet_put_int(c->remote_id);
                    236:                packet_send();
                    237:                break;
                    238:        default:
1.28      markus    239:                error("channel %d: cannot send ieof for istate %d",
1.13      markus    240:                    c->self, c->istate);
1.3       markus    241:                break;
1.1       markus    242:        }
                    243: }
1.3       markus    244: static void
1.13      markus    245: chan_send_oclose1(Channel *c)
1.6       markus    246: {
1.13      markus    247:        debug("channel %d: send oclose", c->self);
1.6       markus    248:        switch (c->ostate) {
1.3       markus    249:        case CHAN_OUTPUT_OPEN:
                    250:        case CHAN_OUTPUT_WAIT_DRAIN:
                    251:                chan_shutdown_write(c);
1.34      markus    252:                buffer_clear(&c->output);
1.3       markus    253:                packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
                    254:                packet_put_int(c->remote_id);
                    255:                packet_send();
                    256:                break;
                    257:        default:
1.28      markus    258:                error("channel %d: cannot send oclose for ostate %d",
1.33      deraadt   259:                    c->self, c->ostate);
1.3       markus    260:                break;
1.1       markus    261:        }
                    262: }
1.6       markus    263:
1.13      markus    264: /*
                    265:  * the same for SSH2
                    266:  */
                    267: static void
                    268: chan_rcvd_oclose2(Channel *c)
                    269: {
                    270:        debug("channel %d: rcvd close", c->self);
                    271:        if (c->flags & CHAN_CLOSE_RCVD)
                    272:                error("channel %d: protocol error: close rcvd twice", c->self);
                    273:        c->flags |= CHAN_CLOSE_RCVD;
                    274:        if (c->type == SSH_CHANNEL_LARVAL) {
                    275:                /* tear down larval channels immediately */
1.37    ! markus    276:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
        !           277:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    278:                return;
                    279:        }
                    280:        switch (c->ostate) {
                    281:        case CHAN_OUTPUT_OPEN:
1.28      markus    282:                /*
                    283:                 * wait until a data from the channel is consumed if a CLOSE
                    284:                 * is received
                    285:                 */
1.37    ! markus    286:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13      markus    287:                break;
                    288:        }
                    289:        switch (c->istate) {
                    290:        case CHAN_INPUT_OPEN:
                    291:                chan_shutdown_read(c);
                    292:                break;
                    293:        case CHAN_INPUT_WAIT_DRAIN:
                    294:                chan_send_eof2(c);
                    295:                break;
                    296:        }
1.37    ! markus    297:        chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    298: }
                    299: static void
                    300: chan_ibuf_empty2(Channel *c)
                    301: {
                    302:        debug("channel %d: ibuf empty", c->self);
                    303:        if (buffer_len(&c->input)) {
1.28      markus    304:                error("channel %d: chan_ibuf_empty for non empty buffer",
1.33      deraadt   305:                    c->self);
1.13      markus    306:                return;
                    307:        }
                    308:        switch (c->istate) {
                    309:        case CHAN_INPUT_WAIT_DRAIN:
                    310:                if (!(c->flags & CHAN_CLOSE_SENT))
                    311:                        chan_send_eof2(c);
1.37    ! markus    312:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    313:                break;
                    314:        default:
1.28      markus    315:                error("channel %d: chan_ibuf_empty for istate %d",
1.33      deraadt   316:                    c->self, c->istate);
1.13      markus    317:                break;
                    318:        }
                    319: }
                    320: static void
                    321: chan_rcvd_ieof2(Channel *c)
                    322: {
                    323:        debug("channel %d: rcvd eof", c->self);
1.37    ! markus    324:        if (c->ostate == CHAN_OUTPUT_OPEN)
        !           325:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13      markus    326: }
                    327: static void
                    328: chan_write_failed2(Channel *c)
                    329: {
                    330:        debug("channel %d: write failed", c->self);
                    331:        switch (c->ostate) {
                    332:        case CHAN_OUTPUT_OPEN:
1.15      markus    333:                chan_shutdown_write(c); /* ?? */
1.37    ! markus    334:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    335:                break;
                    336:        case CHAN_OUTPUT_WAIT_DRAIN:
                    337:                chan_shutdown_write(c);
1.37    ! markus    338:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    339:                break;
                    340:        default:
1.28      markus    341:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    342:                    c->self, c->ostate);
                    343:                break;
                    344:        }
                    345: }
                    346: static void
                    347: chan_obuf_empty2(Channel *c)
                    348: {
                    349:        debug("channel %d: obuf empty", c->self);
                    350:        if (buffer_len(&c->output)) {
1.28      markus    351:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    352:                    c->self);
                    353:                return;
                    354:        }
                    355:        switch (c->ostate) {
                    356:        case CHAN_OUTPUT_WAIT_DRAIN:
                    357:                chan_shutdown_write(c);
1.37    ! markus    358:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    359:                break;
                    360:        default:
1.28      markus    361:                error("channel %d: chan_obuf_empty for ostate %d",
1.13      markus    362:                    c->self, c->ostate);
                    363:                break;
                    364:        }
                    365: }
1.3       markus    366: static void
1.13      markus    367: chan_send_eof2(Channel *c)
1.6       markus    368: {
1.13      markus    369:        debug("channel %d: send eof", c->self);
                    370:        switch (c->istate) {
                    371:        case CHAN_INPUT_WAIT_DRAIN:
                    372:                packet_start(SSH2_MSG_CHANNEL_EOF);
                    373:                packet_put_int(c->remote_id);
                    374:                packet_send();
                    375:                break;
                    376:        default:
1.28      markus    377:                error("channel %d: cannot send eof for istate %d",
1.13      markus    378:                    c->self, c->istate);
                    379:                break;
                    380:        }
1.1       markus    381: }
1.3       markus    382: static void
1.13      markus    383: chan_send_close2(Channel *c)
1.6       markus    384: {
1.13      markus    385:        debug("channel %d: send close", c->self);
                    386:        if (c->ostate != CHAN_OUTPUT_CLOSED ||
                    387:            c->istate != CHAN_INPUT_CLOSED) {
1.28      markus    388:                error("channel %d: cannot send close for istate/ostate %d/%d",
1.13      markus    389:                    c->self, c->istate, c->ostate);
                    390:        } else if (c->flags & CHAN_CLOSE_SENT) {
1.28      markus    391:                error("channel %d: already sent close", c->self);
1.13      markus    392:        } else {
                    393:                packet_start(SSH2_MSG_CHANNEL_CLOSE);
                    394:                packet_put_int(c->remote_id);
                    395:                packet_send();
                    396:                c->flags |= CHAN_CLOSE_SENT;
                    397:        }
1.1       markus    398: }
1.23      markus    399:
                    400: /* shared */
                    401:
1.24      markus    402: void
                    403: chan_mark_dead(Channel *c)
                    404: {
1.26      markus    405:        c->type = SSH_CHANNEL_ZOMBIE;
1.24      markus    406: }
                    407:
1.23      markus    408: int
1.32      markus    409: chan_is_dead(Channel *c, int send)
1.6       markus    410: {
1.26      markus    411:        if (c->type == SSH_CHANNEL_ZOMBIE) {
                    412:                debug("channel %d: zombie", c->self);
1.24      markus    413:                return 1;
1.26      markus    414:        }
1.23      markus    415:        if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
                    416:                return 0;
                    417:        if (!compat20) {
                    418:                debug("channel %d: is dead", c->self);
                    419:                return 1;
                    420:        }
                    421:        /*
                    422:         * we have to delay the close message if the efd (for stderr) is
                    423:         * still active
                    424:         */
                    425:        if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
                    426:            buffer_len(&c->extended) > 0)
                    427: #if 0
                    428:            || ((c->extended_usage == CHAN_EXTENDED_READ) &&
                    429:            c->efd != -1)
                    430: #endif
                    431:            ) {
                    432:                debug2("channel %d: active efd: %d len %d type %s",
                    433:                    c->self, c->efd, buffer_len(&c->extended),
                    434:                    c->extended_usage==CHAN_EXTENDED_READ ?
1.33      deraadt   435:                    "read": "write");
1.23      markus    436:        } else {
1.13      markus    437:                if (!(c->flags & CHAN_CLOSE_SENT)) {
1.32      markus    438:                        if (send) {
                    439:                                chan_send_close2(c);
                    440:                        } else {
                    441:                                /* channel would be dead if we sent a close */
                    442:                                if (c->flags & CHAN_CLOSE_RCVD) {
                    443:                                        debug("channel %d: almost dead",
                    444:                                            c->self);
                    445:                                        return 1;
                    446:                                }
                    447:                        }
1.13      markus    448:                }
1.14      markus    449:                if ((c->flags & CHAN_CLOSE_SENT) &&
1.13      markus    450:                    (c->flags & CHAN_CLOSE_RCVD)) {
1.23      markus    451:                        debug("channel %d: is dead", c->self);
                    452:                        return 1;
1.14      markus    453:                }
1.1       markus    454:        }
1.23      markus    455:        return 0;
1.3       markus    456: }
1.13      markus    457:
1.3       markus    458: void
1.6       markus    459: chan_init_iostates(Channel *c)
                    460: {
                    461:        c->ostate = CHAN_OUTPUT_OPEN;
                    462:        c->istate = CHAN_INPUT_OPEN;
1.13      markus    463:        c->flags = 0;
                    464: }
                    465:
                    466: /* init */
                    467: void
                    468: chan_init(void)
                    469: {
                    470:        if (compat20) {
                    471:                chan_rcvd_oclose                = chan_rcvd_oclose2;
                    472:                chan_read_failed                = chan_read_failed_12;
                    473:                chan_ibuf_empty                 = chan_ibuf_empty2;
                    474:
                    475:                chan_rcvd_ieof                  = chan_rcvd_ieof2;
                    476:                chan_write_failed               = chan_write_failed2;
                    477:                chan_obuf_empty                 = chan_obuf_empty2;
                    478:        } else {
                    479:                chan_rcvd_oclose                = chan_rcvd_oclose1;
                    480:                chan_read_failed                = chan_read_failed_12;
                    481:                chan_ibuf_empty                 = chan_ibuf_empty1;
                    482:
                    483:                chan_rcvd_ieof                  = chan_rcvd_ieof1;
                    484:                chan_write_failed               = chan_write_failed1;
                    485:                chan_obuf_empty                 = chan_obuf_empty1;
                    486:        }
                    487: }
                    488:
                    489: /* helper */
                    490: static void
                    491: chan_shutdown_write(Channel *c)
                    492: {
1.34      markus    493:        buffer_clear(&c->output);
1.13      markus    494:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    495:                return;
                    496:        /* shutdown failure is allowed if write failed already */
                    497:        debug("channel %d: close_write", c->self);
                    498:        if (c->sock != -1) {
                    499:                if (shutdown(c->sock, SHUT_WR) < 0)
1.28      markus    500:                        debug("channel %d: chan_shutdown_write: "
                    501:                            "shutdown() failed for fd%d: %.100s",
1.13      markus    502:                            c->self, c->sock, strerror(errno));
                    503:        } else {
1.31      markus    504:                if (channel_close_fd(&c->wfd) < 0)
1.28      markus    505:                        log("channel %d: chan_shutdown_write: "
                    506:                            "close() failed for fd%d: %.100s",
1.13      markus    507:                            c->self, c->wfd, strerror(errno));
                    508:        }
                    509: }
                    510: static void
                    511: chan_shutdown_read(Channel *c)
                    512: {
                    513:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    514:                return;
                    515:        debug("channel %d: close_read", c->self);
                    516:        if (c->sock != -1) {
                    517:                if (shutdown(c->sock, SHUT_RD) < 0)
1.28      markus    518:                        error("channel %d: chan_shutdown_read: "
                    519:                            "shutdown() failed for fd%d [i%d o%d]: %.100s",
                    520:                            c->self, c->sock, c->istate, c->ostate,
                    521:                            strerror(errno));
1.13      markus    522:        } else {
1.31      markus    523:                if (channel_close_fd(&c->rfd) < 0)
1.28      markus    524:                        log("channel %d: chan_shutdown_read: "
                    525:                            "close() failed for fd%d: %.100s",
1.13      markus    526:                            c->self, c->rfd, strerror(errno));
                    527:        }
1.1       markus    528: }