20001206
 - (bal) OpenSSH CVS updates:
   - markus@cvs.openbsd.org 2000/12/05 20:34:09
     [channels.c channels.h clientloop.c serverloop.c]
     async connects for -R/-L; ok deraadt@
   - todd@cvs.openssh.org 2000/12/05 16:47:28
     [sshd.c]
     tweak comment to reflect real location of pid file; ok provos@
diff --git a/ChangeLog b/ChangeLog
index 77f2287..6d55313 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+20001206
+ - (bal) OpenSSH CVS updates:
+   - markus@cvs.openbsd.org 2000/12/05 20:34:09
+     [channels.c channels.h clientloop.c serverloop.c]
+     async connects for -R/-L; ok deraadt@
+   - todd@cvs.openssh.org 2000/12/05 16:47:28
+     [sshd.c]
+     tweak comment to reflect real location of pid file; ok provos@
+
 20001205
  - (bal) OpenSSH CVS updates:
    - markus@cvs.openbsd.org 2000/12/04 19:24:02
@@ -16,7 +25,8 @@
      remove fallback to SSH_BUG_HMAC now that the drafts are updated
    - markus@cvs.openbsd.org 2000/12/03 11:27:55
      [compat.c]
-     correctly match "2.1.0.pl2 SSH" etc; from pekkas@netcore.fi/bugzilla.redhat
+     correctly match "2.1.0.pl2 SSH" etc; from 
+     pekkas@netcore.fi/bugzilla.redhat
    - markus@cvs.openbsd.org 2000/12/03 11:15:03
      [auth2.c compat.c compat.h sshconnect2.c]
      support f-secure/ssh.com 2.0.12; ok niels@
diff --git a/channels.c b/channels.c
index 91a1b50..49023a2 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.74 2000/11/30 22:54:31 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.75 2000/12/05 20:34:09 markus Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -346,6 +346,13 @@
 }
 
 void
+channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset)
+{
+	debug3("channel %d: waiting for connection", c->self);
+	FD_SET(c->sock, writeset);
+}
+
+void
 channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
 {
 	if (buffer_len(&c->input) < packet_get_maxsize())
@@ -685,6 +692,28 @@
 	}
 }
 
+void
+channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
+{
+	if (FD_ISSET(c->sock, writeset)) {
+		int err = 0;
+		int sz = sizeof(err);
+		c->type = SSH_CHANNEL_OPEN;
+                if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &sz) < 0) {
+			debug("getsockopt SO_ERROR failed");
+		} else {
+			if (err == 0) {
+				debug("channel %d: connected)", c->self);
+			} else {
+				debug("channel %d: not connected: %s",
+				    c->self, strerror(err));
+				chan_read_failed(c);
+				chan_write_failed(c);
+			}
+		}
+	}
+}
+
 int
 channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
 {
@@ -843,12 +872,14 @@
 	channel_pre[SSH_CHANNEL_RPORT_LISTENER] =	&channel_pre_listener;
 	channel_pre[SSH_CHANNEL_X11_LISTENER] =		&channel_pre_listener;
 	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
+	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
 
 	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open_2;
 	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
 	channel_post[SSH_CHANNEL_RPORT_LISTENER] =	&channel_post_port_listener;
 	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
 	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
+	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
 }
 
 void
@@ -861,12 +892,14 @@
 	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
 	channel_pre[SSH_CHANNEL_INPUT_DRAINING] =	&channel_pre_input_draining;
 	channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_pre_output_draining;
+	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
 
 	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open_1;
 	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
 	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
 	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
 	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain_13;
+	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
 }
 
 void
@@ -877,11 +910,13 @@
 	channel_pre[SSH_CHANNEL_X11_LISTENER] =		&channel_pre_listener;
 	channel_pre[SSH_CHANNEL_PORT_LISTENER] =	&channel_pre_listener;
 	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
+	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
 
 	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
 	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
 	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
 	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open_1;
+	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
 }
 
 void
@@ -1397,6 +1432,7 @@
 		case SSH_CHANNEL_RPORT_LISTENER:
 		case SSH_CHANNEL_CLOSED:
 		case SSH_CHANNEL_AUTH_SOCKET:
