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(); }
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)); }
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 })); } } }