diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/channels.c b/channels.c index 91a1b50c3..49023a278 100644 --- a/channels.c +++ b/channels.c | |||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: channels.c,v 1.74 2000/11/30 22:54:31 markus Exp $"); | 43 | RCSID("$OpenBSD: channels.c,v 1.75 2000/12/05 20:34:09 markus Exp $"); |
44 | 44 | ||
45 | #include "ssh.h" | 45 | #include "ssh.h" |
46 | #include "packet.h" | 46 | #include "packet.h" |
@@ -346,6 +346,13 @@ channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | void | 348 | void |
349 | channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset) | ||
350 | { | ||
351 | debug3("channel %d: waiting for connection", c->self); | ||
352 | FD_SET(c->sock, writeset); | ||
353 | } | ||
354 | |||
355 | void | ||
349 | channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) | 356 | channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) |
350 | { | 357 | { |
351 | if (buffer_len(&c->input) < packet_get_maxsize()) | 358 | if (buffer_len(&c->input) < packet_get_maxsize()) |
@@ -685,6 +692,28 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) | |||
685 | } | 692 | } |
686 | } | 693 | } |
687 | 694 | ||
695 | void | ||
696 | channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset) | ||
697 | { | ||
698 | if (FD_ISSET(c->sock, writeset)) { | ||
699 | int err = 0; | ||
700 | int sz = sizeof(err); | ||
701 | c->type = SSH_CHANNEL_OPEN; | ||
702 | if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &sz) < 0) { | ||
703 | debug("getsockopt SO_ERROR failed"); | ||
704 | } else { | ||
705 | if (err == 0) { | ||
706 | debug("channel %d: connected)", c->self); | ||
707 | } else { | ||
708 | debug("channel %d: not connected: %s", | ||
709 | c->self, strerror(err)); | ||
710 | chan_read_failed(c); | ||
711 | chan_write_failed(c); | ||
712 | } | ||
713 | } | ||
714 | } | ||
715 | } | ||
716 | |||
688 | int | 717 | int |
689 | channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) | 718 | channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) |
690 | { | 719 | { |
@@ -843,12 +872,14 @@ channel_handler_init_20(void) | |||
843 | channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; | 872 | channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; |
844 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; | 873 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; |
845 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; | 874 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
875 | channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; | ||
846 | 876 | ||
847 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; | 877 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; |
848 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; | 878 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
849 | channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; | 879 | channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; |
850 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; | 880 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
851 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; | 881 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
882 | channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; | ||
852 | } | 883 | } |
853 | 884 | ||
854 | void | 885 | void |
@@ -861,12 +892,14 @@ channel_handler_init_13(void) | |||
861 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; | 892 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
862 | channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; | 893 | channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining; |
863 | channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; | 894 | channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; |
895 | channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; | ||
864 | 896 | ||
865 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; | 897 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; |
866 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; | 898 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
867 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; | 899 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
868 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; | 900 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
869 | channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; | 901 | channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; |
902 | channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; | ||
870 | } | 903 | } |
871 | 904 | ||
872 | void | 905 | void |
@@ -877,11 +910,13 @@ channel_handler_init_15(void) | |||
877 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; | 910 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; |
878 | channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; | 911 | channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; |
879 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; | 912 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
913 | channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; | ||
880 | 914 | ||
881 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; | 915 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
882 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; | 916 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
883 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; | 917 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
884 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; | 918 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_1; |
919 | channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; | ||
885 | } | 920 | } |
886 | 921 | ||
887 | void | 922 | void |
@@ -1397,6 +1432,7 @@ channel_still_open() | |||
1397 | case SSH_CHANNEL_RPORT_LISTENER: | 1432 | case SSH_CHANNEL_RPORT_LISTENER: |
1398 | case SSH_CHANNEL_CLOSED: | 1433 | case SSH_CHANNEL_CLOSED: |
1399 | case SSH_CHANNEL_AUTH_SOCKET: | 1434 | case SSH_CHANNEL_AUTH_SOCKET: |
1435 | case SSH_CHANNEL_CONNECTING: /* XXX ??? */ | ||
1400 | continue; | 1436 | continue; |
1401 | case SSH_CHANNEL_LARVAL: | 1437 | case SSH_CHANNEL_LARVAL: |
1402 | if (!compat20) | 1438 | if (!compat20) |
@@ -1446,6 +1482,7 @@ channel_open_message() | |||
1446 | continue; | 1482 | continue; |
1447 | case SSH_CHANNEL_LARVAL: | 1483 | case SSH_CHANNEL_LARVAL: |
1448 | case SSH_CHANNEL_OPENING: | 1484 | case SSH_CHANNEL_OPENING: |
1485 | case SSH_CHANNEL_CONNECTING: | ||
1449 | case SSH_CHANNEL_OPEN: | 1486 | case SSH_CHANNEL_OPEN: |
1450 | case SSH_CHANNEL_X11_OPEN: | 1487 | case SSH_CHANNEL_X11_OPEN: |
1451 | case SSH_CHANNEL_INPUT_DRAINING: | 1488 | case SSH_CHANNEL_INPUT_DRAINING: |
@@ -1702,8 +1739,11 @@ channel_connect_to(const char *host, u_short host_port) | |||
1702 | error("socket: %.100s", strerror(errno)); | 1739 | error("socket: %.100s", strerror(errno)); |
1703 | continue; | 1740 | continue; |
1704 | } | 1741 | } |
1742 | if (fcntl(sock, F_SETFL, O_NDELAY) < 0) | ||
1743 | fatal("connect_to: F_SETFL: %s", strerror(errno)); | ||
1705 | /* Connect to the host/port. */ | 1744 | /* Connect to the host/port. */ |
1706 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { | 1745 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && |
1746 | errno != EINPROGRESS) { | ||
1707 | error("connect %.100s port %s: %.100s", ntop, strport, | 1747 | error("connect %.100s port %s: %.100s", ntop, strport, |
1708 | strerror(errno)); | 1748 | strerror(errno)); |
1709 | close(sock); | 1749 | close(sock); |
@@ -1789,7 +1829,9 @@ channel_input_port_open(int type, int plen, void *ctxt) | |||
1789 | sock = denied ? -1 : channel_connect_to(host, host_port); | 1829 | sock = denied ? -1 : channel_connect_to(host, host_port); |
1790 | if (sock > 0) { | 1830 | if (sock > 0) { |
1791 | /* Allocate a channel for this connection. */ | 1831 | /* Allocate a channel for this connection. */ |
1792 | newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string); | 1832 | newch = channel_allocate(SSH_CHANNEL_CONNECTING, |
1833 | sock, originator_string); | ||
1834 | /*XXX delay answer? */ | ||
1793 | channels[newch].remote_id = remote_channel; | 1835 | channels[newch].remote_id = remote_channel; |
1794 | 1836 | ||
1795 | packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); | 1837 | packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |