public void Handles_ServerGetPeerAddress(string username, IPAddress ip, int port)
        {
            GetPeerAddressResponse result = null;

            var waiter = new Mock <IWaiter>();

            waiter.Setup(m => m.Complete(It.IsAny <WaitKey>(), It.IsAny <GetPeerAddressResponse>()))
            .Callback <WaitKey, GetPeerAddressResponse>((key, response) => result = response);

            var ipBytes = ip.GetAddressBytes();

            Array.Reverse(ipBytes);

            var message = new MessageBuilder()
                          .Code(MessageCode.ServerGetPeerAddress)
                          .WriteString(username)
                          .WriteBytes(ipBytes)
                          .WriteInteger(port)
                          .Build();

            using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object))
            {
                s.InvokeMethod("ServerConnection_MessageRead", null, message);

                Assert.Equal(username, result.Username);
                Assert.Equal(ip, result.IPAddress);
                Assert.Equal(port, result.Port);
            }
        }
        public void Handles_ServerGetPeerAddress(string username, IPAddress ip, int port)
        {
            GetPeerAddressResponse result = null;

            var(handler, mocks) = GetFixture();

            mocks.Waiter.Setup(m => m.Complete(It.IsAny <WaitKey>(), It.IsAny <GetPeerAddressResponse>()))
            .Callback <WaitKey, GetPeerAddressResponse>((key, response) => result = response);

            var ipBytes = ip.GetAddressBytes();

            Array.Reverse(ipBytes);

            var message = new MessageBuilder()
                          .WriteCode(MessageCode.Server.GetPeerAddress)
                          .WriteString(username)
                          .WriteBytes(ipBytes)
                          .WriteInteger(port)
                          .Build();

            handler.HandleMessage(null, message);

            Assert.Equal(username, result.Username);
            Assert.Equal(ip, result.IPAddress);
            Assert.Equal(port, result.Port);
        }
        public void Parse_Throws_MessageException_On_Code_Mismatch()
        {
            var msg = new MessageBuilder()
                      .Code(MessageCode.PeerBrowseRequest)
                      .Build();

            var ex = Record.Exception(() => GetPeerAddressResponse.Parse(msg));

            Assert.NotNull(ex);
            Assert.IsType <MessageException>(ex);
        }
        public void Parse_Throws_MessageReadException_On_Missing_Data()
        {
            var msg = new MessageBuilder()
                      .Code(MessageCode.ServerGetPeerAddress)
                      .WriteString("foo")
                      .Build();

            var ex = Record.Exception(() => GetPeerAddressResponse.Parse(msg));

            Assert.NotNull(ex);
            Assert.IsType <MessageReadException>(ex);
        }
        public void Instantiates_With_The_Given_Data()
        {
            var un   = RandomGuid;
            var ip   = new IPAddress(Random.Next(1024));
            var port = Random.Next();

            GetPeerAddressResponse response = null;

            var ex = Record.Exception(() => response = new GetPeerAddressResponse(un, ip, port));

            Assert.Null(ex);

            Assert.Equal(un, response.Username);
            Assert.Equal(ip, response.IPAddress);
            Assert.Equal(port, response.Port);
        }
        public void Parse_Returns_Expected_Data()
        {
            var un = RandomGuid;

            var ip      = new IPAddress(Random.Next(1024));
            var ipBytes = ip.GetAddressBytes();

            Array.Reverse(ipBytes);

            var port = Random.Next();

            var msg = new MessageBuilder()
                      .Code(MessageCode.ServerGetPeerAddress)
                      .WriteString(un)
                      .WriteBytes(ipBytes)
                      .WriteInteger(port)
                      .Build();

            var response = GetPeerAddressResponse.Parse(msg);

            Assert.Equal(un, response.Username);
            Assert.Equal(ip, response.IPAddress);
            Assert.Equal(port, response.Port);
        }
