channels.c (221420) | channels.c (224638) |
---|---|
1/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */ | 1/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */ |
2/* $FreeBSD$ */ |
|
2/* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * This file contains functions for generic socket connection forwarding. 7 * There is also code for initiating connection forwarding for X11 connections, 8 * arbitrary tcp/ip connections, and the authentication agent connection. 9 * --- 155 unchanged lines hidden (view full) --- 165 166/* helper */ 167static void port_open_helper(Channel *c, char *rtype); 168 169/* non-blocking connect helpers */ 170static int connect_next(struct channel_connect *); 171static void channel_connect_ctx_free(struct channel_connect *); 172 | 3/* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * This file contains functions for generic socket connection forwarding. 8 * There is also code for initiating connection forwarding for X11 connections, 9 * arbitrary tcp/ip connections, and the authentication agent connection. 10 * --- 155 unchanged lines hidden (view full) --- 166 167/* helper */ 168static void port_open_helper(Channel *c, char *rtype); 169 170/* non-blocking connect helpers */ 171static int connect_next(struct channel_connect *); 172static void channel_connect_ctx_free(struct channel_connect *); 173 |
174/* -- HPN */ 175 176static int hpn_disabled = 0; 177static u_int buffer_size = CHAN_HPN_MIN_WINDOW_DEFAULT; 178 |
|
173/* -- channel core */ 174 175Channel * 176channel_by_id(int id) 177{ 178 Channel *c; 179 180 if (id < 0 || (u_int)id >= channels_alloc) { --- 123 unchanged lines hidden (view full) --- 304 c->path = NULL; 305 c->ostate = CHAN_OUTPUT_OPEN; 306 c->istate = CHAN_INPUT_OPEN; 307 c->flags = 0; 308 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); 309 c->self = found; 310 c->type = type; 311 c->ctype = ctype; | 179/* -- channel core */ 180 181Channel * 182channel_by_id(int id) 183{ 184 Channel *c; 185 186 if (id < 0 || (u_int)id >= channels_alloc) { --- 123 unchanged lines hidden (view full) --- 310 c->path = NULL; 311 c->ostate = CHAN_OUTPUT_OPEN; 312 c->istate = CHAN_INPUT_OPEN; 313 c->flags = 0; 314 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); 315 c->self = found; 316 c->type = type; 317 c->ctype = ctype; |
318 c->dynamic_window = 0; |
|
312 c->local_window = window; 313 c->local_window_max = window; 314 c->local_consumed = 0; 315 c->local_maxpacket = maxpack; 316 c->remote_id = -1; 317 c->remote_name = xstrdup(remote_name); 318 c->remote_window = 0; 319 c->remote_maxpacket = 0; --- 483 unchanged lines hidden (view full) --- 803channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) 804{ 805 if (buffer_len(&c->input) < packet_get_maxsize()) 806 FD_SET(c->sock, readset); 807 if (buffer_len(&c->output) > 0) 808 FD_SET(c->sock, writeset); 809} 810 | 319 c->local_window = window; 320 c->local_window_max = window; 321 c->local_consumed = 0; 322 c->local_maxpacket = maxpack; 323 c->remote_id = -1; 324 c->remote_name = xstrdup(remote_name); 325 c->remote_window = 0; 326 c->remote_maxpacket = 0; --- 483 unchanged lines hidden (view full) --- 810channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) 811{ 812 if (buffer_len(&c->input) < packet_get_maxsize()) 813 FD_SET(c->sock, readset); 814 if (buffer_len(&c->output) > 0) 815 FD_SET(c->sock, writeset); 816} 817 |
818static u_int 819channel_tcpwinsz(void) 820{ 821 u_int32_t tcpwinsz; 822 socklen_t optsz; 823 int ret, sd; 824 u_int maxlen; 825 826 /* If we are not on a socket return 128KB. */ 827 if (!packet_connection_is_on_socket()) 828 return (128 * 1024); 829 830 tcpwinsz = 0; 831 optsz = sizeof(tcpwinsz); 832 sd = packet_get_connection_in(); 833 ret = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); 834 835 /* Return no more than the maximum buffer size. */ 836 maxlen = buffer_get_max_len(); 837 if ((ret == 0) && tcpwinsz > maxlen) 838 tcpwinsz = maxlen; 839 /* In case getsockopt() failed return a minimum. */ 840 if (tcpwinsz == 0) 841 tcpwinsz = CHAN_TCP_WINDOW_DEFAULT; 842 debug2("tcpwinsz: %d for connection: %d", tcpwinsz, sd); 843 return (tcpwinsz); 844} 845 |
|
811static void 812channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) 813{ | 846static void 847channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) 848{ |
814 u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); | 849 u_int limit; |
815 | 850 |
851 /* Check buffer limits. */ 852 if (!c->tcpwinsz || c->dynamic_window > 0) 853 c->tcpwinsz = channel_tcpwinsz(); 854 855 limit = MIN(compat20 ? c->remote_window : packet_get_maxsize(), 856 2 * c->tcpwinsz); 857 |
|
816 if (c->istate == CHAN_INPUT_OPEN && 817 limit > 0 && 818 buffer_len(&c->input) < limit && 819 buffer_check_alloc(&c->input, CHAN_RBUF)) 820 FD_SET(c->rfd, readset); 821 if (c->ostate == CHAN_OUTPUT_OPEN || 822 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 823 if (buffer_len(&c->output) > 0) { --- 960 unchanged lines hidden (view full) --- 1784channel_check_window(Channel *c) 1785{ 1786 if (c->type == SSH_CHANNEL_OPEN && 1787 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && 1788 ((c->local_window_max - c->local_window > 1789 c->local_maxpacket*3) || 1790 c->local_window < c->local_window_max/2) && 1791 c->local_consumed > 0) { | 858 if (c->istate == CHAN_INPUT_OPEN && 859 limit > 0 && 860 buffer_len(&c->input) < limit && 861 buffer_check_alloc(&c->input, CHAN_RBUF)) 862 FD_SET(c->rfd, readset); 863 if (c->ostate == CHAN_OUTPUT_OPEN || 864 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 865 if (buffer_len(&c->output) > 0) { --- 960 unchanged lines hidden (view full) --- 1826channel_check_window(Channel *c) 1827{ 1828 if (c->type == SSH_CHANNEL_OPEN && 1829 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && 1830 ((c->local_window_max - c->local_window > 1831 c->local_maxpacket*3) || 1832 c->local_window < c->local_window_max/2) && 1833 c->local_consumed > 0) { |
1834 u_int addition = 0; 1835 1836 /* Adjust max window size if we are in a dynamic environment. */ 1837 if (c->dynamic_window && c->tcpwinsz > c->local_window_max) { 1838 /* 1839 * Grow the window somewhat aggressively to maintain 1840 * pressure. 1841 */ 1842 addition = 1.5 * (c->tcpwinsz - c->local_window_max); 1843 c->local_window_max += addition; 1844 } |
|
1792 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); 1793 packet_put_int(c->remote_id); | 1845 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); 1846 packet_put_int(c->remote_id); |
1794 packet_put_int(c->local_consumed); | 1847 packet_put_int(c->local_consumed + addition); |
1795 packet_send(); 1796 debug2("channel %d: window %d sent adjust %d", 1797 c->self, c->local_window, 1798 c->local_consumed); | 1848 packet_send(); 1849 debug2("channel %d: window %d sent adjust %d", 1850 c->self, c->local_window, 1851 c->local_consumed); |
1799 c->local_window += c->local_consumed; | 1852 c->local_window += c->local_consumed + addition; |
1800 c->local_consumed = 0; 1801 } 1802 return 1; 1803} 1804 1805static void 1806channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) 1807{ --- 821 unchanged lines hidden (view full) --- 2629/* -- tcp forwarding */ 2630 2631void 2632channel_set_af(int af) 2633{ 2634 IPv4or6 = af; 2635} 2636 | 1853 c->local_consumed = 0; 1854 } 1855 return 1; 1856} 1857 1858static void 1859channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) 1860{ --- 821 unchanged lines hidden (view full) --- 2682/* -- tcp forwarding */ 2683 2684void 2685channel_set_af(int af) 2686{ 2687 IPv4or6 = af; 2688} 2689 |
2690void 2691channel_set_hpn(int disabled, u_int buf_size) 2692{ 2693 hpn_disabled = disabled; 2694 buffer_size = buf_size; 2695 debug("HPN Disabled: %d, HPN Buffer Size: %d", 2696 hpn_disabled, buffer_size); 2697} 2698 |
|
2637static int 2638channel_setup_fwd_listener(int type, const char *listen_addr, 2639 u_short listen_port, int *allocated_listen_port, 2640 const char *host_to_connect, u_short port_to_connect, int gateway_ports) 2641{ 2642 Channel *c; 2643 int sock, r, success = 0, wildcard = 0, is_client; 2644 struct addrinfo hints, *ai, *aitop; --- 136 unchanged lines hidden (view full) --- 2781 if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && 2782 allocated_listen_port != NULL && 2783 *allocated_listen_port == 0) { 2784 *allocated_listen_port = get_sock_port(sock, 1); 2785 debug("Allocated listen port %d", 2786 *allocated_listen_port); 2787 } 2788 | 2699static int 2700channel_setup_fwd_listener(int type, const char *listen_addr, 2701 u_short listen_port, int *allocated_listen_port, 2702 const char *host_to_connect, u_short port_to_connect, int gateway_ports) 2703{ 2704 Channel *c; 2705 int sock, r, success = 0, wildcard = 0, is_client; 2706 struct addrinfo hints, *ai, *aitop; --- 136 unchanged lines hidden (view full) --- 2843 if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && 2844 allocated_listen_port != NULL && 2845 *allocated_listen_port == 0) { 2846 *allocated_listen_port = get_sock_port(sock, 1); 2847 debug("Allocated listen port %d", 2848 *allocated_listen_port); 2849 } 2850 |
2789 /* Allocate a channel number for the socket. */ 2790 c = channel_new("port listener", type, sock, sock, -1, 2791 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 2792 0, "port listener", 1); | 2851 /* 2852 * Allocate a channel number for the socket. Explicitly test 2853 * for hpn disabled option. If true use smaller window size. 2854 */ 2855 if (hpn_disabled) 2856 c = channel_new("port listener", type, sock, sock, -1, 2857 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 2858 0, "port listener", 1); 2859 else 2860 c = channel_new("port listener", type, sock, sock, -1, 2861 buffer_size, CHAN_TCP_PACKET_DEFAULT, 2862 0, "port listener", 1); |
2793 c->path = xstrdup(host); 2794 c->host_port = port_to_connect; 2795 c->listening_port = listen_port; 2796 success = 1; 2797 } 2798 if (success == 0) 2799 error("channel_setup_fwd_listener: cannot listen to port: %d", 2800 listen_port); --- 528 unchanged lines hidden (view full) --- 3329 return -1; 3330 } 3331 } 3332 3333 /* Allocate a channel for each socket. */ 3334 *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); 3335 for (n = 0; n < num_socks; n++) { 3336 sock = socks[n]; | 2863 c->path = xstrdup(host); 2864 c->host_port = port_to_connect; 2865 c->listening_port = listen_port; 2866 success = 1; 2867 } 2868 if (success == 0) 2869 error("channel_setup_fwd_listener: cannot listen to port: %d", 2870 listen_port); --- 528 unchanged lines hidden (view full) --- 3399 return -1; 3400 } 3401 } 3402 3403 /* Allocate a channel for each socket. */ 3404 *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); 3405 for (n = 0; n < num_socks; n++) { 3406 sock = socks[n]; |
3337 nc = channel_new("x11 listener", 3338 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, 3339 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 3340 0, "X11 inet listener", 1); | 3407 if (hpn_disabled) 3408 nc = channel_new("x11 listener", 3409 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, 3410 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 3411 0, "X11 inet listener", 1); 3412 else 3413 nc = channel_new("x11 listener", 3414 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, 3415 buffer_size, CHAN_X11_PACKET_DEFAULT, 3416 0, "X11 inet listener", 1); |
3341 nc->single_connection = single_connection; 3342 (*chanids)[n] = nc->self; 3343 } 3344 (*chanids)[n] = -1; 3345 3346 /* Return the display number for the DISPLAY environment variable. */ 3347 *display_numberp = display_number; 3348 return (0); --- 294 unchanged lines hidden --- | 3417 nc->single_connection = single_connection; 3418 (*chanids)[n] = nc->self; 3419 } 3420 (*chanids)[n] = -1; 3421 3422 /* Return the display number for the DISPLAY environment variable. */ 3423 *display_numberp = display_number; 3424 return (0); --- 294 unchanged lines hidden --- |