Exemple #1
0
        public void RetrieveValues_NoValuesInStorage()
        {
            KadNode node1 = new KadNode(new System.Net.IPEndPoint(IPAddress.Loopback, 55555));
            KadNode node2 = new KadNode(new System.Net.IPEndPoint(IPAddress.Loopback, 55556));

            List <KadContactNode> nodes = new List <KadContactNode>(20);

            for (int i = 0; i < 20; i++)
            {
                var contact = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                nodes.Add(contact);
                node2.BucketList.Put(contact);
                Thread.Sleep(500);
            }
            nodes = nodes.OrderBy((n) => n.Id.GetNumericValue()).ToList();
            node1.BucketList.Put(new KadContactNode(node2.Id, node2.EndPoint));

            var foundNodes = node1.FindValue(node2.Id, KadId.GenerateRandom()).Contacts;

            CollectionAssert.AreEqual(foundNodes.Select((n) => n.Id.GetNumericValue()).OrderBy((n) => n).ToList(),
                                      nodes.Select((n) => n.Id.GetNumericValue()).OrderBy((n) => n).ToList());

            node1.Shutdown();
            node2.Shutdown();
        }
        private Tuple <KadContactNode, KadValue> LookupValue(KadId valueId, out SortedSet <KadContactNode> retSortList)
        {
            var closestNodes = Owner.BucketList.GetClosestNodes(valueId, MaxConcurrentThreads);
            SortedSet <KadContactNode> shortList = new SortedSet <KadContactNode>(closestNodes, new KadId.KadIdToBaseComparator(valueId));

            retSortList = shortList;
            if (shortList.Count == 0)
            {
                return(null);
            }

            SortedSet <KadId> queriedNodes   = new SortedSet <KadId>(new KadId.KadIdToIdComparator());
            KadId             closestId      = shortList.Min.Id;
            SemaphoreSlim     tasksSemaphore = new SemaphoreSlim(MaxConcurrentThreads);
            KadContactNode    returnedNode   = null;
            KadValue          value          = null;
            //Should do fine for small alpha
            List <Task> tasks = new List <Task>();

            while (queriedNodes.Count < ReplicationCount)
            {
                var shortListSnapshot = shortList.Where((n) => !queriedNodes.Contains(n.Id)).ToList();
                foreach (var node in shortListSnapshot)
                {
                    tasks.Add(Task.Run(() => {
                        var response = Owner.FindValue(node, valueId);
                        if (response != null)
                        {
                            if (response.Type == MessageType.FindNode)
                            {
                                foreach (var contact in response.Contacts)
                                {
                                    shortList.Add(contact);
                                }
                            }
                            else if (response.Type == MessageType.FindValue)
                            {
                                value        = new KadValue(valueId, DateTime.Now, response.Payload);
                                returnedNode = node;
                            }
                        }
                        tasksSemaphore.Release();
                    }));
                    queriedNodes.Add(node.Id);
                    tasksSemaphore.Wait();
                }

                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                if ((shortList.Min.Id ^ closestId) >= closestId)
                {
                    break;
                }

                closestId = shortList.Min.Id;
            }

            return(value != null ? new Tuple <KadContactNode, KadValue>(returnedNode, value) : null);
        }
Exemple #3
0
        /// <summary>
        /// Pings other node
        /// </summary>
        /// <param name="node">Node to ping</param>
        /// <returns></returns>
        public NodeMessage Ping(KadContactNode node)
        {
            NodeMessage msg = new NodeMessage.Builder()
                              .SetType(MessageType.Ping)
                              .SetOriginator(node.Id)
                              .Build();

            msg.AddCallback(UpdateLastSeen);
            return(_server.SendMessageSync(node.EndPoint, msg, TimeoutInMSec).Response);
        }
Exemple #4
0
        public void Bucket_Contains()
        {
            Bucket bucket = new Bucket(1, 20);

            KadContactNode node = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));

            bucket.Put(node);
            Assert.IsTrue(bucket.Contains(node.Id));
            Assert.IsFalse(bucket.Contains(KadId.GenerateRandom()));
        }
Exemple #5
0
        /// <summary>
        /// Retrives value from other node
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="valId">Value id</param>
        /// <returns>Value if queried node has value, otherwise closest nodes to id</returns>
        public NodeMessage FindValue(KadContactNode node, KadId valId)
        {
            NodeMessage findValMsg = new NodeMessage.Builder()
                                     .SetType(MessageType.FindValue)
                                     .SetOriginator(Id)
                                     .SetIsRequest(true)
                                     .SetPayload(valId.Value)
                                     .Build();

            findValMsg.AddCallback(UpdateLastSeen);

            return(_server.SendMessageSync(node.EndPoint, findValMsg, TimeoutInMSec).Response);
        }
