Mercurial > dropbear
diff common-channel.c @ 70:b0316ce64e4b
Merging in the changes from 0.41-0.43 main Dropbear tree
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 16:41:58 +0000 |
parents | 20563735e8b5 |
children | d3eb1fa8484e |
line wrap: on
line diff
--- a/common-channel.c Thu Aug 12 15:41:36 2004 +0000 +++ b/common-channel.c Thu Aug 12 16:41:58 2004 +0000 @@ -172,6 +172,7 @@ struct Channel *channel; unsigned int i; + int ret; /* iterate through all the possible channels */ for (i = 0; i < ses.chansize; i++) { @@ -196,8 +197,15 @@ * see if it has errors */ if (channel->infd >= 0 && channel->infd != channel->outfd && FD_ISSET(channel->infd, readfd)) { - int ret; - ret = write(channel->infd, NULL, 0); + if (channel->initconn) { + /* Handling for "in progress" connection - this is needed + * to avoid spinning 100% CPU when we connect to a server + * which doesn't send anything (tcpfwding) */ + checkinitdone(channel); + continue; /* Important not to use the channel after + checkinitdone(), as it may be NULL */ + } + ret = write(channel->infd, NULL, 0); /* Fake write */ if (ret < 0 && errno != EINTR && errno != EAGAIN) { closeinfd(channel); } @@ -209,9 +217,8 @@ checkinitdone(channel); continue; /* Important not to use the channel after checkinitdone(), as it may be NULL */ - } else { - writechannel(channel); } + writechannel(channel); } /* now handle any of the channel-closing type stuff */ @@ -285,10 +292,14 @@ if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen) || val != 0) { + send_msg_channel_open_failure(channel->remotechan, + SSH_OPEN_CONNECT_FAILED, "", ""); close(channel->infd); deletechannel(channel); TRACE(("leave checkinitdone: fail")); } else { + send_msg_channel_open_confirmation(channel, channel->recvwindow, + channel->recvmaxpacket); channel->outfd = channel->infd; channel->initconn = 0; TRACE(("leave checkinitdone: success")); @@ -489,6 +500,7 @@ TRACE(("channel index is %d", channel->index)); buf_free(channel->writebuf); + channel->writebuf = NULL; /* close the FDs in case they haven't been done * yet (ie they were shutdown etc */ @@ -497,6 +509,7 @@ if (channel->errfd >= 0) { close(channel->errfd); } + channel->typedata = NULL; deletechannel(channel); @@ -587,6 +600,7 @@ TRACE(("leave send_msg_channel_data: read err %d", channel->index)); } buf_free(buf); + buf = NULL; return; } buf_incrlen(buf, len); @@ -601,6 +615,7 @@ buf_putstring(ses.writepayload, buf_getptr(buf, len), len); buf_free(buf); + buf = NULL; channel->transwindow -= len; @@ -764,6 +779,10 @@ if (channel->type->inithandler) { ret = channel->type->inithandler(channel); if (ret > 0) { + if (ret == SSH_OPEN_IN_PROGRESS) { + /* We'll send the confirmation later */ + goto cleanup; + } errtype = ret; deletechannel(channel); TRACE(("inithandler returned failure %d", ret));