]> andersk Git - gssapi-openssh.git/blobdiff - openssh/channels.c
merged OpenSSH 3.9p1 to trunk
[gssapi-openssh.git] / openssh / channels.c
index 639e69c0c2afeddc29f486b5b49e3f39a9e452c3..87dcb730f177a0130be91402649ace3bf06a42a9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.266 2006/08/29 10:40:18 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.272 2008/01/19 23:02:40 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -76,7 +76,6 @@
 #include "authfd.h"
 #include "pathnames.h"
 
-
 /* -- channel core */
 
 /*
@@ -771,10 +770,13 @@ int channel_tcpwinsz () {
         u_int32_t tcpwinsz = 0;
         socklen_t optsz = sizeof(tcpwinsz);
        int ret = -1;
+
+       /* if we aren't on a socket return 128KB*/
        if(!packet_connection_is_on_socket()) 
-           return(131072);
+           return(128*1024);
        ret = getsockopt(packet_get_connection_in(),
                         SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
+       /* return no more than 64MB */
        if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
            tcpwinsz = BUFFER_MAX_LEN_HPN;
        debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
@@ -788,10 +790,8 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
        u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
 
         /* check buffer limits */
-       if (!c->tcpwinsz) 
+       if ((!c->tcpwinsz) || (c->dynamic_window > 0))
            c->tcpwinsz = channel_tcpwinsz();
-       if (c->dynamic_window > 0)
-           c->tcpwinsz = channel_tcpwinsz();
        
        limit = MIN(limit, 2 * c->tcpwinsz);
        
@@ -1077,7 +1077,7 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
                if (have < nmethods + 2)
                        return 0;
                /* look for method: "NO AUTHENTICATION REQUIRED" */
-               for (found = 0, i = 2 ; i < nmethods + 2; i++) {
+               for (found = 0, i = 2; i < nmethods + 2; i++) {
                        if (p[i] == SSH_SOCKS5_NOAUTH) {
                                found = 1;
                                break;
@@ -1471,13 +1471,13 @@ static int
 channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char buf[CHAN_RBUF];
-       int len;
+       int len, force;
 
-       if (c->rfd != -1 &&
-           FD_ISSET(c->rfd, readset)) {
+       force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
+       if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) {
                errno = 0;
                len = read(c->rfd, buf, sizeof(buf));
-               if (len < 0 && (errno == EINTR || errno == EAGAIN))
+               if (len < 0 && (errno == EINTR || (errno == EAGAIN && !force)))
                        return 1;
 #ifndef PTY_ZEROREAD
                if (len <= 0) {
@@ -1629,11 +1629,12 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
                                c->local_consumed += len;
                        }
                } else if (c->extended_usage == CHAN_EXTENDED_READ &&
-                   FD_ISSET(c->efd, readset)) {
+                   (c->detach_close || FD_ISSET(c->efd, readset))) {
                        len = read(c->efd, buf, sizeof(buf));
                        debug2("channel %d: read %d from efd %d",
                            c->self, len, c->efd);
-                       if (len < 0 && (errno == EINTR || errno == EAGAIN))
+                       if (len < 0 && (errno == EINTR ||
+                           (errno == EAGAIN && !c->detach_close)))
                                return 1;
                        if (len <= 0) {
                                debug2("channel %d: closing read-efd %d",
@@ -1681,12 +1682,15 @@ channel_check_window(Channel *c)
 {
        if (c->type == SSH_CHANNEL_OPEN &&
            !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
-           c->local_window < c->local_window_max/2 &&
+           ((c->local_window_max - c->local_window >
+           c->local_maxpacket*3) ||
+           c->local_window < c->local_window_max/2) &&
            c->local_consumed > 0) {
                u_int addition = 0;
                /* adjust max window size if we are in a dynamic environment */
                if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
-                       addition = c->tcpwinsz - c->local_window_max;
+                       /* grow the window somewhat aggressively to maintain pressure */
+                       addition = 1.5*(c->tcpwinsz - c->local_window_max);
                        c->local_window_max += addition;
                }
                packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
@@ -1899,11 +1903,12 @@ channel_after_select(fd_set *readset, fd_set *writeset)
 
 
 /* If there is data to send to the connection, enqueue some of it now. */
-void
+int
 channel_output_poll(void)
 {
        Channel *c;
        u_int i, len;
+       int packet_length = 0;
 
        for (i = 0; i < channels_alloc; i++) {
                c = channels[i];
@@ -1943,7 +1948,7 @@ channel_output_poll(void)
                                        packet_start(SSH2_MSG_CHANNEL_DATA);
                                        packet_put_int(c->remote_id);
                                        packet_put_string(data, dlen);
-                                       packet_send();
+                                       packet_length = packet_send();
                                        c->remote_window -= dlen + 4;
                                        xfree(data);
                                }
@@ -1973,7 +1978,7 @@ channel_output_poll(void)
                                    SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
                                packet_put_int(c->remote_id);
                                packet_put_string(buffer_ptr(&c->input), len);
-                               packet_send();
+                               packet_length = packet_send();
                                buffer_consume(&c->input, len);
                                c->remote_window -= len;
                        }
@@ -2008,12 +2013,13 @@ channel_output_poll(void)
                        packet_put_int(c->remote_id);
                        packet_put_int(SSH2_EXTENDED_DATA_STDERR);
                        packet_put_string(buffer_ptr(&c->extended), len);
-                       packet_send();
+                       packet_length = packet_send();
                        buffer_consume(&c->extended, len);
                        c->remote_window -= len;
                        debug2("channel %d: sent ext data %d", c->self, len);
                }
        }
+       return (packet_length);
 }
 
 
@@ -2414,7 +2420,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                        wildcard = 1;
        } else if (gateway_ports || is_client) {
                if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
-                   strcmp(listen_addr, "0.0.0.0") == 0) ||
+                   strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
                    *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
                    (!is_client && gateway_ports == 1))
                        wildcard = 1;
@@ -2438,10 +2444,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                if (addr == NULL) {
                        /* This really shouldn't happen */
                        packet_disconnect("getaddrinfo: fatal error: %s",
-                           gai_strerror(r));
+                           ssh_gai_strerror(r));
                } else {
                        error("channel_setup_fwd_listener: "
-                           "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+                           "getaddrinfo(%.64s): %s", addr,
+                           ssh_gai_strerror(r));
                }
                return 0;
        }
@@ -2486,9 +2493,9 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                /* Allocate a channel number for the socket. */
                /* explicitly test for hpn disabled option. if true use smaller window size */
                if (hpn_disabled)
-                       c = channel_new("port listener", type, sock, sock, -1,
-                         CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-                         0, "port listener", 1); 
+               c = channel_new("port listener", type, sock, sock, -1,
+                   CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
+                   0, "port listener", 1);
                else
                        c = channel_new("port listener", type, sock, sock, -1,
                          hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
@@ -2565,11 +2572,18 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
        /* Send the forward request to the remote side. */
        if (compat20) {
                const char *address_to_bind;
-               if (listen_host == NULL)
-                       address_to_bind = "localhost";
-               else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0)
-                       address_to_bind = "";
-               else
+               if (listen_host == NULL) {
+                       if (datafellows & SSH_BUG_RFWD_ADDR)
+                               address_to_bind = "127.0.0.1";
+                       else
+                               address_to_bind = "localhost";
+               } else if (*listen_host == '\0' ||
+                          strcmp(listen_host, "*") == 0) {
+                       if (datafellows & SSH_BUG_RFWD_ADDR)
+                               address_to_bind = "0.0.0.0";
+                       else
+                               address_to_bind = "";
+               } else
                        address_to_bind = listen_host;
 
                packet_start(SSH2_MSG_GLOBAL_REQUEST);
@@ -2763,7 +2777,7 @@ connect_to(const char *host, u_short port)
        snprintf(strport, sizeof strport, "%d", port);
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
                error("connect_to %.100s: unknown host (%s)", host,
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2906,7 +2920,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
                hints.ai_socktype = SOCK_STREAM;
                snprintf(strport, sizeof strport, "%d", port);
                if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
-                       error("getaddrinfo: %.100s", gai_strerror(gaierr));
+                       error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
                        return -1;
                }
                for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2981,11 +2995,12 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
        *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
        for (n = 0; n < num_socks; n++) {
                sock = socks[n];
+               /* Is this really necassary? */
                if (hpn_disabled) 
-                       nc = channel_new("x11 listener",
-                           SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
-                           CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-                           0, "X11 inet listener", 1);
+               nc = channel_new("x11 listener",
+                   SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
+                   CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
+                   0, "X11 inet listener", 1);
                else 
                        nc = channel_new("x11 listener",
                            SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
@@ -3085,7 +3100,8 @@ x11_connect_display(void)
        hints.ai_socktype = SOCK_STREAM;
        snprintf(strport, sizeof strport, "%u", 6000 + display_number);
        if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
-               error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
+               error("%.100s: unknown host. (%s)", buf,
+               ssh_gai_strerror(gaierr));
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
This page took 0.05061 seconds and 4 git commands to generate.