Exemple #6
0
        /// <summary>
        /// Checks if other node can store value
        /// </summary>
        /// <param name="node">Node to check</param>
        /// <returns>True if node can store value</returns>
        public bool CanStoreValue(KadContactNode node)
        {
            NodeMessage canStoreValueMsg = new NodeMessage.Builder()
                                           .SetType(MessageType.CanStoreValue)
                                           .SetOriginator(Id)
                                           .SetIsRequest(true)
                                           .Build();

            canStoreValueMsg.AddCallback(UpdateLastSeen);
            NodeMessage response = _server.SendMessageSync(node.EndPoint, canStoreValueMsg, TimeoutInMSec).Response;

            return(response != null && response.Payload[0] > 0);
        }
Exemple #7
0
        /// <summary>
        /// Store value in contact
        /// </summary>
        /// <param name="node">Contact node</param>
        /// <param name="value">Value to store</param>
        /// <returns>true, if node stored value</returns>
        public bool StoreValue(KadContactNode node, KadValue value)     //TODO: support chunking
        {
            NodeMessage storeValueMsg = new NodeMessage.Builder()
                                        .SetType(MessageType.StoreValue)
                                        .SetOriginator(Id)
                                        .SetIsRequest(true)
                                        .SetKadValueAsPayload(value)
                                        .Build();

            storeValueMsg.AddCallback(UpdateLastSeen);
            var response = _server.SendMessageSync(node.EndPoint, storeValueMsg, TimeoutInMSec).Response;

            return(response != null && response.Type == MessageType.CanStoreValue && response.Payload[0] > 0);
        }
        public bool TryReplaceLeastSeenContactFromBucket(KadContactNode newContact)
        {
            var bucket    = Owner.BucketList.GetBucket(newContact.Id);
            var leastSeen = bucket.GetLeastSeen();

            NodeMessage pongMsg = Owner.Ping(leastSeen);

            if (pongMsg == null)
            {
                bucket.Replace(leastSeen.Id, newContact);
                return(true);
            }

            return(false);
        }
