private void CreateInvitationPrivateChat(BinaryID hashedPeerEmailAddress, BinaryID networkID, IPEndPoint peerEP, string message) { BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, hashedPeerEmailAddress, networkID, null, BitChatNetworkStatus.Offline, peerEP.ToString(), message); BitChat chat = CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, 0, null, new BitChatProfile.SharedFileInfo[] { }, _profile.TrackerURIs, true, false, false); RaiseEventBitChatInvitationReceived(chat); }
public bool RequestStartTcpRelay(BinaryID[] networkIDs, Uri[] trackerURIs, int timeout) { BinaryID channelName = BinaryID.GenerateRandomID160(); object lockObject = new object(); lock (_tcpRelayRequestLockList) { _tcpRelayRequestLockList.Add(channelName, lockObject); } try { lock (lockObject) { using (MemoryStream mS = new MemoryStream(1024)) { byte[] XORnetworkID = new byte[20]; byte[] randomChannelID = channelName.ID; //write networkid list mS.WriteByte(Convert.ToByte(networkIDs.Length)); foreach (BinaryID networkID in networkIDs) { byte[] network = networkID.ID; for (int i = 0; i < 20; i++) { XORnetworkID[i] = (byte)(randomChannelID[i] ^ network[i]); } mS.Write(XORnetworkID, 0, 20); } //write tracker uri list mS.WriteByte(Convert.ToByte(trackerURIs.Length)); foreach (Uri trackerURI in trackerURIs) { byte[] buffer = Encoding.UTF8.GetBytes(trackerURI.AbsoluteUri); mS.WriteByte(Convert.ToByte(buffer.Length)); mS.Write(buffer, 0, buffer.Length); } byte[] data = mS.ToArray(); WriteFrame(SignalType.StartTcpRelay, channelName, data, 0, data.Length); } return(Monitor.Wait(lockObject, timeout)); } } finally { lock (_tcpRelayRequestLockList) { _tcpRelayRequestLockList.Remove(channelName); } } }
public ConnectionManager(IPEndPoint localEP, ChannelRequest requestHandler) { try { _tcpListener = new TcpListener(localEP); _tcpListener.Start(10); } catch { _tcpListener = new TcpListener(new IPEndPoint(localEP.Address, 0)); _tcpListener.Start(10); } _externalSelfEP = (IPEndPoint)_tcpListener.LocalEndpoint; _requestHandler = requestHandler; _localPeerID = BinaryID.GenerateRandomID160(); //start accepting connections _tcpListenerThread = new Thread(AcceptTcpConnectionAsync); _tcpListenerThread.IsBackground = true; _tcpListenerThread.Start(); //start upnp process _upnpTimer = new Timer(UPnPTimerCallback, null, 1000, Timeout.Infinite); }
public BitChat CreateGroupChat(string networkName, string sharedSecret, bool enableTracking, bool dhtOnlyTracking) { Uri[] trackerURIs; if (dhtOnlyTracking) { trackerURIs = new Uri[] { } } ; else { trackerURIs = _profile.TrackerURIs; } BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, networkName, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online); return(CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, -1, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, false, false)); }
public BitChat CreatePrivateChat(MailAddress peerEmailAddress, string sharedSecret, bool enableTracking, bool dhtOnlyTracking, string invitationMessage) { Uri[] trackerURIs; if (dhtOnlyTracking) { trackerURIs = new Uri[] { } } ; else { trackerURIs = _profile.TrackerURIs; } BitChatNetwork network = new BitChatNetwork(_connectionManager, _trustedRootCertificates, _supportedCryptoOptions, peerEmailAddress, sharedSecret, null, null, new Certificate[] { }, BitChatNetworkStatus.Online, _profile.LocalCertificateStore.Certificate.IssuedTo.EmailAddress.Address, invitationMessage); return(CreateBitChat(network, BinaryID.GenerateRandomID160().ToString(), BinaryID.GenerateRandomID256().ID, 0, null, new BitChatProfile.SharedFileInfo[] { }, trackerURIs, enableTracking, !string.IsNullOrEmpty(invitationMessage), false)); }
private void RefreshBucketAsync(object state) { try { DhtClient dhtClient = state as DhtClient; //get random node ID in the bucket range BinaryID randomNodeID = (BinaryID.GenerateRandomID160() << _bucketDepth) | _bucketID; //find closest contacts for current node id NodeContact[] initialContacts = GetKClosestContacts(randomNodeID); if (initialContacts.Length > 0) { dhtClient.QueryFindNode(initialContacts, randomNodeID); //query manager auto add contacts that respond } } catch { } }
private void ReadFrameAsync() { try { //frame parameters int signalType; BinaryID channelName = new BinaryID(new byte[20]); int dataLength; byte[] dataBuffer = new byte[BUFFER_SIZE]; while (true) { #region Read frame from base stream //read frame signal signalType = _baseStream.ReadByte(); if (signalType == -1) { return; //End of stream } //read channel name OffsetStream.StreamRead(_baseStream, channelName.ID, 0, 20); //read data length OffsetStream.StreamRead(_baseStream, dataBuffer, 0, 2); dataLength = BitConverter.ToUInt16(dataBuffer, 0); //read data if (dataLength > 0) { OffsetStream.StreamRead(_baseStream, dataBuffer, 0, dataLength); } #endregion switch ((SignalType)signalType) { case SignalType.NOOP: break; case SignalType.ConnectChannelBitChatNetwork: #region ConnectChannelBitChatNetwork lock (_bitChatNetworkChannels) { if (_bitChatNetworkChannels.ContainsKey(channelName)) { WriteFrame(SignalType.DisconnectChannelBitChatNetwork, channelName, null, 0, 0); } else { ChannelStream channel = new ChannelStream(this, channelName.Clone(), ChannelType.BitChatNetwork); _bitChatNetworkChannels.Add(channel.ChannelName, channel); BitChatNetworkChannelRequest.BeginInvoke(this, channel.ChannelName, channel, null, null); } } //check if tcp relay is hosted for the channel. reply back tcp relay peers list if available try { List <IPEndPoint> peerEPs = TcpRelayService.GetPeerEPs(channelName, this); if ((peerEPs != null) && (peerEPs.Count > 0)) { using (MemoryStream mS = new MemoryStream(128)) { mS.WriteByte(Convert.ToByte(peerEPs.Count)); foreach (IPEndPoint peerEP in peerEPs) { IPEndPointParser.WriteTo(peerEP, mS); } byte[] data = mS.ToArray(); WriteFrame(SignalType.TcpRelayResponsePeerList, channelName, data, 0, data.Length); } } } catch { } #endregion break; case SignalType.DataChannelBitChatNetwork: #region DataChannelBitChatNetwork try { ChannelStream channel = null; lock (_bitChatNetworkChannels) { channel = _bitChatNetworkChannels[channelName]; } channel.WriteBuffer(dataBuffer, 0, dataLength, _channelWriteTimeout); } catch { } #endregion break; case SignalType.DisconnectChannelBitChatNetwork: #region DisconnectChannelBitChatNetwork try { ChannelStream channel; lock (_bitChatNetworkChannels) { channel = _bitChatNetworkChannels[channelName]; _bitChatNetworkChannels.Remove(channelName); } channel.SetDisconnected(); channel.Dispose(); } catch { } #endregion break; case SignalType.ConnectChannelProxyTunnel: #region ConnectChannelProxyTunnel { ChannelStream remoteChannel1 = null; lock (_proxyChannels) { if (_proxyChannels.ContainsKey(channelName)) { WriteFrame(SignalType.DisconnectChannelProxy, channelName, null, 0, 0); } else { //add first stream into list remoteChannel1 = new ChannelStream(this, channelName.Clone(), ChannelType.ProxyTunnel); _proxyChannels.Add(remoteChannel1.ChannelName, remoteChannel1); } } if (remoteChannel1 != null) { IPEndPoint tunnelToRemotePeerEP = ConvertChannelNameToEp(channelName); //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.RequestProxyConnection(_remotePeerEP); //join current and remote stream Joint joint = new Joint(remoteChannel1, remoteChannel2); joint.Disposed += joint_Disposed; lock (_proxyTunnelJointList) { _proxyTunnelJointList.Add(joint); } joint.Start(); } catch { remoteChannel1.Dispose(); } } } } #endregion break; case SignalType.ConnectChannelProxyConnection: #region ConnectChannelProxyConnection lock (_proxyChannels) { if (_proxyChannels.ContainsKey(channelName)) { WriteFrame(SignalType.DisconnectChannelProxy, channelName, null, 0, 0); } else { //add proxy channel stream into list ChannelStream channel = new ChannelStream(this, channelName.Clone(), ChannelType.ProxyTunnel); _proxyChannels.Add(channel.ChannelName, channel); //pass channel as connection async ThreadPool.QueueUserWorkItem(AcceptProxyConnectionAsync, channel); } } #endregion break; case SignalType.DataChannelProxy: #region DataChannelProxy try { ChannelStream channel = null; lock (_proxyChannels) { channel = _proxyChannels[channelName]; } channel.WriteBuffer(dataBuffer, 0, dataLength, _channelWriteTimeout); } catch { } #endregion break; case SignalType.DisconnectChannelProxy: #region DisconnectChannelProxy try { ChannelStream channel; lock (_proxyChannels) { channel = _proxyChannels[channelName]; _proxyChannels.Remove(channelName); } channel.SetDisconnected(); channel.Dispose(); } catch { } #endregion break; case SignalType.PeerStatusQuery: #region PeerStatusQuery try { if (_connectionManager.IsPeerConnectionAvailable(ConvertChannelNameToEp(channelName))) { WriteFrame(SignalType.PeerStatusAvailable, channelName, null, 0, 0); } } catch { } #endregion break; case SignalType.PeerStatusAvailable: #region PeerStatusAvailable try { lock (_peerStatusLockList) { object lockObject = _peerStatusLockList[channelName]; lock (lockObject) { Monitor.Pulse(lockObject); } } } catch { } #endregion break; case SignalType.StartTcpRelay: #region StartTcpRelay { BinaryID[] networkIDs; Uri[] trackerURIs; using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false)) { //read network id list networkIDs = new BinaryID[mS.ReadByte()]; byte[] XORnetworkID = new byte[20]; for (int i = 0; i < networkIDs.Length; i++) { mS.Read(XORnetworkID, 0, 20); byte[] networkID = new byte[20]; for (int j = 0; j < 20; j++) { networkID[j] = (byte)(channelName.ID[j] ^ XORnetworkID[j]); } networkIDs[i] = new BinaryID(networkID); } //read tracker uri list trackerURIs = new Uri[mS.ReadByte()]; byte[] data = new byte[255]; for (int i = 0; i < trackerURIs.Length; i++) { int length = mS.ReadByte(); mS.Read(data, 0, length); trackerURIs[i] = new Uri(Encoding.UTF8.GetString(data, 0, length)); } } lock (_tcpRelays) { foreach (BinaryID networkID in networkIDs) { if (!_tcpRelays.ContainsKey(networkID)) { TcpRelayService relay = TcpRelayService.StartTcpRelay(networkID, this, _connectionManager.LocalPort, _connectionManager.DhtClient, trackerURIs); _tcpRelays.Add(networkID, relay); } } } WriteFrame(SignalType.TcpRelayResponseSuccess, channelName, null, 0, 0); } #endregion break; case SignalType.StopTcpRelay: #region StopTcpRelay { BinaryID[] networkIDs; using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false)) { //read network id list networkIDs = new BinaryID[mS.ReadByte()]; byte[] XORnetworkID = new byte[20]; for (int i = 0; i < networkIDs.Length; i++) { mS.Read(XORnetworkID, 0, 20); byte[] networkID = new byte[20]; for (int j = 0; j < 20; j++) { networkID[j] = (byte)(channelName.ID[j] ^ XORnetworkID[j]); } networkIDs[i] = new BinaryID(networkID); } } lock (_tcpRelays) { foreach (BinaryID networkID in networkIDs) { if (_tcpRelays.ContainsKey(networkID)) { _tcpRelays[networkID].StopTcpRelay(this); _tcpRelays.Remove(networkID); } } } WriteFrame(SignalType.TcpRelayResponseSuccess, channelName, null, 0, 0); } #endregion break; case SignalType.TcpRelayResponseSuccess: #region TcpRelayResponseSuccess try { lock (_tcpRelayRequestLockList) { object lockObject = _tcpRelayRequestLockList[channelName]; lock (lockObject) { Monitor.Pulse(lockObject); } } } catch { } #endregion break; case SignalType.TcpRelayResponsePeerList: #region TcpRelayResponsePeerList using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false)) { int count = mS.ReadByte(); List <IPEndPoint> peerEPs = new List <IPEndPoint>(count); for (int i = 0; i < count; i++) { peerEPs.Add(IPEndPointParser.Parse(mS)); } TcpRelayPeersAvailable.BeginInvoke(this, channelName.Clone(), peerEPs, null, null); } #endregion break; case SignalType.DhtPacketData: #region DhtPacketData byte[] response = _connectionManager.DhtClient.ProcessPacket(dataBuffer, 0, dataLength, _remotePeerEP.Address); if (response != null) { WriteFrame(SignalType.DhtPacketData, BinaryID.GenerateRandomID160(), response, 0, response.Length); } #endregion break; case SignalType.BitChatNetworkInvitation: #region ChannelInvitationBitChatNetwork if (_connectionManager.Profile.AllowInboundInvitations) { BitChatNetworkInvitation.BeginInvoke(channelName.Clone(), _remotePeerEP, Encoding.UTF8.GetString(dataBuffer, 0, dataLength), null, null); } #endregion break; default: throw new IOException("Invalid frame signal type."); } } } catch { } finally { Dispose(); } }
public void SendDhtPacket(byte[] buffer, int offset, int count) { WriteFrame(SignalType.DhtPacketData, BinaryID.GenerateRandomID160(), buffer, offset, count); }
public void SendNOOP() { WriteFrame(SignalType.NOOP, BinaryID.GenerateRandomID160(), null, 0, 0); }
public ConnectionManager(BitChatProfile profile) { IPEndPoint localEP; switch (Environment.OSVersion.Platform) { case PlatformID.Win32NT: if (Environment.OSVersion.Version.Major < 6) { //below vista _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); } else { //vista & above _tcpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); _tcpListener.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); localEP = new IPEndPoint(IPAddress.IPv6Any, profile.LocalPort); } break; case PlatformID.Unix: //mono framework if (Socket.OSSupportsIPv6) { _tcpListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.IPv6Any, profile.LocalPort); } else { _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); } break; default: //unknown _tcpListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); localEP = new IPEndPoint(IPAddress.Any, profile.LocalPort); break; } try { _tcpListener.Bind(localEP); _tcpListener.Listen(10); } catch { localEP.Port = 0; _tcpListener.Bind(localEP); _tcpListener.Listen(10); } _profile = profile; _localPort = (_tcpListener.LocalEndPoint as IPEndPoint).Port; _localPeerID = BinaryID.GenerateRandomID160(); //start dht _dhtClient = new DhtClient(_localPort, this); _dhtClient.ProxyEnabled = (_profile.Proxy != null); _dhtClient.AddNode(profile.BootstrapDhtNodes); //setup dht seeding tracker _dhtSeedingTracker = new TrackerManager(_dhtSeedingNetworkID, _localPort, null, DHT_SEED_TRACKER_UPDATE_INTERVAL); _dhtSeedingTracker.Proxy = _profile.Proxy; _dhtSeedingTracker.DiscoveredPeers += dhtSeedingTracker_DiscoveredPeers; _dhtSeedingTracker.StartTracking(profile.TrackerURIs); //start accepting connections _tcpListenerThread = new Thread(AcceptTcpConnectionAsync); _tcpListenerThread.IsBackground = true; _tcpListenerThread.Start(_tcpListener); //start upnp process _connectivityCheckTimer = new Timer(ConnectivityCheckTimerCallback, null, 1000, Timeout.Infinite); }
protected NodeContact(int udpDhtPort) { _nodeID = BinaryID.GenerateRandomID160(); _nodeEP = new IPEndPoint(IPAddress.Loopback, udpDhtPort); _currentNode = true; }