Esempio n. 1
0
 internal StoreObjectClient(KyruApplication app, NodeInformation targetNode, KademliaId objectId, byte[] bytes, Action<Error> done)
     : base(app, targetNode)
 {
     this.objectId = objectId;
     this.bytes = bytes;
     this.done = done;
 }
Esempio n. 2
0
        public void TestKademliaBucket()
        {
            var bytes = new byte[20];

            bytes[19] = 0xff;
            var id = new KademliaId(bytes);
            Assert.AreEqual(7, id.KademliaBucket());

            bytes[19] = 0x89;
            id = new KademliaId(bytes);
            Assert.AreEqual(7, id.KademliaBucket());

            bytes[19] = 0x01;
            id = new KademliaId(bytes);
            Assert.AreEqual(0, id.KademliaBucket());

            bytes[19] = 0x74;
            id = new KademliaId(bytes);
            Assert.AreEqual(6, id.KademliaBucket());

            bytes[10] = 0xff;
            id = new KademliaId(bytes);
            Assert.AreEqual(79, id.KademliaBucket());

            bytes[0] = 0xff;
            id = new KademliaId(bytes);
            Assert.AreEqual(159, id.KademliaBucket());
        }
Esempio n. 3
0
 /// <summary>
 /// Returns the metadata if it is stored, otherwise null.
 /// </summary>
 internal KyruObjectMetadata[] Get(KademliaId id)
 {
     lock (storage)
     {
         List<KyruObjectMetadata> metadata;
         if (storage.TryGetValue(id, out metadata) && metadata.Count != 0)
             return metadata.ToArray();
         return null;
     }
 }
Esempio n. 4
0
        internal KyruObject GetObject(KademliaId id)
        {
            var bytes = Get(id);
            if (bytes == null)
                return null;

            using (var stream = new MemoryStream(bytes))
            {
                var obj = Serializer.Deserialize<KyruObject>(stream);
                obj.ObjectId = id;
                return obj;
            }
        }
Esempio n. 5
0
        public void TestToString()
        {
            var bytes = new byte[20];
            var id = new KademliaId(bytes);

            // Length must be okay
            Assert.AreEqual("0000000000000000000000000000000000000000", id.ToString().ToLower());

            bytes[0] = 0xff;
            id = new KademliaId(bytes);
            Assert.AreEqual("ff00000000000000000000000000000000000000", id.ToString().ToLower());

            bytes[0] = 0x00;
            bytes[19] = 0xff;
            id = new KademliaId(bytes);
            Assert.AreEqual("00000000000000000000000000000000000000ff", id.ToString().ToLower());
        }
        internal void PrepareKademlia()
        {
            node = new Node(null);
            kademlia = node.Kademlia;

            node2 = new Node(12345, null);
            kademlia2 = node2.Kademlia;

            targetId = node2.Id;

            var ni = new NodeInformation(new IPEndPoint(IPAddress.Loopback, 12345), targetId);
            TestHelper.RegisterFakeContact(kademlia, ni);

            // set LastSeen to a time beyond the ping interval
            var contact = Mirror.ForObject(kademlia)["FirstContact"].Invoke();
            Mirror.ForObject(contact)["LastSeen"].Value = DateTime.Now - TimeSpan.FromHours(1.1);
        }
Esempio n. 7
0
        internal void PrepareKademlia()
        {
            node = new Node(null);
            kademlia = node.Kademlia;

            node2 = new Node(12345, null);
            kademlia2 = node.Kademlia;

            targetEndPoint = new IPEndPoint(IPAddress.Loopback, 12345);
            targetId = node2.Id;

            node.Start();
            node2.Start();

            kademlia.AddNode(new IPEndPoint(IPAddress.Loopback, 12345));
            Thread.Sleep(TestParameters.LocalhostCommunicationTimeout);
        }
Esempio n. 8
0
 internal Chunk(byte[] data, KademliaId objectId)
 {
     Data = data;
     ObjectId = objectId;
 }
Esempio n. 9
0
        private void StoreTestObject()
        {
            // create the test object

            objectId = KademliaId.RandomId;
            var chunkId = KademliaId.RandomId;

            var user = new User();
            user.ObjectId = objectId;
            var userFile = new UserFile();
            userFile.ChunkList.Add(chunkId);
            user.Add(userFile);

            var ms = new MemoryStream();
            Serializer.Serialize(ms, user);
            bytes = ms.ToArray();

            // store it

            var ct = new CallbackTimeout<Error>();
            var ni = new NodeInformation(new IPEndPoint(IPAddress.Loopback, nodes[1].Port), nodes[1].Id);
            nodes[0].StoreObject(ni, objectId, bytes, ct.Done);
            if (!ct.Block(TestParameters.LocalhostCommunicationTimeout))
            {
                Assert.Fail("No response within timeout");
            }
            Assert.AreEqual(Error.Success, ct.Result);
        }
