public void SocketShouldBeClosedAndBindShouldEndWhenOnErrorOccurredIsInvoked()
        {
            _sessionMock.Setup(p => p.IsConnected).Returns(true);
            _sessionMock.Setup(p => p.SendMessage(It.IsAny <ChannelOpenMessage>()))
            .Callback <Message>(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null,
                                                        new MessageEventArgs <ChannelOpenConfirmationMessage>(
                                                            new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber,
                                                                                               _remoteWindowSize,
                                                                                               _remotePacketSize,
                                                                                               _remoteChannelNumber))));
            _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny <EventWaitHandle>()))
            .Callback <WaitHandle>(p => p.WaitOne(Session.Infinite));

            var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);

            using (var localPortListener = new AsyncSocketListener(localPortEndPoint))
            {
                localPortListener.Start();

                localPortListener.Connected += socket =>
                {
                    var channel = new ChannelDirectTcpip(_sessionMock.Object,
                                                         _localChannelNumber,
                                                         _localWindowSize,
                                                         _localPacketSize);
                    channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket);

                    var signalSessionErrorOccurredThread =
                        new Thread(() =>
                    {
                        // sleep for a short period to allow channel to actually start receiving from socket
                        Thread.Sleep(100);
                        // raise ErrorOccured event on session
                        _sessionMock.Raise(s => s.ErrorOccured += null,
                                           new ExceptionEventArgs(new SystemException()));
                    });
                    signalSessionErrorOccurredThread.Start();

                    channel.Bind();

                    signalSessionErrorOccurredThread.Join();
                };

                var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(localPortEndPoint);

                // attempt to receive from socket to verify it was shut down by channel
                var buffer        = new byte[16];
                var bytesReceived = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                Assert.AreEqual(0, bytesReceived);
                Assert.IsTrue(client.Connected);
                // signal to server that we also shut down the socket at our end
                client.Shutdown(SocketShutdown.Send);
            }
        }
Пример #2
0
        private void Arrange()
        {
            var random = new Random();

            _localChannelNumber = (uint)random.Next(0, int.MaxValue);
            _localWindowSize    = (uint)random.Next(2000, 3000);
            _localPacketSize    = (uint)random.Next(1000, 2000);
            _remoteHost         = random.Next().ToString(CultureInfo.InvariantCulture);
            _port = (uint)random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort);
            _channelBindFinishedWaitHandle    = new ManualResetEvent(false);
            _clientReceivedFinishedWaitHandle = new ManualResetEvent(false);
            _channelException = null;

            _remoteChannelNumber = (uint)random.Next(0, int.MaxValue);
            _remoteWindowSize    = (uint)random.Next(0, int.MaxValue);
            _remotePacketSize    = (uint)random.Next(100, 200);

            _sessionMock        = new Mock <ISession>(MockBehavior.Strict);
            _forwardedPortMock  = new Mock <IForwardedPort>(MockBehavior.Strict);
            _connectionInfoMock = new Mock <IConnectionInfo>(MockBehavior.Strict);

            var sequence = new MockSequence();

            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence)
            .Setup(p => p.SendMessage(It.Is <ChannelOpenMessage>(m => AssertExpectedMessage(m))));
            _sessionMock.InSequence(sequence)
            .Setup(p => p.WaitOnHandle(It.IsNotNull <WaitHandle>()))
            .Callback <WaitHandle>(
                w =>
            {
                _sessionMock.Raise(
                    s => s.ChannelOpenConfirmationReceived += null,
                    new MessageEventArgs <ChannelOpenConfirmationMessage>(
                        new ChannelOpenConfirmationMessage(
                            _localChannelNumber,
                            _remoteWindowSize,
                            _remotePacketSize,
                            _remoteChannelNumber)));
                w.WaitOne();
            });
            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence)
            .Setup(
                p => p.TrySendMessage(It.Is <ChannelEofMessage>(m => m.LocalChannelNumber == _remoteChannelNumber)))
            .Returns(true);
            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence)
            .Setup(
                p => p.TrySendMessage(It.Is <ChannelCloseMessage>(m => m.LocalChannelNumber == _remoteChannelNumber)))
            .Returns(true);
            _sessionMock.InSequence(sequence)
            .Setup(p => p.WaitOnHandle(It.IsNotNull <WaitHandle>()))
            .Callback <WaitHandle>(
                w =>
            {
                _sessionMock.Raise(
                    s => s.ChannelCloseReceived += null,
                    new MessageEventArgs <ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
                w.WaitOne();
            });

            var localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122);

            _listener            = new AsyncSocketListener(localEndpoint);
            _listener.Connected += socket =>
            {
                try
                {
                    _channel = new ChannelDirectTcpip(
                        _sessionMock.Object,
                        _localChannelNumber,
                        _localWindowSize,
                        _localPacketSize);
                    _channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket);
                    _channel.Bind();
                }
                catch (Exception ex)
                {
                    _channelException = ex;
                }
                finally
                {
                    _channelBindFinishedWaitHandle.Set();
                }
            };
            _listener.Start();

            _client = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            _client.Connect(localEndpoint);

            var clientReceiveThread = new Thread(
                () =>
            {
                var buffer        = new byte[16];
                var bytesReceived = _client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                if (bytesReceived == 0)
                {
                    _client.Shutdown(SocketShutdown.Send);
                    _clientReceivedFinishedWaitHandle.Set();
                }
            }
                );

            clientReceiveThread.Start();

            // give channel time to bind to socket
            Thread.Sleep(200);
        }
