예제 #1
0
        public static BDictionary CreateGetPeersResponse(
            BString transactionID, byte[] nid, byte[] infoHash,
            IList <IDHTPeer> peersList, IList <DHTNode> nodesList)
        {
            BList values = DHTHelper.CompactPeers(peersList);
            var   nodes  = new BString(DHTHelper.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("t", transactionID);
            sendData.Add("y", "r");

            var r = new BDictionary();

            r.Add("id", new BString(nid));
            r.Add("token", new BString(infoHash.Take(2)));
            if (values != null)
            {
                r.Add("values", values);
            }
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(sendData);
        }
예제 #2
0
        public override BDictionary Construct()
        {
            BDictionary arguments = new BDictionary
            {
                { "id", new BString(QueriedNode.Bytes) }
            };

            if (Nodes != null)
            {
                byte[] nodes = new byte[IPv4Node.CompactInfoSize * Nodes.Length];
                for (int i = 0; i < Nodes.Length; i++)
                {
                    Nodes[i].Encode(((Span <byte>)nodes).Slice(i * IPv4Node.CompactInfoSize));
                }
                arguments.Add("nodes", new BString(nodes));
            }
            if (Nodes6 != null)
            {
                byte[] nodes6 = new byte[IPv6Node.CompactInfoSize * Nodes6.Length];
                for (int i = 0; i < Nodes6.Length; i++)
                {
                    Nodes6[i].Encode(((Span <byte>)nodes6).Slice(i * IPv6Node.CompactInfoSize));
                }
                arguments.Add("nodes6", new BString(nodes6));
            }
            return(ConstructResponse(arguments));
        }
예제 #3
0
 public void Save(BDictionary data)
 {
     data.Add("uname", UserName);
     data.Add("uctry", Country);
     data.Add("utz", TimeZone);
     data.Add("ulangs", Languages);
 }
예제 #4
0
        private void PrepareRequest()
        {
            /* BEndode get_peers Request
             *
             * "t" -> <transId>,
             * "y" -> "q",
             * "q" -> "get_peers",
             * "a" -> { "id" -> <nodeId> , "info_hash" -> <infoHashBytes> }
             *
             */
            byte[] transId = new byte[2]; rnd.NextBytes(transId);
            byte[] nodeId  = new byte[20]; rnd.NextBytes(nodeId);

            BDictionary bRequest = new BDictionary();

            bRequest.Add("t", new BString(transId));
            bRequest.Add("y", "q");
            bRequest.Add("q", "get_peers");

            BDictionary bDicA = new BDictionary();

            bDicA.Add("id", new BString(nodeId));
            bDicA.Add("info_hash", new BString(infoHashBytes));
            bRequest.Add("a", bDicA);

            getPeersBytes = bRequest.EncodeAsBytes();
        }
예제 #5
0
        public static DHTMessage CreateGetPeersResponse(
            BString transactionID, DHTId nodeId, DHTId infoHash,
            IList <IDHTPeer> peersList, IList <DHTNode> nodesList)
        {
            BList values = DHTNode.CompactPeers(peersList);
            var   nodes  = new BString(DHTNode.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("t", transactionID);
            sendData.Add("y", "r");

            var r = new BDictionary();

            r.Add("id", nodeId.ToBencodedString());
            r.Add("token", new BString(infoHash.Data.SubArray(0, 2)));
            if (values != null)
            {
                r.Add("values", values);
            }
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
예제 #6
0
        /// <summary>
        /// 将 Peer 集合的数据转换为 BT 协议规定的格式
        /// </summary>
        private void HandlePeersData(BDictionary resultDict, IReadOnlyList <Peer> peers, AnnounceInputParameters inputParameters)
        {
            var total = Math.Min(peers.Count, inputParameters.PeerWantCount);

            //var startIndex = new Random().Next(total);

            // 判断当前 BT 客户端是否需要紧凑模式的数据。
            if (inputParameters.IsEnableCompact)
            {
                var compactResponse = new byte[total * 6];
                for (int index = 0; index < total; index++)
                {
                    var peer = peers[index];
                    Buffer.BlockCopy(peer.ToBytes(), 0, compactResponse, (total - 1) * 6, 6);
                }

                resultDict.Add(TrackerServerConsts.PeersKey, new BString(compactResponse));
            }
            else
            {
                var nonCompactResponse = new BList();
                for (int index = 0; index < total; index++)
                {
                    var peer = peers[index];
                    nonCompactResponse.Add(peer.ToEncodedDictionary());
                }

                resultDict.Add(TrackerServerConsts.PeersKey, nonCompactResponse);
            }
        }
예제 #7
0
        public static BDictionary CreateHandshakeResponse()
        {
            var data = new BDictionary();

            data.Add("y", "r");
            data.Add("r", "handshake");

            return(data);
        }
예제 #8
0
        public static BDictionary CreateGetPeerInfoQuery()
        {
            var data = new BDictionary();

            data.Add("y", "q");
            data.Add("q", "getpeerinfo");

            return(data);
        }
예제 #9
0
        public void Save(BDictionary data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            data.Add("uname", UserName);
            data.Add("uctry", Country);
            data.Add("utz", TimeZone);
            data.Add("ulangs", Languages);
        }
예제 #10
0
        public static BDictionary CreatePingResponse(BString transactionID, byte[] nid)
        {
            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", new BString(nid));
            sendData.Add("r", r);

            return(sendData);
        }
예제 #11
0
        public static DHTMessage CreatePingResponse(BString transactionID, DHTId nodeId)
        {
            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", nodeId.ToBencodedString());
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
예제 #12
0
        public async Task GetPeersInfo(GetPeersInfoInput input)
        {
            // 如果 BT 客户端没有传递 IP,则通过 Context 获得。
            if (string.IsNullOrEmpty(input.Ip))
            {
                input.Ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
            }

            // 本机测试用。
            input.Ip = "127.0.0.1";

            AnnounceInputParameters inputPara = input;
            var resultDict = new BDictionary();

            // 如果产生了错误,则不执行其他操作,直接返回结果。
            if (inputPara.Error.Count == 0)
            {
                _bitTorrentManager.UpdatePeer(input.Info_Hash, inputPara);
                _bitTorrentManager.ClearZombiePeers(input.Info_Hash, TimeSpan.FromMinutes(10));
                var peers = _bitTorrentManager.GetPeers(input.Info_Hash);

                HandlePeersData(resultDict, peers, inputPara);

                // 构建剩余字段信息
                // 客户端等待时间
                resultDict.Add(TrackerServerConsts.IntervalKey, new BNumber((int)TimeSpan.FromSeconds(30).TotalSeconds));
                // 最小等待间隔
                resultDict.Add(TrackerServerConsts.MinIntervalKey, new BNumber((int)TimeSpan.FromSeconds(30).TotalSeconds));
                // Tracker 服务器的 Id
                resultDict.Add(TrackerServerConsts.TrackerIdKey, new BString("Tracker-DEMO"));
                // 已完成的 Peer 数量
                resultDict.Add(TrackerServerConsts.CompleteKey, new BNumber(_bitTorrentManager.GetComplete(input.Info_Hash)));
                // 非做种状态的 Peer 数量
                resultDict.Add(TrackerServerConsts.IncompleteKey, new BNumber(_bitTorrentManager.GetInComplete(input.Info_Hash)));
            }
            else
            {
                resultDict = inputPara.Error;
            }

            // 写入响应结果。
            var resultDictBytes = resultDict.EncodeAsBytes();
            var response        = _httpContextAccessor.HttpContext.Response;

            response.ContentType   = "text/plain";
            response.StatusCode    = 200;
            response.ContentLength = resultDictBytes.Length;
            await response.Body.WriteAsync(resultDictBytes);
        }
예제 #13
0
        public static BDictionary CreateGetPeerInfoQuery(BString transactionID, DHTId nodeId)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "q");
            data.Add("q", "get_peer_info");

            var args = new BDictionary();

            args.Add("id", nodeId.ToBencodedString());
            data.Add("a", args);

            return(data);
        }
예제 #14
0
        public static DHTMessage CreatePingQuery(BString transactionID, DHTId nodeId)
        {
            BDictionary sendData = new BDictionary();

            sendData.Add("t", transactionID);
            sendData.Add("y", "q");
            sendData.Add("q", "ping");

            var args = new BDictionary();

            args.Add("id", nodeId.ToBencodedString());
            sendData.Add("a", args);

            return(new DHTMessage(MessageType.Query, QueryType.Ping, sendData));
        }
예제 #15
0
        public static BDictionary CreatePingQuery(BString transactionID, byte[] nodeId)
        {
            BDictionary sendData = new BDictionary();

            sendData.Add("t", transactionID);
            sendData.Add("y", "q");
            sendData.Add("q", "ping");

            var args = new BDictionary();

            args.Add("id", new BString(nodeId));
            sendData.Add("a", args);

            return(sendData);
        }
예제 #16
0
        public static BDictionary CreateHandshakeQuery()
        {
            var data = new BDictionary();

            data.Add("y", "q");
            data.Add("q", "handshake");

            var args = new BDictionary();

            args.Add("app", "GEDKeeper Communicator");
            args.Add("ver", "2.14.0");

            data.Add("a", args);

            return(data);
        }
예제 #17
0
        public void Add_NullIBobjectValue_ThrowsArgumentNullException()
        {
            var    dict   = new BDictionary();
            Action action = () => dict.Add("key", (IBObject)null);

            action.ShouldThrow <ArgumentNullException>();
        }
예제 #18
0
        public void Add_KeyValuePairWithNullValue_ThrowsArgumentException()
        {
            var    dict   = new BDictionary();
            Action action = () => dict.Add(new KeyValuePair <BString, IBObject>("key", null));

            action.ShouldThrow <ArgumentException>();
        }
예제 #19
0
        public static BDictionary CreateGetPeerInfoResponse()
        {
            var data = new BDictionary();

            data.Add("y", "r");
            data.Add("r", "getpeerinfo");

            var retvals  = new BDictionary();
            var peerInfo = new PeerProfile();

            peerInfo.ResetSystem();
            peerInfo.Save(retvals);
            data.Add("rv", retvals);

            return(data);
        }
예제 #20
0
        public static BDictionary CreateGetPeerInfoResponse(BString transactionID, DHTId nodeId, UserProfile peerProfile)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "r");

            var r = new BDictionary();

            r.Add("q", "get_peer_info");
            r.Add("id", nodeId.ToBencodedString());
            peerProfile.Save(r);
            data.Add("r", r);

            return(data);
        }
