*/
#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"
FD_SET(c->sock, readset);
}
+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)
{
}
}
+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)
{
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
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
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
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)
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:
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);
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);