示例#1
0
        public void Test_GetRandomHashID()
        {
            var randShaId = DHTId.CreateRandom();

            Assert.IsNotNull(randShaId);
            Assert.AreEqual(20, randShaId.Data.Length);
        }
示例#2
0
        internal void SendAnnouncePeerQuery(DHTNode remoteNode, DHTId infoHash, byte implied_port, int port, BString token)
        {
            if (remoteNode == null || token == null || token.Length == 0)
            {
                return;
            }

            long nowTicks = DateTime.UtcNow.Ticks;

            if (nowTicks - remoteNode.LastAnnouncementTime < AnnounceLife.Ticks)
            {
                return;
            }
            remoteNode.LastAnnouncementTime = nowTicks;

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Send announce peer query {0}, {1}, {2}", remoteNode.EndPoint, implied_port, port);
#endif

            // https://www.bittorrent.org/beps/bep_0005.html
            // If implied_port (0/1) is present and non-zero, the port argument should be ignored
            // and the source port of the UDP packet should be used as the peer's port instead.

            var transactionID = DHTTransactions.GetNextId();
            var msg           = DHTMessage.CreateAnnouncePeerQuery(transactionID, fLocalID, infoHash, implied_port, port, token);
            fTransactions.SetQuery(transactionID, msg);
            Send(remoteNode.EndPoint, msg);
        }
示例#3
0
        private void OnRecvAnnouncePeerQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var t    = data.Get <BString>("t");
            var args = data.Get <BDictionary>("a");

            var id          = args.Get <BString>("id");
            var infoHash    = new DHTId(args.Get <BString>("info_hash"));
            var impliedPort = args.Get <BNumber>("implied_port");
            int port        = (impliedPort != null && impliedPort.Value == 1) ? ipinfo.Port : (int)args.Get <BNumber>("port").Value;

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Receive `announce_peer` query from {0} for {1}", remoteNode.ToString(), infoHash.ToString());
#endif

            // skip response for another infohash query
            if (infoHash == fSearchInfoHash)
            {
                // receive `announce_peer` query for our infohash
                var nodesList = fRoutingTable.GetClosest(infoHash.Data);
                Send(ipinfo, DHTMessage.CreateAnnouncePeerResponse(t, fLocalID, nodesList));

                if (PeersFound != null)
                {
                    PeersFound(this, new PeersFoundEventArgs(new List <IPEndPoint>()
                    {
                        ipinfo
                    }));
                }
            }
        }
        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));
        }
示例#5
0
        private void SearchNodes(DHTId searchInfoHash)
        {
            fLogger.WriteDebug("Search for: {0}", searchInfoHash.ToString());

            fSearchInfoHash = searchInfoHash;

            new Thread(() => {
                while (Connected)
                {
                    long nowTicks = DateTime.UtcNow.Ticks;

                    int count = 0;
                    lock (fRoutingTable) {
                        // if the routing table has not been updated for more
                        // than a minute - reset routing table
                        if (nowTicks - fLastNodesUpdateTime > NODES_UPDATE_TIME)
                        {
                            fRoutingTable.Clear();
                            fLogger.WriteDebug("DHT reset routing table");
                        }

                        count = fRoutingTable.Count;
                    }

                    if (count == 0)
                    {
                        // reboot if empty
                        foreach (var t in fRouters)
                        {
                            SendFindNodeQuery(new IPEndPoint(t, PublicDHTPort), null);
                        }
                    }
                    else
                    {
                        // search
                        // bucket = 32 - significantly increases the speed and reliability of peers discovery
                        var nodes = fRoutingTable.GetClosest(fSearchInfoHash.Data, 32);

#if DEBUG_DHT_INTERNALS
                        fLogger.WriteDebug("RoutingTable size: {0}", fRoutingTable.Count);
                        fLogger.WriteDebug("Closest list size: {0}", nodes.Count);
#endif

                        foreach (var node in nodes)
                        {
                            if (nowTicks - node.LastGetPeersTime > GetPeersRange.Ticks)
                            {
                                SendGetPeersQuery(node.EndPoint, fSearchInfoHash);
                                node.LastGetPeersTime = nowTicks;
                            }
                        }
                    }

                    RefreshRoutingTable();

                    Thread.Sleep(1000);
                }
            }).Start();
        }
示例#6
0
 public DHTClient(IPEndPoint localEndPoint, IDHTPeersHolder peersHolder, string clientVer) : base(localEndPoint)
 {
     fPeersHolder  = peersHolder;
     fLocalID      = peersHolder.ClientNodeId;
     fClientVer    = clientVer;
     fLogger       = LogManager.GetLogger(ProtocolHelper.LOG_FILE, ProtocolHelper.LOG_LEVEL, "DHTClient");
     fRoutingTable = new DHTRoutingTable(KTableSize);
     fTransactions = new DHTTransactions();
 }
        public void Test_UpdateNode_DDoS_Protection()
        {
            var table = new DHTRoutingTable(10);

            // do not use nodes with ports below 1024
            var node   = new DHTNode(DHTId.CreateRandom(), new IPEndPoint(IPAddress.Any, 111));
            var result = table.UpdateNode(node);

            Assert.IsFalse(result);
        }
        public void Test_UpdateNode()
        {
            var table = new DHTRoutingTable(10);

            table.UpdateNode(null);

            var node = new DHTNode(DHTId.CreateRandom(), new IPEndPoint(IPAddress.Any, 0));

            table.UpdateNode(node);
        }