Exemple #9
0
        public void BucketList_Put()
        {
            BucketList bucketList = new BucketList(KadId.GenerateRandom(), 20);

            byte[] kadId = new byte[20];

            for (int i = 0; i < 20; i++)
            {
                kadId[19] = (byte)(i + 1);
                var contact = new kademlia_dht.Base.KadContactNode(new KadId(kadId), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                bucketList.Put(contact);
                Thread.Sleep(1000);
            }
            kadId[19] = 20;
            Assert.IsTrue(bucketList.Put(new KadContactNode(new KadId(kadId), new IPEndPoint(IPAddress.Loopback, 20000))) == BucketList.BucketPutResult.BucketIsFull);
        }
Exemple #10
0
        public void Bucket_GetLeastSeen_Reversed()
        {
            Bucket bucket = new Bucket(1, 20);

            KadContactNode leastSeen = null;

            for (int i = 0; i < 20; i++)
            {
                var contact = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                leastSeen = contact;
                bucket.Put(contact);
                Thread.Sleep(1000);
            }

            Assert.IsTrue(bucket.IsFull());
            Assert.IsFalse(leastSeen.Id.GetNumericValue() == bucket.GetLeastSeen().Id.GetNumericValue());
        }
Exemple #11
0
        public void Bucket_PutAndRetrive()
        {
            Bucket bucket = new Bucket(1, 20);

            List <KadContactNode> nodes = new List <KadContactNode>(20);

            for (int i = 0; i < 20; i++)
            {
                var contact = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                nodes.Add(contact);
                bucket.Put(contact);
            }

            for (int i = 0; i < nodes.Count; i++)
            {
                Debug.WriteLine(bucket.GetNode(nodes[i].Id));
            }
        }
Exemple #12
0
        public KadHashTable(KadNode node, KadContactNode knownNode = null, KadHashTableConfiguration kadHashTableConfig = null)
        {
            Owner = node;
            if (knownNode != null)
            {
                Owner.BucketList.Put(knownNode);
            }

            if (kadHashTableConfig != null)
            {
                ReplicationCount     = kadHashTableConfig.ReplicationCount ?? ReplicationCount;
                MaxConcurrentThreads = kadHashTableConfig.MaxConcurrentThreads ?? MaxConcurrentThreads;
                ReplicationInSecs    = kadHashTableConfig.ReplicationInSecs ?? ReplicationInSecs;
                RepublicationInSecs  = kadHashTableConfig.RepublicationInSecs ?? RepublicationInSecs;
                BucketsRefreshInSecs = kadHashTableConfig.BucketsRefreshInSecs ?? BucketsRefreshInSecs;
            }

            InitTable();
        }
Exemple #13
0
        /// <summary>
        /// Find contact's closest nodes to id
        /// </summary>
        /// <param name="node">Node to query</param>
        /// <param name="id">Id to compare</param>
        /// <returns>Closest nodes to id</returns>
        public IEnumerable <KadContactNode> FindNode(KadContactNode node, KadId id)
        {
            NodeMessage msg = new NodeMessage.Builder()
                              .SetType(MessageType.FindNode)
                              .SetOriginator(Id)
                              .SetIsRequest(true)
                              .SetPayload(id.Value)
                              .Build();

            NodeMessage response = _server.SendMessageSync(node.EndPoint, msg, TimeoutInMSec).Response;

            msg.AddCallback(UpdateLastSeen);
            if (response != null)
            {
                return(new List <KadContactNode>(response.Contacts));
            }

            return(new List <KadContactNode>());
        }
Exemple #14
0
        public void KadNodeUnit_SaveLoadBuckets()
        {
            KadNode     kadNode = new KadNode(new System.Net.IPEndPoint(IPAddress.Loopback, 55555));
            KadNodeUnit unit    = new KadNodeUnit(kadNode);

            for (int i = 0; i < 20; i++)
            {
                var contact = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                unit.Node.BucketList.Put(contact);
                Thread.Sleep(1000);
            }
            string savePath = "nodewithbuckets.xml";

            unit.SaveToFile(savePath);
            unit.Stop();

            KadNodeUnit unit2 = new KadNodeUnit(savePath);

            Assert.IsTrue(unit2.Node.Id.GetNumericValue() == unit.Node.Id.GetNumericValue());
            Assert.IsTrue(unit2.Node.EndPoint.Address.ToString() == unit.Node.EndPoint.Address.ToString());
            Assert.IsTrue(unit2.Node.EndPoint.Port == unit.Node.EndPoint.Port);
            CollectionAssert.AreEqual(unit2.Node.BucketList
                                      .Buckets.Select((b) => b.Id).ToList(), unit.Node.BucketList.Buckets.Select((b) => b.Id).ToList());

            CollectionAssert.AreEqual(unit2.Node.BucketList
                                      .Buckets
                                      .SelectMany((b) => b.GetNodes())
                                      .Select((n) => n.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList(),
                                      unit.Node.BucketList
                                      .Buckets
                                      .SelectMany((b) => b.GetNodes())
                                      .Select((n) => n.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList());
        }
Exemple #15
0
        public void KadNodeUnit_SaveLoadBucketsAndValues()
        {
            KadNode     kadNode = new KadNode(new System.Net.IPEndPoint(IPAddress.Loopback, 55555));
            KadNodeUnit unit    = new KadNodeUnit(kadNode);

            for (int i = 0; i < 20; i++)
            {
                var contact = new kademlia_dht.Base.KadContactNode(kademlia_dht.Base.KadId.GenerateRandom(), new System.Net.IPEndPoint(IPAddress.Loopback, 20000));
                unit.Node.BucketList.Put(contact);
                Thread.Sleep(1000);
            }

            byte[] value = new byte[20];
            for (int i = 0; i < 20; i++)
            {
                value[0] = (byte)(i + 1);
                var valId = new KadId(value);
                value[19] = (byte)i;
                var kadValue = new KadValue(valId, DateTime.UtcNow, value);

                if (i % 3 == 0)
                {
                    byte[] ownId = new byte[20];
                    ownId[3] = (byte)i;
                    unit.Node.Storage.PutOwnerVal(new KadValue(new KadId(ownId), DateTime.UtcNow, value));
                }
                else
                {
                    unit.Node.Storage.Put(kadValue);
                }

                Thread.Sleep(1000);
            }

            string savePath = "nodewithbuckets.xml";

            unit.SaveToFile(savePath);
            unit.Stop();

            KadNodeUnit unit2 = new KadNodeUnit(savePath);

            Assert.IsTrue(unit2.Node.Id.GetNumericValue() == unit.Node.Id.GetNumericValue());
            Assert.IsTrue(unit2.Node.EndPoint.Address.ToString() == unit.Node.EndPoint.Address.ToString());
            Assert.IsTrue(unit2.Node.EndPoint.Port == unit.Node.EndPoint.Port);
            CollectionAssert.AreEqual(unit2.Node.BucketList
                                      .Buckets.Select((b) => b.Id).ToList(), unit.Node.BucketList.Buckets.Select((b) => b.Id).ToList());

            CollectionAssert.AreEqual(unit2.Node.BucketList
                                      .Buckets
                                      .SelectMany((b) => b.GetNodes())
                                      .Select((n) => n.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList(),
                                      unit.Node.BucketList
                                      .Buckets
                                      .SelectMany((b) => b.GetNodes())
                                      .Select((n) => n.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList());
            CollectionAssert.AreEqual(unit2.Node.Storage.Values
                                      .Select((v) => v.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList(),
                                      unit.Node.Storage.Values
                                      .Select((v) => v.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList());

            CollectionAssert.AreEqual(unit2.Node.Storage.OwnerValues
                                      .Select((v) => v.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList(),
                                      unit.Node.Storage.OwnerValues
                                      .Select((v) => v.Id.GetNumericValue())
                                      .OrderBy((id) => id)
                                      .ToList());

            CollectionAssert.AreEqual(unit2.Node.Storage.OwnerValues
                                      .Select((v) => v.Timestamp)
                                      .OrderBy((t) => t)
                                      .ToList(),
                                      unit.Node.Storage.OwnerValues
                                      .Select((v) => v.Timestamp)
                                      .OrderBy((t) => t)
                                      .ToList());
        }