Exemple #7
0
        /// <summary>
        ///     Handles incoming messages.
        /// </summary>
        /// <param name="sender">The <see cref="IMessageConnection"/> instance from which the message originated.</param>
        /// <param name="message">The message.</param>
        public async void HandleMessage(object sender, byte[] message)
        {
            var code = new MessageReader <MessageCode.Server>(message).ReadCode();

            Diagnostic.Debug($"Server message received: {code}");

            try
            {
                switch (code)
                {
                case MessageCode.Server.ParentMinSpeed:
                case MessageCode.Server.ParentSpeedRatio:
                case MessageCode.Server.WishlistInterval:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), IntegerResponse.FromByteArray <MessageCode.Server>(message));
                    break;

                case MessageCode.Server.Login:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), LoginResponse.FromByteArray(message));
                    break;

                case MessageCode.Server.RoomList:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), RoomList.FromByteArray(message));
                    break;

                case MessageCode.Server.PrivilegedUsers:
                    SoulseekClient.Waiter.Complete(new WaitKey(code), PrivilegedUserList.FromByteArray(message));
                    break;

                case MessageCode.Server.NetInfo:
                    var netInfo = NetInfo.FromByteArray(message);

                    try
                    {
                        await SoulseekClient.DistributedConnectionManager.AddParentConnectionAsync(netInfo.Parents).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        Diagnostic.Debug($"Error handling NetInfo message: {ex.Message}");
                    }

                    break;

                case MessageCode.Server.ConnectToPeer:
                    ConnectToPeerResponse connectToPeerResponse = default;

                    try
                    {
                        connectToPeerResponse = ConnectToPeerResponse.FromByteArray(message);

                        if (connectToPeerResponse.Type == Constants.ConnectionType.Transfer)
                        {
                            // ensure that we are expecting at least one file from this user before we connect. the response
                            // doesn't contain any other identifying information about the file.
                            if (!SoulseekClient.Downloads.IsEmpty && SoulseekClient.Downloads.Values.Any(d => d.Username == connectToPeerResponse.Username))
                            {
                                var(connection, remoteToken) = await SoulseekClient.PeerConnectionManager.GetTransferConnectionAsync(connectToPeerResponse).ConfigureAwait(false);

                                var download = SoulseekClient.Downloads.Values.FirstOrDefault(v => v.RemoteToken == remoteToken && v.Username == connectToPeerResponse.Username);

                                if (download != default(Transfer))
                                {
                                    SoulseekClient.Waiter.Complete(new WaitKey(Constants.WaitKey.IndirectTransfer, download.Username, download.Filename, download.RemoteToken), connection);
                                }
                            }
                            else
                            {
                                throw new SoulseekClientException($"Unexpected transfer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPAddress}:{connectToPeerResponse.Port}); Ignored");
                            }
                        }
                        else if (connectToPeerResponse.Type == Constants.ConnectionType.Peer)
                        {
                            await SoulseekClient.PeerConnectionManager.GetOrAddMessageConnectionAsync(connectToPeerResponse).ConfigureAwait(false);
                        }
                        else if (connectToPeerResponse.Type == Constants.ConnectionType.Distributed)
                        {
                            await SoulseekClient.DistributedConnectionManager.AddChildConnectionAsync(connectToPeerResponse).ConfigureAwait(false);
                        }
                        else
                        {
                            throw new MessageException($"Unknown Connect To Peer connection type '{connectToPeerResponse.Type}'");
                        }
                    }
                    catch (Exception ex)
                    {
                        Diagnostic.Debug($"Error handling ConnectToPeer response from {connectToPeerResponse?.Username} ({connectToPeerResponse?.IPAddress}:{connectToPeerResponse.Port}): {ex.Message}");
                    }

                    break;

                case MessageCode.Server.AddUser:
                    var addUserResponse = AddUserResponse.FromByteArray(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, addUserResponse.Username), addUserResponse);
                    break;

                case MessageCode.Server.GetStatus:
                    var statsResponse = GetStatusResponse.FromByteArray(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, statsResponse.Username), statsResponse);
                    UserStatusChanged?.Invoke(this, new UserStatusChangedEventArgs(statsResponse));
                    break;

                case MessageCode.Server.PrivateMessage:
                    var pm = PrivateMessage.FromByteArray(message);
                    PrivateMessageReceived?.Invoke(this, pm);

                    if (SoulseekClient.Options.AutoAcknowledgePrivateMessages)
                    {
                        await SoulseekClient.AcknowledgePrivateMessageAsync(pm.Id, CancellationToken.None).ConfigureAwait(false);
                    }

                    break;

                case MessageCode.Server.GetPeerAddress:
                    var peerAddressResponse = GetPeerAddressResponse.FromByteArray(message);
                    SoulseekClient.Waiter.Complete(new WaitKey(code, peerAddressResponse.Username), peerAddressResponse);
                    break;

                default:
                    Diagnostic.Debug($"Unhandled server message: {code}; {message.Length} bytes");
                    break;
                }
            }
            catch (Exception ex)
            {
                Diagnostic.Warning($"Error handling server message: {code}; {ex.Message}", ex);
            }
        }