Beispiel #1
0
        public NodeContact(Stream s)
        {
            byte[] nodeID = new byte[20];

            OffsetStream.StreamRead(s, nodeID, 0, 20);
            _nodeID = new BinaryID(nodeID);

            byte[] address;
            byte[] port;

            switch (s.ReadByte())
            {
            case 0:
                address = new byte[4];
                port    = new byte[2];

                OffsetStream.StreamRead(s, address, 0, 4);
                OffsetStream.StreamRead(s, port, 0, 2);
                break;

            case 1:
                address = new byte[16];
                port    = new byte[2];

                OffsetStream.StreamRead(s, address, 0, 16);
                OffsetStream.StreamRead(s, port, 0, 2);
                break;

            default:
                throw new Exception("AddressFamily not supported.");
            }

            _nodeEP = new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0));
        }
Beispiel #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);
                }
            }
        }
        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 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);
        }
Beispiel #5
0
        private IPEndPoint ConvertChannelNameToEp(BinaryID channelName)
        {
            byte[] address;
            byte[] port;

            switch (channelName.ID[0])
            {
            case 0:
                address = new byte[4];
                port    = new byte[2];
                Buffer.BlockCopy(channelName.ID, 1, address, 0, 4);
                Buffer.BlockCopy(channelName.ID, 1 + 4, port, 0, 2);
                break;

            case 1:
                address = new byte[16];
                port    = new byte[2];
                Buffer.BlockCopy(channelName.ID, 1, address, 0, 16);
                Buffer.BlockCopy(channelName.ID, 1 + 16, port, 0, 2);
                break;

            default:
                throw new Exception("AddressFamily not supported.");
            }

            return(new IPEndPoint(new IPAddress(address), BitConverter.ToUInt16(port, 0)));
        }
Beispiel #6
0
 public bool BitChatNetworkChannelExists(BinaryID channelName)
 {
     lock (_bitChatNetworkChannels)
     {
         return(_bitChatNetworkChannels.ContainsKey(channelName));
     }
 }
Beispiel #7
0
 public Connection(Stream baseStream, BinaryID remotePeerID, IPEndPoint remotePeerEP, ConnectionManager connectionManager)
 {
     _baseStream        = baseStream;
     _remotePeerID      = remotePeerID;
     _remotePeerEP      = remotePeerEP;
     _connectionManager = connectionManager;
 }
Beispiel #8
0
        public bool RequestPeerStatus(IPEndPoint remotePeerEP)
        {
            BinaryID channelName = ConvertEpToChannelName(remotePeerEP);
            object   lockObject  = new object();

            lock (_peerStatusLockList)
            {
                _peerStatusLockList.Add(channelName, lockObject);
            }

            try
            {
                lock (lockObject)
                {
                    WriteFrame(SignalType.PeerStatusQuery, channelName, null, 0, 0);

                    return(Monitor.Wait(lockObject, 10000));
                }
            }
            finally
            {
                lock (_peerStatusLockList)
                {
                    _peerStatusLockList.Remove(channelName);
                }
            }
        }
 public FileBlockRequest(BinaryID fileID, int blockNumber, int blockOffset, ushort length)
 {
     _fileID = fileID;
     _blockNumber = blockNumber;
     _blockOffset = blockOffset;
     _length = length;
 }
Beispiel #10
0
        public SharedFileMetaData(Stream s)
        {
            BinaryReader bR = new BinaryReader(s);

            switch (bR.ReadByte()) //version
            {
            case 1:
                _fileName     = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte()));
                _contentType  = new ContentType(Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte())));
                _lastModified = _epoch.AddSeconds(bR.ReadInt64());

                _fileSize  = bR.ReadInt64();
                _blockSize = bR.ReadInt32();

                _hashAlgo = Encoding.ASCII.GetString(bR.ReadBytes(bR.ReadByte()));

                int totalBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((double)_fileSize / _blockSize)));

                _blockHash = new byte[totalBlocks][];

                int hashLength = bR.ReadByte();

                for (int i = 0; i < totalBlocks; i++)
                {
                    _blockHash[i] = bR.ReadBytes(hashLength);
                }

                _fileID = ComputeFileID();
                break;

            default:
                throw new BitChatException("FileMetaData format version not supported.");
            }
        }
Beispiel #11
0
        public FileBlockWanted(Stream s)
        {
            BinaryReader bR = new BinaryReader(s);

            _fileID      = new BinaryID(bR.ReadBytes(bR.ReadByte()));
            _blockNumber = bR.ReadInt32();
        }
Beispiel #12
0
 public FileBlockRequest(BinaryID fileID, int blockNumber, int blockOffset, ushort length)
 {
     _fileID      = fileID;
     _blockNumber = blockNumber;
     _blockOffset = blockOffset;
     _length      = length;
 }
Beispiel #13
0
        private void WriteDataFrame(byte[] buffer, int offset, int count, BinaryID channelName, ChannelType type)
        {
            //Debug.Write("Connection.WriteDataFrame", _remotePeerEP.ToString() + "; channel:" + channelName.ToString() + "; dataSize:" + count);

            if (count < 1)
            {
                return;
            }

            lock (_baseStream)
            {
                //write frame signal
                _writeBufferData[0] = SIGNAL_DATA;

                //write channel name
                Buffer.BlockCopy(channelName.ID, 0, _writeBufferData, 1, 20);

                //write channel type
                _writeBufferData[21] = (byte)type;

                //write data
                byte[] bufferCount = BitConverter.GetBytes(Convert.ToUInt16(count - 1));
                _writeBufferData[22] = bufferCount[0];
                _writeBufferData[23] = bufferCount[1];
                Buffer.BlockCopy(buffer, offset, _writeBufferData, 24, count);

                //output to base stream
                _baseStream.Write(_writeBufferData, 0, 24 + count);
                _baseStream.Flush();
            }
        }
        public BitChatNetwork(MailAddress peerEmailAddress, string sharedSecret, BinaryID networkID, Certificate[] knownPeerCerts, IBitChatNetworkManager networkManager, ISecureChannelSecurityManager securityManager)
        {
            _type = BitChatNetworkType.PrivateChat;
            _peerEmailAddress = peerEmailAddress;
            _sharedSecret = sharedSecret;
            _networkManager = networkManager;
            _securityManager = securityManager;

            LoadPeers(knownPeerCerts);

            if (knownPeerCerts.Length > 0)
                _peerName = knownPeerCerts[0].IssuedTo.Name;

            if (networkID == null)
            {
                //compute network id
                HashAlgorithm hash = HashAlgorithm.Create("SHA1");

                byte[] peerEmailAddressHash = hash.ComputeHash(Encoding.UTF8.GetBytes(_peerEmailAddress.Address.ToLower()));
                byte[] selfEmailAddressHash = hash.ComputeHash(Encoding.UTF8.GetBytes(networkManager.GetLocalCredentials().Certificate.IssuedTo.EmailAddress.Address.ToLower()));
                byte[] salt = new byte[20];

                for (int i = 0; i < 20; i++)
                {
                    salt[i] = (byte)(peerEmailAddressHash[i] ^ selfEmailAddressHash[i]);
                }

                _networkID = new BinaryID(PBKDF2.CreateHMACSHA1(_sharedSecret, salt, 200000).GetBytes(20));
            }
            else
            {
                _networkID = networkID;
            }
        }
        private Connection MakeConnectionInitiateProtocol(Stream networkStream, IPEndPoint remotePeerEP)
        {
            try
            {
                //send request
                {
                    byte[] buffer = new byte[23];                                                            //request buffer

                    buffer[0] = 1;                                                                           //version
                    Buffer.BlockCopy(_localPeerID.ID, 0, buffer, 1, 20);                                     //peer id
                    Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(_localPort)), 0, buffer, 21, 2); //service port

                    networkStream.Write(buffer, 0, 23);
                }

                //read response
                int response = networkStream.ReadByte();
                if (response == 0)
                {
                    byte[] buffer = new byte[20];
                    networkStream.Read(buffer, 0, 20);
                    BinaryID remotePeerID = new BinaryID(buffer);

                    Connection connection = AddConnection(networkStream, remotePeerID, remotePeerEP);
                    if (connection == null)
                    {
                        //check for existing connection again!
                        Connection existingConnection = GetExistingConnection(remotePeerEP);
                        if (existingConnection != null)
                        {
                            networkStream.Dispose();
                            return(existingConnection);
                        }

                        throw new IOException("Cannot connect to remote peer: connection already exists.");
                    }

                    return(connection);
                }
                else
                {
                    Thread.Sleep(500); //wait so that other thread gets time to add his connection in list so that this thread can pick same connection to proceed

                    //check for existing connection again!
                    Connection existingConnection = GetExistingConnection(remotePeerEP);
                    if (existingConnection != null)
                    {
                        networkStream.Dispose();
                        return(existingConnection);
                    }

                    throw new IOException("Cannot connect to remote peer: request rejected.");
                }
            }
            catch
            {
                networkStream.Dispose();
                throw;
            }
        }