Esempio n. 10
0
 /// <summary>
 /// Determines whether an object is locally stored. If it is, the access timestamp is updated.
 /// </summary>
 /// <returns>Whether the object with this id is locally stored.</returns>
 internal bool KeepObject(KademliaId id)
 {
     if (currentObjects.ContainsKey(id))
     {
         currentObjects[id] = DateTime.Now;
         return true;
     }
     return false;
 }
Esempio n. 11
0
        internal void GetObjectFromNode(List<NodeInformation> nodes, KademliaId objectId, Action<Error, byte[]> done)
        {
            if (nodes.Count == 0)
            {
                done(Error.NotFound, null);
                return;
            }

            // TODO: implement fallback to next nodes in list in GetObjectClient
            new Thread(new GetObjectClient(app, nodes[0], objectId, done).ThreadStart).Start();
        }
Esempio n. 12
0
 internal void GetObjectFromNetwork(KademliaId objectId, Action<Error, byte[]> done)
 {
     Kademlia.ValueLookup(objectId, node =>
                                    {
                                        if (node == null)
                                            done(Error.NotFound, null);
                                        else
                                            GetObjectFromNode(node, objectId, done);
                                    });
 }
Esempio n. 13
0
        private bool GetKContacts(List<NodeInformation> contacts, int bucket, KademliaId ignoreId)
        {
            foreach (var contact in buckets[bucket])
            {
                if (contact.Node.NodeId == ignoreId)
                    continue;

                contacts.Add(contact.Node);
                if (contacts.Count == k)
                    return true;
            }
            return false;
        }
Esempio n. 14
0
 /// <summary>
 /// Removes a node that didn't respond from the Kademlia contact list.
 /// </summary>
 internal void RemoveNode(KademliaId nodeId)
 {
     var bucket = (node.Id - nodeId).KademliaBucket();
     if (buckets[bucket].RemoveAll(n => n.Node.NodeId == nodeId) != 0)
     {
         this.Log("Removing contact {0}", nodeId);
     }
 }
Esempio n. 15
0
 /// <summary>
 /// Adds a known-good node to the kademlia contacts. This must only be called if the identity of the node is verified, such as with correct ping replies or a TCP connection.
 /// </summary>
 internal void AddVerifiedNode(IPEndPoint endPoint, KademliaId nodeId)
 {
     AddContact(new NodeInformation(endPoint, nodeId));
 }
Esempio n. 16
0
        /// <summary>Sends an UDP message to a given node.</summary>
        /// <param name="message">The message to be sent.</param>
        /// <param name="target">The address of the target node.</param>
        /// <param name="targetNodeId">The target node ID.</param>
        internal void SendUdpMessage(UdpMessage message, IPEndPoint target, KademliaId targetNodeId)
        {
            message.RequestId = Random.UInt64();
            message.SenderNodeId = Id;

            var requestIdentifier = new RequestIdentifier {EndPoint = target, RequestId = message.RequestId};
            var requestInformation = new RequestInformation {OutgoingMessage = message, SecondAttempt = false, NodeId = targetNodeId};

            if (message.IsRequest)
            {
                lock (outstandingRequests)
                {
                    outstandingRequests.Add(requestIdentifier, requestInformation);
                }
            }

            SendUdp(message, target);
        }
Esempio n. 17
0
 internal void StoreObject(KademliaId objectId, byte[] bytes)
 {
     // TODO: store at one node, not at all
     new Thread(() => Kademlia.NodeLookup(KademliaId.RandomId, list =>
                                                    {
                                                        foreach (var item in list)
                                                        {
                                                            StoreObject(item, objectId, bytes, error => { });
                                                        }
                                                    })).Start();
 }
Esempio n. 18
0
 internal void StoreObject(NodeInformation targetNode, KademliaId objectId, byte[] bytes, Action<Error> done)
 {
     new Thread(new StoreObjectClient(app, targetNode, objectId, bytes, done).ThreadStart).Start();
 }
Esempio n. 19
0
 public void AllZeroIdMustNotHaveKademliaBucket()
 {
     var id = new KademliaId(new byte[20]);
     id.KademliaBucket();
 }
Esempio n. 20
0
 internal GetObjectClient(KyruApplication app, NodeInformation targetNode, KademliaId objectId, Action<Error, byte[]> done)
     : base(app, targetNode)
 {
     this.objectId = objectId;
     this.done = done;
 }