示例#9
0
        public void Test_CreateAnnouncePeerResponse()
        {
            var        tid    = DHTTransactions.GetNextId();
            var        nodeId = DHTId.CreateRandom();
            DHTMessage msg    = DHTMessage.CreateAnnouncePeerResponse(tid, nodeId, new List <DHTNode>());

            Assert.IsNotNull(msg);
            Assert.AreEqual(MessageType.Response, msg.Type);
            // TODO: test contents
        }
        public void Test_PeerPingedEventArgs()
        {
            IPEndPoint peerEndPoint = new IPEndPoint(IPAddress.Any, 1111);
            var        nodeId       = DHTId.CreateRandom();
            var        evt          = new PeerPingedEventArgs(peerEndPoint, nodeId);

            Assert.IsNotNull(evt);
            Assert.AreEqual(peerEndPoint, evt.EndPoint);
            Assert.AreEqual(nodeId, evt.NodeId);
        }
示例#11
0
        internal void SendFindNodeQuery(IPEndPoint address, DHTId target, bool neighbor = true)
        {
            var   transactionID = DHTTransactions.GetNextId();
            DHTId targetId      = (target == null) ? fLocalID : ((neighbor) ? DHTNode.GetNeighbor(target.Data, fLocalID.Data) : target);

            var msg = DHTMessage.CreateFindNodeQuery(transactionID, fLocalID, targetId);

            fTransactions.SetQuery(transactionID, msg);
            Send(address, msg);
        }
示例#12
0
        internal void SendGetPeersQuery(IPEndPoint address, DHTId infoHash)
        {
#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Send get peers query {0}", address);
#endif

            var transactionID = DHTTransactions.GetNextId();
            var msg           = DHTMessage.CreateGetPeersQuery(transactionID, fLocalID, infoHash);
            fTransactions.SetQuery(transactionID, msg);
            Send(address, msg);
        }
示例#13
0
        public void Test_CreateFindNodeQuery()
        {
            var        tid    = DHTTransactions.GetNextId();
            var        nodeId = DHTId.CreateRandom();
            DHTMessage msg    = DHTMessage.CreateFindNodeQuery(tid, nodeId, nodeId);

            Assert.IsNotNull(msg);
            Assert.AreEqual(MessageType.Query, msg.Type);
            Assert.AreEqual(QueryType.FindNode, msg.QueryType);
            // TODO: test contents
        }
示例#14
0
        public void Test_CreateAnnouncePeerQuery()
        {
            var        tid      = DHTTransactions.GetNextId();
            var        nodeId   = DHTId.CreateRandom();
            var        infoHash = DHTId.CreateRandom();
            DHTMessage msg      = DHTMessage.CreateAnnouncePeerQuery(tid, nodeId, infoHash, 1, 1, new BString("XX"));

            Assert.IsNotNull(msg);
            Assert.AreEqual(MessageType.Query, msg.Type);
            Assert.AreEqual(QueryType.AnnouncePeer, msg.QueryType);
            // TODO: test contents
        }
        public void Test_MessageEventArgs()
        {
            IPEndPoint  peerEndPoint = new IPEndPoint(IPAddress.Any, 1111);
            var         nodeId       = DHTId.CreateRandom();
            BDictionary data         = new BDictionary();
            var         evt          = new MessageEventArgs(peerEndPoint, nodeId, data);

            Assert.IsNotNull(evt);
            Assert.AreEqual(peerEndPoint, evt.EndPoint);
            Assert.AreEqual(nodeId, evt.NodeId);
            Assert.AreEqual(data, evt.Data);
        }
示例#16
0
        public void Test_CreateGetPeersResponse()
        {
            var        tid      = DHTTransactions.GetNextId();
            var        nodeId   = DHTId.CreateRandom();
            var        infoHash = DHTId.CreateRandom();
            var        peers    = new List <IDHTPeer>();
            var        nodes    = new List <DHTNode>();
            DHTMessage msg      = DHTMessage.CreateGetPeersResponse(tid, nodeId, infoHash, peers, nodes);

            Assert.IsNotNull(msg);
            Assert.AreEqual(MessageType.Response, msg.Type);
            // TODO: test contents
        }
        public void Test_ctor()
        {
            var table = new DHTRoutingTable(10);

            Assert.IsNotNull(table);

            Assert.AreEqual(0, table.Count);

            table.Clear();

            var randId = DHTId.CreateRandom();
            var nodes  = table.GetClosest(randId.Data);
        }
