]> andersk Git - gssapi-openssh.git/blobdiff - openssh/channels.c
update to http://www.psc.edu/networking/projects/hpn-ssh/openssh-4.7p1-hpn13v1.diff.gz
[gssapi-openssh.git] / openssh / channels.c
index b4617cd8496cbb6d44a90457b316d650b19d9990..2ef1af902fc7a35c1ee546d0bc706355a43e14a9 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.270 2007/06/25 08:20:03 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -766,11 +766,35 @@ channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
                FD_SET(c->sock, writeset);
 }
 
+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(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, 
+              packet_get_connection_in());
+       return(tcpwinsz);
+}
+
 static void
 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) || (c->dynamic_window > 0))
+           c->tcpwinsz = channel_tcpwinsz();
+       
+       limit = MIN(limit, 2 * c->tcpwinsz);
+       
        if (c->istate == CHAN_INPUT_OPEN &&
            limit > 0 &&
            buffer_len(&c->input) < limit &&
@@ -1053,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;
@@ -1447,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) {
@@ -1605,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",
@@ -1657,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);
@@ -1875,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];
@@ -1919,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);
                                }
@@ -1949,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;
                        }
@@ -1984,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);
 }
 
 
@@ -2462,9 +2492,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,
@@ -2541,11 +2571,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);
@@ -2628,8 +2665,8 @@ channel_request_rforward_cancel(const char *host, u_short port)
  * message if there was an error).
  */
 int
-channel_input_port_forward_request(int is_root, int gateway_ports, 
-       int hpn_disabled, int hpn_buffer_size)
+channel_input_port_forward_request(int is_root, int gateway_ports,
+                                  int hpn_disabled, int hpn_buffer_size)
 {
        u_short port, host_port;
        int success = 0;
@@ -2957,11 +2994,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,
This page took 0.044045 seconds and 4 git commands to generate.