+		case SSH_CHANNEL_CONNECTING: 	/* XXX ??? */
 			continue;
 		case SSH_CHANNEL_LARVAL:
 			if (!compat20)
@@ -1446,6 +1482,7 @@
 			continue;
 		case SSH_CHANNEL_LARVAL:
 		case SSH_CHANNEL_OPENING:
+		case SSH_CHANNEL_CONNECTING:
 		case SSH_CHANNEL_OPEN:
 		case SSH_CHANNEL_X11_OPEN:
 		case SSH_CHANNEL_INPUT_DRAINING:
@@ -1702,8 +1739,11 @@
 			error("socket: %.100s", strerror(errno));
 			continue;
 		}
+		if (fcntl(sock, F_SETFL, O_NDELAY) < 0)
+			fatal("connect_to: F_SETFL: %s", strerror(errno));
 		/* Connect to the host/port. */
-		if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+		if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 &&
+		    errno != EINPROGRESS) {
 			error("connect %.100s port %s: %.100s", ntop, strport,
 			    strerror(errno));
 			close(sock);
@@ -1789,7 +1829,9 @@
 	sock = denied ? -1 : channel_connect_to(host, host_port);
 	if (sock > 0) {
 		/* Allocate a channel for this connection. */
-		newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
+		newch = channel_allocate(SSH_CHANNEL_CONNECTING,
+		    sock, originator_string);
+/*XXX delay answer? */
 		channels[newch].remote_id = remote_channel;
 
 		packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
diff --git a/channels.h b/channels.h
index 8f5e987..45b783f 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$OpenBSD: channels.h,v 1.23 2000/11/06 23:04:56 markus Exp $"); */
+/* RCSID("$OpenBSD: channels.h,v 1.24 2000/12/05 20:34:10 markus Exp $"); */
 
 #ifndef CHANNELS_H
 #define CHANNELS_H
@@ -50,7 +50,8 @@
 #define SSH_CHANNEL_OUTPUT_DRAINING	9	/* sending remaining data to app */
 #define SSH_CHANNEL_LARVAL		10	/* larval session */
 #define SSH_CHANNEL_RPORT_LISTENER	11	/* Listening to a R-style port  */
-#define SSH_CHANNEL_MAX_TYPE		12
+#define SSH_CHANNEL_CONNECTING		12
+#define SSH_CHANNEL_MAX_TYPE		13
 
 /*
  * Data structure for channel data.  This is iniailized in channel_allocate
diff --git a/clientloop.c b/clientloop.c
index 8f16d2f..3a0f977 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.40 2000/11/06 23:04:56 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.41 2000/12/05 20:34:10 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -1041,7 +1041,7 @@
 	sock = channel_connect_by_listen_adress(listen_port);
 	if (sock >= 0) {
 		newch = channel_new("forwarded-tcpip",
-		    SSH_CHANNEL_OPEN, sock, sock, -1,
+		    SSH_CHANNEL_CONNECTING, sock, sock, -1,
 		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
 		    xstrdup(originator_address), 1);
 		c = channel_lookup(newch);
diff --git a/serverloop.c b/serverloop.c
index d1816b5..79ef360 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.35 2000/11/06 23:04:56 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.36 2000/12/05 20:34:10 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -750,7 +750,7 @@
 	xfree(originator);
 	if (sock < 0)
 		return NULL;
-	newch = channel_new(ctype, SSH_CHANNEL_OPEN,
+	newch = channel_new(ctype, SSH_CHANNEL_CONNECTING,
 	    sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
 	    CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
 	return (newch >= 0) ? channel_lookup(newch) : NULL;
diff --git a/sshd.c b/sshd.c
index 4a01ebe..4bd0cbe 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.135 2000/11/29 21:11:59 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.136 2000/12/05 16:47:28 todd Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -881,9 +881,9 @@
 
 		if (!debug_flag) {
 			/*
-			 * Record our pid in /etc/sshd_pid to make it easier
-			 * to kill the correct sshd.  We don\'t want to do
-			 * this before the bind above because the bind will
+			 * Record our pid in /var/run/sshd.pid to make it
+			 * easier to kill the correct sshd.  We don't want to
+			 * do this before the bind above because the bind will
 			 * fail if there already is a daemon, and this will
 			 * overwrite any old pid in the file.
 			 */