示例#18
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));
        }
        public void Test_DHTNode()
        {
            var endPoint = new IPEndPoint(IPAddress.Any, 0);
            var randId   = DHTId.CreateRandom();
            var node     = new DHTNode(randId, endPoint);

            Assert.IsNotNull(node);
            Assert.AreEqual(randId.Data, node.Id.Data);
            Assert.AreEqual(endPoint, node.EndPoint);
            Assert.IsNotNullOrEmpty(node.ToString());

            Assert.AreEqual(0, node.LastAnnouncementTime);
            Assert.AreEqual(0, node.LastUpdateTime);
        }
示例#20
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));
        }
示例#21
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));
        }
        public void Test_FindNode()
        {
            var table = new DHTRoutingTable(10);

            var randId       = DHTId.CreateRandom();
            var nodeEndPoint = new IPEndPoint(IPAddress.Any, 6881);
            var node         = new DHTNode(randId, nodeEndPoint);

            table.UpdateNode(node);

            var node2 = table.FindNode(nodeEndPoint);

            Assert.IsNotNull(node2);

            node2 = table.FindNode(null);
            Assert.IsNull(node2);
        }
        public void Test_FindNodes()
        {
            var table = new DHTRoutingTable(10);

            var randId = DHTId.CreateRandom();
            var nodes  = table.GetClosest(randId.Data);

            Assert.IsNotNull(nodes);
            Assert.AreEqual(0, nodes.Count);

            var node = new DHTNode(randId, new IPEndPoint(IPAddress.Any, 6881));

            table.UpdateNode(node);
            nodes = table.GetClosest(randId.Data);
            Assert.IsNotNull(nodes);
            Assert.AreEqual(1, nodes.Count);
        }
示例#24
0
        private void OnRecvCustomQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var args = data.Get <BDictionary>("a");

            if (args == null)
            {
                return;
            }

            var   id     = args.Get <BString>("id");
            DHTId nodeId = (id != null) ? new DHTId(id) : null;

            if (QueryReceived != null)
            {
                QueryReceived(this, new MessageEventArgs(ipinfo, nodeId, data));
            }
        }
示例#25
0
        public static DHTMessage CreateAnnouncePeerQuery(BString transactionID, DHTId nodeId, DHTId infoHash,
                                                         byte implied_port, int port, BString token)
        {
            BDictionary sendData = new BDictionary();

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

            var args = new BDictionary();

            args.Add("id", nodeId.ToBencodedString());
            args.Add("implied_port", new BNumber(implied_port));
            args.Add("info_hash", infoHash.ToBencodedString());
            args.Add("port", new BNumber(port));
            args.Add("token", token);
            sendData.Add("a", args);

            return(new DHTMessage(MessageType.Query, QueryType.AnnouncePeer, sendData));
        }
示例#26
0
        public static DHTMessage CreateGetPeersQuery(BString transactionID, DHTId nodeId, DHTId infoHash)
        {
            BDictionary sendData = new BDictionary();

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

            #if IP6
            var want = new BList();
            want.Add("n6");
            sendData.Add("want", want);
            #endif

            var args = new BDictionary();
            args.Add("id", nodeId.ToBencodedString());
            args.Add("info_hash", infoHash.ToBencodedString());
            sendData.Add("a", args);

            return(new DHTMessage(MessageType.Query, QueryType.GetPeers, sendData));
        }
示例#27
0
        public static DHTMessage CreateFindNodeQuery(BString transactionID, DHTId nodeId, DHTId targetNodeId)
        {
            BDictionary sendData = new BDictionary();

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

            #if IP6
            var want = new BList();
            want.Add("n6");
            sendData.Add("want", want);
            #endif

            var args = new BDictionary();
            args.Add("id", nodeId.ToBencodedString());
            args.Add("target", targetNodeId.ToBencodedString());
            sendData.Add("a", args);

            return(new DHTMessage(MessageType.Query, QueryType.FindNode, sendData));
        }
示例#28
0
        private void OnRecvGetPeersQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var t    = data.Get <BString>("t");
            var args = data.Get <BDictionary>("a");

            var id       = args.Get <BString>("id");
            var infoHash = new DHTId(args.Get <BString>("info_hash"));

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Receive `get_peers` query from {0} for {1}", remoteNode.ToString(), infoHash.ToString());
#endif

            var neighbor  = DHTNode.GetNeighbor(infoHash.Data, fLocalID.Data);
            var peersList = (infoHash == fSearchInfoHash) ? fPeersHolder.GetPeersList() : null;
            var nodesList = fRoutingTable.GetClosest(infoHash.Data);
            Send(ipinfo, DHTMessage.CreateGetPeersResponse(t, neighbor, infoHash, peersList, nodesList));
        }
示例#29
0
 public DHTNode(DHTId id, IPEndPoint endPoint)
 {
     Id       = id;
     EndPoint = endPoint;
 }
示例#30
0
 public DHTNode(byte[] id, IPEndPoint endPoint)
 {
     Id       = new DHTId(id);
     EndPoint = endPoint;
 }