/// <summary>
        /// Attempt to find the value in the peer network.
        /// </summary>
        /// <returns>A null contact list is acceptable here as it is a valid return if the value is found.
        /// The caller is responsible for checking the timeoutError flag to make sure null contacts is not
        /// the result of a timeout error.</returns>
        public (List <Contact> contacts, string val, RpcError error) FindValue(Contact sender, ID key)
        {
            ErrorResponse error;
            ID            id = ID.RandomID;
            bool          timeoutError;

            var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//FindValue",
                                                                       new FindValueRequest()
            {
                Protocol     = sender.Protocol,
                ProtocolName = sender.Protocol.GetType().Name,
                Subnet       = subnet,
                Sender       = sender.ID.Value,
                Key          = key.Value,
                RandomID     = id.Value
            }, out error, out timeoutError);

            try
            {
                var contacts = ret?.Contacts?.Select(val => new Contact(Protocol.InstantiateProtocol(val.Protocol, val.ProtocolName), new ID(val.Contact))).ToList();

                // Return only contacts with supported protocols.
                return(contacts?.Where(c => c.Protocol != null).ToList(), ret.Value, GetRpcError(id, ret, timeoutError, error));
            }
            catch (Exception ex)
            {
                return(null, null, new RpcError()
                {
                    ProtocolError = true, ProtocolErrorMessage = ex.Message
                });
            }
        }
        /// <summary>
        /// PingBack is called in response to a ping for a few reasons:
        /// 1. This registers the node we're pinging in the sender's list of peers
        /// 2. It minimally verifies that the sender is a peer.
        /// 3. We can't simply ping the sender of the ping we received, as this would create an infinite loop of ping - reping.
        /// NOTE: THIS IS NOT IN THE KADEMLIA SPEC EXCEPT FOR DISCUSSION OF "piggyback" PING RESPONSE.
        /// </summary>
        public RpcError PingBack(Contact sender)
        {
#if DEBUG
            // For unit tests:
            if (!Responds)
            {
                return(new RpcError()
                {
                    TimeoutError = !Responds
                });
            }
#endif
            ErrorResponse error;
            ID            id = ID.RandomID;
            bool          timeoutError;

            var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//PingBack",
                                                                       new PingSubnetRequest()
            {
                Protocol     = sender.Protocol,
                ProtocolName = sender.Protocol.GetType().Name,
                Subnet       = subnet,
                Sender       = sender.ID.Value,
                RandomID     = id.Value
            },
                                                                       out error, out timeoutError);

            return(GetRpcError(id, ret, timeoutError, error));
        }
Exemple #3
0
        /// <summary>
        /// PingBack is called in response to a ping for a few reasons:
        /// 1. This registers the node we're pinging in the sender's list of peers
        /// 2. It minimally verifies that the sender is a peer.
        /// 3. We can't simply ping the sender of the ping we received, as this would create an infinite loop of ping - reping.
        /// NOTE: THIS IS NOT IN THE KADEMLIA SPEC EXCEPT FOR DISCUSSION OF "piggyback" PING RESPONSE.
        public RpcError PingBack(Contact sender)
        {
            ErrorResponse error;
            ID            id = ID.RandomID;
            bool          timeoutError;

            var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//PingBack",
                                                                       new PingSubnetRequest()
            {
                Protocol     = sender.Protocol,
                ProtocolName = sender.Protocol.GetType().Name,
                Sender       = sender.ID.Value,
                RandomID     = id.Value
            },
                                                                       out error, out timeoutError);

            return(GetRpcError(id, ret, timeoutError, error));
        }
Exemple #4
0
        public RpcError Store(Contact sender, ID key, string val, bool isCached = false, int expirationTimeSec = 0)
        {
            ErrorResponse error;
            ID            id = ID.RandomID;
            bool          timeoutError;

            var ret = RestCall.Post <FindValueResponse, ErrorResponse>(url + ":" + port + "//Store",
                                                                       new StoreSubnetRequest()
            {
                Protocol          = sender.Protocol,
                ProtocolName      = sender.Protocol.GetType().Name,
                Sender            = sender.ID.Value,
                Key               = key.Value,
                Value             = val,
                IsCached          = isCached,
                ExpirationTimeSec = expirationTimeSec,
                RandomID          = id.Value
            },
                                                                       out error, out timeoutError);

            return(GetRpcError(id, ret, timeoutError, error));
        }