Beispiel #16
0
            public PeerInfo(IPEndPoint peerEP, BinaryID networkID)
            {
                _peerEP    = peerEP;
                _networkID = networkID;

                _dateAdded = DateTime.UtcNow;
            }
        public KBucket FindClosestBucket(BinaryID nodeID)
        {
            KBucket currentBucket            = this;
            ReaderWriterLockSlim currentLock = this._lock;

            while (true)
            {
                currentLock.TryEnterReadLock(LOCK_TIMEOUT);
                try
                {
                    if (currentBucket._contacts != null)
                    {
                        break;
                    }

                    if ((currentBucket._leftBucket._bucketID & nodeID) == currentBucket._leftBucket._bucketID)
                    {
                        currentBucket = currentBucket._leftBucket;
                    }
                    else
                    {
                        currentBucket = currentBucket._rightBucket;
                    }
                }
                finally
                {
                    currentLock.ExitReadLock();
                }

                currentLock = currentBucket._lock;
            }

            currentBucket._lastChanged = DateTime.UtcNow;
            return(currentBucket);
        }
        private void SendAnnouncementBlockWanted(BinaryID fileID, int blockNumber)
        {
            byte[] packetData = BitChatMessage.CreateFileBlockWanted(fileID, blockNumber);

            //announce to all peers
            _peersLock.EnterReadLock();
            try
            {
                foreach (BitChatNetwork.VirtualPeer.VirtualSession peer in _peers)
                {
                    peer.WriteMessage(packetData, 0, packetData.Length);
                }
            }
            finally
            {
                _peersLock.ExitReadLock();
            }

            //announce to all seeds
            _seedersLock.EnterReadLock();
            try
            {
                foreach (BitChatNetwork.VirtualPeer.VirtualSession seeder in _seeders)
                {
                    seeder.WriteMessage(packetData, 0, packetData.Length);
                }
            }
            finally
            {
                _seedersLock.ExitReadLock();
            }
        }
Beispiel #19
0
            public void StorePeer(BinaryID networkID, PeerEndPoint peerEP)
            {
                lock (_data)
                {
                    List <PeerEndPoint> peerList;

                    if (_data.ContainsKey(networkID))
                    {
                        peerList = _data[networkID];
                    }
                    else
                    {
                        peerList = new List <PeerEndPoint>();
                        _data.Add(networkID, peerList);
                    }

                    foreach (PeerEndPoint peer in peerList)
                    {
                        if (peer.Equals(peerEP))
                        {
                            peer.UpdateDateAdded();
                            return;
                        }
                    }

                    peerList.Add(peerEP);
                }
            }
Beispiel #20
0
            public PeerEndPoint[] GetPeers(BinaryID networkID)
            {
                lock (_data)
                {
                    if (_data.ContainsKey(networkID))
                    {
                        List <PeerEndPoint> peers = _data[networkID];

                        if (peers.Count > MAX_PEERS_TO_RETURN)
                        {
                            List <PeerEndPoint> finalPeers = new List <PeerEndPoint>(peers);
                            Random rnd = new Random(DateTime.UtcNow.Millisecond);

                            while (finalPeers.Count > MAX_PEERS_TO_RETURN)
                            {
                                finalPeers.RemoveAt(rnd.Next(finalPeers.Count - 1));
                            }

                            return(finalPeers.ToArray());
                        }
                        else
                        {
                            return(_data[networkID].ToArray());
                        }
                    }
                    else
                    {
                        return(new PeerEndPoint[] { });
                    }
                }
            }
        public NodeContact FindContactInCurrentBucket(BinaryID nodeID)
        {
            _lock.TryEnterReadLock(LOCK_TIMEOUT);
            try
            {
                if (_contacts == null)
                {
                    return(null);
                }

                if (_contacts.ContainsKey(nodeID))
                {
                    return(_contacts[nodeID]);
                }

                if (_replacementContacts.ContainsKey(nodeID))
                {
                    return(_replacementContacts[nodeID]);
                }

                return(null);
            }
            finally
            {
                _lock.ExitReadLock();
            }
        }
Beispiel #22
0
        public bool RequestPeerStatus(IPEndPoint remotePeerEP)
        {
            BinaryID channelName = new BinaryID(ConvertToBinary(remotePeerEP));
            object   lockObject  = new object();

            lock (_peerStatusLockList)
            {
                _peerStatusLockList.Add(channelName, lockObject);
            }

            lock (lockObject)
            {
                WriteSignalFrame(channelName, SIGNAL_PEER_STATUS);

                if (!Monitor.Wait(lockObject, 10000))
                {
                    lock (_peerStatusLockList)
                    {
                        _peerStatusLockList.Remove(channelName);
                    }

                    return(false);
                }

                return(true);
            }
        }
        public FileBlockWanted(Stream s)
        {
            BinaryReader bR = new BinaryReader(s);

            _fileID = new BinaryID(bR.ReadBytes(bR.ReadByte()));
            _blockNumber = bR.ReadInt32();
        }
        public static NodeContact[] GetClosestContacts(IEnumerable <NodeContact> contacts, BinaryID nodeID, int count)
        {
            NodeContact[] closestContacts = new NodeContact[count];
            BinaryID[]    min             = new BinaryID[count];
            BinaryID      distance;
            int           ubound = count - 1;
            int           i;
            int           j;

            foreach (NodeContact contact in contacts)
            {
                distance = nodeID ^ contact.NodeID;

                for (i = 0; i < count; i++)
                {
                    if ((min[i] == null) || (distance < min[i]))
                    {
                        //demote existing values
                        for (j = ubound; j > i; j--)
                        {
                            min[j]             = min[j - 1];
                            closestContacts[j] = closestContacts[j - 1];
                        }

                        //place current on top
                        min[i]             = distance;
                        closestContacts[i] = contact;
                        break;
                    }
                }
            }

            return(closestContacts);
        }
        private void ReadFrom(BinaryReader bR)
        {
            switch (bR.ReadByte()) //version
            {
            case 1:
                _fileName     = Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte()));
                _contentType  = new System.Net.Mime.ContentType(Encoding.UTF8.GetString(bR.ReadBytes(bR.ReadByte())));
                _lastModified = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(bR.ReadUInt64());

                _fileSize  = bR.ReadInt64();
                _blockSize = bR.ReadInt32();

                _hashAlgo = Encoding.ASCII.GetString(bR.ReadBytes(bR.ReadByte()));
                _hash     = HashAlgorithm.Create(_hashAlgo);

                int totalBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((double)_fileSize / _blockSize)));

                _blockHash = new byte[totalBlocks][];

                int hashLength = bR.ReadByte();

                for (int i = 0; i < totalBlocks; i++)
                {
                    _blockHash[i] = bR.ReadBytes(hashLength);
                }

                _fileID = ComputeFileID();
                break;

            default:
                throw new BitChatException("FileMetaData format version not supported.");
            }
        }
