コード例 #1
0
        public Stream RequestBitChatNetworkChannel(BinaryID channelName)
        {
            ChannelStream channel;

            lock (_bitChatNetworkChannels)
            {
                if (_bitChatNetworkChannels.ContainsKey(channelName))
                {
                    throw new ArgumentException("Channel already exists.");
                }

                channel = new ChannelStream(this, channelName.Clone(), ChannelType.BitChatNetwork);
                _bitChatNetworkChannels.Add(channel.ChannelName, channel);
            }

            //send connect signal
            WriteFrame(SignalType.ConnectChannelBitChatNetwork, channelName, null, 0, 0);

            return(channel);
        }
コード例 #2
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();
            }
        }
コード例 #3
0
        public DhtRpcPacket(Stream s, IPAddress nodeIP)
        {
            int version = s.ReadByte();

            switch (version)
            {
            case 1:
                byte[] buffer = new byte[20];

                OffsetStream.StreamRead(s, buffer, 0, 4);
                _transactionID = BitConverter.ToInt32(buffer, 0);

                OffsetStream.StreamRead(s, buffer, 0, 20);
                BinaryID nodeID = BinaryID.Clone(buffer, 0, 20);

                OffsetStream.StreamRead(s, buffer, 0, 2);
                _sourceNode = new NodeContact(nodeID, new IPEndPoint(nodeIP, BitConverter.ToUInt16(buffer, 0)));

                _type      = (RpcPacketType)s.ReadByte();
                _queryType = (RpcQueryType)s.ReadByte();

                switch (_queryType)
                {
                case RpcQueryType.FIND_NODE:
                    OffsetStream.StreamRead(s, buffer, 0, 20);
                    _networkID = BinaryID.Clone(buffer, 0, 20);

                    if (_type == RpcPacketType.Response)
                    {
                        int count = s.ReadByte();
                        _contacts = new NodeContact[count];

                        for (int i = 0; i < count; i++)
                        {
                            _contacts[i] = new NodeContact(s);
                        }
                    }
                    break;

                case RpcQueryType.FIND_PEERS:
                    OffsetStream.StreamRead(s, buffer, 0, 20);
                    _networkID = BinaryID.Clone(buffer, 0, 20);

                    if (_type == RpcPacketType.Response)
                    {
                        int count = s.ReadByte();
                        _contacts = new NodeContact[count];

                        for (int i = 0; i < count; i++)
                        {
                            _contacts[i] = new NodeContact(s);
                        }

                        count  = s.ReadByte();
                        _peers = new PeerEndPoint[count];

                        for (int i = 0; i < count; i++)
                        {
                            _peers[i] = new PeerEndPoint(s);
                        }

                        OffsetStream.StreamRead(s, buffer, 0, 20);
                        _token = new BinaryID(buffer);
                    }
                    break;

                case RpcQueryType.ANNOUNCE_PEER:
                    OffsetStream.StreamRead(s, buffer, 0, 20);
                    _networkID = BinaryID.Clone(buffer, 0, 20);

                    if (_type == RpcPacketType.Query)
                    {
                        OffsetStream.StreamRead(s, buffer, 0, 2);
                        _servicePort = BitConverter.ToUInt16(buffer, 0);

                        OffsetStream.StreamRead(s, buffer, 0, 20);
                        _token = new BinaryID(buffer);
                    }
                    break;
                }

                break;

            default:
                throw new IOException("DHT-RPC packet version not supported: " + version);
            }
        }
コード例 #4
0
ファイル: Connection.cs プロジェクト: thaolt/BitChatClient
 public ChannelStream(Connection connection, BinaryID channelName, ChannelType channelType)
 {
     _connection  = connection;
     _channelName = channelName.Clone();
     _channelType = channelType;
 }
コード例 #5
0
 public ChannelStream(Connection connection, BinaryID channelName, ChannelType channelType)
 {
     _connection = connection;
     _channelName = channelName.Clone();
     _channelType = channelType;
 }