Пример #3
0
        public void SocketShouldBeClosedAndEofShouldBeSentToServerWhenClientShutsDownSocket()
        {
            _sessionMock.Setup(p => p.IsConnected).Returns(true);
            _sessionMock.Setup(p => p.SendMessage(It.IsAny <ChannelOpenMessage>()))
            .Callback <Message>(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null,
                                                        new MessageEventArgs <ChannelOpenConfirmationMessage>(
                                                            new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber,
                                                                                               _remoteWindowSize, _remotePacketSize, _remoteChannelNumber))));
            _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny <EventWaitHandle>()))
            .Callback <WaitHandle>(p => p.WaitOne(-1));
            _sessionMock.Setup(p => p.TrySendMessage(It.IsAny <ChannelEofMessage>()))
            .Returns(true)
            .Callback <Message>(
                m => new Thread(() =>
            {
                Thread.Sleep(50);
                _sessionMock.Raise(s => s.ChannelEofReceived += null,
                                   new MessageEventArgs <ChannelEofMessage>(new ChannelEofMessage(_localChannelNumber)));
            }).Start());
            _sessionMock.Setup(p => p.TrySendMessage(It.IsAny <ChannelCloseMessage>()))
            .Returns(true)
            .Callback <Message>(
                m => new Thread(() =>
            {
                Thread.Sleep(50);
                _sessionMock.Raise(s => s.ChannelCloseReceived += null,
                                   new MessageEventArgs <ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
            }).Start());
            var                channelBindFinishedWaitHandle = new ManualResetEvent(false);
            Socket             handler = null;
            ChannelDirectTcpip channel = null;

            var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);

            using (var localPortListener = new AsyncSocketListener(localPortEndPoint))
            {
                localPortListener.Start();

                localPortListener.Connected += socket =>
                {
                    channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize,
                                                     _localPacketSize);
                    channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket);
                    channel.Bind();
                    channel.Close();

                    handler = socket;

                    channelBindFinishedWaitHandle.Set();
                };

                var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(localPortEndPoint);
                client.Shutdown(SocketShutdown.Send);
                Assert.IsFalse(client.Connected);

                channelBindFinishedWaitHandle.WaitOne();

                Assert.IsNotNull(handler);
                Assert.IsFalse(handler.Connected);

                _sessionMock.Verify(p => p.TrySendMessage(It.IsAny <ChannelEofMessage>()), Times.Once);
                _sessionMock.Verify(p => p.TrySendMessage(It.IsAny <ChannelCloseMessage>()), Times.Once);

                channel.Close();

                _sessionMock.Verify(p => p.TrySendMessage(It.IsAny <ChannelEofMessage>()), Times.Once);
                _sessionMock.Verify(p => p.TrySendMessage(It.IsAny <ChannelCloseMessage>()), Times.Once);
            }
        }