Beispiel #26
0
 public FileBlockDataPart(BinaryID fileID, int blockNumber, int blockOffset, ushort length, byte[] blockDataPart)
 {
     _fileID        = fileID;
     _blockNumber   = blockNumber;
     _blockOffset   = blockOffset;
     _length        = length;
     _blockDataPart = blockDataPart;
 }
 public FileBlockDataPart(BinaryID fileID, int blockNumber, int blockOffset, ushort length, byte[] blockDataPart)
 {
     _fileID = fileID;
     _blockNumber = blockNumber;
     _blockOffset = blockOffset;
     _length = length;
     _blockDataPart = blockDataPart;
 }
        public static DhtRpcPacket CreateFindNodePacketQuery(NodeContact sourceNode, BinaryID networkID)
        {
            DhtRpcPacket packet = new DhtRpcPacket(GetRandomTransactionID(), sourceNode, RpcPacketType.Query, RpcQueryType.FIND_NODE);

            packet._networkID = networkID;

            return(packet);
        }
        private void Announce(BinaryID[] networkIDs, IPAddress[] remoteIPs, int times, bool isReply)
        {
            List <byte[]> packets = new List <byte[]>(networkIDs.Length);

            //CREATE ADVERTISEMENT
            foreach (BinaryID networkID in networkIDs)
            {
                byte[] challenge = BinaryID.GenerateRandomID256().ID;

                using (MemoryStream mS = new MemoryStream(BUFFER_MAX_SIZE))
                {
                    //version 1 byte
                    if (isReply)
                    {
                        mS.WriteByte(4);
                    }
                    else
                    {
                        mS.WriteByte(3);
                    }

                    mS.Write(BitConverter.GetBytes(_announcePort), 0, 2); //service port
                    mS.Write(challenge, 0, 32);                           //challenge

                    using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                    {
                        byte[] hmac = hmacSHA256.ComputeHash(challenge);
                        mS.Write(hmac, 0, 32);
                    }

                    packets.Add(mS.ToArray());
                }
            }

            //SEND ADVERTISEMENT
            for (int i = 0; i < times; i++)
            {
                foreach (byte[] packet in packets)
                {
                    if (remoteIPs == null)
                    {
                        _listener.Broadcast(packet, 0, packet.Length);
                    }
                    else
                    {
                        foreach (IPAddress remoteIP in remoteIPs)
                        {
                            _listener.SendTo(packet, 0, packet.Length, remoteIP);
                        }
                    }
                }

                if (i < times - 1)
                {
                    Thread.Sleep(ANNOUNCEMENT_RETRY_INTERVAL);
                }
            }
        }
        public NodeContact[] GetKClosestContacts(BinaryID networkID)
        {
            NodeContact[] contacts      = null;
            KBucket       closestBucket = FindClosestBucket(networkID);

            if (closestBucket._totalContacts >= DhtClient.KADEMLIA_K)
            {
                contacts = closestBucket.GetAllContacts(false);

                if (contacts.Length > DhtClient.KADEMLIA_K)
                {
                    return(GetClosestContacts(contacts, networkID, DhtClient.KADEMLIA_K));
                }
                else if (contacts.Length == DhtClient.KADEMLIA_K)
                {
                    return(contacts);
                }
                else if (closestBucket._parentBucket == null)
                {
                    return(contacts);
                }
                else
                {
                    contacts = null;
                }
            }

            while (closestBucket._parentBucket != null)
            {
                KBucket parentBucket = closestBucket._parentBucket;

                if (parentBucket._totalContacts >= DhtClient.KADEMLIA_K)
                {
                    contacts = parentBucket.GetAllContacts(false);

                    if (contacts.Length > DhtClient.KADEMLIA_K)
                    {
                        return(GetClosestContacts(contacts, networkID, DhtClient.KADEMLIA_K));
                    }
                    else if (contacts.Length == DhtClient.KADEMLIA_K)
                    {
                        return(contacts);
                    }
                }

                closestBucket = parentBucket;
            }

            if (contacts == null)
            {
                return(closestBucket.GetAllContacts(false));
            }
            else
            {
                return(contacts);
            }
        }
        public FileBlockRequest(Stream s)
        {
            BinaryReader bR = new BinaryReader(s);

            _fileID = new BinaryID(bR.ReadBytes(bR.ReadByte()));
            _blockNumber = bR.ReadInt32();
            _blockOffset = bR.ReadInt32();
            _length = bR.ReadUInt16();
        }
