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); }
private void ReceiveUdpPacketAsync(object parameter) { EndPoint remoteEP = null; byte[] buffer = new byte[BUFFER_MAX_SIZE]; int bytesRecv; if (_udpListener.AddressFamily == AddressFamily.InterNetwork) { remoteEP = new IPEndPoint(IPAddress.Any, 0); } else { remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0); } #region this code ignores ICMP port unreachable responses which creates SocketException in ReceiveFrom() if (Environment.OSVersion.Platform == PlatformID.Win32NT) { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; _udpListener.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); } #endregion try { while (true) { try { //receive message from remote bytesRecv = _udpListener.ReceiveFrom(buffer, ref remoteEP); } catch (SocketException ex) { switch (ex.SocketErrorCode) { case SocketError.ConnectionReset: case SocketError.HostUnreachable: case SocketError.MessageSize: case SocketError.NetworkReset: bytesRecv = 0; break; default: throw; } } if (bytesRecv > 0) { IPAddress remoteNodeIP = (remoteEP as IPEndPoint).Address; if (remoteNodeIP.IsIPv4MappedToIPv6) { remoteNodeIP = remoteNodeIP.MapToIPv4(); } if (remoteNodeIP.AddressFamily == AddressFamily.InterNetworkV6) { remoteNodeIP.ScopeId = 0; } try { DhtNodeDiscoveryPacket packet = new DhtNodeDiscoveryPacket(new MemoryStream(buffer, false)); IPEndPoint remoteNodeEP = new IPEndPoint(remoteNodeIP, packet.DhtPort); if (!remoteNodeEP.Equals(_dhtEndPoint)) { Debug.Write(this.GetType().Name, "dht node discovered: " + _dhtEndPoint.ToString()); //add node _dhtNode.AddNode(remoteNodeEP); } } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } } } } catch (ThreadAbortException) { //stopping } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } }