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> /// 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); }
/// <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)); }