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

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.38    ! markus     26: RCSID("$OpenBSD: nchan.c,v 1.37 2002/01/13 21:31:20 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.38    ! markus    194:                chan_shutdown_write(c);
1.13      markus    195:                chan_send_oclose1(c);
1.37      markus    196:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
1.3       markus    197:                break;
                    198:        case CHAN_OUTPUT_WAIT_DRAIN:
1.38    ! markus    199:                chan_shutdown_write(c);
1.13      markus    200:                chan_send_oclose1(c);
1.37      markus    201:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3       markus    202:                break;
                    203:        default:
1.28      markus    204:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    205:                    c->self, c->ostate);
1.3       markus    206:                break;
                    207:        }
                    208: }
1.13      markus    209: static void
                    210: chan_obuf_empty1(Channel *c)
1.6       markus    211: {
1.13      markus    212:        debug("channel %d: obuf empty", c->self);
1.6       markus    213:        if (buffer_len(&c->output)) {
1.28      markus    214:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    215:                    c->self);
1.3       markus    216:                return;
                    217:        }
1.6       markus    218:        switch (c->ostate) {
1.3       markus    219:        case CHAN_OUTPUT_WAIT_DRAIN:
1.38    ! markus    220:                chan_shutdown_write(c);
1.13      markus    221:                chan_send_oclose1(c);
1.37      markus    222:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3       markus    223:                break;
                    224:        default:
1.28      markus    225:                error("channel %d: internal error: obuf_empty for ostate %d",
1.13      markus    226:                    c->self, c->ostate);
1.3       markus    227:                break;
                    228:        }
                    229: }
                    230: static void
1.13      markus    231: chan_send_ieof1(Channel *c)
1.6       markus    232: {
1.13      markus    233:        debug("channel %d: send ieof", c->self);
1.6       markus    234:        switch (c->istate) {
1.3       markus    235:        case CHAN_INPUT_OPEN:
                    236:        case CHAN_INPUT_WAIT_DRAIN:
                    237:                packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
                    238:                packet_put_int(c->remote_id);
                    239:                packet_send();
                    240:                break;
                    241:        default:
1.28      markus    242:                error("channel %d: cannot send ieof for istate %d",
1.13      markus    243:                    c->self, c->istate);
1.3       markus    244:                break;
1.1       markus    245:        }
                    246: }
1.3       markus    247: static void
1.13      markus    248: chan_send_oclose1(Channel *c)
1.6       markus    249: {
1.13      markus    250:        debug("channel %d: send oclose", c->self);
1.6       markus    251:        switch (c->ostate) {
1.3       markus    252:        case CHAN_OUTPUT_OPEN:
                    253:        case CHAN_OUTPUT_WAIT_DRAIN:
1.34      markus    254:                buffer_clear(&c->output);
1.3       markus    255:                packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
                    256:                packet_put_int(c->remote_id);
                    257:                packet_send();
                    258:                break;
                    259:        default:
1.28      markus    260:                error("channel %d: cannot send oclose for ostate %d",
1.33      deraadt   261:                    c->self, c->ostate);
1.3       markus    262:                break;
1.1       markus    263:        }
                    264: }
