Beispiel #1
0
        /// <summary>
        /// Stops remote port forwarding.
        /// </summary>
        /// <param name="timeout">The maximum amount of time to wait for the port to stop.</param>
        protected override void StopPort(TimeSpan timeout)
        {
            if (!ForwardedPortStatus.ToStopping(ref _status))
            {
                return;
            }

            base.StopPort(timeout);

            // send global request to cancel direct tcpip
            Session.SendMessage(new CancelTcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
            // wait for response on global request to cancel direct tcpip or completion of message
            // listener loop (in which case response on global request can never be received)
            WaitHandle.WaitAny(new[] { _globalRequestResponse, Session.MessageListenerCompleted }, timeout);

            // unsubscribe from session events as either the tcpip forward is cancelled at the
            // server, or our session message loop has completed
            Session.RequestSuccessReceived -= Session_RequestSuccess;
            Session.RequestFailureReceived -= Session_RequestFailure;
            Session.ChannelOpenReceived    -= Session_ChannelOpening;

            // wait for pending channels to close
            _pendingChannelCountdown.Signal();
            _pendingChannelCountdown.Wait(timeout);

            _status = ForwardedPortStatus.Stopped;
        }
Beispiel #2
0
        /// <summary>
        /// Returns a value indicating whether <paramref name="status"/> has been changed to <see cref="Stopping"/>.
        /// </summary>
        /// <param name="status">The status to transition from.</param>
        /// <returns>
        /// <c>true</c> if <paramref name="status"/> has been changed to <see cref="Stopping"/>; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="InvalidOperationException">Cannot transition <paramref name="status"/> to <see cref="Stopping"/>.</exception>
        /// <remarks>
        /// While a transition from <see cref="Stopped"/> to <see cref="Stopping"/> is not possible, this method will
        /// return <c>false</c> for any such attempts.  This is related to concurrency.
        /// </remarks>
        public static bool ToStopping(ref ForwardedPortStatus status)
        {
            // attempt to transition from Started to Stopping
            var previousStatus = Interlocked.CompareExchange(ref status, Stopping, Started);
            if (previousStatus == Stopping || previousStatus == Stopped)
            {
                // status is already Stopping or Stopped, so no transition to Stopping is necessary
                return false;
            }

            // we've successfully transitioned from Started to Stopping
            if (status == Stopping)
                return true;

            // attempt to transition from Starting to Stopping
            previousStatus = Interlocked.CompareExchange(ref status, Stopping, Starting);
            if (previousStatus == Stopping || previousStatus == Stopped)
            {
                // status is already Stopping or Stopped, so no transition to Stopping is necessary
                return false;
            }

            // we've successfully transitioned from Starting to Stopping
            if (status == Stopping)
                return true;

            // there's no valid transition from status to Stopping
            throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
                                                              previousStatus,
                                                              Stopping));
        }
        /// <summary>
        /// Stops local port forwarding, and waits for the specified timeout until all pending
        /// requests are processed.
        /// </summary>
        /// <param name="timeout">The maximum amount of time to wait for pending requests to finish processing.</param>
        protected override void StopPort(TimeSpan timeout)
        {
            if (!ForwardedPortStatus.ToStopping(ref _status))
                return;

            // signal existing channels that the port is closing
            base.StopPort(timeout);
            // prevent new requests from getting processed
            StopListener();
            // wait for open channels to close
            InternalStop(timeout);
            // mark port stopped
            _status = ForwardedPortStatus.Stopped;
        }
        /// <summary>
        /// Starts local port forwarding.
        /// </summary>
        protected override void StartPort()
        {
            if (!ForwardedPortStatus.ToStarting(ref _status))
                return;

            try
            {
                InternalStart();
            }
            catch (Exception)
            {
                _status = ForwardedPortStatus.Stopped;
                throw;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Starts remote port forwarding.
        /// </summary>
        protected override void StartPort()
        {
            if (!ForwardedPortStatus.ToStarting(ref _status))
            {
                return;
            }

            InitializePendingChannelCountdown();

            try
            {
                Session.RegisterMessage("SSH_MSG_REQUEST_FAILURE");
                Session.RegisterMessage("SSH_MSG_REQUEST_SUCCESS");
                Session.RegisterMessage("SSH_MSG_CHANNEL_OPEN");

                Session.RequestSuccessReceived += Session_RequestSuccess;
                Session.RequestFailureReceived += Session_RequestFailure;
                Session.ChannelOpenReceived    += Session_ChannelOpening;

                // send global request to start forwarding
                Session.SendMessage(new TcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
                // wat for response on global request to start direct tcpip
                Session.WaitOnHandle(_globalRequestResponse);

                if (!_requestStatus)
                {
                    throw new SshException(string.Format(CultureInfo.CurrentCulture, "Port forwarding for '{0}' port '{1}' failed to start.", Host, Port));
                }
            }
            catch (Exception)
            {
                // mark port stopped
                _status = ForwardedPortStatus.Stopped;

                // when the request to start port forward was rejected or failed, then we're no longer
                // interested in these events
                Session.RequestSuccessReceived -= Session_RequestSuccess;
                Session.RequestFailureReceived -= Session_RequestFailure;
                Session.ChannelOpenReceived    -= Session_ChannelOpening;

                throw;
            }

            _status = ForwardedPortStatus.Started;
        }
Beispiel #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ForwardedPortRemote" /> class.
        /// </summary>
        /// <param name="boundHostAddress">The bound host address.</param>
        /// <param name="boundPort">The bound port.</param>
        /// <param name="hostAddress">The host address.</param>
        /// <param name="port">The port.</param>
        /// <exception cref="ArgumentNullException"><paramref name="boundHostAddress"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="hostAddress"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        public ForwardedPortRemote(IPAddress boundHostAddress, uint boundPort, IPAddress hostAddress, uint port)
        {
            if (boundHostAddress == null)
            {
                throw new ArgumentNullException("boundHostAddress");
            }
            if (hostAddress == null)
            {
                throw new ArgumentNullException("hostAddress");
            }

            boundPort.ValidatePort("boundPort");
            port.ValidatePort("port");

            BoundHostAddress = boundHostAddress;
            BoundPort        = boundPort;
            HostAddress      = hostAddress;
            Port             = port;
            _status          = ForwardedPortStatus.Stopped;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ForwardedPortLocal"/> class.
        /// </summary>
        /// <param name="boundHost">The bound host.</param>
        /// <param name="boundPort">The bound port.</param>
        /// <param name="host">The host.</param>
        /// <param name="port">The port.</param>
        /// <exception cref="ArgumentNullException"><paramref name="boundHost"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        public ForwardedPortLocal(string boundHost, uint boundPort, string host, uint port)
        {
            if (boundHost == null)
            {
                throw new ArgumentNullException("boundHost");
            }

            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            boundPort.ValidatePort("boundPort");
            port.ValidatePort("port");

            BoundHost = boundHost;
            BoundPort = boundPort;
            Host      = host;
            Port      = port;
            _status   = ForwardedPortStatus.Stopped;
        }
        /// <summary>
        /// Returns a value indicating whether <paramref name="status"/> has been changed to <see cref="Starting"/>.
        /// </summary>
        /// <param name="status">The status to transition from.</param>
        /// <returns>
        /// <c>true</c> if <paramref name="status"/> has been changed to <see cref="Starting"/>; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="InvalidOperationException">Cannot transition <paramref name="status"/> to <see cref="Starting"/>.</exception>
        /// <remarks>
        /// While a transition from <see cref="Started"/> to <see cref="Starting"/> is not possible, this method will
        /// return <c>false</c> for any such attempts.  This is related to concurrency.
        /// </remarks>
        public static bool ToStarting(ref ForwardedPortStatus status)
        {
            // attemp to transition from Stopped to Starting
            var previousStatus = Interlocked.CompareExchange(ref status, Starting, Stopped);

            if (previousStatus == Starting || previousStatus == Started)
            {
                // port is already Starting or Started, so no transition to Starting is necessary
                return(false);
            }

            // we've successfully transitioned from Stopped to Starting
            if (status == Starting)
            {
                return(true);
            }

            // there's no valid transition from status to Starting
            throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
                                                              previousStatus,
                                                              Starting));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ForwardedPortDynamic"/> class.
 /// </summary>
 /// <param name="host">The host.</param>
 /// <param name="port">The port.</param>
 public ForwardedPortDynamic(string host, uint port)
 {
     BoundHost = host;
     BoundPort = port;
     _status = ForwardedPortStatus.Stopped;
 }
Beispiel #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ForwardedPortRemote" /> class.
        /// </summary>
        /// <param name="boundHostAddress">The bound host address.</param>
        /// <param name="boundPort">The bound port.</param>
        /// <param name="hostAddress">The host address.</param>
        /// <param name="port">The port.</param>
        /// <exception cref="ArgumentNullException"><paramref name="boundHostAddress"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="hostAddress"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        public ForwardedPortRemote(IPAddress boundHostAddress, uint boundPort, IPAddress hostAddress, uint port)
        {
            if (boundHostAddress == null)
                throw new ArgumentNullException("boundHostAddress");
            if (hostAddress == null)
                throw new ArgumentNullException("hostAddress");

            boundPort.ValidatePort("boundPort");
            port.ValidatePort("port");

            BoundHostAddress = boundHostAddress;
            BoundPort = boundPort;
            HostAddress = hostAddress;
            Port = port;
            _status = ForwardedPortStatus.Stopped;
        }
Beispiel #11
0
        /// <summary>
        /// Stops remote port forwarding.
        /// </summary>
        /// <param name="timeout">The maximum amount of time to wait for the port to stop.</param>
        protected override void StopPort(TimeSpan timeout)
        {
            if (!ForwardedPortStatus.ToStopping(ref _status))
                return;

            base.StopPort(timeout);

            // send global request to cancel direct tcpip
            Session.SendMessage(new CancelTcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
            // wait for response on global request to cancel direct tcpip or completion of message
            // listener loop (in which case response on global request can never be received)
            WaitHandle.WaitAny(new[] { _globalRequestResponse, Session.MessageListenerCompleted }, timeout);

            // unsubscribe from session events as either the tcpip forward is cancelled at the
            // server, or our session message loop has completed
            Session.RequestSuccessReceived -= Session_RequestSuccess;
            Session.RequestFailureReceived -= Session_RequestFailure;
            Session.ChannelOpenReceived -= Session_ChannelOpening;

            // wait for pending channels to close
            _pendingChannelCountdown.Signal();
            _pendingChannelCountdown.Wait(timeout);

            _status = ForwardedPortStatus.Stopped;
        }
Beispiel #12
0
        /// <summary>
        /// Starts remote port forwarding.
        /// </summary>
        protected override void StartPort()
        {
            if (!ForwardedPortStatus.ToStarting(ref _status))
                return;

            InitializePendingChannelCountdown();

            try
            {
                Session.RegisterMessage("SSH_MSG_REQUEST_FAILURE");
                Session.RegisterMessage("SSH_MSG_REQUEST_SUCCESS");
                Session.RegisterMessage("SSH_MSG_CHANNEL_OPEN");

                Session.RequestSuccessReceived += Session_RequestSuccess;
                Session.RequestFailureReceived += Session_RequestFailure;
                Session.ChannelOpenReceived += Session_ChannelOpening;

                // send global request to start forwarding
                Session.SendMessage(new TcpIpForwardGlobalRequestMessage(BoundHost, BoundPort));
                // wat for response on global request to start direct tcpip
                Session.WaitOnHandle(_globalRequestResponse);

                if (!_requestStatus)
                {
                    throw new SshException(string.Format(CultureInfo.CurrentCulture, "Port forwarding for '{0}' port '{1}' failed to start.", Host, Port));
                }
            }
            catch (Exception)
            {
                // mark port stopped
                _status = ForwardedPortStatus.Stopped;

                // when the request to start port forward was rejected or failed, then we're no longer
                // interested in these events
                Session.RequestSuccessReceived -= Session_RequestSuccess;
                Session.RequestFailureReceived -= Session_RequestFailure;
                Session.ChannelOpenReceived -= Session_ChannelOpening;

                throw;
            }

            _status = ForwardedPortStatus.Started;
        }
Beispiel #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ForwardedPortLocal"/> class.
        /// </summary>
        /// <param name="boundHost">The bound host.</param>
        /// <param name="boundPort">The bound port.</param>
        /// <param name="host">The host.</param>
        /// <param name="port">The port.</param>
        /// <exception cref="ArgumentNullException"><paramref name="boundHost"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="host"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="boundPort" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="port" /> is greater than <see cref="F:System.Net.IPEndPoint.MaxPort" />.</exception>
        public ForwardedPortLocal(string boundHost, uint boundPort, string host, uint port)
        {
            if (boundHost == null)
                throw new ArgumentNullException("boundHost");

            if (host == null)
                throw new ArgumentNullException("host");

            boundPort.ValidatePort("boundPort");
            port.ValidatePort("port");

            BoundHost = boundHost;
            BoundPort = boundPort;
            Host = host;
            Port = port;
            _status = ForwardedPortStatus.Stopped;
        }