private void BroadCastClose(KademliaNode close, List <KademliaNode> nodes, int prefixLength) { if (!_alive) { return; } if (this != close) { int plength = CommonPrefixLength(_id, close._id); _table[plength].Remove(close); foreach (KademliaNode node in nodes) { Update(node); } } KademliaNode target; for (int i = prefixLength; i < k_TableSize; i++) { target = _table[i].GetRandomNode(); if (target == null) { continue; } target.BroadCastClose(close, nodes, i + 1); } }
private void SendNeighbours(KademliaNode remote, List <KademliaNode> neighbours) { // receive List <KademliaNode> nodes = new List <KademliaNode>(); foreach (KademliaNode node in neighbours) { if (node != this && !IsInTable(node)) { nodes.Add(node); } } if (_find_request != -1) { nodes = SortByDistance(nodes, _find_request); List <KademliaNode> closest_candidate = FindNeighbours(_find_request); foreach (KademliaNode node in nodes) { node.Ping(this); } KademliaNode closest_known = closest_candidate.Count == 0 ? null : closest_candidate[0]; for (int i = 0; i < k_FindConcurrency && i < nodes.Count; i++) { if (closest_known is null || (nodes[i]._id ^ _find_request) < (closest_known._id ^ _find_request)) { nodes[i].SendFindNode(this, _find_request); } } } }
private void SendFindNode(KademliaNode remote, int target_id) { Update(remote); List <KademliaNode> found = FindNeighbours(target_id); remote.SendNeighbours(this, found); }
private void Transfer(KademliaNode remote, string msg, int prefixLength) { if (!_alive) { return; } if (this != remote) { Update(remote); } if (prefixLength != 0) { _touched = true; _log.Add("Received : " + '"' + msg + '"'); _downloads++; } KademliaNode target; for (int i = prefixLength; i < k_TableSize; i++) { target = _table[i].GetRandomNode(); if (target == null) { continue; } _log.Add("Transfer " + '"' + msg + '"' + " to Node " + target.GetId()); _uploads++; target.Transfer(this, msg, i + 1); } }
public void Remove(KademliaNode node) { if (_contents.Contains(node)) { _contents.Remove(node); } }
public bool Add(KademliaNode node) { if (_contents.Contains(node)) { // move node to most recently used _contents.Remove(node); _contents.Add(node); return(false); } if (_contents.Count < BucketSize) { _contents.Add(node); return(true); } if (_contents.First().Respond()) { // discard apped return(false); } else { // evict least recently used node _contents.RemoveAt(0); _contents.Add(node); return(true); } }
private void AddNeighbours(KademliaNode target, List <KademliaNode> neighbours, List <KademliaNode> querry) { KademliaNode[] closest = GetCloseNodes(target._id, querry); for (int i = 0; i < k_FindConcurrency; i++) { if (closest[i] is null) { break; } querry.Add(closest[i]); closest[i].AddNeighbours(target, neighbours, querry); } for (int i = 0; i < k_FindConcurrency; i++) { if (closest[i] is null || neighbours.Count > Bucket.BucketSize * 2) { break; } if (neighbours.Contains(closest[i])) { continue; } neighbours.Add(closest[i]); } AddNode(target); }
private void Ping(KademliaNode remote) { if (_alive) { Update(remote); } // actually if node is dead, no respond and cause timeout exception remote.Pong(this, _alive); }
public void Update(KademliaNode node) { if (node.GetId() == _id) { return; } int plength = CommonPrefixLength(_id, node.GetId()); _table[plength].Update(node); }
// Initial connect to bootstrap node public void Bootstrap(KademliaNode bootstrapNode) { if (bootstrapNode is null) { return; } Update(bootstrapNode); FindNode(_id, bootstrapNode); }
private void Pong(KademliaNode remote, bool alive) { if (alive) { Update(remote); } else { RemoveNode(remote); } }
private bool IsInTable(KademliaNode node) { foreach (Bucket bucket in _table) { if (bucket._contents.Contains(node)) { return(true); } } return(false); }
private void FindNode(int target_id, KademliaNode via_node = null) { _find_request = target_id; if (via_node is null) { QuerryNeighbours(target_id); } else { via_node.SendFindNode(this, target_id); } _find_request = -1; }
// Initial connect to bootstrap node public void Connect(KademliaNode bootstrapNode) { if (bootstrapNode is null) { return; } AddNode(bootstrapNode); foreach (KademliaNode node in bootstrapNode.FindNode(this)) { AddNode(node); } }
private List <KademliaNode> FindNode(KademliaNode target) { List <KademliaNode> neighbours = new List <KademliaNode>(); AddNeighbours(target, neighbours, new List <KademliaNode>()); /*int index = 0; * while (neighbours.Count < Bucket.BucketSize * 2 && index < neighbours.Count) * neighbours[index++].AddNeighbours(target, neighbours);*/ /*for (index = 0; index < neighbours.Count; index++) * neighbours[index].AddNeighbours(target, neighbours);*/ return(neighbours); }
static public bool CreateKademliaNode(int id) { foreach (KademliaNode node in _kademliaNodes) { if (node.GetId() == id) { return(false); } } KademliaNode newNode = new KademliaNode(id); if (id != 0) { newNode.Bootstrap(_kademliaNodes[0]); } _kademliaNodes.Add(newNode); return(true); }
private KademliaNode[] GetCloseNodes(int target_id, List <KademliaNode> querry) { KademliaNode[] closeNodes = new KademliaNode[k_FindConcurrency]; for (int i = 0; i < k_TableSize; i++) { foreach (KademliaNode node in _table[i]._contents) { if (querry.Contains(node) || CommonPrefixLength(target_id, _id) > CommonPrefixLength(target_id, node._id) || CommonPrefixLength(target_id, node._id) == 32) { continue; } if (closeNodes[0] is null || CommonPrefixLength(target_id, node._id) >= CommonPrefixLength(target_id, closeNodes[0]._id)) { closeNodes[2] = closeNodes[1]; closeNodes[1] = closeNodes[0]; closeNodes[0] = node; }
private void BroadCastPing(KademliaNode remote, KademliaNode from, int prefixLength) { if (!_alive) { return; } KademliaNode target; for (int i = prefixLength; i < k_TableSize; i++) { target = _table[i].GetRandomNode(); if (target == null || target == remote || target == from) { continue; } target.BroadCastPing(this, from, i + 1); Update(from); } }
private List <KademliaNode> FindNeighbours(KademliaNode target, int k = Bucket.BucketSize) { return(FindNeighbours(target._id, k)); }
public void RemoveNode(KademliaNode node) { //int plength = CommonPrefixLength(_id, node.GetId()); }
public void RemoveNode(KademliaNode node) { int plength = CommonPrefixLength(_id, node.GetId()); _table[plength].Remove(node); }
/// <summary> /// Create a DHT using the given master server, and specify whether to publish our IP. /// PRECONDITION: Create one per app or you will have a node ID collision. /// </summary> /// <param name="dhtNode">The KademliaNode that is used to communicate using the protocol</param> /// <param name="alreadyBootstrapped">Checks if the node have or not to bootstrap</param> /// <param name="btpNode">The node to bootstrap with (can be leaved null)</param> public Dht(KademliaNode dhtNode = null, bool alreadyBootstrapped = false, string btpNode = "") { if (dhtNode != null) { this.dhtNode = dhtNode; } else { dhtNode = new KademliaNode(); } if (!alreadyBootstrapped) { if (btpNode == "") { int ourPort = dhtNode.GetPort(); log.Info("We are on UDP port " + ourPort.ToString()); log.Info("Getting bootstrap list..."); AppSettingsReader asr = new AppSettingsReader(); XDocument xmlDoc = XDocument.Load((string)asr.GetValue("KademliaNodesFile", typeof(string))); List <EndpointAddress> nodes = new List <EndpointAddress>(from node in xmlDoc.Descendants("Node") select new EndpointAddress("soap.udp://" + node.Element("Host").Value + ":" + node.Element("Port").Value + "/kademlia")); foreach (var node in nodes) { if (dhtNode.AsyncBootstrap(nodes)) { log.Debug("OK!"); } else { log.Debug("Failed."); } } } else { try { log.Debug("Bootstrapping with " + btpNode); EndpointAddress bootstrapNode = new EndpointAddress(btpNode); if (dhtNode.Bootstrap(bootstrapNode)) { log.Debug("OK!"); } else { log.Debug("Failed."); } } catch (Exception ex) { log.Error("Bad entry!", ex); } } } else { log.Info("Self Bootstrapping"); dhtNode.Bootstrap(); } // Join the network officially log.Info("Trying to join network...."); if (dhtNode.JoinNetwork()) { log.Info("Online"); } else { log.Warn("Unable to connect to Kademlia overlay!\n" + "Check that nodes list has accessible nodes."); } }