private void ProcessReject(IPeerWireClient client, byte[] payload) { Int32 index = UnpackHelper.Int32(payload, 0, UnpackHelper.Endianness.Big); Int32 begin = UnpackHelper.Int32(payload, 4, UnpackHelper.Endianness.Big); Int32 length = UnpackHelper.Int32(payload, 8, UnpackHelper.Endianness.Big); this.OnReject(client, index, begin, length); }
private static IEnumerable <IPEndPoint> GetPeers(byte[] peerData) { for (int i = 0; i < peerData.Length; i += 6) { long addr = UnpackHelper.UInt32(peerData, i, UnpackHelper.Endianness.Big); ushort port = UnpackHelper.UInt16(peerData, i + 4, UnpackHelper.Endianness.Big); yield return(new IPEndPoint(addr, port)); } }
public bool OnCommand(IPeerWireClient client, int commandLength, byte commandId, byte[] payload) { if (commandId == 9) { UInt16 port = UnpackHelper.UInt16(payload, 0, UnpackHelper.Endianness.Big); this.OnPort(client, port); return(true); } return(false); }
private void ProcessHave() { Int32 pieceIndex = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big); lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(4); } this.PeerBitField[pieceIndex] = true; this.OnHave(pieceIndex); }
private void ProcessPiece(Int32 length) { Int32 index = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big); Int32 begin = UnpackHelper.Int32(this._internalBuffer, 4, UnpackHelper.Endianness.Big); lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(8); } byte[] buffer = this._internalBuffer.GetBytes(0, length - 8); lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(length - 8); } this.OnPiece(index, begin, buffer); }
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 = UnpackHelper.UInt32(pexList.ByteValue, i * 6, UnpackHelper.Endianness.Little); UInt16 port = UnpackHelper.UInt16(pexList.ByteValue, (i * 6) + 4, UnpackHelper.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 = UnpackHelper.UInt32(pexList.ByteValue, i * 6, UnpackHelper.Endianness.Little); UInt16 port = UnpackHelper.UInt16(pexList.ByteValue, (i * 6) + 4, UnpackHelper.Endianness.Big); IPEndPoint ipAddr = new IPEndPoint(ip, port); if (Dropped != null) { Dropped(peerWireClient, this, ipAddr); } } } }
private void ProcessRequest(bool cancel) { Int32 index = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big); Int32 begin = UnpackHelper.Int32(this._internalBuffer, 4, UnpackHelper.Endianness.Big); Int32 length = UnpackHelper.Int32(this._internalBuffer, 8, UnpackHelper.Endianness.Big); lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(12); } if (!cancel) { this.OnRequest(index, begin, length); } else { this.OnCancel(index, begin, length); } }
public IDictionary <string, ScrapeInfo> Scrape(string url, String[] hashes) { Dictionary <string, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>(); this.ValidateInput(url, hashes, ScraperType.UDP); Int32 transactionId = this.Random.Next(0, 65535); UdpClient udpClient = new UdpClient(this.Tracker, this.Port) { Client = { SendTimeout = this.Timeout * 1000, ReceiveTimeout = this.Timeout * 1000 } }; byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(transactionId)).ToArray(); udpClient.Send(sendBuf, sendBuf.Length); IPEndPoint endPoint = null; byte[] recBuf = udpClient.Receive(ref endPoint); if (recBuf == null) { throw new NoNullAllowedException("udpClient failed to receive"); } if (recBuf.Length < 0) { throw new InvalidOperationException("udpClient received no response"); } if (recBuf.Length < 16) { throw new InvalidOperationException("udpClient did not receive entire response"); } UInt32 recAction = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big); UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big); if (recAction != 0 || recTrasactionId != transactionId) { throw new Exception("Invalid response from tracker"); } this._currentConnectionId = CopyBytes(recBuf, 8, 8); byte[] hashBytes = new byte[0]; hashBytes = hashes.Aggregate(hashBytes, (current, hash) => current.Concat(PackHelper.Hex(hash)).ToArray()); int expectedLength = 8 + (12 * hashes.Length); sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(2)).Concat(PackHelper.Int32(transactionId)).Concat(hashBytes).ToArray(); udpClient.Send(sendBuf, sendBuf.Length); recBuf = udpClient.Receive(ref endPoint); if (recBuf == null) { throw new NoNullAllowedException("udpClient failed to receive"); } if (recBuf.Length < 0) { throw new InvalidOperationException("udpClient received no response"); } if (recBuf.Length < expectedLength) { throw new InvalidOperationException("udpClient did not receive entire response"); } recAction = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big); recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big); this._currentConnectionId = CopyBytes(recBuf, 8, 8); if (recAction != 2 || recTrasactionId != transactionId) { throw new Exception("Invalid response from tracker"); } Int32 startIndex = 8; foreach (string hash in hashes) { UInt32 seeders = UnpackHelper.UInt32(recBuf, startIndex, UnpackHelper.Endianness.Big); UInt32 completed = UnpackHelper.UInt32(recBuf, startIndex + 4, UnpackHelper.Endianness.Big); UInt32 Leechers = UnpackHelper.UInt32(recBuf, startIndex + 8, UnpackHelper.Endianness.Big); returnVal.Add(hash, new ScrapeInfo(seeders, completed, Leechers, ScraperType.UDP)); startIndex += 12; } udpClient.Close(); return(returnVal); }
public AnnounceInfo Announce(string url, string hash, string peerId, Int64 bytesDownloaded, Int64 bytesLeft, Int64 bytesUploaded, Int32 eventTypeFilter, Int32 ipAddress, Int32 numWant, Int32 listenPort, Int32 extensions) { List <IPEndPoint> returnValue = new List <IPEndPoint>(); this.ValidateInput(url, new[] { hash }, ScraperType.UDP); this._currentConnectionId = this.BaseCurrentConnectionId; Int32 trasactionId = this.Random.Next(0, 65535); UdpClient udpClient = new UdpClient(this.Tracker, this.Port) { DontFragment = true, Client = { SendTimeout = this.Timeout * 1000, ReceiveTimeout = this.Timeout * 1000 } }; byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(trasactionId)).ToArray(); udpClient.Send(sendBuf, sendBuf.Length); IPEndPoint endPoint = null; byte[] recBuf; try { recBuf = udpClient.Receive(ref endPoint); } catch (Exception) { return(null); } if (recBuf == null) { throw new NoNullAllowedException("udpClient failed to receive"); } if (recBuf.Length < 0) { throw new InvalidOperationException("udpClient received no response"); } if (recBuf.Length < 16) { throw new InvalidOperationException("udpClient did not receive entire response"); } UInt32 recAction = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big); UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big); if (recAction != 0 || recTrasactionId != trasactionId) { throw new Exception("Invalid response from tracker"); } this._currentConnectionId = CopyBytes(recBuf, 8, 8); byte[] hashBytes = PackHelper.Hex(hash).ToArray(); Int32 key = this.Random.Next(0, 65535); sendBuf = this._currentConnectionId. /*connection id*/ Concat(PackHelper.Int32(1)). /*action*/ Concat(PackHelper.Int32(trasactionId)). /*trasaction Id*/ Concat(hashBytes). /*hash*/ Concat(Encoding.ASCII.GetBytes(peerId)). /*my peer id*/ Concat(PackHelper.Int64(bytesDownloaded)). /*bytes downloaded*/ Concat(PackHelper.Int64(bytesLeft)). /*bytes left*/ Concat(PackHelper.Int64(bytesUploaded)). /*bytes uploaded*/ Concat(PackHelper.Int32(eventTypeFilter)). /*event, 0 for none, 2 for just started*/ Concat(PackHelper.Int32(ipAddress)). /*ip, 0 for this one*/ Concat(PackHelper.Int32(key)). /*unique key*/ Concat(PackHelper.Int32(numWant)). /*num want, -1 for as many as pos*/ Concat(PackHelper.Int32(listenPort)). /*listen port*/ Concat(PackHelper.Int32(extensions)).ToArray(); /*extensions*/ udpClient.Send(sendBuf, sendBuf.Length); try { recBuf = udpClient.Receive(ref endPoint); } catch (Exception) { return(null); } recAction = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big); recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big); int waitTime = (int)UnpackHelper.UInt32(recBuf, 8, UnpackHelper.Endianness.Big); int Leechers = (int)UnpackHelper.UInt32(recBuf, 12, UnpackHelper.Endianness.Big); int seeders = (int)UnpackHelper.UInt32(recBuf, 16, UnpackHelper.Endianness.Big); if (recAction != 1 || recTrasactionId != trasactionId) { throw new Exception("Invalid response from tracker"); } for (Int32 i = 20; i < recBuf.Length; i += 6) { UInt32 ip = UnpackHelper.UInt32(recBuf, i, UnpackHelper.Endianness.Big); UInt16 port = UnpackHelper.UInt16(recBuf, i + 4, UnpackHelper.Endianness.Big); returnValue.Add(new IPEndPoint(ip, port)); } udpClient.Close(); return(new AnnounceInfo(returnValue, waitTime, seeders, Leechers)); }
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 = PackHelper.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 = UnpackHelper.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); }
private void ProcessSuggest(IPeerWireClient client, byte[] payload) { Int32 index = UnpackHelper.Int32(payload, 0, UnpackHelper.Endianness.Big); this.OnSuggest(client, index); }
private bool _process() { if (!this._receiving) { byte[] recBuffer = new byte[this._dynamicBufferSize]; try { this._async = this.Socket.BeginReceive(recBuffer, 0, this._dynamicBufferSize, this.OnReceived, recBuffer); } catch (Exception ex) { Trace.TraceInformation(ex.Message); return(false); } this._receiving = true; } if (this._internalBuffer.Length < 4) { this.OnNoData(); return(this.Socket.Connected); } if (!this._handshakeComplete) { Int32 resLen = this._internalBuffer[0]; if (resLen != 19) { if (resLen == 0) { // keep alive? Thread.Sleep(100); this.Disconnect(); return(false); } } this._handshakeComplete = true; byte[] recReserved = this._internalBuffer.GetBytes(20, 8); this.RemoteUsesDHT = (recReserved[7] & 0x1) == 0x1; byte[] remoteHashBytes = this._internalBuffer.GetBytes(28, 20); if (String.IsNullOrEmpty(this.Hash)) { string remoteHash = UnpackHelper.Hex(remoteHashBytes); this.Hash = remoteHash; } byte[] remoteIdbytes = this._internalBuffer.GetBytes(48, 20); this.RemotePeerID = Encoding.ASCII.GetString(remoteIdbytes); lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(68); } this.OnHandshake(); if (this._handshakeSent) { return(true); } this.Handshake(); this.SendBitField(this.PeerBitField); return(true); } Int32 commandLength = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big); if (commandLength > (this._internalBuffer.Length - 4)) { //need more data first return(true); } lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(4); } if (commandLength == 0) { if (!this.KeepConnectionAlive) { return(true); } this.SendKeepAlive(); this.OnKeepAlive(); return(true); } Int32 commandId = this._internalBuffer[0]; lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(1); } switch (commandId) { case 0: //choke this.OnChoke(); break; case 1: //unchoke this.OnUnChoke(); break; case 2: //interested this.OnInterested(); break; case 3: //not interested this.OnNotInterested(); break; case 4: //have this.ProcessHave(); break; case 5: //bitfield this.ProcessBitfield(commandLength - 1); break; case 6: //request this.ProcessRequest(false); break; case 7: //piece this.ProcessPiece(commandLength - 1); break; case 8: //cancel this.ProcessRequest(true); break; default: { foreach (IProtocolExtension extension in this._btProtocolExtensions) { if (!extension.CommandIDs.Contains(b => b == commandId)) { continue; } if (extension.OnCommand(this, commandLength, (byte)commandId, this._internalBuffer)) { break; } } lock (this._locker) { this._internalBuffer = this._internalBuffer.GetBytes(commandLength - 1); } } break; } return(true); }