private void UpdateLastSeen(NodeMessage msg) { var bucket = BucketList.GetBucket(msg.OriginatorId); if (bucket.Contains(msg.OriginatorId)) { bucket.SeenNow(bucket.GetNode(msg.OriginatorId)); } }
private void UpdateLastSeen(ContactNode node) { var bucket = BucketList.GetBucket(node.Id); if (bucket.Contains(node.Id)) { bucket.SeenNow(node); } }
/// <summary> /// Checks whether value is expired /// Algorithm described in http://xlattice.sourceforge.net/components/protocol/kademlia/specs.html#expiration /// </summary> /// <param name="kadVal">Value to be checked</param> /// <returns>True if value expired</returns> public bool IsValueExpired(KadValue kadVal) { var valBucket = BucketList.GetBucket(kadVal.Id); int cA = 0, cB = 0; foreach (var bucket in BucketList.Buckets.Where((b) => b.Id < valBucket.Id)) { cA += bucket.NodesCount; } foreach (var contact in valBucket.GetNodes()) { if (contact.Id < kadVal.Id) { cB++; } } int c = cA + cB; if (c == 0) { return(true); } int secondsBtw = (int)(DateTime.UtcNow - kadVal.Timestamp).TotalSeconds; if (c > Storage.Size()) { if (secondsBtw >= ValueExpirationInSec) { return(true); } } else if (secondsBtw >= ValueExpirationInSec * Math.Exp(Storage.Size() / c)) { return(true); } return(false); }
protected bool CheckPossibleMaliciousMessage(IPEndPoint originator, Id originatorId, MnlMessage maliciousMsg) { var malciousNodes = BucketList.GetClosestNodes(originatorId, 8); foreach (var maliciousNode in malciousNodes) { if (Ping(maliciousNode) == null) { if (BucketList.GetBucket(maliciousNode.Id).Remove(maliciousNode)) { Debug.WriteLine($"Removed malicious node {maliciousNode} from bucket list"); } else { Debug.WriteLine($"Can't remove malicious node {maliciousNode} from bucket list"); } } } return(true); }
/// <summary> /// Pings other node /// </summary> /// <param name="id">Node id to ping</param> /// <returns></returns> public NodeMessage Ping(KadId id) { var bucket = BucketList.GetBucket(id); return(Ping(bucket.GetNode(id))); }
/// <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(KadId id, KadId valId) { var bucket = BucketList.GetBucket(id); return(FindValue(bucket.GetNode(id), valId)); }
/// <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(KadId id, KadValue value) { var bucket = BucketList.GetBucket(id); return(StoreValue(bucket.GetNode(id), value)); }
/// <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(KadId id, KadId idToFind) { var bucket = BucketList.GetBucket(id); return(FindNode(bucket.GetNode(id), idToFind)); }
/// <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 ProcessQuery(Message.MnlMessage msg, IPEndPoint origAddress) { switch (msg.QueryType) { case QueryType.Ping: { _server.SendMessage(origAddress, PrepareResponse(msg)); break; } case QueryType.FindNode: { Message.MnlMessage response = PrepareResponse(msg); Id targetId = new Id((byte[])msg.Payload["target"]); var closestNodes = BucketList.GetClosestNodes(targetId, NodesPerQuery); response.Payload.Add("nodes", closestNodes.Select((n) => n.ToBytes()).ToList()); _server.SendMessage(origAddress, response); break; } case QueryType.GetPeers: { Message.MnlMessage response = PrepareResponse(msg); Id targetId = new Id((byte[])msg.Payload["info_hash"]); if (Storage.ContainsPeersFor(targetId)) { response.Payload.Add("values", Storage.GetForinfoHash(targetId) .Select((n) => n.ToBytes(true)).ToList()); response.Payload.Add("token", _tokenStorage.AcquireNewToken(origAddress.Address).AsBytes()); } else { response.Payload.Add("nodes", BucketList.GetClosestNodes(targetId, NodesPerQuery) .Select((n) => n.ToBytes()).ToList()); } _server.SendMessage(origAddress, response); break; } case QueryType.AnnouncePeer: { Message.MnlMessage response = PrepareResponse(msg); Token token = Token.FromBytes((byte[])msg.Payload["token"]); if (_tokenStorage.Validate(origAddress.Address, token)) { Id infoHash = new Id((byte[])msg.Payload["info_hash"]); Id originatorId = new Id((byte[])msg.Payload["id"]); Bucket originatorBucket = BucketList.GetBucket(originatorId); ContactNode originatorNode = originatorBucket.GetNode(originatorId); bool isImpliedPort = !msg.Payload.ContainsKey("port") || (int)msg.Payload["port"] > 0; originatorNode.UtpPort = isImpliedPort ? originatorNode.EndPoint.Port : (int)msg.Payload["port"]; Storage.Put(originatorNode, infoHash); _server.SendMessage(origAddress, response); } else { _server.SendBadToken(origAddress); } break; } } Id msgOrigId = new Id((byte[])msg.Payload["id"]); var bucket = BucketList.GetBucket(msgOrigId); //UpdateLastSeen(bucket.GetNode(msgOrigId)); }