Example #1
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();
        }
Example #2
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));
        }
Example #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
                    }));
                }
            }
        }