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);
        }
示例#2
0
        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);
                }
            }
        }
示例#3
0
        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
            { }
        }
示例#7
0
        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();
            }
        }
示例#8
0
 public void SendDhtPacket(byte[] buffer, int offset, int count)
 {
     WriteFrame(SignalType.DhtPacketData, BinaryID.GenerateRandomID160(), buffer, offset, count);
 }
示例#9
0
 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);
        }
示例#11
0
 protected NodeContact(int udpDhtPort)
 {
     _nodeID      = BinaryID.GenerateRandomID160();
     _nodeEP      = new IPEndPoint(IPAddress.Loopback, udpDhtPort);
     _currentNode = true;
 }