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); }
internal void RefreshBucket(DhtNode dhtNode) { List <KBucket> allLeafKBuckets = GetAllLeafKBuckets(); foreach (KBucket kBucket in allLeafKBuckets) { if (kBucket._contacts != null) { if ((DateTime.UtcNow - kBucket._lastChanged).TotalSeconds > BUCKET_STALE_TIMEOUT_SECONDS) { ThreadPool.QueueUserWorkItem(delegate(object state) { //get random node ID in the bucket range BinaryNumber randomNodeID = BinaryNumber.GenerateRandomNumber256(); if (kBucket._bucketID != null) { randomNodeID = (randomNodeID >> kBucket._bucketDepth) | kBucket._bucketID; } //find closest contacts for current node id NodeContact[] initialContacts = kBucket.GetKClosestContacts(randomNodeID, true); if (initialContacts.Length > 0) { dhtNode.QueryFindNode(initialContacts, randomNodeID); } }); } } } }
internal void CheckContactHealth(DhtNode dhtNode) { List <KBucket> allLeafKBuckets = GetAllLeafKBuckets(); foreach (KBucket kBucket in allLeafKBuckets) { NodeContact[] contacts = kBucket._contacts; if (contacts != null) { foreach (NodeContact contact in contacts) { if ((contact != null) && contact.IsStale()) { ThreadPool.QueueUserWorkItem(delegate(object state) { if (!dhtNode.Ping(contact)) { //remove stale node contact kBucket.RemoveStaleContact(contact); } }); } } } } }
public LocalNetworkDhtManager(NetworkInfo network) { _network = network; //start udp & tcp listeners switch (_network.LocalIP.AddressFamily) { case AddressFamily.InterNetwork: _udpListener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); break; case AddressFamily.InterNetworkV6: _udpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); _tcpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); if ((Environment.OSVersion.Platform == PlatformID.Win32NT) && (Environment.OSVersion.Version.Major >= 6)) { //windows vista & above _udpListener.DualMode = true; _tcpListener.DualMode = true; } break; default: throw new NotSupportedException("Address family not supported."); } _udpListener.EnableBroadcast = true; _udpListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _udpListener.Bind(new IPEndPoint(_network.LocalIP, LOCAL_DISCOVERY_ANNOUNCE_PORT)); _tcpListener.Bind(new IPEndPoint(_network.LocalIP, 0)); _tcpListener.Listen(10); _dhtEndPoint = _tcpListener.LocalEndPoint as IPEndPoint; //init dht node _dhtNode = new DhtNode(this, _dhtEndPoint); if (_udpListener.AddressFamily == AddressFamily.InterNetworkV6) { NetworkInterface nic = _network.Interface; if ((nic.OperationalStatus == OperationalStatus.Up) && (nic.Supports(NetworkInterfaceComponent.IPv6)) && nic.SupportsMulticast) { try { _udpListener.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(IPAddress.Parse(IPV6_MULTICAST_IP), nic.GetIPProperties().GetIPv6Properties().Index)); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } } } //start reading packets _udpListenerThread = new Thread(ReceiveUdpPacketAsync); _udpListenerThread.IsBackground = true; _udpListenerThread.Start(); //start accepting connections _tcpListenerThread = new Thread(AcceptTcpConnectionAsync); _tcpListenerThread.IsBackground = true; _tcpListenerThread.Start(); //announce async _announceTimer = new Timer(AnnounceAsync, null, 1000, ANNOUNCEMENT_INTERVAL); }