1.6       markus    265:
1.13      markus    266: /*
                    267:  * the same for SSH2
                    268:  */
                    269: static void
                    270: chan_rcvd_oclose2(Channel *c)
                    271: {
                    272:        debug("channel %d: rcvd close", c->self);
                    273:        if (c->flags & CHAN_CLOSE_RCVD)
                    274:                error("channel %d: protocol error: close rcvd twice", c->self);
                    275:        c->flags |= CHAN_CLOSE_RCVD;
                    276:        if (c->type == SSH_CHANNEL_LARVAL) {
                    277:                /* tear down larval channels immediately */
1.37      markus    278:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
                    279:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    280:                return;
                    281:        }
                    282:        switch (c->ostate) {
                    283:        case CHAN_OUTPUT_OPEN:
1.28      markus    284:                /*
                    285:                 * wait until a data from the channel is consumed if a CLOSE
                    286:                 * is received
                    287:                 */
1.37      markus    288:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13      markus    289:                break;
                    290:        }
                    291:        switch (c->istate) {
                    292:        case CHAN_INPUT_OPEN:
                    293:                chan_shutdown_read(c);
                    294:                break;
                    295:        case CHAN_INPUT_WAIT_DRAIN:
                    296:                chan_send_eof2(c);
                    297:                break;
                    298:        }
1.37      markus    299:        chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    300: }
                    301: static void
                    302: chan_ibuf_empty2(Channel *c)
                    303: {
                    304:        debug("channel %d: ibuf empty", c->self);
                    305:        if (buffer_len(&c->input)) {
1.28      markus    306:                error("channel %d: chan_ibuf_empty for non empty buffer",
1.33      deraadt   307:                    c->self);
1.13      markus    308:                return;
                    309:        }
                    310:        switch (c->istate) {
                    311:        case CHAN_INPUT_WAIT_DRAIN:
                    312:                if (!(c->flags & CHAN_CLOSE_SENT))
                    313:                        chan_send_eof2(c);
1.37      markus    314:                chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13      markus    315:                break;
                    316:        default:
1.28      markus    317:                error("channel %d: chan_ibuf_empty for istate %d",
1.33      deraadt   318:                    c->self, c->istate);
1.13      markus    319:                break;
                    320:        }
                    321: }
                    322: static void
                    323: chan_rcvd_ieof2(Channel *c)
                    324: {
                    325:        debug("channel %d: rcvd eof", c->self);
1.37      markus    326:        if (c->ostate == CHAN_OUTPUT_OPEN)
                    327:                chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13      markus    328: }
                    329: static void
                    330: chan_write_failed2(Channel *c)
                    331: {
                    332:        debug("channel %d: write failed", c->self);
                    333:        switch (c->ostate) {
                    334:        case CHAN_OUTPUT_OPEN:
1.15      markus    335:                chan_shutdown_write(c); /* ?? */
1.37      markus    336:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    337:                break;
                    338:        case CHAN_OUTPUT_WAIT_DRAIN:
                    339:                chan_shutdown_write(c);
1.37      markus    340:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    341:                break;
                    342:        default:
1.28      markus    343:                error("channel %d: chan_write_failed for ostate %d",
1.13      markus    344:                    c->self, c->ostate);
                    345:                break;
                    346:        }
                    347: }
                    348: static void
                    349: chan_obuf_empty2(Channel *c)
                    350: {
                    351:        debug("channel %d: obuf empty", c->self);
                    352:        if (buffer_len(&c->output)) {
1.28      markus    353:                error("channel %d: chan_obuf_empty for non empty buffer",
1.13      markus    354:                    c->self);
                    355:                return;
                    356:        }
                    357:        switch (c->ostate) {
                    358:        case CHAN_OUTPUT_WAIT_DRAIN:
                    359:                chan_shutdown_write(c);
1.37      markus    360:                chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13      markus    361:                break;
                    362:        default:
1.28      markus    363:                error("channel %d: chan_obuf_empty for ostate %d",
1.13      markus    364:                    c->self, c->ostate);
                    365:                break;
                    366:        }
                    367: }
1.3       markus    368: static void
1.13      markus    369: chan_send_eof2(Channel *c)
1.6       markus    370: {
1.13      markus    371:        debug("channel %d: send eof", c->self);
                    372:        switch (c->istate) {
                    373:        case CHAN_INPUT_WAIT_DRAIN:
                    374:                packet_start(SSH2_MSG_CHANNEL_EOF);
                    375:                packet_put_int(c->remote_id);
                    376:                packet_send();
                    377:                break;
                    378:        default:
1.28      markus    379:                error("channel %d: cannot send eof for istate %d",
1.13      markus    380:                    c->self, c->istate);
                    381:                break;
                    382:        }
1.1       markus    383: }
1.3       markus    384: static void
1.13      markus    385: chan_send_close2(Channel *c)
1.6       markus    386: {
1.13      markus    387:        debug("channel %d: send close", c->self);
                    388:        if (c->ostate != CHAN_OUTPUT_CLOSED ||
                    389:            c->istate != CHAN_INPUT_CLOSED) {
1.28      markus    390:                error("channel %d: cannot send close for istate/ostate %d/%d",
1.13      markus    391:                    c->self, c->istate, c->ostate);
                    392:        } else if (c->flags & CHAN_CLOSE_SENT) {
1.28      markus    393:                error("channel %d: already sent close", c->self);
1.13      markus    394:        } else {
                    395:                packet_start(SSH2_MSG_CHANNEL_CLOSE);
                    396:                packet_put_int(c->remote_id);
                    397:                packet_send();
                    398:                c->flags |= CHAN_CLOSE_SENT;
                    399:        }
1.1       markus    400: }
1.23      markus    401:
                    402: /* shared */
                    403:
1.24      markus    404: void
                    405: chan_mark_dead(Channel *c)
                    406: {
1.26      markus    407:        c->type = SSH_CHANNEL_ZOMBIE;
1.24      markus    408: }
                    409:
