示例#1
0
        private void BroadCastClose(KademliaNode close, List <KademliaNode> nodes, int prefixLength)
        {
            if (!_alive)
            {
                return;
            }

            if (this != close)
            {
                int plength = CommonPrefixLength(_id, close._id);
                _table[plength].Remove(close);

                foreach (KademliaNode node in nodes)
                {
                    Update(node);
                }
            }

            KademliaNode target;

            for (int i = prefixLength; i < k_TableSize; i++)
            {
                target = _table[i].GetRandomNode();
                if (target == null)
                {
                    continue;
                }

                target.BroadCastClose(close, nodes, i + 1);
            }
        }
示例#2
0
        private void SendNeighbours(KademliaNode remote, List <KademliaNode> neighbours)
        {
            // receive
            List <KademliaNode> nodes = new List <KademliaNode>();

            foreach (KademliaNode node in neighbours)
            {
                if (node != this && !IsInTable(node))
                {
                    nodes.Add(node);
                }
            }

            if (_find_request != -1)
            {
                nodes = SortByDistance(nodes, _find_request);

                List <KademliaNode> closest_candidate = FindNeighbours(_find_request);
                foreach (KademliaNode node in nodes)
                {
                    node.Ping(this);
                }
                KademliaNode closest_known = closest_candidate.Count == 0 ? null : closest_candidate[0];
                for (int i = 0; i < k_FindConcurrency && i < nodes.Count; i++)
                {
                    if (closest_known is null || (nodes[i]._id ^ _find_request) < (closest_known._id ^ _find_request))
                    {
                        nodes[i].SendFindNode(this, _find_request);
                    }
                }
            }
        }
示例#3
0
        private void SendFindNode(KademliaNode remote, int target_id)
        {
            Update(remote);
            List <KademliaNode> found = FindNeighbours(target_id);

            remote.SendNeighbours(this, found);
        }
示例#4
0
        private void Transfer(KademliaNode remote, string msg, int prefixLength)
        {
            if (!_alive)
            {
                return;
            }

            if (this != remote)
            {
                Update(remote);
            }

            if (prefixLength != 0)
            {
                _touched = true;
                _log.Add("Received : " + '"' + msg + '"');
                _downloads++;
            }

            KademliaNode target;

            for (int i = prefixLength; i < k_TableSize; i++)
            {
                target = _table[i].GetRandomNode();
                if (target == null)
                {
                    continue;
                }
                _log.Add("Transfer " + '"' + msg + '"' + " to Node " + target.GetId());
                _uploads++;
                target.Transfer(this, msg, i + 1);
            }
        }
示例#5
0
 public void Remove(KademliaNode node)
 {
     if (_contents.Contains(node))
     {
         _contents.Remove(node);
     }
 }
示例#6
0
        public bool Add(KademliaNode node)
        {
            if (_contents.Contains(node))
            {
                // move node to most recently used
                _contents.Remove(node);
                _contents.Add(node);
                return(false);
            }

            if (_contents.Count < BucketSize)
            {
                _contents.Add(node);
                return(true);
            }

            if (_contents.First().Respond())
            {
                // discard apped
                return(false);
            }
            else
            {
                // evict least recently used node
                _contents.RemoveAt(0);
                _contents.Add(node);
                return(true);
            }
        }
示例#7
0
        private void AddNeighbours(KademliaNode target, List <KademliaNode> neighbours, List <KademliaNode> querry)
        {
            KademliaNode[] closest = GetCloseNodes(target._id, querry);
            for (int i = 0; i < k_FindConcurrency; i++)
            {
                if (closest[i] is null)
                {
                    break;
                }

                querry.Add(closest[i]);
                closest[i].AddNeighbours(target, neighbours, querry);
            }

            for (int i = 0; i < k_FindConcurrency; i++)
            {
                if (closest[i] is null || neighbours.Count > Bucket.BucketSize * 2)
                {
                    break;
                }
                if (neighbours.Contains(closest[i]))
                {
                    continue;
                }

                neighbours.Add(closest[i]);
            }

            AddNode(target);
        }
示例#8
0
 private void Ping(KademliaNode remote)
 {
     if (_alive)
     {
         Update(remote);
     }
     // actually if node is dead, no respond and cause timeout exception
     remote.Pong(this, _alive);
 }
示例#9
0
        public void Update(KademliaNode node)
        {
            if (node.GetId() == _id)
            {
                return;
            }
            int plength = CommonPrefixLength(_id, node.GetId());

            _table[plength].Update(node);
        }
示例#10
0
        // Initial connect to bootstrap node
        public void Bootstrap(KademliaNode bootstrapNode)
        {
            if (bootstrapNode is null)
            {
                return;
            }

            Update(bootstrapNode);
            FindNode(_id, bootstrapNode);
        }
示例#11
0
 private void Pong(KademliaNode remote, bool alive)
 {
     if (alive)
     {
         Update(remote);
     }
     else
     {
         RemoveNode(remote);
     }
 }
