/// <summary> /// Return IP and Port of remote connection. /// </summary> /// <param name="socket"></param> /// <returns></returns> public PeerDetails GetConnectingPeerDetails(Socket socket) { PeerDetails peerDetails = new PeerDetails { ip = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString(), port = ((IPEndPoint)(socket.RemoteEndPoint)).Port }; return(peerDetails); }
/// <summary> /// Decode peer list sent by remote tracker. /// </summary> /// <param name="peers"></param> /// <param name="offset"></param> /// <returns></returns> internal List <PeerDetails> GetCompactPeerList(byte[] peers, int offset) { List <PeerDetails> peerList = new List <PeerDetails>(); for (var num = offset; num < peers.Length; num += 6) { PeerDetails peer = new PeerDetails { infoHash = InfoHash, peerID = String.Empty, ip = $"{peers[num]}.{peers[num + 1]}.{peers[num + 2]}.{peers[num + 3]}" }; peer.port = ((int)peers[num + 4] * 256) + peers[num + 5]; if (peer.ip != Ip) // Ignore self in peers list { Log.Logger.Trace($"(Tracker) Peer {peer.ip} Port {peer.port} found."); peerList.Add(peer); } } return(peerList); }
private readonly Bencode _Bencode; // Bencode encode/decode /// <summary> /// Decodes the announce request BEncoded response recieved from a tracker. /// </summary> /// <param name="announceResponse">Announce response.</param> /// <param name="decodedResponse">Response.</param> private void DecodeAnnounceResponse(Tracker tracker, byte[] announceResponse, ref AnnounceResponse decodedResponse) { if (announceResponse.Length != 0) { BNodeBase decodedAnnounce = _Bencode.Decode(announceResponse); decodedResponse.statusMessage = _Bencode.GetDictionaryEntryString(decodedAnnounce, "failure reason"); if (decodedResponse.statusMessage != "") { decodedResponse.failure = true; return; // If failure present then ignore rest of reply. } int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "complete"), out decodedResponse.complete); int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "incomplete"), out decodedResponse.incomplete); BNodeBase field = _Bencode.GetDictionaryEntry(decodedAnnounce, "peers"); if (field != null) { decodedResponse.peerList = new List <PeerDetails>(); if (field is BNodeString bNodeString) // Compact peer list reply { decodedResponse.peerList = tracker.GetCompactPeerList((bNodeString).str, 0); } else if (field is BNodeList bNodeList) // Non-compact peer list reply { foreach (var listItem in (bNodeList).list) { if (listItem is BNodeDictionary bNodeDictionary) { PeerDetails peer = new PeerDetails { infoHash = tracker.InfoHash }; BNodeBase peerDictionaryItem = (bNodeDictionary); BNodeBase peerField = _Bencode.GetDictionaryEntry(peerDictionaryItem, "ip"); if (peerField != null) { peer.ip = Encoding.ASCII.GetString(((BitTorrentLibrary.BNodeString)peerField).str); } if (peer.ip.Contains(":")) { peer.ip = peer.ip.Substring(peer.ip.LastIndexOf(":", StringComparison.Ordinal) + 1); } peerField = _Bencode.GetDictionaryEntry(peerDictionaryItem, "port"); if (peerField != null) { peer.port = int.Parse(Encoding.ASCII.GetString(((BitTorrentLibrary.BNodeNumber)peerField).number)); } if (peer.ip != tracker.Ip) // Ignore self in peers list { Log.Logger.Trace($"(Tracker) Peer {peer.ip} Port {peer.port} found."); decodedResponse.peerList.Add(peer); } } } } } int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "interval"), out decodedResponse.interval); int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "min interval"), out decodedResponse.minInterval); decodedResponse.trackerID = _Bencode.GetDictionaryEntryString(decodedAnnounce, "tracker id"); decodedResponse.statusMessage = _Bencode.GetDictionaryEntryString(decodedAnnounce, "warning message"); decodedResponse.announceCount++; } }