예제 #21
0
        public static byte[] CreateSignInfoKey()
        {
            BDictionary subnetKey = new BDictionary();

            subnetKey.Add("info", ProtocolHelper.NETWORK_SIGN);
            return(DHTHelper.CalculateInfoHashBytes(subnetKey));
        }
예제 #22
0
        public static BDictionary CreateChatResponse(BString transactionID, DHTId nodeId, long timestamp)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "r");

            var r = new BDictionary();

            r.Add("q", MSG_SIGN_CHAT);
            r.Add("id", nodeId.ToBencodedString());
            r.Add("ts", timestamp);
            data.Add("r", r);

            return(data);
        }
예제 #23
0
        public static BDictionary CreateHandshakeQuery(BString transactionID, DHTId nodeId)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "q");
            data.Add("q", "handshake");

            var args = new BDictionary();

            args.Add("id", nodeId.ToBencodedString());
            args.Add("app", "GEDKeeper Communicator");
            args.Add("ver", "2.14.0");
            data.Add("a", args);

            return(data);
        }
예제 #24
0
        public static BDictionary CreateChatMessage(string message)
        {
            var data = new BDictionary();

            data.Add("y", "q");
            data.Add("q", "chat");

            var args = new BDictionary();

            args.Add("msg", message);

            data.Add("a", args);

            data.Add("handshake", "gkn");

            return(data);
        }
