public MoreContainer(BencodedValue bencoded) { byId = new Dictionary <byte, string>(); byCode = new Dictionary <string, byte>(); Decode(bencoded, byId, byCode); }
private static void Handle(FileHash hash, PeerHash peer, byte[] payload, Action <FileHash, PeerHash, NetworkAddress[]> callback) { BencodedValue value = Bencoder.Decode(payload); byte[] added = value.Find("added", x => x?.Data?.GetBytes()); List <NetworkAddress> peers = new List <NetworkAddress>(); if (added != null) { for (int i = 0; i < added.Length; i += 6) { string host = GetHost(added, i); int port = GetPort(added, i); if (port > 0) { peers.Add(new NetworkAddress(host, port)); } } } if (added?.Length > 0) { callback(hash, peer, peers.ToArray()); } }
public static BencodedValue GetBencoded(this NetworkIncomingMessage incoming) { byte[] binary = incoming.ToBytes(6); BencodedValue bencoded = Bencoder.Decode(binary); return(bencoded); }
public void OnMessageSent(FileHash hash, PeerHash peer, byte[] payload) { BencodedValue bencoded = Bencoder.Decode(payload); int? message = bencoded.Find("msg_type", x => x?.ToInt32()); int? piece = bencoded.Find("piece", x => x?.ToInt32()); int? size = bencoded.Find("total_size", x => x?.ToInt32()); if (message == 0 && piece != null) { hooks.CallMetadataRequestSent(hash, peer, piece.Value); } if (message == 1 && size != null) { hooks.CallMetadataMeasured(hash, peer, size.Value); } if (message == 1 && piece != null) { byte[] content = Bytes.Copy(payload, bencoded.Data.Length); hooks.MetadataPieceSent(hash, peer, piece.Value, content); } if (message == 2 && piece != null) { hooks.CallMetadataRejectSent(hash, peer, piece.Value); } }
private static void FindEntriesList(BencodedValue value, List <MetainfoEntry> entries) { BencodedValue files = value.Find("files", x => x); if (files?.Array != null) { foreach (BencodedValue item in files.Array) { long? size = item.Find("length", x => x?.ToInt64()); BencodedValue path = item.Find("path", x => x); if (size != null && path?.Array != null) { List <string> names = new List <string>(); foreach (BencodedValue name in path.Array) { names.Add(name.ToText(Encoding.UTF8)); } entries.Add(new MetainfoEntry(names.ToArray(), size.Value)); } } } }
public static Metainfo FromBytes(byte[] bytes) { BencodedValue decoded = Bencoder.Decode(bytes); Metainfo metainfo = DecodeMetainfo(decoded); return(metainfo); }
public static void SendMetadataRequest(this CoordinatorService glue, PeerHash peer, int piece) { BencodedValue bencoded = new BencodedValue { Dictionary = new[] { new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("msg_type") }, Value = new BencodedValue { Number = new BencodedNumber(0) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("piece") }, Value = new BencodedValue { Number = new BencodedNumber(piece) } } } }; glue.SendExtension(peer, MetadataPlugin.Name, Bencoder.Encode(bencoded)); }
public Metainfo ToMetainfo(out byte[] bytes) { BencodedValue entries = Build(); bytes = Bencoder.Encode(entries); return(MetainfoFactory.FromBytes(bytes)); }
private static MetainfoProperties FindProperties(BencodedValue value, MetainfoEntry[] entries, MetainfoHash[] pieces) { long totalSize = entries.Sum(x => x.Size); int blockSize = 16384; int pieceSize = value.Find("piece length", x => (int)x.ToInt64()); return(new MetainfoProperties(totalSize, pieces.Length, pieceSize, blockSize)); }
public Extended GetHandshake() { BencodedValue encoded = more.Encode(metadata?.Size); byte[] binary = Bencoder.Encode(encoded); return(new Extended(0, binary)); }
public byte[] ToBytes() { BencodedValue entries = Build(); byte[] bytes = Bencoder.Encode(entries); return(bytes); }
private static MetainfoEntry[] FindEntries(BencodedValue value) { List <MetainfoEntry> entries = new List <MetainfoEntry>(); FindEntriesValue(value, entries); FindEntriesList(value, entries); return(entries.ToArray()); }
private static string[] FindTrackers(BencodedValue value) { HashSet <string> trackers = new HashSet <string>(); FindTrackerValue(value, trackers); FindTrackerList(value, trackers); return(trackers.ToArray()); }
public void ShouldDecodeAsInteger() { byte[] data = Encoding.ASCII.GetBytes("i10e"); BencodedValue value = Bencoder.Decode(data); value.Should().NotBeNull(); value.Number.Should().NotBeNull(); value.Number.ToInt32().Should().Be(10); }
private static void FindEntriesValue(BencodedValue value, List <MetainfoEntry> entries) { string name = value.Find("name", x => x?.ToText(Encoding.UTF8)); long? size = value.Find("length", x => x?.ToInt64()); if (name != null && size != null) { entries.Add(new MetainfoEntry(name, size.Value)); } }
public void OnHandshake(FileHash hash, PeerHash peer, byte[] payload) { BencodedValue bencoded = Bencoder.Decode(payload); int? size = bencoded.Find("metadata_size", x => x?.ToInt32()); if (size != null) { hooks.CallMetadataMeasured(hash, peer, size.Value); } }
private static Metainfo DecodeMetainfo(BencodedValue value) { FileHash hash = ComputeHash(value.Data); MetainfoEntry[] entries = FindEntries(value); MetainfoHash[] pieces = FindPieces(value); MetainfoProperties properties = FindProperties(value, entries, pieces); return(new Metainfo(hash, entries, pieces, properties)); }
private BencodedValue Build() { BencodedValue entries = new BencodedValue { Dictionary = new[] { new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("name") }, Value = new BencodedValue { Text = new BencodedText(this.entries[0].Name) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("length") }, Value = new BencodedValue { Number = new BencodedNumber(this.entries[0].Size) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("pieces") }, Value = new BencodedValue { Data = new BencodedData(ComputePieceHashes()) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("piece length") }, Value = new BencodedValue { Number = new BencodedNumber(16384) } } } }; return(entries); }
public FileHash ToHash() { BencodedValue entries = Build(); byte[] bytes = Bencoder.Encode(entries); Metainfo metainfo = MetainfoFactory.FromBytes(bytes); FileHash hash = metainfo.Hash; return(hash); }
public static MetainfoFile FromFile(string path) { byte[] bytes = File.ReadAllBytes(path); BencodedValue decoded = Bencoder.Decode(bytes); BencodedValue info = decoded.Find("info", x => x); Metainfo metainfo = DecodeMetainfo(info); string[] trackers = FindTrackers(decoded); return(new MetainfoFile(metainfo, trackers)); }
private static void FindTrackerValue(BencodedValue value, HashSet <string> trackers) { value.Find("announce", node => { if (node != null) { trackers.Add(node.ToText()); } return(node); }); }
private static MetainfoHash[] FindPieces(BencodedValue value) { byte[] data = value.Find("pieces", x => x.Data.GetBytes()); List <MetainfoHash> pieces = new List <MetainfoHash>(); for (int i = 0; i < data.Length; i += 20) { pieces.Add(new MetainfoHash(Bytes.Copy(data, i, 20))); } return(pieces.ToArray()); }
private static void FindTrackerList(BencodedValue value, HashSet <string> trackers) { value.Find("announce-list", node => { if (node != null) { foreach (string text in node.AllTexts()) { if (Uri.IsWellFormedUriString(text, UriKind.Absolute)) { trackers.Add(text); } } } return(node); }); }
private static void Decode(BencodedValue bencoded, IDictionary <byte, string> byId, IDictionary <string, byte> byCode) { BencodedValue received = bencoded.Find("m", x => x); if (received?.Dictionary != null) { foreach (BencodedEntry entry in received.Dictionary) { byte? id = entry.Value?.Number?.ToByte(); string code = entry.Key?.Text?.GetString(); if (id != null && code != null) { byId.Add(id.Value, code.ToLower()); byCode.Add(code.ToLower(), id.Value); } } } }
public static void SendPeers(this CoordinatorService glue, PeerHash peer, params NetworkAddress[] remotes) { BencodedValue bencoded = new BencodedValue { Dictionary = new[] { new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("added") }, Value = new BencodedValue { Data = ToData(remotes) } } } }; glue.SendExtension(peer, PeersPlugin.Name, Bencoder.Encode(bencoded)); }
public static void SendMetadataPiece(this CoordinatorService glue, PeerHash peer, int piece, int total, byte[] data) { BencodedValue bencoded = new BencodedValue { Dictionary = new[] { new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("msg_type") }, Value = new BencodedValue { Number = new BencodedNumber(1) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("piece") }, Value = new BencodedValue { Number = new BencodedNumber(piece) } }, new BencodedEntry { Key = new BencodedValue { Text = new BencodedText("total_size") }, Value = new BencodedValue { Number = new BencodedNumber(total) } } } }; byte[] payload = Bencoder.Encode(bencoded); Bytes.Append(ref payload, data); glue.SendExtension(peer, MetadataPlugin.Name, payload); }
private TcpSocketReceiveCallback OnReceived(TrackerGetHttpEntry entry) { return(received => { if (received.Status == SocketStatus.OK) { context.Queue.Add(() => { byte[] data = Bytes.Copy(entry.Buffer.Data, entry.Buffer.Offset, received.Count); string text = Encoding.ASCII.GetString(data); context.CallPacketReceived(entry.Endpoint, data.Length); if (text.StartsWith(TrackerGetHttpProtocol.ResponseHeader) == false) { context.CallPacketIgnored(entry.Endpoint, data.Length); return; } int counter = 0, position = 0; bool r = false, n = false; for (int i = 0; i < data.Length; i++) { if (data[i] == '\r') { r = true; counter++; continue; } if (data[i] == '\n') { n = true; counter++; continue; } if (counter == 4 && r && n) { position = i; break; } if (counter == 2 && !(r && n)) { position = i; break; } counter = 0; } if (position == 0) { context.CallPacketIgnored(entry.Endpoint, data.Length); return; } BencodedValue decoded = Bencoder.Decode(data, position); if (decoded.Dictionary == null) { context.CallPacketIgnored(entry.Endpoint, data.Length); return; } string failure = decoded.Find("failure reason", x => x?.Text?.GetString()); if (failure != null) { context.CallFailed(entry.Address, entry.Request.Hash, failure); return; } int?interval = decoded.Find("interval", x => x?.ToInt32()); BencodedValue peers = decoded.Find("peers", x => x); if (interval != null && peers.Text != null && peers.Text.Length % 6 == 0) { List <NetworkAddress> result = new List <NetworkAddress>(peers.Text.Length / 6); byte[] bytes = peers.Data.GetBytes(); for (int i = 0; i < bytes.Length; i += 6) { int port = Bytes.ReadUInt16(bytes, i + 4); StringBuilder address = new StringBuilder(); address.Append(bytes[i].ToString()); address.Append('.'); address.Append(bytes[i + 1].ToString()); address.Append('.'); address.Append(bytes[i + 2].ToString()); address.Append('.'); address.Append(bytes[i + 3].ToString()); if (port > 0) { result.Add(new NetworkAddress(address.ToString(), port)); } } collection.Remove(entry.Socket); entry.Callback.Invoke(TimeSpan.FromSeconds(interval.Value)); context.CallAnnounced(entry.Address, entry.Request.Hash, TimeSpan.FromSeconds(interval.Value), result.ToArray()); } }); } }); }
public static byte[] Encode(BencodedValue value) { return(new BencoderDecoder().Encode(value)); }