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

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