]> andersk Git - openssh.git/blobdiff - channels.c
- (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too.
[openssh.git] / channels.c
index 884c14c992799c4bf0ec44057939f0af169127ba..e8589d8c4d148287f46e3cab4c850f12eb8ede39 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.297 2009/10/28 16:38:18 reyk Exp $ */
+/* $OpenBSD: channels.c,v 1.301 2010/01/11 01:39:46 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -53,6 +53,7 @@
 #include <arpa/inet.h>
 
 #include <errno.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -162,9 +163,6 @@ static u_int x11_fake_data_len;
 /* AF_UNSPEC or AF_INET or AF_INET6 */
 static int IPv4or6 = AF_UNSPEC;
 
-/* Set the routing domain a.k.a. VRF */
-static int channel_rdomain = -1;
-
 /* helper */
 static void port_open_helper(Channel *c, char *rtype);
 
@@ -231,7 +229,12 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
        channel_max_fd = MAX(channel_max_fd, wfd);
        channel_max_fd = MAX(channel_max_fd, efd);
 
-       /* XXX set close-on-exec -markus */
+       if (rfd != -1)
+               fcntl(rfd, F_SETFD, FD_CLOEXEC);
+       if (wfd != -1 && wfd != rfd)
+               fcntl(wfd, F_SETFD, FD_CLOEXEC);
+       if (efd != -1 && efd != rfd && efd != wfd)
+               fcntl(efd, F_SETFD, FD_CLOEXEC);
 
        c->rfd = rfd;
        c->wfd = wfd;
@@ -325,6 +328,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        c->output_filter = NULL;
        c->filter_ctx = NULL;
        c->filter_cleanup = NULL;
+       c->delayed = 1;         /* prevent call to channel_post handler */
        TAILQ_INIT(&c->status_confirms);
        debug("channel %d: new [%s]", found, remote_name);
        return c;
@@ -1213,6 +1217,35 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
        return 1;
 }
 
+Channel *
+channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect)
+{
+       Channel *c;
+       int in, out;
+
+       debug("channel_connect_stdio_fwd %s:%d", host_to_connect,
+           port_to_connect);
+
+       in = dup(STDIN_FILENO);
+       out = dup(STDOUT_FILENO);
+       if (in < 0 || out < 0)
+               fatal("channel_connect_stdio_fwd: dup() in/out failed");
+
+       c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out,
+           -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+           0, "stdio-forward", /*nonblock*/0);
+
+       c->path = xstrdup(host_to_connect);
+       c->host_port = port_to_connect;
+       c->listening_port = 0;
+       c->force_drain = 1;
+
+       channel_register_fds(c, in, out, -1, 0, 1, 0);
+       port_open_helper(c, "direct-tcpip");
+
+       return c;
+}
+
 /* dynamic port forwarding */
 static void
 channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
@@ -1222,7 +1255,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
        int ret;
 
        have = buffer_len(&c->input);
-       c->delayed = 0;
        debug2("channel %d: pre_dynamic: have %d", c->self, have);
        /* buffer_dump(&c->input); */
        /* check if the fixed size part of the packet is in buffer. */
@@ -1426,16 +1458,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
                if (c->path != NULL)
                        nc->path = xstrdup(c->path);
 
-               if (nextstate == SSH_CHANNEL_DYNAMIC) {
-                       /*
-                        * do not call the channel_post handler until
-                        * this flag has been reset by a pre-handler.
-                        * otherwise the FD_ISSET calls might overflow
-                        */
-                       nc->delayed = 1;
-               } else {
+               if (nextstate != SSH_CHANNEL_DYNAMIC)
                        port_open_helper(nc, rtype);
-               }
        }
 }
 
@@ -1780,8 +1804,6 @@ channel_check_window(Channel *c)
 static void
 channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
 {
-       if (c->delayed)
-               return;
        channel_handle_rfd(c, readset, writeset);
        channel_handle_wfd(c, readset, writeset);
        if (!compat20)
@@ -1913,17 +1935,23 @@ static void
 channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
 {
        static int did_init = 0;
-       u_int i;
+       u_int i, oalloc;
        Channel *c;
 
        if (!did_init) {
                channel_handler_init();
                did_init = 1;
        }
-       for (i = 0; i < channels_alloc; i++) {
+       for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
                c = channels[i];
                if (c == NULL)
                        continue;
+               if (c->delayed) {
+                       if (ftab == channel_pre)
+                               c->delayed = 0;
+                       else
+                               continue;
+               }
                if (ftab[c->type] != NULL)
                        (*ftab[c->type])(c, readset, writeset);
                channel_garbage_collect(c);
@@ -2464,12 +2492,6 @@ channel_set_af(int af)
        IPv4or6 = af;
 }
 
-void
-channel_set_rdomain(int rdomain)
-{
-       channel_rdomain = rdomain;
-}
-
 static int
 channel_setup_fwd_listener(int type, const char *listen_addr,
     u_short listen_port, int *allocated_listen_port,
@@ -2578,8 +2600,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr,
                        continue;
                }
                /* Create a port to listen for the host. */
-               sock = socket_rdomain(ai->ai_family, ai->ai_socktype,
-                   ai->ai_protocol, channel_rdomain);
+               sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if (sock < 0) {
                        /* this is no error since kernel may not support ipv6 */
                        verbose("socket: %.100s", strerror(errno));
@@ -2920,9 +2941,8 @@ connect_next(struct channel_connect *cctx)
                        error("connect_next: getnameinfo failed");
                        continue;
                }
-               if ((sock = socket_rdomain(cctx->ai->ai_family,
-                   cctx->ai->ai_socktype, cctx->ai->ai_protocol,
-                   channel_rdomain)) == -1) {
+               if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,
+                   cctx->ai->ai_protocol)) == -1) {
                        if (cctx->ai->ai_next == NULL)
                                error("socket: %.100s", strerror(errno));
                        else
@@ -3108,8 +3128,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
                for (ai = aitop; ai; ai = ai->ai_next) {
                        if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
                                continue;
-                       sock = socket_rdomain(ai->ai_family, ai->ai_socktype,
-                           ai->ai_protocol, channel_rdomain);
+                       sock = socket(ai->ai_family, ai->ai_socktype,
+                           ai->ai_protocol);
                        if (sock < 0) {
                                if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
                                        error("socket: %.100s", strerror(errno));
@@ -3284,8 +3304,7 @@ x11_connect_display(void)
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
                /* Create a socket. */
-               sock = socket_rdomain(ai->ai_family, ai->ai_socktype,
-                   ai->ai_protocol, channel_rdomain);
+               sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if (sock < 0) {
                        debug2("socket: %.100s", strerror(errno));
                        continue;
This page took 0.042419 seconds and 4 git commands to generate.