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/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);