Beispiel #32
0
        public FileBlockRequest(Stream s)
        {
            BinaryReader bR = new BinaryReader(s);

            _fileID      = new BinaryID(bR.ReadBytes(bR.ReadByte()));
            _blockNumber = bR.ReadInt32();
            _blockOffset = bR.ReadInt32();
            _length      = bR.ReadUInt16();
        }
Beispiel #33
0
        public void SendBitChatNetworkInvitation(string message)
        {
            BinaryID hashedEmailAddress = BitChatNetwork.GetHashedEmailAddress(_connectionManager.Profile.LocalCertificateStore.Certificate.IssuedTo.EmailAddress);

            byte[] buffer = Encoding.UTF8.GetBytes(message);

            //send invitation signal with message
            WriteFrame(SignalType.BitChatNetworkInvitation, hashedEmailAddress, buffer, 0, buffer.Length);
        }
        private void Network_NetworkChanged(BitChatNetwork network, BinaryID newNetworkID)
        {
            lock (_chats)
            {
                BitChat chat = _chats[network.NetworkID];

                _chats.Add(newNetworkID, chat);
                _chats.Remove(network.NetworkID);
            }
        }
Beispiel #35
0
        public static BinaryID GetChannelName(BinaryID localPeerID, BinaryID remotePeerID, BinaryID networkID)
        {
            // this is done to avoid disclosing networkID to passive network sniffing
            // channelName = hmac( localPeerID XOR remotePeerID, networkID)

            using (HMACSHA1 hmacSHA1 = new HMACSHA1(networkID.ID))
            {
                return(new BinaryID(hmacSHA1.ComputeHash((localPeerID ^ remotePeerID).ID)));
            }
        }
 public static byte[] CreateFileUnparticipate(BinaryID fileID)
 {
     using (MemoryStream mS = new MemoryStream(fileID.ID.Length + 1))
     {
         mS.WriteByte((byte)BitChatMessageType.FileShareUnparticipate); //1 byte
         mS.Write(fileID.ID, 0, fileID.ID.Length);
         return mS.ToArray();
     }
 }
 private void _localDiscovery_PeerDiscovered(LocalPeerDiscovery sender, IPEndPoint peerEP, BinaryID networkID)
 {
     lock (_networks)
     {
         if (_networks.ContainsKey(networkID))
             _networks[networkID].MakeConnection(peerEP);
     }
 }
