summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-05-21 14:57:10 +1000
committerDamien Miller <djm@mindrot.org>2010-05-21 14:57:10 +1000
commitd530f5f471491b6be9edb58a063f2590e4dce48d (patch)
treee536e2b4031a4dd70026ff49c39b02b72af06f30 /channels.c
parentc6afb5f2c095a6a4380cc13a6480abb7614d949f (diff)
- djm@cvs.openbsd.org 2010/05/14 23:29:23
[channels.c channels.h mux.c ssh.c] Pause the mux channel while waiting for reply from aynch callbacks. Prevents misordering of replies if new requests arrive while waiting. Extend channel open confirm callback to allow signalling failure conditions as well as success. Use this to 1) fix a memory leak, 2) start using the above pause mechanism and 3) delay sending a success/ failure message on mux slave session open until we receive a reply from the server. motivated by and with feedback from markus@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/channels.c b/channels.c
index a55d27817..0f750c4d4 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.303 2010/01/30 21:12:08 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.304 2010/05/14 23:29:23 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -330,6 +330,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
330 c->ctl_chan = -1; 330 c->ctl_chan = -1;
331 c->mux_rcb = NULL; 331 c->mux_rcb = NULL;
332 c->mux_ctx = NULL; 332 c->mux_ctx = NULL;
333 c->mux_pause = 0;
333 c->delayed = 1; /* prevent call to channel_post handler */ 334 c->delayed = 1; /* prevent call to channel_post handler */
334 TAILQ_INIT(&c->status_confirms); 335 TAILQ_INIT(&c->status_confirms);
335 debug("channel %d: new [%s]", found, remote_name); 336 debug("channel %d: new [%s]", found, remote_name);
@@ -703,7 +704,7 @@ channel_register_status_confirm(int id, channel_confirm_cb *cb,
703} 704}
704 705
705void 706void
706channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx) 707channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx)
707{ 708{
708 Channel *c = channel_lookup(id); 709 Channel *c = channel_lookup(id);
709 710
@@ -991,7 +992,7 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
991static void 992static void
992channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) 993channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
993{ 994{
994 if (c->istate == CHAN_INPUT_OPEN && 995 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
995 buffer_check_alloc(&c->input, CHAN_RBUF)) 996 buffer_check_alloc(&c->input, CHAN_RBUF))
996 FD_SET(c->rfd, readset); 997 FD_SET(c->rfd, readset);
997 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { 998 if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
@@ -1840,7 +1841,7 @@ channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
1840 if (!compat20) 1841 if (!compat20)
1841 fatal("%s: entered with !compat20", __func__); 1842 fatal("%s: entered with !compat20", __func__);
1842 1843
1843 if (c->rfd != -1 && FD_ISSET(c->rfd, readset) && 1844 if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&
1844 (c->istate == CHAN_INPUT_OPEN || 1845 (c->istate == CHAN_INPUT_OPEN ||
1845 c->istate == CHAN_INPUT_WAIT_DRAIN)) { 1846 c->istate == CHAN_INPUT_WAIT_DRAIN)) {
1846 /* 1847 /*
@@ -2463,7 +2464,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2463 c->remote_maxpacket = packet_get_int(); 2464 c->remote_maxpacket = packet_get_int();
2464 if (c->open_confirm) { 2465 if (c->open_confirm) {
2465 debug2("callback start"); 2466 debug2("callback start");
2466 c->open_confirm(c->self, c->open_confirm_ctx); 2467 c->open_confirm(c->self, 1, c->open_confirm_ctx);
2467 debug2("callback done"); 2468 debug2("callback done");
2468 } 2469 }
2469 debug2("channel %d: open confirm rwindow %u rmax %u", c->self, 2470 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
@@ -2514,6 +2515,11 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2514 xfree(msg); 2515 xfree(msg);
2515 if (lang != NULL) 2516 if (lang != NULL)
2516 xfree(lang); 2517 xfree(lang);
2518 if (c->open_confirm) {
2519 debug2("callback start");
2520 c->open_confirm(c->self, 0, c->open_confirm_ctx);
2521 debug2("callback done");
2522 }
2517 } 2523 }
2518 packet_check_eom(); 2524 packet_check_eom();
2519 /* Schedule the channel for cleanup/deletion. */ 2525 /* Schedule the channel for cleanup/deletion. */