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 EndPoint ConvertChannelIdToEp(BinaryNumber channelId) { using (MemoryStream mS = new MemoryStream(channelId.Value, false)) { return(EndPointExtension.Parse(new BinaryReader(mS))); } }
public NameServerAddress(BinaryReader bR) { switch (bR.ReadByte()) { case 1: if (bR.ReadBoolean()) { _dohEndPoint = new Uri(bR.ReadShortString()); } if (bR.ReadBoolean()) { _domainEndPoint = EndPointExtension.Parse(bR) as DomainEndPoint; } if (bR.ReadBoolean()) { _ipEndPoint = EndPointExtension.Parse(bR) as IPEndPoint; } if (_dohEndPoint != null) { _originalAddress = _dohEndPoint.AbsoluteUri; } else if (_ipEndPoint != null) { _originalAddress = _ipEndPoint.ToString(); } else if (_domainEndPoint != null) { _originalAddress = _domainEndPoint.ToString(); } GuessProtocol(); break; case 2: Parse(bR.ReadShortString()); GuessProtocol(); break; case 3: _protocol = (DnsTransportProtocol)bR.ReadByte(); Parse(bR.ReadShortString()); break; default: throw new InvalidDataException("NameServerAddress version not supported"); } }
public MeshNetworkPeerInfo(BinaryReader bR) { _peerUserId = new BinaryNumber(bR.BaseStream); _peerName = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte())); if (_peerName == "") { _peerName = null; } { _peerEPs = new EndPoint[bR.ReadByte()]; for (int i = 0; i < _peerEPs.Length; i++) { _peerEPs[i] = EndPointExtension.Parse(bR); } } }
public DhtRpcPacket(BinaryReader bR) { int version = bR.ReadByte(); switch (version) { case 1: _sourceNodeEP = EndPointExtension.Parse(bR); _type = (DhtRpcType)bR.ReadByte(); switch (_type) { case DhtRpcType.PING: break; case DhtRpcType.FIND_NODE: _networkId = new BinaryNumber(bR.BaseStream); _contacts = new NodeContact[bR.ReadByte()]; for (int i = 0; i < _contacts.Length; i++) { _contacts[i] = new NodeContact(bR); } break; case DhtRpcType.FIND_PEERS: _networkId = new BinaryNumber(bR.BaseStream); _contacts = new NodeContact[bR.ReadByte()]; for (int i = 0; i < _contacts.Length; i++) { _contacts[i] = new NodeContact(bR); } _peers = new EndPoint[bR.ReadByte()]; for (int i = 0; i < _peers.Length; i++) { _peers[i] = EndPointExtension.Parse(bR); } break; case DhtRpcType.ANNOUNCE_PEER: _networkId = new BinaryNumber(bR.BaseStream); _peers = new EndPoint[bR.ReadByte()]; for (int i = 0; i < _peers.Length; i++) { _peers[i] = EndPointExtension.Parse(bR); } break; default: throw new IOException("Invalid DHT-RPC type."); } break; default: throw new InvalidDataException("DHT-RPC packet version not supported: " + version); } }
private void ReadFrameAsync() { try { //frame parameters int signal; BinaryNumber channelId = new BinaryNumber(new byte[32]); byte[] dataLengthBuffer = new byte[2]; OffsetStream dataStream = new OffsetStream(_baseStream, 0, 0, true, false); while (true) { #region read frame from base stream //read frame signal signal = _baseStream.ReadByte(); if (signal == -1) { return; //End of stream } //read channel id _baseStream.ReadBytes(channelId.Value, 0, 32); //read data length _baseStream.ReadBytes(dataLengthBuffer, 0, 2); dataStream.Reset(0, BitConverter.ToUInt16(dataLengthBuffer, 0), 0); #endregion switch ((ConnectionSignal)signal) { case ConnectionSignal.PingRequest: WriteFrame(ConnectionSignal.PingResponse, channelId, null, 0, 0); break; case ConnectionSignal.PingResponse: //do nothing! break; case ConnectionSignal.ConnectChannelMeshNetwork: #region ConnectChannelMeshNetwork lock (_channels) { if (_channels.ContainsKey(channelId)) { WriteFrame(ConnectionSignal.DisconnectChannel, channelId, null, 0, 0); } else { ChannelStream channel = new ChannelStream(this, channelId.Clone()); _channels.Add(channel.ChannelId, channel); ThreadPool.QueueUserWorkItem(delegate(object state) { try { //done async since the call is blocking and will block the current read thread which can cause DOS _connectionManager.Node.MeshNetworkRequest(this, channel.ChannelId, channel); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); channel.Dispose(); } }); } } //check if tcp relay is hosted for the channel. reply back tcp relay peers list if available Connection[] connections = _connectionManager.GetTcpRelayServerHostedNetworkConnections(channelId); if (connections.Length > 0) { int count = connections.Length; for (int i = 0; i < connections.Length; i++) { if (connections[i].RemotePeerEP.Equals(_remotePeerEP)) { connections[i] = null; count--; break; } } using (MemoryStream mS = new MemoryStream(128)) { BinaryWriter bW = new BinaryWriter(mS); bW.Write(Convert.ToByte(count)); foreach (Connection connection in connections) { if (connection != null) { connection.RemotePeerEP.WriteTo(bW); } } byte[] data = mS.ToArray(); WriteFrame(ConnectionSignal.MeshNetworkPeers, channelId, data, 0, data.Length); } } #endregion break; case ConnectionSignal.ChannelData: #region ChannelData try { ChannelStream channel = null; lock (_channels) { channel = _channels[channelId]; } channel.FeedReadBuffer(dataStream, _channelWriteTimeout); } catch { } #endregion break; case ConnectionSignal.DisconnectChannel: #region DisconnectChannel try { ChannelStream channel; lock (_channels) { channel = _channels[channelId]; _channels.Remove(channelId); } channel.SetDisconnected(); channel.Dispose(); } catch { } #endregion break; case ConnectionSignal.ConnectChannelTunnel: #region ConnectChannelTunnel if (IsStreamVirtualConnection(_baseStream)) { //nesting virtual connections not allowed WriteFrame(ConnectionSignal.DisconnectChannel, channelId, null, 0, 0); } else { ChannelStream remoteChannel1 = null; lock (_channels) { if (_channels.ContainsKey(channelId)) { WriteFrame(ConnectionSignal.DisconnectChannel, channelId, null, 0, 0); } else { //add first stream into list remoteChannel1 = new ChannelStream(this, channelId.Clone()); _channels.Add(remoteChannel1.ChannelId, remoteChannel1); } } if (remoteChannel1 != null) { EndPoint tunnelToRemotePeerEP = ConvertChannelIdToEp(channelId); //get remote peer ep Connection remotePeerConnection = _connectionManager.GetExistingConnection(tunnelToRemotePeerEP); //get remote channel service if (remotePeerConnection == null) { remoteChannel1.Dispose(); } else { try { //get remote proxy connection channel stream ChannelStream remoteChannel2 = remotePeerConnection.MakeVirtualConnection(_remotePeerEP); //join current and remote stream Joint joint = new Joint(remoteChannel1, remoteChannel2); joint.Disposed += delegate(object sender, EventArgs e) { lock (_tunnelJointList) { _tunnelJointList.Remove(sender as Joint); } }; lock (_tunnelJointList) { _tunnelJointList.Add(joint); } joint.Start(); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); remoteChannel1.Dispose(); } } } } #endregion break; case ConnectionSignal.ConnectChannelVirtualConnection: #region ConnectChannelVirtualConnection if (IsStreamVirtualConnection(_baseStream)) { //nesting virtual connections not allowed WriteFrame(ConnectionSignal.DisconnectChannel, channelId, null, 0, 0); } else { lock (_channels) { if (_channels.ContainsKey(channelId)) { WriteFrame(ConnectionSignal.DisconnectChannel, channelId, null, 0, 0); } else { //add proxy channel stream into list ChannelStream channel = new ChannelStream(this, channelId.Clone()); _channels.Add(channel.ChannelId, channel); //pass channel as connection async ThreadPool.QueueUserWorkItem(delegate(object state) { try { _connectionManager.AcceptConnectionInitiateProtocol(channel, ConvertChannelIdToEp(channel.ChannelId)); } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); channel.Dispose(); } }); } } } #endregion break; case ConnectionSignal.TcpRelayServerRegisterHostedNetwork: #region TcpRelayServerRegisterHostedNetwork _connectionManager.TcpRelayServerRegisterHostedNetwork(this, channelId.Clone()); _tcpRelayServerModeEnabled = true; #endregion break; case ConnectionSignal.TcpRelayServerUnregisterHostedNetwork: #region TcpRelayServerUnregisterHostedNetwork _connectionManager.TcpRelayServerUnregisterHostedNetwork(this, channelId); #endregion break; case ConnectionSignal.MeshNetworkPeers: #region MeshNetworkPeers { BinaryReader bR = new BinaryReader(dataStream); int count = bR.ReadByte(); List <EndPoint> peerEPs = new List <EndPoint>(count); for (int i = 0; i < count; i++) { peerEPs.Add(EndPointExtension.Parse(bR)); } _connectionManager.Node.ReceivedMeshNetworkPeersViaTcpRelay(this, channelId, peerEPs); } #endregion break; default: throw new IOException("Invalid frame signal."); } //discard any unread data if (dataStream.Length > dataStream.Position) { dataStream.CopyTo(Stream.Null, 1024, Convert.ToInt32(dataStream.Length - dataStream.Position)); } } } catch (ThreadAbortException) { //stopping } catch (Exception ex) { Debug.Write(this.GetType().Name, ex); } finally { Dispose(); } }
public NodeContact(BinaryReader bR) { _nodeEP = EndPointExtension.Parse(bR); _nodeId = GetNodeId(_nodeEP); }
private void InitMeshNode(BinaryReader bR, TorController torController) { switch (bR.ReadByte()) //version { case 1: _type = (MeshNodeType)bR.ReadByte(); _privateKey = bR.ReadBuffer(); _supportedCiphers = (SecureChannelCipherSuite)bR.ReadByte(); // _userId = new BinaryNumber(bR.BaseStream); // _localServicePort = bR.ReadUInt16(); _downloadFolder = bR.ReadShortString(); // _profileDateModified = bR.ReadDate(); _profileDisplayName = bR.ReadShortString(); _profileStatus = (MeshProfileStatus)bR.ReadByte(); _profileStatusMessage = bR.ReadShortString(); // _profileImageDateModified = bR.ReadDate(); _profileDisplayImage = bR.ReadBuffer(); // _ipv4BootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _ipv4BootstrapDhtNodes.Length; i++) { _ipv4BootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } _ipv6BootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _ipv6BootstrapDhtNodes.Length; i++) { _ipv6BootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } _torBootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _torBootstrapDhtNodes.Length; i++) { _torBootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } // _enableUPnP = bR.ReadBoolean(); _allowInboundInvitations = bR.ReadBoolean(); _allowOnlyLocalInboundInvitations = bR.ReadBoolean(); // if (bR.ReadBoolean()) { _proxy = new NetProxy((NetProxyType)bR.ReadByte(), bR.ReadShortString(), bR.ReadUInt16(), (bR.ReadBoolean() ? new NetworkCredential(bR.ReadShortString(), bR.ReadShortString()) : null)); } // _appData = bR.ReadBuffer(); //start connection manager _connectionManager = new ConnectionManager(this, torController); // int networkCount = bR.ReadInt32(); for (int i = 0; i < networkCount; i++) { MeshNetwork network = new MeshNetwork(_connectionManager, bR); _networks.Add(network.NetworkId, network); } InitAnnounceTimer(); break; default: throw new InvalidDataException("MeshNode format version not supported."); } }