private static void Check(IMessage message, MessageType type) { var e = message.Encode(); Assert.AreEqual(e.Length, message.ByteLength, "#1"); Assert.IsTrue(Toolbox.ByteMatch(e, UdpTrackerMessage.DecodeMessage(e, 0, e.Length, type).Encode()), "#2"); }
async Task <UdpTrackerMessage> ReceiveAsync(UdpClient client, int transactionId, CancellationToken token) { while (!token.IsCancellationRequested) { UdpReceiveResult received = await client.ReceiveAsync(); var rsp = UdpTrackerMessage.DecodeMessage(received.Buffer, 0, received.Buffer.Length, MessageType.Response); if (transactionId == rsp.TransactionId) { if (rsp is ErrorMessage error) { FailureMessage = error.Error; throw new Exception("The tracker returned an error."); } else { return(rsp); } } } // If we get here then the token will have been cancelled. We need the additional // 'throw' statement to keep the compiler happy. token.ThrowIfCancellationRequested(); throw new OperationCanceledException("The tracker did not respond."); }
async void ReceiveAsync(UdpClient client, CancellationToken token) { Task sendTask = null; while (!token.IsCancellationRequested) { try { var result = await client.ReceiveAsync(); byte[] data = result.Buffer; if (data.Length < 16) { return;//bad request } UdpTrackerMessage request = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Request); if (sendTask != null) { try { await sendTask; } catch { } } switch (request.Action) { case 0: sendTask = ReceiveConnect(client, (ConnectMessage)request, result.RemoteEndPoint); break; case 1: sendTask = ReceiveAnnounce(client, (AnnounceMessage)request, result.RemoteEndPoint); break; case 2: sendTask = ReceiveScrape(client, (ScrapeMessage)request, result.RemoteEndPoint); break; case 3: sendTask = ReceiveError(client, (ErrorMessage)request, result.RemoteEndPoint); break; default: throw new ProtocolException(string.Format("Invalid udp message received: {0}", request.Action)); } } catch (Exception e) { Logger.Log(null, e.ToString()); } } }
private void ReceiveData(IAsyncResult ar) { try { System.Net.Sockets.UdpClient listener = (System.Net.Sockets.UdpClient)ar.AsyncState; byte[] data = listener.EndReceive(ar, ref endpoint); #endif if (data.Length < 16) { return;//bad request } UdpTrackerMessage request = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Request); switch (request.Action) { case 0: ReceiveConnect((ConnectMessage)request); break; case 1: ReceiveAnnounce((AnnounceMessage)request); break; case 2: ReceiveScrape((ScrapeMessage)request); break; case 3: ReceiveError((ErrorMessage)request); break; default: throw new ProtocolException(string.Format("Invalid udp message received: {0}", request.Action)); } } catch (Exception e) { Logger.Log(null, e.ToString()); } finally { if (Running) { #if NETSTANDARD1_5 result = await listener.ReceiveAsync(); ReceiveData(result, client); #else listener.BeginReceive(new AsyncCallback(ReceiveData), listener); #endif } } }
public void AnnounceMessageTest() { AnnounceMessage m = new AnnounceMessage(0, 12345, announceparams); AnnounceMessage d = (AnnounceMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request); Check(m, MessageType.Request); Assert.AreEqual(1, m.Action); Assert.AreEqual(m.Action, d.Action); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode())); Assert.AreEqual(12345, d.ConnectionId); }
public void ConnectMessageTest() { ConnectMessage m = new ConnectMessage(); ConnectMessage d = (ConnectMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request); Check(m, MessageType.Request); Assert.AreEqual(0, m.Action, "#0"); Assert.AreEqual(m.Action, d.Action, "#1"); Assert.AreEqual(m.ConnectionId, d.ConnectionId, "#2"); Assert.AreEqual(m.TransactionId, d.TransactionId, "#3"); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()), "#4"); }
public void AnnounceResponseTest() { var peers = peerEndpoints.Select(t => new Peer("", new Uri($"ipv4://{t.Address}:{t.Port}"))).ToList(); AnnounceResponseMessage m = new AnnounceResponseMessage(12345, TimeSpan.FromSeconds(10), 43, 65, peers); AnnounceResponseMessage d = (AnnounceResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response); Check(m, MessageType.Response); Assert.AreEqual(1, m.Action); Assert.AreEqual(m.Action, d.Action); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode())); Assert.AreEqual(12345, d.TransactionId); }
private UdpTrackerMessage Receive(UdpTrackerAsyncState trackerState, byte[] receivedMessage) { timeout = 0;//we have receive so unactive the timeout byte[] data = receivedMessage; UdpTrackerMessage rsp = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Response); if (trackerState.Message.TransactionId != rsp.TransactionId) { FailureMessage = "Invalid transaction Id in response from udp tracker!"; return(null);//to raise event fail outside } return(rsp); }
public void ConnectResponseTest() { ConnectResponseMessage m = new ConnectResponseMessage(5371, 12345); ConnectResponseMessage d = (ConnectResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), MessageType.Response); Check(m, MessageType.Response); Assert.AreEqual(0, m.Action, "#0"); Assert.AreEqual(m.Action, d.Action, "#1"); Assert.AreEqual(m.ConnectionId, d.ConnectionId, "#2"); Assert.AreEqual(m.TransactionId, d.TransactionId, "#3"); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()), "#4"); Assert.AreEqual(12345, d.ConnectionId); Assert.AreEqual(5371, d.TransactionId); }
public void ConnectResponseTest() { var expectedMessage = new ConnectResponseMessage(5371, 12345); var actualMessage = (ConnectResponseMessage) UdpTrackerMessage.DecodeMessage(expectedMessage.Encode(), 0, expectedMessage.ByteLength, MessageType.Response); Check(expectedMessage, MessageType.Response); Assert.AreEqual(0, expectedMessage.Action, "#0"); Assert.AreEqual(expectedMessage.Action, actualMessage.Action, "#1"); Assert.AreEqual(expectedMessage.ConnectionId, actualMessage.ConnectionId, "#2"); Assert.AreEqual(expectedMessage.TransactionId, actualMessage.TransactionId, "#3"); Assert.IsTrue(Toolbox.ByteMatch(expectedMessage.Encode(), actualMessage.Encode()), "#4"); Assert.AreEqual(12345, actualMessage.ConnectionId); Assert.AreEqual(5371, actualMessage.TransactionId); }
public void ScrapeResponseTest() { List <ScrapeDetails> details = new List <ScrapeDetails>(); details.Add(new ScrapeDetails(1, 2, 3)); details.Add(new ScrapeDetails(4, 5, 6)); details.Add(new ScrapeDetails(7, 8, 9)); ScrapeResponseMessage m = new ScrapeResponseMessage(12345, details); ScrapeResponseMessage d = (ScrapeResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response); Check(m, MessageType.Response); Assert.AreEqual(2, m.Action); Assert.AreEqual(m.Action, d.Action); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode())); Assert.AreEqual(12345, d.TransactionId); }
public void AnnounceResponseTest() { List <Peer> peers = new List <Peer>(); peers.Add(new Peer(new string('1', 20), new Uri("tcp://127.0.0.1:1"))); peers.Add(new Peer(new string('2', 20), new Uri("tcp://127.0.0.1:2"))); peers.Add(new Peer(new string('3', 20), new Uri("tcp://127.0.0.1:3"))); AnnounceResponseMessage m = new AnnounceResponseMessage(12345, TimeSpan.FromSeconds(10), 43, 65, peers); AnnounceResponseMessage d = (AnnounceResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response); Check(m, MessageType.Response); Assert.AreEqual(1, m.Action); Assert.AreEqual(m.Action, d.Action); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode())); Assert.AreEqual(12345, d.TransactionId); }
public void ScrapeResponseTest() { var details = new List <ScrapeDetails> { new ScrapeDetails(1, 2, 3), new ScrapeDetails(4, 5, 6), new ScrapeDetails(7, 8, 9) }; var expectedMessage = new ScrapeResponseMessage(12345, details); var actualMessage = (ScrapeResponseMessage) UdpTrackerMessage.DecodeMessage(expectedMessage.Encode(), 0, expectedMessage.ByteLength, MessageType.Response); Check(expectedMessage, MessageType.Response); Assert.AreEqual(2, expectedMessage.Action); Assert.AreEqual(expectedMessage.Action, actualMessage.Action); Assert.IsTrue(Toolbox.ByteMatch(expectedMessage.Encode(), actualMessage.Encode())); Assert.AreEqual(12345, actualMessage.TransactionId); }
async Task <UdpTrackerMessage> ReceiveAsync(UdpClient client, int transactionId, CancellationToken token) { while (!token.IsCancellationRequested) { var received = await client.ReceiveAsync(); UdpTrackerMessage rsp = UdpTrackerMessage.DecodeMessage(received.Buffer, 0, received.Buffer.Length, MessageType.Response); if (transactionId == rsp.TransactionId) { if (rsp is ErrorMessage error) { FailureMessage = error.Error; throw new Exception("The tracker returned an error."); } else { return(rsp); } } } throw new Exception("The tracker did not respond."); }
public void ScrapeMessageTest() { List <byte[]> hashes = new List <byte[]>(); Random r = new Random(); byte[] hash1 = new byte[20]; byte[] hash2 = new byte[20]; byte[] hash3 = new byte[20]; r.NextBytes(hash1); r.NextBytes(hash2); r.NextBytes(hash3); hashes.Add(hash1); hashes.Add(hash2); hashes.Add(hash3); ScrapeMessage m = new ScrapeMessage(12345, 123, hashes); ScrapeMessage d = (ScrapeMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request); Check(m, MessageType.Request); Assert.AreEqual(2, m.Action); Assert.AreEqual(m.Action, d.Action); Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode())); }
async void ReceiveAsync(UdpClient client, CancellationToken token) { Task sendTask = null; while (!token.IsCancellationRequested) { try { UdpReceiveResult result = await client.ReceiveAsync(); byte[] data = result.Buffer; if (data.Length < 16) { return; //bad request } var request = UdpTrackerMessage.DecodeMessage(data.AsSpan(0, data.Length), MessageType.Request); if (sendTask != null) { try { await sendTask; } catch { } } sendTask = request.Action switch { 0 => ReceiveConnect(client, (ConnectMessage)request, result.RemoteEndPoint), 1 => ReceiveAnnounce(client, (AnnounceMessage)request, result.RemoteEndPoint), 2 => ReceiveScrape(client, (ScrapeMessage)request, result.RemoteEndPoint), 3 => ReceiveError(client, (ErrorMessage)request, result.RemoteEndPoint), _ => throw new InvalidOperationException($"Invalid udp message received: {request.Action}") }; } catch (Exception e) { logger.Exception(e, "Exception while receiving a message"); } } }
void Check(UdpTrackerMessage message, MessageType type) { byte[] e = message.Encode(); Assert.AreEqual(e.Length, message.ByteLength, "#1"); Assert.IsTrue(Toolbox.ByteMatch(e, UdpTrackerMessage.DecodeMessage(e, type).Encode()), "#2"); }