public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes) { BDict d = (BDict)BencodingUtils.Decode(bytes); if (d.ContainsKey("added") && d.ContainsKey("added.f")) { BString pexList = (BString)d["added"]; BString pexFlags = (BString)d["added.f"]; for (int i = 0; i < pexList.ByteValue.Length / 6; i++) { UInt32 ip = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little); UInt16 port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big); byte flags = pexFlags.ByteValue[i]; IPEndPoint ipAddr = new IPEndPoint(ip, port); if (Added != null) { Added(peerWireClient, this, ipAddr, flags); } } } if (d.ContainsKey("dropped")) { BString pexList = (BString)d["dropped"]; for (int i = 0; i < pexList.ByteValue.Length / 6; i++) { UInt32 ip = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little); UInt16 port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big); IPEndPoint ipAddr = new IPEndPoint(ip, port); if (Dropped != null) { Dropped(peerWireClient, this, ipAddr); } } } }
public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes) { BDict dictionary = (BDict)BencodingUtils.Decode(bytes); if (!dictionary.ContainsKey(ADDED_KEY) && !dictionary.ContainsKey(ADDED_FLAGS_KEY) && !dictionary.ContainsKey(DROPPED_KEY)) { return; } if (dictionary.ContainsKey(ADDED_KEY) && dictionary.ContainsKey(ADDED_FLAGS_KEY)) { var pexList = (BString)dictionary[ADDED_KEY]; var pexFlags = (BString)dictionary[ADDED_FLAGS_KEY]; for (int i = 0; i < pexList.ByteValue.Length / 6; i++) { var ip = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little); var port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big); var flags = pexFlags.ByteValue[i]; var ipAddr = new IPEndPoint(ip, port); Added?.Invoke(peerWireClient, this, ipAddr, flags); } } else //if (d.ContainsKey(DROPPED_KEY)) { BString pexList = (BString)dictionary[DROPPED_KEY]; for (int i = 0; i < pexList.ByteValue.Length / 6; i++) { var ip = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little); var port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big); var ipAddr = new IPEndPoint(ip, port); Dropped?.Invoke(peerWireClient, this, ipAddr); } } }
public void OnHandshake(IPeerWireClient peerWireClient, byte[] handshake) { BDict dict = (BDict)BencodingUtils.Decode(handshake); if (dict.ContainsKey("metadata_size")) { BInt size = (BInt)dict["metadata_size"]; this._metadataSize = size; this._pieceCount = (Int64)Math.Ceiling((double)this._metadataSize / 16384); } this.RequestMetaData(peerWireClient); }
public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes) { BDict dict = (BDict)BencodingUtils.Decode(bytes); if (dict.ContainsKey("added")) { var trackerList = (BList)dict["added"]; foreach (var tracker in trackerList) { TrackerAdded?.Invoke(peerWireClient, this, tracker.ToString()); } } }
public static Torrent ReadTorrent(string filename) { // Читаем файл торрента и берем необходимый словарь info List <LostFile> files = new List <LostFile>(); BDict torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.UTF8); BDict fileInfo = (BDict)torrent["info"]; string name = ((BString)fileInfo["name"]).Value; int pieceLength = (int)((BInt)fileInfo["piece length"]).Value; // Перечитываем торрент еще раз, чтобы взять хеш в нужном виде torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.GetEncoding(437)); char[] pieces = ((BString)((BDict)torrent["info"])["pieces"]).Value.ToCharArray(); if (fileInfo.ContainsKey("files")) // Multifile torrent { BList filesData = (BList)fileInfo["files"]; long begin = 0; foreach (BDict file in filesData) { BList filePaths = (BList)file["path"]; long length = ((BInt)file["length"]).Value; string fullPath = name; foreach (BString partOfPath in filePaths) { fullPath += @"\" + partOfPath.Value; } files.Add(new LostFile(fullPath, length, begin)); begin += length; } } else // Singlefile torrent { long Length = ((BInt)fileInfo["length"]).Value; files.Add(new LostFile(name, Length, 0)); } return(new Torrent(name, files, pieceLength, pieces, filename)); }
public AnnounceInfo Announce(string url, string hash, string peerId, long bytesDownloaded, long bytesLeft, long bytesUploaded, int eventTypeFilter, int ipAddress, int numWant, int listenPort, int extensions) { byte[] hashBytes = Pack.Hex(hash); byte[] peerIdBytes = Encoding.ASCII.GetBytes(peerId); String realUrl = url.Replace("scrape", "announce") + "?"; String hashEncoded = ""; foreach (byte b in hashBytes) { hashEncoded += String.Format("%{0:X2}", b); } String peerIdEncoded = ""; foreach (byte b in peerIdBytes) { peerIdEncoded += String.Format("%{0:X2}", b); } realUrl += "info_hash=" + hashEncoded; realUrl += "&peer_id=" + peerIdEncoded; realUrl += "&port=" + listenPort; realUrl += "&uploaded=" + bytesUploaded; realUrl += "&downloaded=" + bytesDownloaded; realUrl += "&left=" + bytesLeft; realUrl += "&event=started"; realUrl += "&compact=1"; HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl); webRequest.Accept = "*/*"; webRequest.UserAgent = "System.Net.Torrent"; HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); if (stream == null) { return(null); } BinaryReader binaryReader = new BinaryReader(stream); byte[] bytes = new byte[0]; while (true) { try { byte[] b = new byte[1]; b[0] = binaryReader.ReadByte(); bytes = bytes.Concat(b).ToArray(); } catch (Exception) { break; } } BDict decoded = (BDict)BencodingUtils.Decode(bytes); if (decoded.Count == 0) { return(null); } if (!decoded.ContainsKey("peers")) { return(null); } if (!(decoded["peers"] is BString)) { throw new NotSupportedException("Dictionary based peers not supported"); } Int32 waitTime = 0; Int32 seeders = 0; Int32 leachers = 0; if (decoded.ContainsKey("interval")) { waitTime = (BInt)decoded["interval"]; } if (decoded.ContainsKey("complete")) { seeders = (BInt)decoded["complete"]; } if (decoded.ContainsKey("incomplete")) { leachers = (BInt)decoded["incomplete"]; } BString peerBinary = (BString)decoded["peers"]; return(new AnnounceInfo(GetPeers(peerBinary.ByteValue), waitTime, seeders, leachers)); }
public IDictionary <string, ScrapeInfo> Scrape(string url, string[] hashes) { Dictionary <String, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>(); String realUrl = url.Replace("announce", "scrape") + "?"; String hashEncoded = ""; foreach (String hash in hashes) { byte[] hashBytes = Pack.Hex(hash); hashEncoded = hashBytes.Aggregate(hashEncoded, (current, b) => current + String.Format("%{0:X2}", b)); realUrl += "info_hash=" + hashEncoded + "&"; } HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl); webRequest.Accept = "*/*"; webRequest.UserAgent = "System.Net.Torrent"; webRequest.Timeout = this.Timeout * 1000; HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); Stream stream = webResponse.GetResponseStream(); if (stream == null) { return(null); } BinaryReader binaryReader = new BinaryReader(stream); byte[] bytes = new byte[0]; while (true) { try { byte[] b = new byte[1]; b[0] = binaryReader.ReadByte(); bytes = bytes.Concat(b).ToArray(); } catch (Exception) { break; } } BDict decoded = (BDict)BencodingUtils.Decode(bytes); if (decoded.Count == 0) { return(null); } if (!decoded.ContainsKey("files")) { return(null); } BDict bDecoded = (BDict)decoded["files"]; foreach (String k in bDecoded.Keys) { BDict d = (BDict)bDecoded[k]; if (d.ContainsKey("complete") && d.ContainsKey("downloaded") && d.ContainsKey("incomplete")) { String rk = Unpack.Hex(BencodingUtils.ExtendedASCIIEncoding.GetBytes(k)); returnVal.Add(rk, new ScrapeInfo((uint)((BInt)d["complete"]).Value, (uint)((BInt)d["downloaded"]).Value, (uint)((BInt)d["incomplete"]).Value, ScraperType.HTTP)); } } return(returnVal); }
/// <summary> /// Background thread handling all incoming traffic /// </summary> private void ReceivePackets() { while (true) { try { // Get a datagram receiveFrom = new IPEndPoint(IPAddress.Any, localPort); byte[] data = udpClient.Receive(ref receiveFrom); // Decode the message Stream stream = new MemoryStream(data); IBencodingType receivedMsg = BencodingUtils.Decode(stream); string decoded = BencodingUtils.ExtendedASCIIEncoding.GetString(data.ToArray()); Log("Received message!"); //Log(decoded); // t is transaction id : todo: check, since ports are reused // y is e for error, r for reply, q for query if (receivedMsg is BDict) // throws error.. todo: fix { BDict dictMsg = (BDict)receivedMsg; if (dictMsg.ContainsKey("y")) { if (dictMsg["y"].Equals(new BString("e"))) { // received error Log("Received error! (ignored)"); } else if (dictMsg["y"].Equals(new BString("r"))) { // received reply if (dictMsg.ContainsKey("r")) { if (dictMsg["r"] is BDict) { BDict dictMsg2 = (BDict)dictMsg["r"]; if (dictMsg2.ContainsKey("values") && dictMsg.ContainsKey("t")) { Log("Received list of peers for torrent!"); countRecvPeerPackets++; BList peerAdrs = (BList)dictMsg2["values"]; UpdateTorrentPeerList(peerAdrs, (BString)dictMsg["t"]); } else if (dictMsg2.ContainsKey("nodes") && dictMsg.ContainsKey("t")) { // could be an answer to find node or get peers Log("Received list of nodeID & IP & port!"); countRecvNodePackets++; BString nodeIDString = (BString)dictMsg2["nodes"]; UpdateContactList(nodeIDString, (BString)dictMsg["t"]); } else { } } else { } } } else if (dictMsg["y"].Equals(new BString("q"))) { // received query Log("Received query! (ignored)"); } } } } catch (Exception ex) { Log("Error receiving data: " + ex.ToString()); } } }
/// <summary> /// Background thread handling all incoming traffic /// </summary> private void ReceivePackets() { while (true) { try { // Get a datagram receiveFrom = new IPEndPoint(IPAddress.Any, localPort); // Stopwatch sw = new Stopwatch(); // sw.Start(); byte[] data = udpClientReceive.Receive(ref receiveFrom); //if (sw.ElapsedMilliseconds > 10) { Console.WriteLine(sw.ElapsedMilliseconds); } //sw.Stop(); // Decode the message Stream stream = new MemoryStream(data); IBencodingType receivedMsg = BencodingUtils.Decode(stream); string decoded = BencodingUtils.ExtendedASCIIEncoding.GetString(data.ToArray()); //Log("Received message!"); // t is transaction id // y is e for error, r for reply, q for query if (receivedMsg is BDict) // throws error.. todo: fix { BDict dictMsg = (BDict)receivedMsg; if (dictMsg.ContainsKey("y")) { if (dictMsg["y"].Equals(new BString("e"))) { //Log("Received error! (ignored)"); } else if (dictMsg["y"].Equals(new BString("r"))) { // received reply if (dictMsg.ContainsKey("r")) { if (dictMsg["r"] is BDict) { BDict dictMsg2 = (BDict)dictMsg["r"]; if (dictMsg2.ContainsKey("values")) { //Log("Received list of peers for torrent!"); countRecvPeerPackets++; } else if (dictMsg2.ContainsKey("nodes")) { // could be an answer to find node or get peers //Log("Received list of nodeID & IP & port!"); countRecvNodePackets++; BString nodeIDString = (BString)dictMsg2["nodes"]; UpdateContactList(nodeIDString); } else { // no values and no nodes, assuming its a ping, // at least some form of response } } else { } } } else if (dictMsg["y"].Equals(new BString("q"))) { // received query countRecvQuery++; //Log("Received query! (ignored)"); } } } } catch (Exception ex) { //Log("Error receiving data: " + ex.ToString()); } } }
public bool Load(Stream stream) { _root = BencodingUtils.Decode(stream); if (_root == null) { return(false); } BDict dictRoot = (_root as BDict); if (dictRoot == null) { return(false); } if (dictRoot.ContainsKey("announce")) { Announce = (BString)dictRoot["announce"]; } if (dictRoot.ContainsKey("announce-list")) { BList announceList = (BList)dictRoot["announce-list"]; foreach (IBencodingType type in announceList) { if (type is BString) { AnnounceList.Add(type as BString); } else { BList list = type as BList; if (list == null) { continue; } BList listType = list; foreach (IBencodingType bencodingType in listType) { BString s = (BString)bencodingType; AnnounceList.Add(s); } } } } if (dictRoot.ContainsKey("comment")) { Comment = (BString)dictRoot["comment"]; } if (dictRoot.ContainsKey("created by")) { CreatedBy = (BString)dictRoot["created by"]; } if (dictRoot.ContainsKey("creation date")) { long ts = (BInt)dictRoot["creation date"]; CreationDate = new DateTime(1970, 1, 1).AddSeconds(ts); } if (dictRoot.ContainsKey("info")) { BDict infoDict = (BDict)dictRoot["info"]; using (SHA1Managed sha1 = new SHA1Managed()) { byte[] str = BencodingUtils.EncodeBytes(infoDict); Hash = sha1.ComputeHash(str); } if (infoDict.ContainsKey("files")) { //multi file mode BList fileList = (BList)infoDict["files"]; foreach (IBencodingType bencodingType in fileList) { BDict fileDict = (BDict)bencodingType; String filename = string.Empty; Int64 filesize = default(Int64); if (fileDict.ContainsKey("path")) { BList filenameList = (BList)fileDict["path"]; foreach (IBencodingType type in filenameList) { filename += (BString)type; filename += "\\"; } filename = filename.Trim('\\'); } if (fileDict.ContainsKey("length")) { filesize = (BInt)fileDict["length"]; } Files.Add(filename, filesize); } } if (infoDict.ContainsKey("name")) { Name = (BString)infoDict["name"]; if (Files.Count == 0 && infoDict.ContainsKey("length")) { Files.Add(Name, (BInt)infoDict["length"]); } } if (infoDict.ContainsKey("private")) { BInt isPrivate = (BInt)infoDict["private"]; Private = isPrivate != 0; } if (infoDict.ContainsKey("pieces")) { BString pieces = (BString)infoDict["pieces"]; for (int x = 0; x < pieces.ByteValue.Length; x += 20) { byte[] hash = pieces.ByteValue.GetBytes(x, 20); PieceHashes.Add(hash); } } if (infoDict.ContainsKey("piece length")) { PieceSize = (BInt)infoDict["piece length"]; } } return(true); }