示例#12
0
        private bool IsInTable(KademliaNode node)
        {
            foreach (Bucket bucket in _table)
            {
                if (bucket._contents.Contains(node))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#13
0
 private void FindNode(int target_id, KademliaNode via_node = null)
 {
     _find_request = target_id;
     if (via_node is null)
     {
         QuerryNeighbours(target_id);
     }
     else
     {
         via_node.SendFindNode(this, target_id);
     }
     _find_request = -1;
 }
示例#14
0
        // Initial connect to bootstrap node
        public void Connect(KademliaNode bootstrapNode)
        {
            if (bootstrapNode is null)
            {
                return;
            }

            AddNode(bootstrapNode);
            foreach (KademliaNode node in bootstrapNode.FindNode(this))
            {
                AddNode(node);
            }
        }
示例#15
0
        private List <KademliaNode> FindNode(KademliaNode target)
        {
            List <KademliaNode> neighbours = new List <KademliaNode>();

            AddNeighbours(target, neighbours, new List <KademliaNode>());

            /*int index = 0;
             * while (neighbours.Count < Bucket.BucketSize * 2 && index < neighbours.Count)
             *      neighbours[index++].AddNeighbours(target, neighbours);*/

            /*for (index = 0; index < neighbours.Count; index++)
             *      neighbours[index].AddNeighbours(target, neighbours);*/

            return(neighbours);
        }
示例#16
0
        static public bool CreateKademliaNode(int id)
        {
            foreach (KademliaNode node in _kademliaNodes)
            {
                if (node.GetId() == id)
                {
                    return(false);
                }
            }

            KademliaNode newNode = new KademliaNode(id);

            if (id != 0)
            {
                newNode.Bootstrap(_kademliaNodes[0]);
            }
            _kademliaNodes.Add(newNode);
            return(true);
        }
示例#17
0
        private KademliaNode[] GetCloseNodes(int target_id, List <KademliaNode> querry)
        {
            KademliaNode[] closeNodes = new KademliaNode[k_FindConcurrency];
            for (int i = 0; i < k_TableSize; i++)
            {
                foreach (KademliaNode node in _table[i]._contents)
                {
                    if (querry.Contains(node) ||
                        CommonPrefixLength(target_id, _id) > CommonPrefixLength(target_id, node._id) ||
                        CommonPrefixLength(target_id, node._id) == 32)
                    {
                        continue;
                    }

                    if (closeNodes[0] is null || CommonPrefixLength(target_id, node._id) >= CommonPrefixLength(target_id, closeNodes[0]._id))
                    {
                        closeNodes[2] = closeNodes[1];
                        closeNodes[1] = closeNodes[0];
                        closeNodes[0] = node;
                    }
示例#18
0
        private void BroadCastPing(KademliaNode remote, KademliaNode from, int prefixLength)
        {
            if (!_alive)
            {
                return;
            }

            KademliaNode target;

            for (int i = prefixLength; i < k_TableSize; i++)
            {
                target = _table[i].GetRandomNode();
                if (target == null || target == remote || target == from)
                {
                    continue;
                }
                target.BroadCastPing(this, from, i + 1);
                Update(from);
            }
        }
示例#19
0
 private List <KademliaNode> FindNeighbours(KademliaNode target, int k = Bucket.BucketSize)
 {
     return(FindNeighbours(target._id, k));
 }
示例#20
0
 public void RemoveNode(KademliaNode node)
 {
     //int plength = CommonPrefixLength(_id, node.GetId());
 }
示例#21
0
        public void RemoveNode(KademliaNode node)
        {
            int plength = CommonPrefixLength(_id, node.GetId());

            _table[plength].Remove(node);
        }
示例#22
0
        /// <summary>
        /// Create a DHT using the given master server, and specify whether to publish our IP.
        /// PRECONDITION: Create one per app or you will have a node ID collision.
        /// </summary>
        /// <param name="dhtNode">The KademliaNode that is used to communicate using the protocol</param>
        /// <param name="alreadyBootstrapped">Checks if the node have or not to bootstrap</param>
        /// <param name="btpNode">The node to bootstrap with (can be leaved null)</param>
        public Dht(KademliaNode dhtNode = null, bool alreadyBootstrapped = false, string btpNode = "")
        {
            if (dhtNode != null)
            {
                this.dhtNode = dhtNode;
            }
            else
            {
                dhtNode = new KademliaNode();
            }
            if (!alreadyBootstrapped)
            {
                if (btpNode == "")
                {
                    int ourPort = dhtNode.GetPort();
                    log.Info("We are on UDP port " + ourPort.ToString());

                    log.Info("Getting bootstrap list...");

                    AppSettingsReader asr = new AppSettingsReader();

                    XDocument xmlDoc = XDocument.Load((string)asr.GetValue("KademliaNodesFile", typeof(string)));

                    List <EndpointAddress> nodes = new List <EndpointAddress>(from node in xmlDoc.Descendants("Node")
                                                                              select new EndpointAddress("soap.udp://" + node.Element("Host").Value + ":" + node.Element("Port").Value + "/kademlia"));

                    foreach (var node in nodes)
                    {
                        if (dhtNode.AsyncBootstrap(nodes))
                        {
                            log.Debug("OK!");
                        }
                        else
                        {
                            log.Debug("Failed.");
                        }
                    }
                }
                else
                {
                    try
                    {
                        log.Debug("Bootstrapping with " + btpNode);
                        EndpointAddress bootstrapNode = new EndpointAddress(btpNode);
                        if (dhtNode.Bootstrap(bootstrapNode))
                        {
                            log.Debug("OK!");
                        }
                        else
                        {
                            log.Debug("Failed.");
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Bad entry!", ex);
                    }
                }
            }
            else
            {
                log.Info("Self Bootstrapping");
                dhtNode.Bootstrap();
            }
            // Join the network officially
            log.Info("Trying to join network....");
            if (dhtNode.JoinNetwork())
            {
                log.Info("Online");
            }
            else
            {
                log.Warn("Unable to connect to Kademlia overlay!\n"
                         + "Check that nodes list has accessible nodes.");
            }
        }