public void InitiateTransfer(CustomConnection connection) { PeerId id = new PeerId(new Peer("", connection.Uri), rig.Manager); id.Connection = connection; byte[] data; EncryptorFactory.EndCheckEncryption(EncryptorFactory.BeginCheckEncryption(id, 68, null, null, new InfoHash[] { id.TorrentManager.InfoHash }), out data); decryptor = id.Decryptor; encryptor = id.Encryptor; TestHandshake(data, connection); }
private void SendMessage(PeerMessage message, CustomConnection connection) { byte[] b = message.Encode(); encryptor.Encrypt(b); IAsyncResult result = connection.BeginSend(b, 0, b.Length, null, null); if (!result.AsyncWaitHandle.WaitOne(5000, true)) { throw new Exception("Message didn't send correctly"); } connection.EndSend(result); }
public ConnectionPair(int port) { socketListener = new TcpListener(IPAddress.Loopback, port); socketListener.Start(); Socket s1a = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s1a.Connect(IPAddress.Loopback, port); Socket s1b = socketListener.AcceptSocket(); Incoming = new CustomConnection(s1a, true); Outgoing = new CustomConnection(s1b, false); socketListener.Stop(); }
public static PeerMessage ReceiveMessage(CustomConnection connection, IEncryption decryptor, TorrentManager manager) { byte[] buffer = new byte[4]; Receive(connection, buffer, 0, buffer.Length); decryptor.Decrypt(buffer); int count = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(buffer, 0)); byte[] message = new byte[count + 4]; Buffer.BlockCopy(buffer, 0, message, 0, 4); Receive(connection, message, 4, count); decryptor.Decrypt(message, 4, count); return(PeerMessage.DecodeMessage(message, 0, message.Length, manager)); }
public void TestHandshake(byte[] buffer, CustomConnection connection) { // 1) Send local handshake SendMessage(new HandshakeMessage(rig.Manager.Torrent.infoHash, new string('g', 20), VersionInfo.ProtocolStringV100, true, false), connection); // 2) Receive remote handshake if (buffer == null || buffer.Length == 0) { buffer = new byte[68]; Receive(connection, buffer, 0, 68); decryptor.Decrypt(buffer); } HandshakeMessage handshake = new HandshakeMessage(); handshake.Decode(buffer, 0, buffer.Length); Assert.AreEqual(rig.Engine.PeerId, handshake.PeerId, "#2"); Assert.AreEqual(VersionInfo.ProtocolStringV100, handshake.ProtocolString, "#3"); Assert.AreEqual(ClientEngine.SupportsFastPeer, handshake.SupportsFastPeer, "#4"); Assert.AreEqual(ClientEngine.SupportsExtended, handshake.SupportsExtendedMessaging, "#5"); // 2) Send local bitfield SendMessage(new BitfieldMessage(rig.Manager.Bitfield), connection); // 3) Receive remote bitfield - have none PeerMessage message = ReceiveMessage(connection); Assert.IsTrue(message is HaveNoneMessage || message is BitfieldMessage, "HaveNone"); // 4) Send a few allowed fast SendMessage(new AllowedFastMessage(1), connection); SendMessage(new AllowedFastMessage(2), connection); SendMessage(new AllowedFastMessage(3), connection); SendMessage(new AllowedFastMessage(0), connection); // 5) Receive a few allowed fast ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); ReceiveMessage(connection); }
public void RequestMetadata() { Setup(false, "path.torrent"); CustomConnection connection = pair.Incoming; // 1) Send local handshake. We've already received the remote handshake as part // of the Connect method. SendMessage(new HandshakeMessage(rig.Manager.Torrent.infoHash, new string('g', 20), VersionInfo.ProtocolStringV100, true, true), connection); ExtendedHandshakeMessage exHand = new ExtendedHandshakeMessage(rig.TorrentDict.LengthInBytes()); exHand.Supports.Add(LTMetadata.Support); SendMessage(exHand, connection); // 2) Send all our metadata requests int length = (rig.TorrentDict.LengthInBytes() + 16383) / 16384; for (int i = 0; i < length; i++) { SendMessage(new LTMetadata(LTMetadata.Support.MessageId, LTMetadata.eMessageType.Request, i, null), connection); } // 3) Receive all the metadata chunks PeerMessage m; var stream = new MemoryStream(); while (length > 0 && (m = ReceiveMessage(connection)) != null) { LTMetadata metadata = m as LTMetadata; if (metadata != null) { if (metadata.MetadataMessageType == LTMetadata.eMessageType.Data) { stream.Write(metadata.MetadataPiece, 0, metadata.MetadataPiece.Length); length--; } } } // 4) Verify the hash is the same. stream.Position = 0; #if NETSTANDARD1_5 Assert.Equal(rig.Torrent.InfoHash, new InfoHash(SHA1.Create().ComputeHash(stream))); #else Assert.Equal(rig.Torrent.InfoHash, new InfoHash(new SHA1Managed().ComputeHash(stream))); #endif }
public ConnectionPair(int port) { socketListener = new TcpListener(IPAddress.Loopback, port); socketListener.Start(); Socket s1a = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s1a.Connect(IPAddress.Loopback, port); #if NETSTANDARD1_5 Socket s1b = socketListener.AcceptSocketAsync().GetAwaiter().GetResult(); #else Socket s1b = socketListener.AcceptSocket(); #endif Incoming = new CustomConnection(s1a, true); Outgoing = new CustomConnection(s1b, false); socketListener.Stop(); }
public static void Receive(CustomConnection connection, byte[] buffer, int offset, int count) { while (count > 0) { var r = connection.BeginReceive(buffer, offset, count, null, null); if (!r.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(4))) { throw new Exception("Could not receive required data"); } int transferred = connection.EndReceive(r); if (transferred == 0) { throw new Exception("The socket was gracefully killed"); } offset += transferred; count -= transferred; } }
public void SendMetadataCore(string expectedPath) { CustomConnection connection = pair.Incoming; // 1) Send local handshake. We've already received the remote handshake as part // of the Connect method. SendMessage(new HandshakeMessage(rig.Manager.InfoHash, new string('g', 20), VersionInfo.ProtocolStringV100, true, true), connection); ExtendedHandshakeMessage exHand = new ExtendedHandshakeMessage(rig.Torrent.Metadata.Length); exHand.Supports.Add(LTMetadata.Support); SendMessage(exHand, connection); // 2) Receive the metadata requests from the other peer and fulfill them byte[] buffer = rig.Torrent.Metadata; int length = (buffer.Length + 16383) / 16384; PeerMessage m; while (length > 0 && (m = ReceiveMessage(connection)) != null) { LTMetadata metadata = m as LTMetadata; if (metadata != null) { if (metadata.MetadataMessageType == LTMetadata.eMessageType.Request) { metadata = new LTMetadata(LTMetadata.Support.MessageId, LTMetadata.eMessageType.Data, metadata.Piece, buffer); SendMessage(metadata, connection); length--; } } } // We've sent all the pieces. Now we just wait for the torrentmanager to process them all. while (rig.Manager.Mode is MetadataMode) { System.Threading.Thread.Sleep(10); } Assert.True(File.Exists(expectedPath), "#1"); Torrent torrent = Torrent.Load(expectedPath); Assert.Equal(rig.Manager.InfoHash, torrent.InfoHash); }
private PeerMessage ReceiveMessage(CustomConnection connection) { return(TransferTest.ReceiveMessage(connection, decryptor, rig.Manager)); }
PeerMessage ReceiveMessage(CustomConnection connection) { return(ReceiveMessage(connection, decryptor, rig.Manager)); }
void SendMessage(PeerMessage message, CustomConnection connection) { byte[] b = message.Encode(); encryptor.Encrypt(b); Send(connection, b, 0, b.Length); }