Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
                            }
                        });
                    }
                }
            }
        }
Ejemplo n.º 3
0
        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);
                                }
                            });
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
            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);
            }