Beispiel #38
0
        private void WriteSignalFrame(BinaryID channelName, byte signal)
        {
            Debug.Write("Connection.WriteSignalFrame", _remotePeerEP.ToString() + "; channel:" + channelName.ToString() + "; signal:" + signal);

            lock (_baseStream)
            {
                //write frame signal
                _writeBufferData[0] = signal;

                //write channel name
                Buffer.BlockCopy(channelName.ID, 0, _writeBufferData, 1, 20);

                //output to base stream
                _baseStream.Write(_writeBufferData, 0, 21);
                _baseStream.Flush();
            }
        }
        public void StartTracking(BinaryID networkID)
        {
            lock (_trackedNetworkIDs)
            {
                int i = FindChatHashIndex(networkID);
                if (i < 0)
                    _trackedNetworkIDs.Add(networkID);

                ThreadPool.QueueUserWorkItem(AnnounceAsync, new object[] { networkID, null, ANNOUNCEMENT_COUNT, false });
            }
        }
            private void RecvDataAsync()
            {
                EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                byte[] bufferRecv = new byte[BUFFER_MAX_SIZE];
                MemoryStream dataRecv = new MemoryStream(bufferRecv);
                int bytesRecv;

                while (true)
                {
                    try
                    {
                        //receive message from remote
                        bytesRecv = _udpListener.ReceiveFrom(bufferRecv, ref remoteEP);

                        IPEndPoint peerEP = remoteEP as IPEndPoint;

                        bool isSelf = false;

                        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
                        {
                            if ((ni.OperationalStatus == OperationalStatus.Up) && (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet))
                            {
                                foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
                                {
                                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                    {
                                        if (peerEP.Address.Equals(ip.Address))
                                        {
                                            isSelf = true;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (isSelf)
                                break;
                        }

                        if (isSelf)
                            continue;

                        if (bytesRecv > 0)
                        {
                            #region parse data

                            dataRecv.Position = 0;
                            dataRecv.SetLength(bytesRecv);

                            int version = dataRecv.ReadByte();

                            switch (version) //version
                            {
                                case 3:
                                case 4:
                                    //read remote service port
                                    byte[] data = new byte[2];
                                    dataRecv.Read(data, 0, 2);
                                    ushort servicePort = BitConverter.ToUInt16(data, 0);
                                    IPEndPoint remoteServiceEP = new IPEndPoint(peerEP.Address, servicePort);

                                    //read challenge
                                    byte[] challenge = new byte[32];
                                    dataRecv.Read(challenge, 0, 32);

                                    //read hmac
                                    BinaryID recvHMAC = new BinaryID(new byte[32]);
                                    dataRecv.Read(recvHMAC.ID, 0, 32);

                                    ReceivedPeerInfo(remoteServiceEP, challenge, recvHMAC, (version == 4));
                                    break;

                                default:
                                    continue;
                            }

                            #endregion
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        break;
                    }
                    catch
                    { }
                }
            }
        private int FindChatHashIndex(BinaryID networkID)
        {
            for (int i = 0; i < _trackedNetworkIDs.Count; i++)
            {
                if (_trackedNetworkIDs[i].Equals(networkID))
                    return i;
            }

            return -1;
        }
        internal Connection AcceptConnectionInitiateProtocol(Stream networkStream, IPEndPoint remotePeerEP)
        {
            //read version
            int version = networkStream.ReadByte();

            switch (version)
            {
                case 1:
                    //read service port
                    byte[] remoteServicePort = new byte[2];
                    networkStream.Read(remoteServicePort, 0, 2);
                    remotePeerEP = new IPEndPoint(remotePeerEP.Address, BitConverter.ToUInt16(remoteServicePort, 0));

                    //read peer id
                    byte[] peerID = new byte[20];
                    networkStream.Read(peerID, 0, 20);
                    BinaryID remotePeerID = new BinaryID(peerID);

                    //add
                    Connection connection = AddConnection(networkStream, remotePeerID, remotePeerEP);
                    if (connection != null)
                    {
                        //send ok
                        networkStream.WriteByte(0);
                        networkStream.Write(_localPeerID.ID, 0, 20);
                    }
                    else
                    {
                        //send cancel
                        networkStream.WriteByte(1);
                        networkStream.Close();
                    }
                    return connection;

                default:
                    networkStream.Close();
                    throw new IOException("Cannot accept remote connection: protocol version not supported.");
            }
        }
        private int ReadSecureChannelFrame()
        {
            //read secure channel frame

            //read first block to read the encrypted packet size
            OffsetStream.StreamRead(_baseStream, _readEncryptedData, 0, _blockSizeBytes);
            _cryptoDecryptor.TransformBlock(_readEncryptedData, 0, _blockSizeBytes, _readBufferData, 0);
            _readBufferPosition = _blockSizeBytes;

            //read frame header 2 byte length
            int dataLength = BitConverter.ToUInt16(_readBufferData, 0);
            _readBufferLength = dataLength;

            dataLength -= _blockSizeBytes;

            if (_cryptoDecryptor.CanTransformMultipleBlocks)
            {
                if (dataLength > 0)
                {
                    int pendingBlocks = dataLength / _blockSizeBytes;

                    if (dataLength % _blockSizeBytes > 0)
                        pendingBlocks++;

                    int pendingBytes = pendingBlocks * _blockSizeBytes;

                    //read pending blocks
                    OffsetStream.StreamRead(_baseStream, _readEncryptedData, _readBufferPosition, pendingBytes);
                    _cryptoDecryptor.TransformBlock(_readEncryptedData, _readBufferPosition, pendingBytes, _readBufferData, _readBufferPosition);
                    _readBufferPosition += pendingBytes;
                }
            }
            else
            {
                while (dataLength > 0)
                {
                    //read next block
                    OffsetStream.StreamRead(_baseStream, _readEncryptedData, _readBufferPosition, _blockSizeBytes);
                    _cryptoDecryptor.TransformBlock(_readEncryptedData, _readBufferPosition, _blockSizeBytes, _readBufferData, _readBufferPosition);
                    _readBufferPosition += _blockSizeBytes;

                    dataLength -= _blockSizeBytes;
                }
            }

            //read auth hmac
            BinaryID authHMAC = new BinaryID(new byte[_authHMACSize]);
            OffsetStream.StreamRead(_baseStream, authHMAC.ID, 0, _authHMACSize);

            //verify auth hmac with computed hmac
            BinaryID computedAuthHMAC = new BinaryID(_authHMACDecrypt.ComputeHash(_readEncryptedData, 0, _readBufferPosition));

            if (!computedAuthHMAC.Equals(authHMAC))
                throw new SecureChannelException(SecureChannelCode.InvalidMessageHMACReceived, _remotePeerEP, _remotePeerCert);

            _readBufferPosition = 3;

            //return bytes available in this frame to read
            return _readBufferLength - _readBufferPosition;
        }
 public FileBlockWanted(BinaryID fileID, int blockNumber)
 {
     _fileID = fileID;
     _blockNumber = blockNumber;
 }
        private Connection AddConnection(Stream networkStream, BinaryID remotePeerID, IPEndPoint remotePeerEP)
        {
            lock (_connectionListByConnectionID)
            {
                //check for self
                if (_localPeerID.Equals(remotePeerID))
                {
                    _externalSelfEP = new IPEndPoint(remotePeerEP.Address, _externalSelfEP.Port);
                    return null;
                }

                string connectionID = remotePeerEP.ToString();

                //check for existing connection by connection id
                if (_connectionListByConnectionID.ContainsKey(connectionID))
                    return null;

                //check for existing connection by peer id
                if (_connectionListByPeerID.ContainsKey(remotePeerID))
                {
                    Connection existingConnection = _connectionListByPeerID[remotePeerID];

                    //compare existing and new peer ip end-point
                    if (AllowNewConnection(existingConnection.RemotePeerEP, remotePeerEP))
                    {
                        //remove existing connection and allow new connection
                        existingConnection.Dispose();
                    }
                    else
                    {
                        //keep existing connection
                        return null;
                    }
                }

                //add connection
                Connection connection = new Connection(networkStream, remotePeerID, remotePeerEP, this, _requestHandler);
                _connectionListByConnectionID.Add(connectionID, connection);
                _connectionListByPeerID.Add(remotePeerID, connection);

                //start service
                connection.Start();

                return connection;
            }
        }
        private Connection MakeConnectionInitiateProtocol(Stream networkStream, IPEndPoint remotePeerEP)
        {
            try
            {
                //send version
                networkStream.WriteByte(1);

                //send service port
                networkStream.Write(BitConverter.GetBytes(Convert.ToUInt16(_externalSelfEP.Port)), 0, 2);

                //send peer id
                networkStream.Write(_localPeerID.ID, 0, 20);

                //read response
                int response = networkStream.ReadByte();
                if (response == 0)
                {
                    byte[] buffer = new byte[20];
                    networkStream.Read(buffer, 0, 20);
                    BinaryID remotePeerID = new BinaryID(buffer);

                    Connection connection = AddConnection(networkStream, remotePeerID, remotePeerEP);
                    if (connection == null)
                    {
                        //check for existing connection again!
                        Connection existingConnection = GetExistingConnection(remotePeerEP);
                        if (existingConnection != null)
                        {
                            networkStream.Dispose();
                            return existingConnection;
                        }

                        throw new IOException("Cannot connect to remote peer: connection already exists.");
                    }

                    return connection;
                }
                else
                {
                    Thread.Sleep(500); //wait so that other thread gets time to add his connection in list so that this thread can pick same connection to proceed

                    //check for existing connection again!
                    Connection existingConnection = GetExistingConnection(remotePeerEP);
                    if (existingConnection != null)
                    {
                        networkStream.Dispose();
                        return existingConnection;
                    }

                    throw new IOException("Cannot connect to remote peer: request rejected.");
                }
            }
            catch
            {
                networkStream.Dispose();
                throw;
            }
        }
        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 void StopLocalAnnouncement(BinaryID networkID)
 {
     _localDiscovery.StopTracking(networkID);
 }
        public BitChatNetwork(string networkName, string sharedSecret, BinaryID networkID, Certificate[] knownPeerCerts, IBitChatNetworkManager networkManager, ISecureChannelSecurityManager securityManager)
        {
            _type = BitChatNetworkType.GroupChat;
            _networkName = networkName;
            _sharedSecret = sharedSecret;
            _networkManager = networkManager;
            _securityManager = securityManager;

            LoadPeers(knownPeerCerts);

            if (networkID == null)
            {
                //compute network id
                _networkID = new BinaryID(PBKDF2.CreateHMACSHA1(_sharedSecret, Encoding.UTF8.GetBytes(_networkName.ToLower()), 200000).GetBytes(20));
            }
            else
            {
                _networkID = networkID;
            }
        }
            public BitChat CreateBitChat(string networkName, string sharedSecret, BinaryID networkID, Certificate[] knownPeerCerts, BitChatProfile.SharedFileInfo[] sharedFileInfoList, Uri[] trackerURIs)
            {
                BitChatNetwork network = new BitChatNetwork(networkName, sharedSecret, networkID, knownPeerCerts, this, this);

                lock (_networks)
                {
                    _networks.Add(network.NetworkID, network);
                }

                if (trackerURIs == null)
                    trackerURIs = _profile.TrackerURIs;

                return new BitChat(this, _profile, network, sharedFileInfoList, trackerURIs);
            }
            public PeerInfo(IPEndPoint peerEP, BinaryID networkID)
            {
                _peerEP = peerEP;
                _networkID = networkID;

                _dateAdded = DateTime.UtcNow;
            }
 public void PauseLocalAnnouncement(BinaryID networkID)
 {
     _localDiscovery.PauseAnnouncement(networkID);
 }
        private void _listener_ReceivedPeerInfo(IPEndPoint peerEP, byte[] challenge, BinaryID recvHMAC, bool isReply)
        {
            if (PeerDiscovered != null)
            {
                BinaryID foundNetworkID = null;

                lock (_trackedNetworkIDs)
                {
                    foreach (BinaryID networkID in _trackedNetworkIDs)
                    {
                        using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                        {
                            BinaryID computedHmac = new BinaryID(hmacSHA256.ComputeHash(challenge));

                            if (computedHmac.Equals(recvHMAC))
                            {
                                foundNetworkID = networkID;
                                break;
                            }
                        }
                    }
                }

                if (foundNetworkID != null)
                {
                    PeerInfo peerInfo = new PeerInfo(peerEP, foundNetworkID);

                    bool peerInCache;

                    if (_peerInfoCache.Contains(peerInfo))
                    {
                        PeerInfo existingPeerInfo = _peerInfoCache[_peerInfoCache.IndexOf(peerInfo)];

                        if (existingPeerInfo.IsExpired())
                        {
                            peerInCache = false;
                            _peerInfoCache.Remove(existingPeerInfo);
                        }
                        else
                        {
                            peerInCache = true;
                        }
                    }
                    else
                    {
                        peerInCache = false;
                    }

                    if (!peerInCache)
                    {
                        _peerInfoCache.Add(peerInfo);

                        PeerDiscovered(this, peerEP, foundNetworkID);
                    }

                    if (!isReply)
                        ThreadPool.QueueUserWorkItem(AnnounceAsync, new object[] { foundNetworkID, new IPAddress[] { peerEP.Address }, 1, true });
                }
            }
        }
 public void ResumeLocalAnnouncement(BinaryID networkID)
 {
     _localDiscovery.ResumeAnnouncement(networkID);
 }
        private void Announce(BinaryID networkID, IPAddress[] remoteIPs, int times, bool isReply)
        {
            //CREATE ADVERTISEMENT
            byte[] challenge = BinaryID.GenerateRandomID256().ID;
            byte[] buffer = new byte[BUFFER_MAX_SIZE];

            using (MemoryStream mS = new MemoryStream(buffer))
            {
                //version 1 byte
                if (isReply)
                    mS.WriteByte(4);
                else
                    mS.WriteByte(3);

                mS.Write(BitConverter.GetBytes(_announcePort), 0, 2); //service port
                mS.Write(challenge, 0, 32); //challenge

                using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                {
                    byte[] hmac = hmacSHA256.ComputeHash(challenge);
                    mS.Write(hmac, 0, 32);
                }

                int length = Convert.ToInt32(mS.Position);

                //SEND ADVERTISEMENT
                for (int i = 0; i < times; i++)
                {
                    if (remoteIPs == null)
                    {
                        _listener.Broadcast(buffer, 0, length);
                    }
                    else
                    {
                        foreach (IPAddress remoteIP in remoteIPs)
                        {
                            _listener.SendTo(buffer, 0, length, remoteIP);
                        }
                    }

                    if (i < times - 1)
                        Thread.Sleep(ANNOUNCEMENT_INTERVAL);
                }
            }
        }
 public void StopLocalTracking(BinaryID networkID)
 {
     _localDiscovery.StopTracking(networkID);
 }
 public void StopTracking(BinaryID networkID)
 {
     lock (_trackedNetworkIDs)
     {
         int i = FindChatHashIndex(networkID);
         if (i > -1)
             _trackedNetworkIDs.RemoveAt(i);
     }
 }
            private void ChannelRequest(Connection connection, BinaryID channelName, ChannelType type, Stream channel)
            {
                try
                {
                    switch (type)
                    {
                        case ChannelType.BitChatNetwork:
                            BitChatNetwork network;

                            lock (_networks)
                            {
                                network = _networks[channelName];
                            }

                            SecureChannelStream secureChannel = new SecureChannelServerStream(channel, connection.RemotePeerEP, _profile.LocalCertificateStore, _trustedRootCertificates, this, _supportedCryptoOptions, _reNegotiateOnBytesSent, _reNegotiateAfterSeconds, network.SharedSecret);

                            network.JoinNetwork(secureChannel.RemotePeerCertificate.IssuedTo.EmailAddress.Address, secureChannel, _profile.CheckCertificateRevocationList);
                            break;
                    }
                }
                catch
                {
                    channel.Dispose();
                }
            }
Beispiel #59
0
 public ChannelStream(Connection connection, BinaryID channelName, ChannelType channelType)
 {
     _connection = connection;
     _channelName = channelName.Clone();
     _channelType = channelType;
 }
Beispiel #60
0
 public Connection(Stream baseStream, BinaryID remotePeerID, IPEndPoint remotePeerEP, ConnectionManager connectionManager, ChannelRequest requestHandler)
 {
     _baseStream = baseStream;
     _remotePeerID = remotePeerID;
     _remotePeerEP = remotePeerEP;
     _connectionManager = connectionManager;
     _requestHandler = requestHandler;
 }