/// <summary> /// Processes the received message. /// </summary> /// <param name="message">The message.</param> private void ProcessRecievedMessage(PeerMessage message) { this.CheckIfObjectIsDisposed(); lock (this.locker) { Debug.WriteLine($"{this.Endpoint} <- {message}"); this.lastMessageReceivedTime = DateTime.UtcNow; if (message is HandshakeMessage) { this.ProcessRecievedMessage(message as HandshakeMessage); } else if (message is ChokeMessage) { this.ProcessRecievedMessage(message as ChokeMessage); } else if (message is UnchokeMessage) { this.ProcessRecievedMessage(message as UnchokeMessage); } else if (message is InterestedMessage) { this.ProcessRecievedMessage(message as InterestedMessage); } else if (message is UninterestedMessage) { this.ProcessRecievedMessage(message as UninterestedMessage); } else if (message is HaveMessage) { this.ProcessRecievedMessage(message as HaveMessage); } else if (message is BitFieldMessage) { this.ProcessRecievedMessage(message as BitFieldMessage); } else if (message is RequestMessage) { this.ProcessRecievedMessage(message as RequestMessage); } else if (message is PieceMessage) { this.ProcessRecievedMessage(message as PieceMessage); } else if (message is CancelMessage) { this.ProcessRecievedMessage(message as CancelMessage); } else if (message is PortMessage) { // TODO } else if (message is KeepAliveMessage) { // do nothing } } }
/// <summary> /// Creates a new PeerMessageEventArgs /// </summary> /// <param name="manager">The manager.</param> /// <param name="message">The peer message involved</param> /// <param name="direction">The direction of the message</param> /// <param name="id">The identifier.</param> internal PeerMessageEventArgs(TorrentManager manager, PeerMessage message, Direction direction, PeerId id) : base(manager) { Direction = direction; ID = id; Message = message; }
private static void HandshakeReceived(bool success, PeerMessage message, object state) { var peer = (PeerState)state; var handshake = (HandshakeMessage)message; if (success) { peer.ReceivedHandshake = true; peer.Id = handshake.PeerId; if (peer.Id == Global.Instance.PeerId) { return; } PeerConnectedCallback callback; if (!InnerDictionary.TryGetValue(handshake.InfoHash, out callback)) { ClosePeerSocket(peer); } else { callback(peer); } } else { ClosePeerSocket(peer); } }
private void UpdateConnectedPeers(PeerMessage message) { if (message != null) { ConnectedPeers.Add(message); } NamedGuests = ConnectedPeers .Where(g => !string.IsNullOrEmpty(g.CustomName) && g.CustomName != PeerMessage.AnonymousName && !g.IsHost).ToList(); AnonymousGuests = ConnectedPeers .Count(g => (string.IsNullOrEmpty(g.CustomName) || g.CustomName == PeerMessage.AnonymousName) && !g.IsHost); NamedHosts = ConnectedPeers .Where(g => !string.IsNullOrEmpty(g.CustomName) && g.CustomName != PeerMessage.AnonymousName && g.IsHost).ToList(); AnonymousHosts = ConnectedPeers .Count(g => (string.IsNullOrEmpty(g.CustomName) || g.CustomName == PeerMessage.AnonymousName) && g.IsHost); RaiseUpdateEvent(); foreach (var guest in ConnectedPeers) { _log.LogDebug($"{guest.CustomName}"); _log.LogDebug($"{guest.DisplayName}"); } }
public void BitFieldDecoding() { var buffer = new byte[] { 0x00, 0x00, 0x00, 0x04, 0x05, 0xff, 0x08, 0xAA, 0xE3, 0x00 }; Console.WriteLine("Pieces: " + _testRig.Manager.Torrent.Pieces.Count); var message = (BitfieldMessage)PeerMessage.DecodeMessage(buffer, 0, 8, _testRig.Manager); for (var i = 0; i < 8; i++) { Assert.IsTrue(message.BitField[i], i.ToString(CultureInfo.InvariantCulture)); } for (var i = 8; i < 12; i++) { Assert.IsFalse(message.BitField[i], i.ToString(CultureInfo.InvariantCulture)); } Assert.IsTrue(message.BitField[12], 12.ToString(CultureInfo.InvariantCulture)); for (var i = 13; i < 15; i++) { Assert.IsFalse(message.BitField[i], i.ToString(CultureInfo.InvariantCulture)); } EncodeDecode(message); }
public void BitfieldCorrupt() { var data = new[] { true, false, false, true, false, true, false, true, false, true, false, true, false, false, false, true }; var encoded = new BitfieldMessage(new BitField(data)).Encode(); PeerMessage.DecodeMessage(encoded, 0, encoded.Length, _testRig.Manager); }
private void MessageReceived(bool successful, PeerMessage message, object state) { PeerId id = (PeerId)state; if (!successful) { id.ConnectionManager.CleanupSocket(id, "Could not receive a message"); return; } try { PeerMessageEventArgs e = new PeerMessageEventArgs(id.TorrentManager, (PeerMessage)message, Direction.Incoming, id); id.ConnectionManager.RaisePeerMessageTransferred(e); message.Handle(id); id.LastMessageReceived = DateTime.Now; PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id); } catch (TorrentException ex) { id.ConnectionManager.CleanupSocket(id, ex.Message); } }
private void SendMessage(PeerId id, PeerMessage message, MessagingCallback callback) { try { id.MessageSentCallback = callback; id.CurrentlySendingMessage = message; RateLimiterGroup limiter = id.TorrentManager.UploadLimiter; if (message is PieceMessage) { PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, limiter, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id); ClientEngine.BufferManager.FreeBuffer(ref ((PieceMessage)message).Data); id.IsRequestingPiecesCount--; } else { PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, null, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id); } } catch (Exception ex) { CleanupSocket(id, ex.Message); } }
/// <param name="id">The peer whose message queue you want to start processing</param> internal void ProcessQueue(PeerId id) { if (id.QueueLength == 0) { id.ProcessingQueue = false; return; } PeerMessage msg = id.Dequeue(); if (msg is PieceMessage) { using (ManualResetEvent handle = new ManualResetEvent(false)) { PieceMessage pm = (PieceMessage)msg; pm.Data = BufferManager.EmptyBuffer; ClientEngine.BufferManager.GetBuffer(ref pm.Data, pm.ByteLength); engine.DiskManager.QueueRead(id.TorrentManager, pm.StartOffset + ((long)pm.PieceIndex * id.TorrentManager.Torrent.PieceLength), pm.Data, pm.RequestLength, delegate { handle.Set(); }); handle.WaitOne(); id.PiecesSent++; } } try { SendMessage(id, msg, this.messageSentCallback); } catch (Exception e) { CleanupSocket(id, "Exception calling SendMessage: " + e.Message); } }
public Peer(string peerId) { Message = new PeerMessage { PeerId = peerId }; }
/// <summary> /// Creates a new PeerMessageEventArgs /// </summary> /// <param name="message">The peer message involved</param> /// <param name="direction">The direction of the message</param> internal PeerMessageEventArgs(TorrentManager manager, PeerMessage message, Direction direction, PeerId id) : base(manager) { this.direction = direction; this.id = id; this.message = message; }
private void PeerHandshakeReceived(bool succeeded, PeerMessage message, object state) { PeerId id = (PeerId)state; if (!succeeded) { CleanupSocket(id, "Handshaking failed"); return; } try { message.Handle(id); // If there are any pending messages, send them otherwise set the queue // processing as finished. if (id.QueueLength > 0) { id.ConnectionManager.ProcessQueue(id); } else { id.ProcessingQueue = false; } PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id); // Alert the engine that there is a new usable connection id.TorrentManager.HandlePeerConnected(id, Direction.Outgoing); } catch (TorrentException ex) { CleanupSocket(id, ex.Message); } }
private static void SendMessageHeader(IO.Stream stream, PeerMessage type, int length) { // Config.LogDebugMessage("Message sent: " + type.ToString()); WriteInt(stream, length + 1); stream.WriteByte((byte)type); }
private void CompleteSendOrReceiveFirst(byte[] buffer, IAsyncResult receiveResult, IAsyncResult sendResult) { int received = 0; Wait(receiveResult.AsyncWaitHandle); while ((received = connection.EndReceive(receiveResult)) != 0) { if (received != 4) { throw new Exception("Should be 4 bytes"); } int size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0)); received = 0; while (received != size) { IAsyncResult r = connection.BeginReceive(buffer, received + 4, size - received, null, null); Wait(r.AsyncWaitHandle); received += connection.EndReceive(r); } PieceMessage m = (PieceMessage)PeerMessage.DecodeMessage(buffer, 0, size + 4, rig.Manager); RequestMessage request = (RequestMessage)requests.Messages[0]; Assert.AreEqual(request.PieceIndex, m.PieceIndex, "#1"); Assert.AreEqual(request.RequestLength, m.RequestLength, "#1"); Assert.AreEqual(request.StartOffset, m.StartOffset, "#1"); for (int i = 0; i < request.RequestLength; i++) { if (buffer[i + 13] != (byte)(m.PieceIndex * rig.Torrent.PieceLength + m.StartOffset + i)) { throw new Exception("Corrupted data received"); } } requests.Messages.RemoveAt(0); if (requests.Messages.Count == 0) { //receiveResult = connection.BeginReceive(buffer, 0, 4, null, null); Wait(sendResult.AsyncWaitHandle); Assert.AreEqual(connection.EndSend(sendResult), amountSent); break; } receiveResult = connection.BeginReceive(buffer, 0, 4, null, null); } var baseUri = new Uri(listenerURL); baseUri = new Uri(baseUri, rig.Manager.Torrent.Name + "/"); if (rig.Manager.Torrent.Files.Length <= 1) { return; } Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[0].Path), _requestedUrl[0]); Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[1].Path), _requestedUrl[1]); }
public static void SendMessage(Socket socket, PeerMessage message, object state, MessageSentCallback callback) { var buffer = message.ToBytes(); var data = SendCache.Get().Init(socket, buffer, 0, buffer.Length, state, callback); SendMessageBase(data); }
protected virtual void MessageReceived(bool success, PeerMessage message, object state) { if (Stopping) { return; } var peer = (PeerState)state; try { if (success) { Monitor.Received(message.MessageLength); HandleMessage(message, peer); } else { CloseSocket(peer); ConnectPeer(peer.EndPoint); } } catch (Exception e) { OnRaisedException(e); } }
private static void EndReceive(bool success, int read, object state) { var data = (ReceiveMessageState)state; try { if (!success) { data.Callback(false, null, data.State); ReceiveCache.Put(data); return; } try { var message = PeerMessage.CreateFromBytes(data.Buffer, 0, read + 4); data.Callback(true, message, data.State); ReceiveCache.Put(data); } catch (Exception) { data.Callback(false, null, data.State); ReceiveCache.Put(data); } } catch (Exception e) { data.Callback(false, null, data.State); ReceiveCache.Put(data); Debug.WriteLine(e, "MessageIO.EndReceive"); } }
public void BitfieldCorrupt() { bool[] data = new bool[] { true, false, false, true, false, true, false, true, false, true, false, true, false, false, false, true }; byte[] encoded = new BitfieldMessage(new BitField(data)).Encode(); PeerMessage.DecodeMessage(encoded, 0, encoded.Length, testRig.Manager); }
internal PeerMessage Dequeue() { PeerMessage message = SendQueue[0]; SendQueue.RemoveAt(0); return(message); }
internal async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id) { await MainLoop.SwitchToThreadpool(); ByteBufferPool.Releaser releaser = default; try { while (true) { if (id.AmRequestingPiecesCount == 0 && releaser.Buffer != null) { releaser.Dispose(); releaser = NetworkIO.BufferPool.Rent(1, out ByteBuffer _); } else if (id.AmRequestingPiecesCount > 0 && releaser.Buffer == null) { releaser.Dispose(); releaser = NetworkIO.BufferPool.Rent(Piece.BlockSize, out ByteBuffer _); } PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, releaser.Buffer).ConfigureAwait(false); HandleReceivedMessage(id, torrentManager, message); } } catch { releaser.Dispose(); await ClientEngine.MainLoop; CleanupSocket(torrentManager, id); } }
public void CompleteChunkBeforeRequestNext() { var messages = new List <RequestMessage> (); var requestsBuffer = requests.Encode().AsMemory(); while (requestsBuffer.Length > 0) { var message = (RequestMessage)PeerMessage.DecodeMessage(requestsBuffer.Span, null).message; messages.Add(message); requestsBuffer = requestsBuffer.Slice(message.ByteLength); } for (int i = 0; i < messages.Count - 1; i++) { rig.Manager.PieceManager.PieceDataReceived(id, new PieceMessage(messages[i].PieceIndex, messages[i].StartOffset, messages[i].RequestLength), out _, out _); int orig = id.AmRequestingPiecesCount; rig.Manager.PieceManager.AddPieceRequests(id); Assert.AreEqual(orig, id.AmRequestingPiecesCount, "#1." + i); } rig.Manager.PieceManager.PieceDataReceived(id, new PieceMessage(messages.Last().PieceIndex, messages.Last().StartOffset, messages.Last().RequestLength), out _, out _); Assert.AreEqual(0, id.AmRequestingPiecesCount, "#2"); rig.Manager.PieceManager.AddPieceRequests(id); Assert.AreNotEqual(0, id.AmRequestingPiecesCount, "#3"); }
public async Task ToggleLikeChat( Chat chat, PeerMessage peer, string sessionId, ILogger log) { log.LogDebug("-> ChatProxy.ToggleLikeChat"); bool isLiked; if (chat.Likes.Any(l => l.PeerId == peer.PeerId)) { // Chat is already liked => Send unlike isLiked = false; } else { // Chat is not already liked => Send like isLiked = true; } await SendLike( isLiked, chat.UniqueId, peer, sessionId, log); }
protected virtual void SendMessage(PeerState peer, PeerMessage message) { if (Stopping) { return; } MessageIo.SendMessage(peer.Socket, message, peer, MessageSent); }
public void BitfieldCorrupt() { bool[] data = new bool[] { true, false, false, true, false, true, false, true, false, true, false, true, false, false, false, true }; byte[] encoded = new BitfieldMessage(new BitField(data)).Encode(); Assert.Catch <MessageException>(() => PeerMessage.DecodeMessage(encoded, 0, encoded.Length, testRig.Manager) ); }
/// <summary> /// Listens to incoming socket messages. /// </summary> private void Listen() { int timeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds; int bufferSize = 1024 * 1024; int bytesRead; int offset = 0; byte[] buffer = new byte[bufferSize]; TcpClient tcp; TransferManager transfer; while (!this.IsDisposed && this.IsRunning) { tcp = this.server.AcceptTcpClient(); tcp.Client.SendTimeout = timeout; tcp.SendBufferSize = bufferSize; tcp.Client.ReceiveTimeout = timeout; tcp.ReceiveBufferSize = bufferSize; offset = 0; try { bytesRead = tcp.GetStream().Read(buffer, 0, buffer.Length); if (bytesRead > 0) { foreach (var message in PeerMessage.Decode(buffer, ref offset, bytesRead)) { if (message is HandshakeMessage) { lock (((IDictionary)this.transfers).SyncRoot) { if (this.transfers.TryGetValue(message.As <HandshakeMessage>().InfoHash, out transfer)) { transfer.AddLeecher(tcp, message.As <HandshakeMessage>().PeerId); } else { Debug.WriteLine($"invalid torrent info hash: {message.As<HandshakeMessage>().InfoHash} received"); } } } } } } catch (IOException ex) { // something is wrong with remote peer -> ignore it Debug.WriteLine($"could not read stream from {tcp.Client.RemoteEndPoint}: {ex.Message}"); // close the connection tcp.Close(); tcp = null; } } }
private void EncodeDecode(Message orig) { orig.Encode(buffer, offset); Message dec = PeerMessage.DecodeMessage(buffer, offset, orig.ByteLength, testRig.Manager); Assert.IsTrue(orig.Equals(dec), string.Format("orig: {0}, new: {1}", orig, dec)); Assert.IsTrue(Toolbox.ByteMatch(orig.Encode(), PeerMessage.DecodeMessage(orig.Encode(), 0, orig.ByteLength, testRig.Manager).Encode())); }
public void LTChatDecodeTest() { var m = new LTChat(LTChat.Support.MessageId, "This Is My Message"); var data = m.Encode(); var decoded = (LTChat)PeerMessage.DecodeMessage(data, 0, data.Length, _rig.Manager); Assert.AreEqual(m.Message, decoded.Message, "#1"); }
public void LTChatDecodeTest() { LTChat m = new LTChat(LTChat.Support.MessageId, "This Is My Message"); byte[] data = m.Encode(); LTChat decoded = (LTChat)PeerMessage.DecodeMessage(data, 0, data.Length, rig.Manager); Assert.Equal(m.Message, decoded.Message); }
private void WEB_onMessage(PeerMessage obj) { if (obj.Content.Type == PeerMessageType.ASSIGN) { var info = (AssignMessage)obj.Content; transform.position = info.Position; } }
internal void Enqueue(PeerMessage msg) { sendQueue.Add(msg); if (!ProcessingQueue) { ProcessingQueue = true; ConnectionManager.ProcessQueue(this); } }
private void MessageReceived(bool successful, PeerMessage message, object state) { var id = (PeerId) state; if (!successful) { id.ConnectionManager.CleanupSocket(id, "Could not receive a message"); return; } try { var e = new PeerMessageEventArgs(id.TorrentManager, message, Direction.Incoming, id); id.ConnectionManager.RaisePeerMessageTransferred(e); message.Handle(id); id.LastMessageReceived = DateTime.Now; PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, MessageReceivedCallback, id); } catch (TorrentException ex) { id.ConnectionManager.CleanupSocket(id, ex.Message); } }
public void SendMessage(PeerMessage message) { if (message == null) throw new ArgumentNullException("message"); ClientEngine.MainLoop.QueueWait((MainLoopTask)delegate { if (Connection == null) return; Enqueue(message); }); }
private void SendMessage(PeerId id, PeerMessage message, MessagingCallback callback) { try { id.MessageSentCallback = callback; id.CurrentlySendingMessage = message; var limiter = id.TorrentManager.UploadLimiter; if (message is PieceMessage) { PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, limiter, id.Monitor, id.TorrentManager.Monitor, _endSendMessageCallback, id); ClientEngine.BufferManager.FreeBuffer(ref ((PieceMessage) message).Data); id.IsRequestingPiecesCount--; } else PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, null, id.Monitor, id.TorrentManager.Monitor, _endSendMessageCallback, id); } catch (Exception ex) { CleanupSocket(id, ex.Message); } }
internal void EnqueueAt(PeerMessage message, int index) { if (sendQueue.Count == 0 || index >= sendQueue.Count) Enqueue(message); else sendQueue.Insert(index, message); }
internal void Enqueue(PeerMessage msg) { sendQueue.Add(msg); if (!processingQueue) { processingQueue = true; ConnectionManager.ProcessQueue(this); } }
public void HandleMessage(PeerId id, PeerMessage message) { if (message is IFastPeerMessage && !id.SupportsFastPeer) throw new MessageException("Peer shouldn't support fast peer messages"); if (message is ExtensionMessage && !id.SupportsLTMessages && !(message is ExtendedHandshakeMessage)) throw new MessageException("Peer shouldn't support extension messages"); if (message is HaveMessage) HandleHaveMessage(id, (HaveMessage) message); else if (message is RequestMessage) HandleRequestMessage(id, (RequestMessage) message); else if (message is PortMessage) HandlePortMessage(id, (PortMessage) message); else if (message is PieceMessage) HandlePieceMessage(id, (PieceMessage) message); else if (message is NotInterestedMessage) HandleNotInterested(id, (NotInterestedMessage) message); else if (message is KeepAliveMessage) HandleKeepAliveMessage(id, (KeepAliveMessage) message); else if (message is InterestedMessage) HandleInterestedMessage(id, (InterestedMessage) message); else if (message is ChokeMessage) HandleChokeMessage(id, (ChokeMessage) message); else if (message is CancelMessage) HandleCancelMessage(id, (CancelMessage) message); else if (message is BitfieldMessage) HandleBitfieldMessage(id, (BitfieldMessage) message); else if (message is UnchokeMessage) HandleUnchokeMessage(id, (UnchokeMessage) message); else if (message is HaveAllMessage) HandleHaveAllMessage(id, (HaveAllMessage) message); else if (message is HaveNoneMessage) HandleHaveNoneMessage(id, (HaveNoneMessage) message); else if (message is RejectRequestMessage) HandleRejectRequestMessage(id, (RejectRequestMessage) message); else if (message is SuggestPieceMessage) HandleSuggestedPieceMessage(id, (SuggestPieceMessage) message); else if (message is AllowedFastMessage) HandleAllowedFastMessage(id, (AllowedFastMessage) message); else if (message is ExtendedHandshakeMessage) HandleExtendedHandshakeMessage(id, (ExtendedHandshakeMessage) message); else if (message is LTMetadata) HandleLtMetadataMessage(id, (LTMetadata) message); else if (message is LTChat) HandleLtChat(id, (LTChat) message); else if (message is PeerExchangeMessage) HandlePeerExchangeMessage(id, (PeerExchangeMessage) message); else if (message is HandshakeMessage) HandleHandshakeMessage(id, (HandshakeMessage) message); else if (message is ExtensionMessage) HandleGenericExtensionMessage(id, (ExtensionMessage) message); else throw new MessageException(string.Format("Unsupported message found: {0}", message.GetType().Name)); }
/// <summary> /// </summary> private void OnPeerHandshakeReceived(bool succeeded, PeerMessage message, object state) { var id = (PeerId) state; try { if (succeeded) HandleHandshake(id, (HandshakeMessage) message); else id.Connection.Dispose(); } catch (Exception) { Logger.Log(id.Connection, "ListenManager - Socket exception receiving handshake"); id.Connection.Dispose(); } }
private static void SendMessageHeader(IO.Stream stream, PeerMessage type, int length) { // Config.LogDebugMessage("Message sent: " + type.ToString()); WriteInt(stream, length+1); stream.WriteByte((byte)type); }
public void ReadMessageHeader(IO.Stream stream, out int length, out PeerMessage type) { length = ReadInt(stream); if (length > 0) type = (PeerMessage)stream.ReadByte(); else type = PeerMessage.KeepAlive; }
private void PeerHandshakeReceived(bool succeeded, PeerMessage message, object state) { var id = (PeerId) state; if (!succeeded) { CleanupSocket(id, "Handshaking failed"); return; } try { message.Handle(id); // If there are any pending messages, send them otherwise set the queue // processing as finished. if (id.QueueLength > 0) id.ConnectionManager.ProcessQueue(id); else id.ProcessingQueue = false; PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, MessageReceivedCallback, id); // Alert the engine that there is a new usable connection id.TorrentManager.HandlePeerConnected(id, Direction.Outgoing); } catch (TorrentException ex) { CleanupSocket(id, ex.Message); } }