예제 #25
0
        public override int Add(BDictionary <int, int> blist, int key, int preferredIndex)
        {
            int i     = blist.FindLowerBound(key);
            int value = _nextValue++;

            blist.Add(key, value);
            return(i);
        }
예제 #26
0
        public static BDictionary CreateAnnouncePeerResponse(BString transactionID, byte[] nid, IList <DHTNode> nodesList)
        {
            var nodes = new BString(DHTHelper.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", new BString(nid));
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(sendData);
        }
예제 #27
0
        public static BDictionary CreateHandshakeResponse(BString transactionID, byte[] nodeId)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "r");

            var r = new BDictionary();

            r.Add("q", "handshake");
            r.Add("id", new BString(nodeId));
            r.Add("app", "GEDKeeper Communicator");
            r.Add("ver", "2.14.0");
            data.Add("r", r);

            return(data);
        }
예제 #28
0
        public static DHTMessage CreateAnnouncePeerResponse(BString transactionID, DHTId nodeId, IList <DHTNode> nodesList)
        {
            var nodes = new BString(DHTNode.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", nodeId.ToBencodedString());
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
예제 #29
0
        public static BDictionary CreateHandshakeResponse(BString transactionID, DHTId nodeId, PresenceStatus presence)
        {
            var data = new BDictionary();

            data.Add("t", transactionID);
            data.Add("y", "r");

            var r = new BDictionary();

            r.Add("q", "handshake");
            r.Add("id", nodeId.ToBencodedString());
            r.Add("app", "GEDKeeper Communicator");
            r.Add("ver", "2.14.0");
            r.Add("presence", new BNumber((int)presence));
            data.Add("r", r);

            return(data);
        }
예제 #30
0
        public static DHTMessage CreateFindNodeResponse(BString transactionID,
                                                        byte[] nodeId, IList <DHTNode> nodesList)
        {
            var nodes = new BString(DHTHelper.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", new BString(nodeId));
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
예제 #31
0
파일: Torrent.cs 프로젝트: jcbarton/MUMS
        /// <summary>
        /// Private method that parses and returns the dictionary in the current position of the stream.
        /// </summary>
        /// <param name="br">The BinaryReader with the data to parse.</param>
        /// <returns>The dictionary parsed.</returns>
        /// <remarks>If the current position does not contain data similar to "dBencoded_stringBencoded_elemente", which is a bencoded dictionary, an exception will be thrown.</remarks>
        private static BDictionary ParseDictionary(BinaryReader br)
        {
            StringBuilder buffer = new StringBuilder(1024);

            char c = (char)br.ReadByte();
            if (c != 'd')
                throw new InvalidCharacterException(c, "'d'");

            BDictionary dictionary = new BDictionary();

            do
            {
                string key = ParseString(br);
                IBValue value = Parse(br);

                dictionary.Add(key, value);
            } while ((char)br.PeekChar() != 'e');

            br.ReadByte(); //skips the 'e' char

            return dictionary;
        }
예제 #32
0
        public static BDictionary DecodeDictionary(BencodeStream stream, Encoding encoding)
        {
            if (stream == null) throw new ArgumentNullException("stream");
            if (encoding == null) throw new ArgumentNullException("encoding");

            var startPosition = stream.Position;

            if (stream.Length < 2)
                throw new BencodeDecodingException<BDictionary>("Minimum valid length is 2 (an empty dictionary: 'de')", startPosition);

            // Dictionaries must start with 'd'
            if (stream.ReadChar() != 'd')
                throw new BencodeDecodingException<BDictionary>(string.Format("Must begin with 'd' but began with '{0}'", stream.ReadPreviousChar()), startPosition);

            var dictionary = new BDictionary();
            // Loop until next character is the end character 'e' or end of stream
            while (stream.Peek() != 'e' && stream.Peek() != -1)
            {
                // Decode next string in stream as the key
                BString key;
                try
                {
                    key = DecodeString(stream, encoding);
                }
                catch (BencodeDecodingException<BString> ex)
                {
                    throw new BencodeDecodingException<BDictionary>("Dictionary keys must be strings.", stream.Position);
                }

                // Decode next object in stream as the value
                var value = Decode(stream, encoding);
                if (value == null)
                    throw new BencodeDecodingException<BDictionary>("All keys must have a corresponding value.", stream.Position);

                dictionary.Add(key, value);
            }

            if (stream.ReadChar() != 'e')
                throw new BencodeDecodingException<BDictionary>("Missing end character 'e'.", stream.Position);

            return dictionary;
        }
예제 #33
0
 public void AddKeyValuePairWithNullValue()
 {
     var dict = new BDictionary();
     dict.Add(new KeyValuePair<BString, IBObject>("key", null));
 }
예제 #34
0
 public void AddNullObjectValue()
 {
     var dict = new BDictionary();
     dict.Add("key", (IBObject)null);
 }
예제 #35
0
 public void AddNullValue()
 {
     var dict = new BDictionary();
     dict.Add("key", null);
 }
예제 #36
0
 public void SetNullValue()
 {
     var dict = new BDictionary();
     dict.Add("key", "value");
     dict["key"] = null;
 }
예제 #37
0
        private static BDictionary ReadDictionary(BinaryReader binaryReader)
        {
            Contract.Requires(binaryReader != null);

            int i = binaryReader.ReadByte();
            if (i != 'd')
            {
                throw Error();
            }

            BDictionary dict = new BDictionary();

            try
            {
                for (int c = binaryReader.PeekChar(); ; c = binaryReader.PeekChar())
                {
                    if (c == -1) throw Error();
                    if (c == 'e')
                    {
                        binaryReader.ReadByte();
                        break;
                    }
                    BString k = ReadString(binaryReader);
                    IBElement v = ReadElement(binaryReader);
                    dict.Add(k, v);
                }
            }
            catch (BencodingException) { throw; }
            catch (Exception e) { throw Error(e); }

            return dict;
        }
예제 #38
0
 public void Add_KeyValuePairWithNullValue_ThrowsArgumentException()
 {
     var dict = new BDictionary();
     Action action = () => dict.Add(new KeyValuePair<BString, IBObject>("key", null));
     action.ShouldThrow<ArgumentException>();
 }
예제 #39
0
 public void Add_NullValue_ThrowsArgumentNullException()
 {
     var dict = new BDictionary();
     Action action = () => dict.Add("key", null);
     action.ShouldThrow<ArgumentNullException>();
 }