コード例 #1
0
/* open new channel for a session */
static int
ssh_session2_open(void)
{
	Channel *c;
	int window, packetmax, in, out, err;
	int sock;
	int socksize;
	int socksizelen = sizeof(int);

	if (stdin_null_flag) {
		in = open(_PATH_DEVNULL, O_RDONLY);
	} else {
		in = dup(STDIN_FILENO);
	}
	out = dup(STDOUT_FILENO);
	err = dup(STDERR_FILENO);

	if (in < 0 || out < 0 || err < 0)
		fatal("dup() in/out/err failed");

	/* enable nonblocking unless tty */
	if (!isatty(in))
		set_nonblock(in);
	if (!isatty(out))
		set_nonblock(out);
	if (!isatty(err))
		set_nonblock(err);

	/* we need to check to see if what they want to do about buffer */
	/* sizes here. In a hpn to nonhpn connection we want to limit */
	/* the window size to something reasonable in case the far side */
	/* has the large window bug. In hpn to hpn connection we want to */
	/* use the max window size but allow the user to override it */
	/* lastly if they disabled hpn then use the ssh std window size */

	/* so why don't we just do a getsockopt() here and set the */
	/* ssh window to that? In the case of a autotuning receive */
	/* window the window would get stuck at the initial buffer */
	/* size generally less than 96k. Therefore we need to set the */
	/* maximum ssh window size to the maximum hpn buffer size */
	/* unless the user has specifically set the tcprcvbufpoll */
	/* to no. In which case we *can* just set the window to the */
	/* minimum of the hpn buffer size and tcp receive buffer size */

	if (tty_flag)
		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
	else
		options.hpn_buffer_size = 2*1024*1024;

	if (datafellows & SSH_BUG_LARGEWINDOW)
	{
		debug("HPN to Non-HPN Connection");
	}
	else
	{
		if (options.tcp_rcv_buf_poll <= 0)
		{
			sock = socket(AF_INET, SOCK_STREAM, 0);
			getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
				   &socksize, &socksizelen);
			close(sock);
			debug("socksize %d", socksize);
			options.hpn_buffer_size = socksize;
			debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
		}
		else
		{
			if (options.tcp_rcv_buf > 0)
			{
				/*create a socket but don't connect it */
				/* we use that the get the rcv socket size */
				sock = socket(AF_INET, SOCK_STREAM, 0);
				/* if they are using the tcp_rcv_buf option */
				/* attempt to set the buffer size to that */
				if (options.tcp_rcv_buf)
					setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf,
						   sizeof(options.tcp_rcv_buf));
				getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
					   &socksize, &socksizelen);
				close(sock);
				debug("socksize %d", socksize);
				options.hpn_buffer_size = socksize;
				debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
			}
		}

	}

	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);

	window = options.hpn_buffer_size;

	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);

	packetmax = CHAN_SES_PACKET_DEFAULT;
	if (tty_flag) {
		window = 4*CHAN_SES_PACKET_DEFAULT;
		window >>= 1;
		packetmax >>= 1;
	}
	c = channel_new(
	    "session", SSH_CHANNEL_OPENING, in, out, err,
	    window, packetmax, CHAN_EXTENDED_WRITE,
	    "client-session", /*nonblock*/0);
	if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
		c->dynamic_window = 1;
		debug ("Enabled Dynamic Window Scaling\n");
	}
	debug3("ssh_session2_open: channel_new: %d", c->self);

	channel_send_open(c->self);
	if (!no_shell_flag)
		channel_register_open_confirm(c->self,
		    ssh_session2_setup, NULL);

	return c->self;
}
コード例 #2
0
/* open new channel for a session */
static int
ssh_session2_open(void)
{
	Channel *c;
	int window, packetmax, in, out, err;

	if (stdin_null_flag) {
		in = open(_PATH_DEVNULL, O_RDONLY);
	} else {
		in = dup(STDIN_FILENO);
	}
	out = dup(STDOUT_FILENO);
	err = dup(STDERR_FILENO);

	if (in < 0 || out < 0 || err < 0)
		fatal("dup() in/out/err failed");

	/* enable nonblocking unless tty */
	if (!isatty(in))
		set_nonblock(in);
	if (!isatty(out))
		set_nonblock(out);
	if (!isatty(err))
		set_nonblock(err);

	/*
	 * We need to check to see what to do about buffer sizes here.
	 * - In an HPN to non-HPN connection we want to limit the window size to
	 *   something reasonable in case the far side has the large window bug.
	 * - In an HPN to HPN connection we want to use the max window size but
	 *   allow the user to override it.
	 * - Lastly if HPN is disabled then use the ssh standard window size.
	 *
	 * We cannot just do a getsockopt() here and set the ssh window to that
	 * as in case of autotuning of socket buffers the window would get stuck
	 * at the initial buffer size, generally less than 96k.  Therefore we
	 * need to set the maximum ssh window size to the maximum HPN buffer
	 * size unless the user has set TcpRcvBufPoll to no.  In that case we
	 * can just set the window to the minimum of HPN buffer size and TCP
	 * receive buffer size.
	 */
	if (tty_flag)
		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
	else
		options.hpn_buffer_size = CHAN_HPN_MIN_WINDOW_DEFAULT;

	if (datafellows & SSH_BUG_LARGEWINDOW) {
		debug("HPN to Non-HPN Connection");
	} else if (options.tcp_rcv_buf_poll <= 0) {
		sock_get_rcvbuf(&options.hpn_buffer_size, 0);
		debug("HPNBufferSize set to TCP RWIN: %d",
		    options.hpn_buffer_size);
	} else if (options.tcp_rcv_buf > 0) {
		sock_get_rcvbuf(&options.hpn_buffer_size,
		    options.tcp_rcv_buf);
		debug("HPNBufferSize set to user TCPRcvBuf: %d",
		    options.hpn_buffer_size);
	}
	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
	window = options.hpn_buffer_size;

	packetmax = CHAN_SES_PACKET_DEFAULT;
	if (tty_flag) {
		window = CHAN_SES_WINDOW_DEFAULT;
		window >>= 1;
		packetmax >>= 1;
	}
	c = channel_new(
	    "session", SSH_CHANNEL_OPENING, in, out, err,
	    window, packetmax, CHAN_EXTENDED_WRITE,
	    "client-session", /*nonblock*/0);
	if (!options.hpn_disabled && options.tcp_rcv_buf_poll > 0) {
		c->dynamic_window = 1;
		debug("Enabled Dynamic Window Scaling\n");
	}

	debug3("ssh_session2_open: channel_new: %d", c->self);

	channel_send_open(c->self);
	if (!no_shell_flag)
		channel_register_open_confirm(c->self,
		    ssh_session2_setup, NULL);

	return c->self;
}