public DhtManager(int localServicePort, IDhtConnectionManager connectionManager, NetProxy proxy, IEnumerable <EndPoint> ipv4BootstrapNodes, IEnumerable <EndPoint> ipv6BootstrapNodes, IEnumerable <EndPoint> torBootstrapNodes, string torOnionAddress, bool enableTorMode) { _localServicePort = localServicePort; //init internet dht nodes _ipv4InternetDhtNode = new DhtNode(connectionManager, new IPEndPoint(IPAddress.Any, localServicePort)); _ipv6InternetDhtNode = new DhtNode(connectionManager, new IPEndPoint(IPAddress.IPv6Any, localServicePort)); //add known bootstrap nodes _ipv4InternetDhtNode.AddNode(ipv4BootstrapNodes); _ipv6InternetDhtNode.AddNode(ipv6BootstrapNodes); if (enableTorMode) { //init tor dht node _torInternetDhtNode = new DhtNode(connectionManager, new DomainEndPoint(torOnionAddress, localServicePort)); //add known bootstrap nodes _torInternetDhtNode.AddNode(torBootstrapNodes); //set higher timeout value for internet and tor DHT nodes since they will be using tor network _ipv4InternetDhtNode.QueryTimeout = 10000; _ipv6InternetDhtNode.QueryTimeout = 10000; _torInternetDhtNode.QueryTimeout = 10000; } else { //start network watcher _networkWatcher = new Timer(NetworkWatcherAsync, null, 1000, NETWORK_WATCHER_INTERVAL); } //add bootstrap nodes via web _bootstrapRetryTimer = new Timer(delegate(object state) { try { using (WebClientEx wC = new WebClientEx()) { wC.Proxy = proxy; wC.Timeout = 10000; using (BinaryReader bR = new BinaryReader(new MemoryStream(wC.DownloadData(DHT_BOOTSTRAP_URL)))) { int count = bR.ReadByte(); for (int i = 0; i < count; i++) { AddNode(EndPointExtension.Parse(bR)); } } } //bootstrap success, stop retry timer _bootstrapRetryTimer.Dispose(); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } }, null, BOOTSTRAP_RETRY_TIMER_INITIAL_INTERVAL, BOOTSTRAP_RETRY_TIMER_INTERVAL); }
public DhtNode(IDhtConnectionManager manager, EndPoint nodeEP) { _manager = manager; switch (nodeEP.AddressFamily) { case AddressFamily.InterNetwork: case AddressFamily.InterNetworkV6: if (IPAddress.IsLoopback((nodeEP as IPEndPoint).Address)) { _currentNode = new CurrentNode(BinaryNumber.GenerateRandomNumber256(), nodeEP); } else { _currentNode = new CurrentNode(nodeEP); } break; case AddressFamily.Unspecified: _currentNode = new CurrentNode(nodeEP); break; default: throw new NotSupportedException(); } //init routing table _routingTable = new KBucket(_currentNode); //start health timer _healthTimer = new Timer(delegate(object state) { try { //remove expired data _currentNode.RemoveExpiredPeers(); //check contact health _routingTable.CheckContactHealth(this); //refresh buckets _routingTable.RefreshBucket(this); //find closest contacts for current node id NodeContact[] initialContacts = _routingTable.GetKClosestContacts(_currentNode.NodeId, true); if (initialContacts.Length > 0) { QueryFindNode(initialContacts, _currentNode.NodeId); //query manager auto add contacts that respond } } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } }, null, HEALTH_CHECK_TIMER_INITIAL_INTERVAL, HEALTH_CHECK_TIMER_INTERVAL); }