summaryrefslogtreecommitdiff
path: root/nchan.c
diff options
context:
space:
mode:
Diffstat (limited to 'nchan.c')
-rw-r--r--nchan.c369
1 files changed, 126 insertions, 243 deletions
diff --git a/nchan.c b/nchan.c
index 20f6a2f49..24929556d 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -33,9 +33,9 @@
33#include <stdarg.h> 33#include <stdarg.h>
34 34
35#include "openbsd-compat/sys-queue.h" 35#include "openbsd-compat/sys-queue.h"
36#include "ssh1.h"
37#include "ssh2.h" 36#include "ssh2.h"
38#include "buffer.h" 37#include "sshbuf.h"
38#include "ssherr.h"
39#include "packet.h" 39#include "packet.h"
40#include "channels.h" 40#include "channels.h"
41#include "compat.h" 41#include "compat.h"
@@ -74,18 +74,15 @@
74/* 74/*
75 * ACTIONS: should never update the channel states 75 * ACTIONS: should never update the channel states
76 */ 76 */
77static void chan_send_ieof1(Channel *); 77static void chan_send_eof2(struct ssh *, Channel *);
78static void chan_send_oclose1(Channel *); 78static void chan_send_eow2(struct ssh *, Channel *);
79static void chan_send_close2(Channel *);
80static void chan_send_eof2(Channel *);
81static void chan_send_eow2(Channel *);
82 79
83/* helper */ 80/* helper */
84static void chan_shutdown_write(Channel *); 81static void chan_shutdown_write(struct ssh *, Channel *);
85static void chan_shutdown_read(Channel *); 82static void chan_shutdown_read(struct ssh *, Channel *);
86 83
87static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 84static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
88static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 85static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
89 86
90static void 87static void
91chan_set_istate(Channel *c, u_int next) 88chan_set_istate(Channel *c, u_int next)
@@ -96,6 +93,7 @@ chan_set_istate(Channel *c, u_int next)
96 istates[next]); 93 istates[next]);
97 c->istate = next; 94 c->istate = next;
98} 95}
96
99static void 97static void
100chan_set_ostate(Channel *c, u_int next) 98chan_set_ostate(Channel *c, u_int next)
101{ 99{
@@ -106,41 +104,13 @@ chan_set_ostate(Channel *c, u_int next)
106 c->ostate = next; 104 c->ostate = next;
107} 105}
108 106
109/*
110 * SSH1 specific implementation of event functions
111 */
112
113static void
114chan_rcvd_oclose1(Channel *c)
115{
116 debug2("channel %d: rcvd oclose", c->self);
117 switch (c->istate) {
118 case CHAN_INPUT_WAIT_OCLOSE:
119 chan_set_istate(c, CHAN_INPUT_CLOSED);
120 break;
121 case CHAN_INPUT_OPEN:
122 chan_shutdown_read(c);
123 chan_send_ieof1(c);
124 chan_set_istate(c, CHAN_INPUT_CLOSED);
125 break;
126 case CHAN_INPUT_WAIT_DRAIN:
127 /* both local read_failed and remote write_failed */
128 chan_send_ieof1(c);
129 chan_set_istate(c, CHAN_INPUT_CLOSED);
130 break;
131 default:
132 error("channel %d: protocol error: rcvd_oclose for istate %d",
133 c->self, c->istate);
134 return;
135 }
136}
137void 107void
138chan_read_failed(Channel *c) 108chan_read_failed(struct ssh *ssh, Channel *c)
139{ 109{
140 debug2("channel %d: read failed", c->self); 110 debug2("channel %d: read failed", c->self);
141 switch (c->istate) { 111 switch (c->istate) {
142 case CHAN_INPUT_OPEN: 112 case CHAN_INPUT_OPEN:
143 chan_shutdown_read(c); 113 chan_shutdown_read(ssh, c);
144 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 114 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
145 break; 115 break;
146 default: 116 default:
@@ -149,25 +119,21 @@ chan_read_failed(Channel *c)
149 break; 119 break;
150 } 120 }
151} 121}
122
152void 123void
153chan_ibuf_empty(Channel *c) 124chan_ibuf_empty(struct ssh *ssh, Channel *c)
154{ 125{
155 debug2("channel %d: ibuf empty", c->self); 126 debug2("channel %d: ibuf empty", c->self);
156 if (buffer_len(&c->input)) { 127 if (sshbuf_len(c->input)) {
157 error("channel %d: chan_ibuf_empty for non empty buffer", 128 error("channel %d: chan_ibuf_empty for non empty buffer",
158 c->self); 129 c->self);
159 return; 130 return;
160 } 131 }
161 switch (c->istate) { 132 switch (c->istate) {
162 case CHAN_INPUT_WAIT_DRAIN: 133 case CHAN_INPUT_WAIT_DRAIN:
163 if (compat20) { 134 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
164 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 135 chan_send_eof2(ssh, c);
165 chan_send_eof2(c); 136 chan_set_istate(c, CHAN_INPUT_CLOSED);
166 chan_set_istate(c, CHAN_INPUT_CLOSED);
167 } else {
168 chan_send_ieof1(c);
169 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
170 }
171 break; 137 break;
172 default: 138 default:
173 error("channel %d: chan_ibuf_empty for istate %d", 139 error("channel %d: chan_ibuf_empty for istate %d",
@@ -175,58 +141,19 @@ chan_ibuf_empty(Channel *c)
175 break; 141 break;
176 } 142 }
177} 143}
178static void 144
179chan_rcvd_ieof1(Channel *c)
180{
181 debug2("channel %d: rcvd ieof", c->self);
182 switch (c->ostate) {
183 case CHAN_OUTPUT_OPEN:
184 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
185 break;
186 case CHAN_OUTPUT_WAIT_IEOF:
187 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
188 break;
189 default:
190 error("channel %d: protocol error: rcvd_ieof for ostate %d",
191 c->self, c->ostate);
192 break;
193 }
194}
195static void
196chan_write_failed1(Channel *c)
197{
198 debug2("channel %d: write failed", c->self);
199 switch (c->ostate) {
200 case CHAN_OUTPUT_OPEN:
201 chan_shutdown_write(c);
202 chan_send_oclose1(c);
203 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
204 break;
205 case CHAN_OUTPUT_WAIT_DRAIN:
206 chan_shutdown_write(c);
207 chan_send_oclose1(c);
208 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
209 break;
210 default:
211 error("channel %d: chan_write_failed for ostate %d",
212 c->self, c->ostate);
213 break;
214 }
215}
216void 145void
217chan_obuf_empty(Channel *c) 146chan_obuf_empty(struct ssh *ssh, Channel *c)
218{ 147{
219 debug2("channel %d: obuf empty", c->self); 148 debug2("channel %d: obuf empty", c->self);
220 if (buffer_len(&c->output)) { 149 if (sshbuf_len(c->output)) {
221 error("channel %d: chan_obuf_empty for non empty buffer", 150 error("channel %d: chan_obuf_empty for non empty buffer",
222 c->self); 151 c->self);
223 return; 152 return;
224 } 153 }
225 switch (c->ostate) { 154 switch (c->ostate) {
226 case CHAN_OUTPUT_WAIT_DRAIN: 155 case CHAN_OUTPUT_WAIT_DRAIN:
227 chan_shutdown_write(c); 156 chan_shutdown_write(ssh, c);
228 if (!compat20)
229 chan_send_oclose1(c);
230 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 157 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
231 break; 158 break;
232 default: 159 default:
@@ -235,47 +162,107 @@ chan_obuf_empty(Channel *c)
235 break; 162 break;
236 } 163 }
237} 164}
238static void 165
239chan_send_ieof1(Channel *c) 166void
167chan_rcvd_eow(struct ssh *ssh, Channel *c)
240{ 168{
241 debug2("channel %d: send ieof", c->self); 169 debug2("channel %d: rcvd eow", c->self);
242 switch (c->istate) { 170 switch (c->istate) {
243 case CHAN_INPUT_OPEN: 171 case CHAN_INPUT_OPEN:
172 chan_shutdown_read(ssh, c);
173 chan_set_istate(c, CHAN_INPUT_CLOSED);
174 break;
175 }
176}
177
178static void
179chan_send_eof2(struct ssh *ssh, Channel *c)
180{
181 int r;
182
183 debug2("channel %d: send eof", c->self);
184 switch (c->istate) {
244 case CHAN_INPUT_WAIT_DRAIN: 185 case CHAN_INPUT_WAIT_DRAIN:
245 packet_start(SSH_MSG_CHANNEL_INPUT_EOF); 186 if (!c->have_remote_id)
246 packet_put_int(c->remote_id); 187 fatal("%s: channel %d: no remote_id",
247 packet_send(); 188 __func__, c->self);
189 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
190 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
191 (r = sshpkt_send(ssh)) != 0)
192 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
193 c->flags |= CHAN_EOF_SENT;
248 break; 194 break;
249 default: 195 default:
250 error("channel %d: cannot send ieof for istate %d", 196 error("channel %d: cannot send eof for istate %d",
251 c->self, c->istate); 197 c->self, c->istate);
252 break; 198 break;
253 } 199 }
254} 200}
201
255static void 202static void
256chan_send_oclose1(Channel *c) 203chan_send_close2(struct ssh *ssh, Channel *c)
257{ 204{
258 debug2("channel %d: send oclose", c->self); 205 int r;
259 switch (c->ostate) { 206
260 case CHAN_OUTPUT_OPEN: 207 debug2("channel %d: send close", c->self);
261 case CHAN_OUTPUT_WAIT_DRAIN: 208 if (c->ostate != CHAN_OUTPUT_CLOSED ||
262 buffer_clear(&c->output); 209 c->istate != CHAN_INPUT_CLOSED) {
263 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); 210 error("channel %d: cannot send close for istate/ostate %d/%d",
264 packet_put_int(c->remote_id); 211 c->self, c->istate, c->ostate);
265 packet_send(); 212 } else if (c->flags & CHAN_CLOSE_SENT) {
266 break; 213 error("channel %d: already sent close", c->self);
267 default: 214 } else {
268 error("channel %d: cannot send oclose for ostate %d", 215 if (!c->have_remote_id)
269 c->self, c->ostate); 216 fatal("%s: channel %d: no remote_id",
270 break; 217 __func__, c->self);
218 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
219 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
220 (r = sshpkt_send(ssh)) != 0)
221 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
222 c->flags |= CHAN_CLOSE_SENT;
271 } 223 }
272} 224}
273 225
274/*
275 * the same for SSH2
276 */
277static void 226static void
278chan_rcvd_close2(Channel *c) 227chan_send_eow2(struct ssh *ssh, Channel *c)
228{
229 int r;
230
231 debug2("channel %d: send eow", c->self);
232 if (c->ostate == CHAN_OUTPUT_CLOSED) {
233 error("channel %d: must not sent eow on closed output",
234 c->self);
235 return;
236 }
237 if (!(datafellows & SSH_NEW_OPENSSH))
238 return;
239 if (!c->have_remote_id)
240 fatal("%s: channel %d: no remote_id", __func__, c->self);
241 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
242 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
243 (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
244 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
245 (r = sshpkt_send(ssh)) != 0)
246 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
247}
248
249/* shared */
250
251void
252chan_rcvd_ieof(struct ssh *ssh, Channel *c)
253{
254 debug2("channel %d: rcvd eof", c->self);
255 c->flags |= CHAN_EOF_RCVD;
256 if (c->ostate == CHAN_OUTPUT_OPEN)
257 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
258 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
259 sshbuf_len(c->output) == 0 &&
260 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
261 chan_obuf_empty(ssh, c);
262}
263
264void
265chan_rcvd_oclose(struct ssh *ssh, Channel *c)
279{ 266{
280 debug2("channel %d: rcvd close", c->self); 267 debug2("channel %d: rcvd close", c->self);
281 if (!(c->flags & CHAN_LOCAL)) { 268 if (!(c->flags & CHAN_LOCAL)) {
@@ -301,46 +288,27 @@ chan_rcvd_close2(Channel *c)
301 } 288 }
302 switch (c->istate) { 289 switch (c->istate) {
303 case CHAN_INPUT_OPEN: 290 case CHAN_INPUT_OPEN:
304 chan_shutdown_read(c); 291 chan_shutdown_read(ssh, c);
305 chan_set_istate(c, CHAN_INPUT_CLOSED); 292 chan_set_istate(c, CHAN_INPUT_CLOSED);
306 break; 293 break;
307 case CHAN_INPUT_WAIT_DRAIN: 294 case CHAN_INPUT_WAIT_DRAIN:
308 if (!(c->flags & CHAN_LOCAL)) 295 if (!(c->flags & CHAN_LOCAL))
309 chan_send_eof2(c); 296 chan_send_eof2(ssh, c);
310 chan_set_istate(c, CHAN_INPUT_CLOSED); 297 chan_set_istate(c, CHAN_INPUT_CLOSED);
311 break; 298 break;
312 } 299 }
313} 300}
314 301
315void 302void
316chan_rcvd_eow(Channel *c) 303chan_write_failed(struct ssh *ssh, Channel *c)
317{
318 debug2("channel %d: rcvd eow", c->self);
319 switch (c->istate) {
320 case CHAN_INPUT_OPEN:
321 chan_shutdown_read(c);
322 chan_set_istate(c, CHAN_INPUT_CLOSED);
323 break;
324 }
325}
326static void
327chan_rcvd_eof2(Channel *c)
328{
329 debug2("channel %d: rcvd eof", c->self);
330 c->flags |= CHAN_EOF_RCVD;
331 if (c->ostate == CHAN_OUTPUT_OPEN)
332 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
333}
334static void
335chan_write_failed2(Channel *c)
336{ 304{
337 debug2("channel %d: write failed", c->self); 305 debug2("channel %d: write failed", c->self);
338 switch (c->ostate) { 306 switch (c->ostate) {
339 case CHAN_OUTPUT_OPEN: 307 case CHAN_OUTPUT_OPEN:
340 case CHAN_OUTPUT_WAIT_DRAIN: 308 case CHAN_OUTPUT_WAIT_DRAIN:
341 chan_shutdown_write(c); 309 chan_shutdown_write(ssh, c);
342 if (strcmp(c->ctype, "session") == 0) 310 if (strcmp(c->ctype, "session") == 0)
343 chan_send_eow2(c); 311 chan_send_eow2(ssh, c);
344 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 312 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
345 break; 313 break;
346 default: 314 default:
@@ -349,97 +317,15 @@ chan_write_failed2(Channel *c)
349 break; 317 break;
350 } 318 }
351} 319}
352static void
353chan_send_eof2(Channel *c)
354{
355 debug2("channel %d: send eof", c->self);
356 switch (c->istate) {
357 case CHAN_INPUT_WAIT_DRAIN:
358 packet_start(SSH2_MSG_CHANNEL_EOF);
359 packet_put_int(c->remote_id);
360 packet_send();
361 c->flags |= CHAN_EOF_SENT;
362 break;
363 default:
364 error("channel %d: cannot send eof for istate %d",
365 c->self, c->istate);
366 break;
367 }
368}
369static void
370chan_send_close2(Channel *c)
371{
372 debug2("channel %d: send close", c->self);
373 if (c->ostate != CHAN_OUTPUT_CLOSED ||
374 c->istate != CHAN_INPUT_CLOSED) {
375 error("channel %d: cannot send close for istate/ostate %d/%d",
376 c->self, c->istate, c->ostate);
377 } else if (c->flags & CHAN_CLOSE_SENT) {
378 error("channel %d: already sent close", c->self);
379 } else {
380 packet_start(SSH2_MSG_CHANNEL_CLOSE);
381 packet_put_int(c->remote_id);
382 packet_send();
383 c->flags |= CHAN_CLOSE_SENT;
384 }
385}
386static void
387chan_send_eow2(Channel *c)
388{
389 debug2("channel %d: send eow", c->self);
390 if (c->ostate == CHAN_OUTPUT_CLOSED) {
391 error("channel %d: must not sent eow on closed output",
392 c->self);
393 return;
394 }
395 if (!(datafellows & SSH_NEW_OPENSSH))
396 return;
397 packet_start(SSH2_MSG_CHANNEL_REQUEST);
398 packet_put_int(c->remote_id);
399 packet_put_cstring("eow@openssh.com");
400 packet_put_char(0);
401 packet_send();
402}
403
404/* shared */
405 320
406void 321void
407chan_rcvd_ieof(Channel *c) 322chan_mark_dead(struct ssh *ssh, Channel *c)
408{
409 if (compat20)
410 chan_rcvd_eof2(c);
411 else
412 chan_rcvd_ieof1(c);
413 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
414 buffer_len(&c->output) == 0 &&
415 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
416 chan_obuf_empty(c);
417}
418void
419chan_rcvd_oclose(Channel *c)
420{
421 if (compat20)
422 chan_rcvd_close2(c);
423 else
424 chan_rcvd_oclose1(c);
425}
426void
427chan_write_failed(Channel *c)
428{
429 if (compat20)
430 chan_write_failed2(c);
431 else
432 chan_write_failed1(c);
433}
434
435void
436chan_mark_dead(Channel *c)
437{ 323{
438 c->type = SSH_CHANNEL_ZOMBIE; 324 c->type = SSH_CHANNEL_ZOMBIE;
439} 325}
440 326
441int 327int
442chan_is_dead(Channel *c, int do_send) 328chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
443{ 329{
444 if (c->type == SSH_CHANNEL_ZOMBIE) { 330 if (c->type == SSH_CHANNEL_ZOMBIE) {
445 debug2("channel %d: zombie", c->self); 331 debug2("channel %d: zombie", c->self);
@@ -447,16 +333,12 @@ chan_is_dead(Channel *c, int do_send)
447 } 333 }
448 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 334 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
449 return 0; 335 return 0;
450 if (!compat20) {
451 debug2("channel %d: is dead", c->self);
452 return 1;
453 }
454 if ((datafellows & SSH_BUG_EXTEOF) && 336 if ((datafellows & SSH_BUG_EXTEOF) &&
455 c->extended_usage == CHAN_EXTENDED_WRITE && 337 c->extended_usage == CHAN_EXTENDED_WRITE &&
456 c->efd != -1 && 338 c->efd != -1 &&
457 buffer_len(&c->extended) > 0) { 339 sshbuf_len(c->extended) > 0) {
458 debug2("channel %d: active efd: %d len %d", 340 debug2("channel %d: active efd: %d len %zu",
459 c->self, c->efd, buffer_len(&c->extended)); 341 c->self, c->efd, sshbuf_len(c->extended));
460 return 0; 342 return 0;
461 } 343 }
462 if (c->flags & CHAN_LOCAL) { 344 if (c->flags & CHAN_LOCAL) {
@@ -465,7 +347,7 @@ chan_is_dead(Channel *c, int do_send)
465 } 347 }
466 if (!(c->flags & CHAN_CLOSE_SENT)) { 348 if (!(c->flags & CHAN_CLOSE_SENT)) {
467 if (do_send) { 349 if (do_send) {
468 chan_send_close2(c); 350 chan_send_close2(ssh, c);
469 } else { 351 } else {
470 /* channel would be dead if we sent a close */ 352 /* channel would be dead if we sent a close */
471 if (c->flags & CHAN_CLOSE_RCVD) { 353 if (c->flags & CHAN_CLOSE_RCVD) {
@@ -485,10 +367,10 @@ chan_is_dead(Channel *c, int do_send)
485 367
486/* helper */ 368/* helper */
487static void 369static void
488chan_shutdown_write(Channel *c) 370chan_shutdown_write(struct ssh *ssh, Channel *c)
489{ 371{
490 buffer_clear(&c->output); 372 sshbuf_reset(c->output);
491 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 373 if (c->type == SSH_CHANNEL_LARVAL)
492 return; 374 return;
493 /* shutdown failure is allowed if write failed already */ 375 /* shutdown failure is allowed if write failed already */
494 debug2("channel %d: close_write", c->self); 376 debug2("channel %d: close_write", c->self);
@@ -498,16 +380,17 @@ chan_shutdown_write(Channel *c)
498 "shutdown() failed for fd %d: %.100s", 380 "shutdown() failed for fd %d: %.100s",
499 c->self, c->sock, strerror(errno)); 381 c->self, c->sock, strerror(errno));
500 } else { 382 } else {
501 if (channel_close_fd(&c->wfd) < 0) 383 if (channel_close_fd(ssh, &c->wfd) < 0)
502 logit("channel %d: chan_shutdown_write: " 384 logit("channel %d: chan_shutdown_write: "
503 "close() failed for fd %d: %.100s", 385 "close() failed for fd %d: %.100s",
504 c->self, c->wfd, strerror(errno)); 386 c->self, c->wfd, strerror(errno));
505 } 387 }
506} 388}
389
507static void 390static void
508chan_shutdown_read(Channel *c) 391chan_shutdown_read(struct ssh *ssh, Channel *c)
509{ 392{
510 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 393 if (c->type == SSH_CHANNEL_LARVAL)
511 return; 394 return;
512 debug2("channel %d: close_read", c->self); 395 debug2("channel %d: close_read", c->self);
513 if (c->sock != -1) { 396 if (c->sock != -1) {
@@ -523,7 +406,7 @@ chan_shutdown_read(Channel *c)
523 c->self, c->sock, c->istate, c->ostate, 406 c->self, c->sock, c->istate, c->ostate,
524 strerror(errno)); 407 strerror(errno));
525 } else { 408 } else {
526 if (channel_close_fd(&c->rfd) < 0) 409 if (channel_close_fd(ssh, &c->rfd) < 0)
527 logit("channel %d: chan_shutdown_read: " 410 logit("channel %d: chan_shutdown_read: "
528 "close() failed for fd %d: %.100s", 411 "close() failed for fd %d: %.100s",
529 c->self, c->rfd, strerror(errno)); 412 c->self, c->rfd, strerror(errno));