Esempio n. 21
0
        private void VerifyOwnership(KademliaId objectId, KyruObjectMetadata newItem)
        {
            var message = new UdpMessage();
            message.KeepObjectRequest = new KeepObjectRequest();
            message.KeepObjectRequest.ObjectId = objectId;
            message.ResponseCallback = delegate(UdpMessage udpMessage)
                                       {
                                           if (!udpMessage.KeepObjectResponse.HasObject) return;

                                           lock (storage)
                                           {
                                               if (!storage.ContainsKey(objectId))
                                                   storage[objectId] = new List<KyruObjectMetadata>();

                                               newItem.Timestamp = DateTime.Now.UnixTimestamp();
                                               storage[objectId].Add(newItem);
                                           }
                                       };
            node.SendUdpMessage(message, new IPEndPoint(newItem.IpAddress, newItem.Port), newItem.NodeId);
        }
Esempio n. 22
0
        /// <summary>
        /// Stores the data on this node
        /// </summary>
        /// <param name="id">the id</param>
        /// <param name="bytes">data</param>
        internal void StoreBytes(KademliaId id, byte[] bytes, bool replicate)
        {
            using (var st = new MemoryStream(bytes))
            {
                var obj = Serializer.Deserialize<KyruObject>(st);
                obj.ObjectId = id;

                if (obj is User)
                {
                    StoreObject(obj, replicate);
                    return;
                }

                if (!VerifyObject(obj)) return;
            }

            Store(id, bytes, replicate);
        }
Esempio n. 23
0
        internal void Store(KademliaId id, KyruObjectMetadata[] newMetadata)
        {
            lock (storage)
            {
                if (!storage.ContainsKey(id))
                {
                    storage[id] = new List<KyruObjectMetadata>();
                }
                var metadata = storage[id];

                foreach (var newItem in newMetadata)
                {
                    // make sure the timestamp isn't in the future
                    newItem.Timestamp = Math.Min(DateTime.Now.UnixTimestamp(), newItem.Timestamp);

                    var item = metadata.FirstOrDefault(m => m.IpAddress == newItem.IpAddress && m.NodeId == newItem.NodeId);

                    if (item == null)
                    {
                        VerifyOwnership(id, newItem);
                        metadata.Add(newItem);
                    }
                    else
                    {
                        item.Timestamp = Math.Max(item.Timestamp, newItem.Timestamp);
                    }
                }
            }
        }
Esempio n. 24
0
        private byte[] Get(KademliaId id)
        {
            if (id.Bytes.All(b => b == 0))
                throw new InvalidOperationException("Possible bug: tried to get object with id zero");

            if (currentObjects.ContainsKey(id))
                currentObjects[id] = DateTime.Now;
            else
                return null;

            return File.ReadAllBytes(PathFor(id));
        }
Esempio n. 25
0
        internal List<NodeInformation> NearestContactsTo(KademliaId nearToId, KademliaId ignoreId)
        {
            var bucketId = nearToId.KademliaBucket();
            var contacts = new List<NodeInformation>();

            for (int i = bucketId; i >= 0; i--)
            {
                if (GetKContacts(contacts, i, ignoreId))
                    return contacts;
            }

            for (int i = bucketId + 1; i < KademliaId.Size; i++)
            {
                if (GetKContacts(contacts, i, ignoreId))
                    return contacts;
            }

            return contacts;
        }
Esempio n. 26
0
 private string PathFor(KademliaId id)
 {
     return Path.Combine(config.StoreDirectory, id.ToString());
 }
Esempio n. 27
0
 internal void ValueLookup(KademliaId id, Action<List<NodeInformation>> done)
 {
     new Thread(new ValueLookup(node, id, done).ThreadStart).Start();
 }
Esempio n. 28
0
        private void Store(KademliaId id, byte[] bytes, bool replicate)
        {
            if (id.Bytes.All(b => b == 0))
                throw new InvalidOperationException("Possible bug: tried to store object with id zero");
            if (bytes.Length > MaxObjectSize + 8) // TODO: remove hack. (8 bytes overhead for 1 MiB chunk)
            {
                this.Warn("Object larger than 1 MiB; it will not be stored. ID: {0}", id);
                return;
            }

            File.WriteAllBytes(PathFor(id), bytes);

            currentObjects[id] = DateTime.Now;

            if (replicate)
                node.StoreObject(id, bytes);
        }
Esempio n. 29
0
 internal byte[] GetBytes(KademliaId id)
 {
     return Get(id);
 }
Esempio n. 30
0
 public NodeInformation(IPEndPoint endPoint, KademliaId nodeId)
 {
     NodeId = nodeId;
     IpAddress = BitConverter.ToUInt32(endPoint.Address.GetAddressBytes(), 0);
     Port = (ushort) endPoint.Port;
 }