Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        public void MessageParseTest()
        {
            KadId       id  = KadId.GenerateRandom();
            NodeMessage msg = new NodeMessage.Builder()
                              .SetType(MessageType.Ping)
                              .SetOriginator(id)
                              .Build();

            NodeMessage msgParsed = new NodeMessage.Builder(msg.ToBytes()).Build();

            Assert.AreEqual(id.GetNumericValue(), new KadId(id.Value).GetNumericValue());

            Assert.AreEqual(msg.Type, msgParsed.Type);
            Assert.AreEqual(msg.Seq, msgParsed.Seq);
            Assert.AreEqual(msg.OriginatorId.GetNumericValue(), msgParsed.OriginatorId.GetNumericValue());
        }
Exemplo n.º 6
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>());
        }
Exemplo n.º 7
0
        private void ListenIncoming(KadNode ownerNode)
        {
            IPEndPoint incomingIpEndPoint = new IPEndPoint(IPAddress.Any, EndPoint.Port);

            while (!_stopped)
            {
                try {
                    byte[]      rawMsg      = _udpClient.Receive(ref incomingIpEndPoint);
                    NodeMessage incomingMsg = new NodeMessage.Builder(rawMsg).Build();                   //TODO: msg validation
                    ulong       msgIdx      = GetMessageId(incomingIpEndPoint.Address, incomingMsg.Seq); //TODO: two spare bytes for port
                    if (_messages.ContainsKey(msgIdx))
                    {
                        NodeMessage rqMsg = null;
                        if (_messages.TryRemove(msgIdx, out rqMsg))
                        {
                            rqMsg.ProcessResponse(incomingMsg);
                        }
                    }
                    else
                    {
                        if (incomingMsg.IsRequest)
                        {
                            ownerNode.ProcessRequest(incomingMsg, incomingIpEndPoint);
                            _messages.AddOrUpdate(msgIdx, incomingMsg, (k, v) => v);
                        }
                    }
                } catch (SocketException se) {
                    if (se.SocketErrorCode != SocketError.Interrupted)
                    {
                        throw se;
                    }
                }

                incomingIpEndPoint = new IPEndPoint(IPAddress.Any, EndPoint.Port);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Processes request from other node. Used by NodeServer class
        /// </summary>
        /// <param name="msg">Request to process</param>
        /// <param name="origAddress">Request originator adress</param>
        public void ProcessRequest(NodeMessage msg, IPEndPoint origAddress)
        {
            switch (msg.Type)
            {
            case MessageType.Ping: {     //TODO: handle cases when bucket is full, etc
                NodeMessage respMsg = new NodeMessage.Builder()
                                      .SetType(MessageType.Ping)
                                      .SetOriginator(Id)
                                      .SetSeq(msg.Seq)
                                      .SetIsRequest(false)
                                      .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }


            case MessageType.FindNode: {
                var         closestNodes = BucketList.GetClosestNodes(new KadId(msg.Payload), 20);
                NodeMessage respMsg      = new NodeMessage.Builder()
                                           .SetType(MessageType.FindNode)
                                           .SetSeq(msg.Seq)
                                           .SetOriginator(Id)
                                           .SetContacts(closestNodes)
                                           .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }

            case MessageType.FindValue: {
                KadId valueId = new KadId(msg.Payload);

                NodeMessage.Builder msgBuilder = new NodeMessage.Builder()
                                                 .SetType(MessageType.FindValue)
                                                 .SetSeq(msg.Seq)
                                                 .SetOriginator(Id);

                if (Storage.Contains(valueId))
                {
                    msgBuilder.SetKadValueAsPayload(Storage.Get(valueId));
                }
                else
                {
                    var closestNodes = BucketList.GetClosestNodes(valueId, 20);
                    msgBuilder.SetContacts(closestNodes)
                    .SetType(MessageType.FindNode);
                }

                _server.SendMessage(origAddress, msgBuilder.Build());
                break;
            }

            case MessageType.CanStoreValue: {
                NodeMessage respMsg = new NodeMessage.Builder()
                                      .SetType(MessageType.CanStoreValue)
                                      .SetSeq(msg.Seq)
                                      .SetOriginator(Id)
                                      .SetIsRequest(false)
                                      .SetFlagAsPayload(!Storage.IsFull())
                                      .Build();

                _server.SendMessage(origAddress, respMsg);
                break;
            }

            case MessageType.StoreValue: {
                NodeMessage.Builder msgBuilder = new NodeMessage.Builder()
                                                 .SetSeq(msg.Seq)
                                                 .SetOriginator(Id)
                                                 .SetIsRequest(false)
                                                 .SetType(MessageType.CanStoreValue);

                if (Storage.IsFull())
                {
                    msgBuilder.SetFlagAsPayload(false);
                }
                else
                {
                    msgBuilder.SetFlagAsPayload(true);
                    Storage.Put(msg.Value);
                }

                _server.SendMessage(origAddress, msgBuilder.Build());
                break;
            }
            }

            UpdateLastSeen(msg);
        }