summaryrefslogtreecommitdiff
path: root/nchan.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-04-30 23:13:25 +0000
committerDamien Miller <djm@mindrot.org>2017-05-01 09:42:37 +1000
commit97f4d3083b036ce3e68d6346a6140a22123d5864 (patch)
tree301c95453934721eca9855cd01b1d0da089e3246 /nchan.c
parent99f95ba82673d33215dce17bfa1512b57f54ec09 (diff)
upstream commit
remove compat20/compat13/compat15 variables ok markus@ Upstream-ID: 43802c035ceb3fef6c50c400e4ecabf12354691c
Diffstat (limited to 'nchan.c')
-rw-r--r--nchan.c266
1 files changed, 66 insertions, 200 deletions
diff --git a/nchan.c b/nchan.c
index 20f6a2f49..312c0b1e6 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.64 2017/04/30 23:13:25 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 *
@@ -74,9 +74,6 @@
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 *);
78static void chan_send_oclose1(Channel *);
79static void chan_send_close2(Channel *);
80static void chan_send_eof2(Channel *); 77static void chan_send_eof2(Channel *);
81static void chan_send_eow2(Channel *); 78static void chan_send_eow2(Channel *);
82 79
@@ -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,34 +104,6 @@ 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(Channel *c)
139{ 109{
@@ -149,6 +119,7 @@ chan_read_failed(Channel *c)
149 break; 119 break;
150 } 120 }
151} 121}
122
152void 123void
153chan_ibuf_empty(Channel *c) 124chan_ibuf_empty(Channel *c)
154{ 125{
@@ -160,14 +131,9 @@ chan_ibuf_empty(Channel *c)
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(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,44 +141,7 @@ 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(Channel *c)
218{ 147{
@@ -225,8 +154,6 @@ chan_obuf_empty(Channel *c)
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(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,82 +162,6 @@ chan_obuf_empty(Channel *c)
235 break; 162 break;
236 } 163 }
237} 164}
238static void
239chan_send_ieof1(Channel *c)
240{
241 debug2("channel %d: send ieof", c->self);
242 switch (c->istate) {
243 case CHAN_INPUT_OPEN:
244 case CHAN_INPUT_WAIT_DRAIN:
245 packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
246 packet_put_int(c->remote_id);
247 packet_send();
248 break;
249 default:
250 error("channel %d: cannot send ieof for istate %d",
251 c->self, c->istate);
252 break;
253 }
254}
255static void
256chan_send_oclose1(Channel *c)
257{
258 debug2("channel %d: send oclose", c->self);
259 switch (c->ostate) {
260 case CHAN_OUTPUT_OPEN:
261 case CHAN_OUTPUT_WAIT_DRAIN:
262 buffer_clear(&c->output);
263 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
264 packet_put_int(c->remote_id);
265 packet_send();
266 break;
267 default:
268 error("channel %d: cannot send oclose for ostate %d",
269 c->self, c->ostate);
270 break;
271 }
272}
273
274/*
275 * the same for SSH2
276 */
277static void
278chan_rcvd_close2(Channel *c)
279{
280 debug2("channel %d: rcvd close", c->self);
281 if (!(c->flags & CHAN_LOCAL)) {
282 if (c->flags & CHAN_CLOSE_RCVD)
283 error("channel %d: protocol error: close rcvd twice",
284 c->self);
285 c->flags |= CHAN_CLOSE_RCVD;
286 }
287 if (c->type == SSH_CHANNEL_LARVAL) {
288 /* tear down larval channels immediately */
289 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
290 chan_set_istate(c, CHAN_INPUT_CLOSED);
291 return;
292 }
293 switch (c->ostate) {
294 case CHAN_OUTPUT_OPEN:
295 /*
296 * wait until a data from the channel is consumed if a CLOSE
297 * is received
298 */
299 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
300 break;
301 }
302 switch (c->istate) {
303 case CHAN_INPUT_OPEN:
304 chan_shutdown_read(c);
305 chan_set_istate(c, CHAN_INPUT_CLOSED);
306 break;
307 case CHAN_INPUT_WAIT_DRAIN:
308 if (!(c->flags & CHAN_LOCAL))
309 chan_send_eof2(c);
310 chan_set_istate(c, CHAN_INPUT_CLOSED);
311 break;
312 }
313}
314 165
315void 166void
316chan_rcvd_eow(Channel *c) 167chan_rcvd_eow(Channel *c)
@@ -323,32 +174,7 @@ chan_rcvd_eow(Channel *c)
323 break; 174 break;
324 } 175 }
325} 176}
326static void 177
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{
337 debug2("channel %d: write failed", c->self);
338 switch (c->ostate) {
339 case CHAN_OUTPUT_OPEN:
340 case CHAN_OUTPUT_WAIT_DRAIN:
341 chan_shutdown_write(c);
342 if (strcmp(c->ctype, "session") == 0)
343 chan_send_eow2(c);
344 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
345 break;
346 default:
347 error("channel %d: chan_write_failed for ostate %d",
348 c->self, c->ostate);
349 break;
350 }
351}
352static void 178static void
353chan_send_eof2(Channel *c) 179chan_send_eof2(Channel *c)
354{ 180{
@@ -366,6 +192,7 @@ chan_send_eof2(Channel *c)
366 break; 192 break;
367 } 193 }
368} 194}
195
369static void 196static void
370chan_send_close2(Channel *c) 197chan_send_close2(Channel *c)
371{ 198{
@@ -383,6 +210,7 @@ chan_send_close2(Channel *c)
383 c->flags |= CHAN_CLOSE_SENT; 210 c->flags |= CHAN_CLOSE_SENT;
384 } 211 }
385} 212}
213
386static void 214static void
387chan_send_eow2(Channel *c) 215chan_send_eow2(Channel *c)
388{ 216{
@@ -406,30 +234,71 @@ chan_send_eow2(Channel *c)
406void 234void
407chan_rcvd_ieof(Channel *c) 235chan_rcvd_ieof(Channel *c)
408{ 236{
409 if (compat20) 237 debug2("channel %d: rcvd eof", c->self);
410 chan_rcvd_eof2(c); 238 c->flags |= CHAN_EOF_RCVD;
411 else 239 if (c->ostate == CHAN_OUTPUT_OPEN)
412 chan_rcvd_ieof1(c); 240 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
413 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 241 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
414 buffer_len(&c->output) == 0 && 242 buffer_len(&c->output) == 0 &&
415 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 243 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
416 chan_obuf_empty(c); 244 chan_obuf_empty(c);
417} 245}
246
418void 247void
419chan_rcvd_oclose(Channel *c) 248chan_rcvd_oclose(Channel *c)
420{ 249{
421 if (compat20) 250 debug2("channel %d: rcvd close", c->self);
422 chan_rcvd_close2(c); 251 if (!(c->flags & CHAN_LOCAL)) {
423 else 252 if (c->flags & CHAN_CLOSE_RCVD)
424 chan_rcvd_oclose1(c); 253 error("channel %d: protocol error: close rcvd twice",
254 c->self);
255 c->flags |= CHAN_CLOSE_RCVD;
256 }
257 if (c->type == SSH_CHANNEL_LARVAL) {
258 /* tear down larval channels immediately */
259 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
260 chan_set_istate(c, CHAN_INPUT_CLOSED);
261 return;
262 }
263 switch (c->ostate) {
264 case CHAN_OUTPUT_OPEN:
265 /*
266 * wait until a data from the channel is consumed if a CLOSE
267 * is received
268 */
269 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
270 break;
271 }
272 switch (c->istate) {
273 case CHAN_INPUT_OPEN:
274 chan_shutdown_read(c);
275 chan_set_istate(c, CHAN_INPUT_CLOSED);
276 break;
277 case CHAN_INPUT_WAIT_DRAIN:
278 if (!(c->flags & CHAN_LOCAL))
279 chan_send_eof2(c);
280 chan_set_istate(c, CHAN_INPUT_CLOSED);
281 break;
282 }
425} 283}
284
426void 285void
427chan_write_failed(Channel *c) 286chan_write_failed(Channel *c)
428{ 287{
429 if (compat20) 288 debug2("channel %d: write failed", c->self);
430 chan_write_failed2(c); 289 switch (c->ostate) {
431 else 290 case CHAN_OUTPUT_OPEN:
432 chan_write_failed1(c); 291 case CHAN_OUTPUT_WAIT_DRAIN:
292 chan_shutdown_write(c);
293 if (strcmp(c->ctype, "session") == 0)
294 chan_send_eow2(c);
295 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
296 break;
297 default:
298 error("channel %d: chan_write_failed for ostate %d",
299 c->self, c->ostate);
300 break;
301 }
433} 302}
434 303
435void 304void
@@ -447,10 +316,6 @@ chan_is_dead(Channel *c, int do_send)
447 } 316 }
448 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 317 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
449 return 0; 318 return 0;
450 if (!compat20) {
451 debug2("channel %d: is dead", c->self);
452 return 1;
453 }
454 if ((datafellows & SSH_BUG_EXTEOF) && 319 if ((datafellows & SSH_BUG_EXTEOF) &&
455 c->extended_usage == CHAN_EXTENDED_WRITE && 320 c->extended_usage == CHAN_EXTENDED_WRITE &&
456 c->efd != -1 && 321 c->efd != -1 &&
@@ -488,7 +353,7 @@ static void
488chan_shutdown_write(Channel *c) 353chan_shutdown_write(Channel *c)
489{ 354{
490 buffer_clear(&c->output); 355 buffer_clear(&c->output);
491 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 356 if (c->type == SSH_CHANNEL_LARVAL)
492 return; 357 return;
493 /* shutdown failure is allowed if write failed already */ 358 /* shutdown failure is allowed if write failed already */
494 debug2("channel %d: close_write", c->self); 359 debug2("channel %d: close_write", c->self);
@@ -504,10 +369,11 @@ chan_shutdown_write(Channel *c)
504 c->self, c->wfd, strerror(errno)); 369 c->self, c->wfd, strerror(errno));
505 } 370 }
506} 371}
372
507static void 373static void
508chan_shutdown_read(Channel *c) 374chan_shutdown_read(Channel *c)
509{ 375{
510 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 376 if (c->type == SSH_CHANNEL_LARVAL)
511 return; 377 return;
512 debug2("channel %d: close_read", c->self); 378 debug2("channel %d: close_read", c->self);
513 if (c->sock != -1) { 379 if (c->sock != -1) {