1.23      markus    410: int
1.32      markus    411: chan_is_dead(Channel *c, int send)
1.6       markus    412: {
1.26      markus    413:        if (c->type == SSH_CHANNEL_ZOMBIE) {
                    414:                debug("channel %d: zombie", c->self);
1.24      markus    415:                return 1;
1.26      markus    416:        }
1.23      markus    417:        if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
                    418:                return 0;
                    419:        if (!compat20) {
                    420:                debug("channel %d: is dead", c->self);
                    421:                return 1;
                    422:        }
                    423:        /*
                    424:         * we have to delay the close message if the efd (for stderr) is
                    425:         * still active
                    426:         */
                    427:        if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
                    428:            buffer_len(&c->extended) > 0)
                    429: #if 0
                    430:            || ((c->extended_usage == CHAN_EXTENDED_READ) &&
                    431:            c->efd != -1)
                    432: #endif
                    433:            ) {
                    434:                debug2("channel %d: active efd: %d len %d type %s",
                    435:                    c->self, c->efd, buffer_len(&c->extended),
                    436:                    c->extended_usage==CHAN_EXTENDED_READ ?
1.33      deraadt   437:                    "read": "write");
1.23      markus    438:        } else {
1.13      markus    439:                if (!(c->flags & CHAN_CLOSE_SENT)) {
1.32      markus    440:                        if (send) {
                    441:                                chan_send_close2(c);
                    442:                        } else {
                    443:                                /* channel would be dead if we sent a close */
                    444:                                if (c->flags & CHAN_CLOSE_RCVD) {
                    445:                                        debug("channel %d: almost dead",
                    446:                                            c->self);
                    447:                                        return 1;
                    448:                                }
                    449:                        }
1.13      markus    450:                }
1.14      markus    451:                if ((c->flags & CHAN_CLOSE_SENT) &&
1.13      markus    452:                    (c->flags & CHAN_CLOSE_RCVD)) {
1.23      markus    453:                        debug("channel %d: is dead", c->self);
                    454:                        return 1;
1.14      markus    455:                }
1.1       markus    456:        }
1.23      markus    457:        return 0;
1.3       markus    458: }
1.13      markus    459:
1.3       markus    460: void
1.6       markus    461: chan_init_iostates(Channel *c)
                    462: {
                    463:        c->ostate = CHAN_OUTPUT_OPEN;
                    464:        c->istate = CHAN_INPUT_OPEN;
1.13      markus    465:        c->flags = 0;
                    466: }
                    467:
                    468: /* init */
                    469: void
                    470: chan_init(void)
                    471: {
                    472:        if (compat20) {
                    473:                chan_rcvd_oclose                = chan_rcvd_oclose2;
                    474:                chan_read_failed                = chan_read_failed_12;
                    475:                chan_ibuf_empty                 = chan_ibuf_empty2;
                    476:
                    477:                chan_rcvd_ieof                  = chan_rcvd_ieof2;
                    478:                chan_write_failed               = chan_write_failed2;
                    479:                chan_obuf_empty                 = chan_obuf_empty2;
                    480:        } else {
                    481:                chan_rcvd_oclose                = chan_rcvd_oclose1;
                    482:                chan_read_failed                = chan_read_failed_12;
                    483:                chan_ibuf_empty                 = chan_ibuf_empty1;
                    484:
                    485:                chan_rcvd_ieof                  = chan_rcvd_ieof1;
                    486:                chan_write_failed               = chan_write_failed1;
                    487:                chan_obuf_empty                 = chan_obuf_empty1;
                    488:        }
                    489: }
                    490:
                    491: /* helper */
                    492: static void
                    493: chan_shutdown_write(Channel *c)
                    494: {
1.34      markus    495:        buffer_clear(&c->output);
1.13      markus    496:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    497:                return;
                    498:        /* shutdown failure is allowed if write failed already */
                    499:        debug("channel %d: close_write", c->self);
                    500:        if (c->sock != -1) {
                    501:                if (shutdown(c->sock, SHUT_WR) < 0)
1.28      markus    502:                        debug("channel %d: chan_shutdown_write: "
                    503:                            "shutdown() failed for fd%d: %.100s",
1.13      markus    504:                            c->self, c->sock, strerror(errno));
                    505:        } else {
1.31      markus    506:                if (channel_close_fd(&c->wfd) < 0)
1.28      markus    507:                        log("channel %d: chan_shutdown_write: "
                    508:                            "close() failed for fd%d: %.100s",
1.13      markus    509:                            c->self, c->wfd, strerror(errno));
                    510:        }
                    511: }
                    512: static void
                    513: chan_shutdown_read(Channel *c)
                    514: {
                    515:        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                    516:                return;
                    517:        debug("channel %d: close_read", c->self);
                    518:        if (c->sock != -1) {
                    519:                if (shutdown(c->sock, SHUT_RD) < 0)
1.28      markus    520:                        error("channel %d: chan_shutdown_read: "
                    521:                            "shutdown() failed for fd%d [i%d o%d]: %.100s",
                    522:                            c->self, c->sock, c->istate, c->ostate,
                    523:                            strerror(errno));
1.13      markus    524:        } else {
1.31      markus    525:                if (channel_close_fd(&c->rfd) < 0)
1.28      markus    526:                        log("channel %d: chan_shutdown_read: "
                    527:                            "close() failed for fd%d: %.100s",
1.13      markus    528:                            c->self, c->rfd, strerror(errno));
                    529:        }
1.1       markus    530: }