SlurpBlock() 공개 메소드

Update the value for the running CRC32 using the given block of bytes. This is useful when using the CRC32() class in a Stream.
public SlurpBlock ( byte block, int offset, int count ) : void
block byte block of bytes to slurp
offset int starting point in the block
count int how many bytes within the block to slurp
리턴 void
예제 #1
0
        /// <summary>
        /// Read from the stream
        /// </summary>
        /// <param name="buffer">the buffer to read</param>
        /// <param name="offset">the offset at which to start</param>
        /// <param name="count">the number of bytes to read</param>
        /// <returns>the number of bytes actually read</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesToRead = count;

            // Need to limit the # of bytes returned, if the stream is intended to have
            // a definite length.  This is especially useful when returning a stream for
            // the uncompressed data directly to the application.  The app won't
            // necessarily read only the UncompressedSize number of bytes.  For example
            // wrapping the stream returned from OpenReader() into a StreadReader() and
            // calling ReadToEnd() on it, We can "over-read" the zip data and get a
            // corrupt string.  The length limits that, prevents that problem.

            if (_lengthLimit != UnsetLengthLimit)
            {
                if (_Crc32.TotalBytesRead >= _lengthLimit)
                {
                    return(0);                                       // EOF
                }
                var bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead;
                if (bytesRemaining < count)
                {
                    bytesToRead = (int)bytesRemaining;
                }
            }
            int n = _innerStream.Read(buffer, offset, bytesToRead);

            if (n > 0)
            {
                _Crc32.SlurpBlock(buffer, offset, n);
            }
            return(n);
        }
예제 #2
0
		public byte[] Encode()
		{
			using (var memoryStream = new MemoryStream())
			{
				using (var binaryWriter = new BinaryWriter(memoryStream))
				{
					// https://core.telegram.org/mtproto#tcp-transport
					/*
                        4 length bytes are added at the front 
                        (to include the length, the sequence number, and CRC32; always divisible by 4)
                        and 4 bytes with the packet sequence number within this TCP connection 
                        (the first packet sent is numbered 0, the next one 1, etc.),
                        and 4 CRC32 bytes at the end (length, sequence number, and payload together).
                    */
					binaryWriter.Write(Body.Length + 12);
					binaryWriter.Write(SequneceNumber);
					binaryWriter.Write(Body);
					var crc32 = new CRC32();
					crc32.SlurpBlock(memoryStream.GetBuffer(), 0, 8 + Body.Length);
					binaryWriter.Write(crc32.Crc32Result);

					var transportPacket = memoryStream.ToArray();

					//					Debug.WriteLine("Tcp packet #{0}\n{1}", SequneceNumber, BitConverter.ToString(transportPacket));

					return transportPacket;
				}
			}
		}
예제 #3
0
        public static TcpMessage Decode(byte[] body)
        {
            if (body == null)
                throw new ArgumentNullException(nameof(body));

            if (body.Length < 12)
                throw new InvalidOperationException("Ops, wrong size of input packet");

            using (var memoryStream = new MemoryStream(body))
            {
                using (var binaryReader = new BinaryReader(memoryStream))
                {
                    var packetLength = binaryReader.ReadInt32();

                    if (packetLength < 12)
                        throw new InvalidOperationException(string.Format("invalid packet length: {0}", packetLength));

                    var seq = binaryReader.ReadInt32();
                    byte[] packet = binaryReader.ReadBytes(packetLength - 12);
                    var checksum = (int)binaryReader.ReadInt32();

                    var crc32 = new CRC32();
                    crc32.SlurpBlock(body, 0, packetLength - 4);
                    var validChecksum = crc32.Crc32Result;

                    if (checksum != validChecksum)
                    {
                        throw new InvalidOperationException("invalid checksum! skip");
                    }

                    return new TcpMessage(seq, packet);
                }
            }
        }
예제 #4
0
        private static async Task <TcpMessage> Receieve(TcpClient tcpClient)
        {
            var stream = tcpClient.GetStream();

            var packetLengthBytes = new byte[4];

            if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the packet length");
            }
            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            var seqBytes = new byte[4];

            if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the sequence");
            }
            int seq = BitConverter.ToInt32(seqBytes, 0);

            int readBytes    = 0;
            var body         = new byte[packetLength - 12];
            int neededToRead = packetLength - 12;

            do
            {
                var bodyByte       = new byte[packetLength - 12];
                var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);

                neededToRead -= availableBytes;
                Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                readBytes += availableBytes;
            }while (readBytes != packetLength - 12);

            var crcBytes = new byte[4];

            if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the crc");
            }
            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, body));
        }
예제 #5
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesToRead = count;

            if (_lengthLimit != UnsetLengthLimit)
            {
                if (_Crc32.TotalBytesRead >= _lengthLimit)
                {
                    return(0);
                }
                long bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead;
                if (bytesRemaining < count)
                {
                    bytesToRead = (int)bytesRemaining;
                }
            }
            int i = _innerStream.Read(buffer, offset, bytesToRead);

            if (i > 0)
            {
                _Crc32.SlurpBlock(buffer, offset, i);
            }
            return(i);
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            int count2 = count;

            if (_lengthLimit != UnsetLengthLimit)
            {
                if (_crc32.TotalBytesRead >= _lengthLimit)
                {
                    return(0);
                }
                long num = _lengthLimit - _crc32.TotalBytesRead;
                if (num < count)
                {
                    count2 = (int)num;
                }
            }
            int num2 = _innerStream.Read(buffer, offset, count2);

            if (num2 > 0)
            {
                _crc32.SlurpBlock(buffer, offset, num2);
            }
            return(num2);
        }
예제 #7
0
 public int Crc32(int currentReadPositionOffset, int length) {
     //Crc32 crc32 = new Crc32();
     //logger.info("calc crc32 offset {0}, length {1} on: {2}", currentReadPositionOffset, length, BitConverter.ToString(buffer, readIndex + currentReadPositionOffset, length));
     //return crc32.ComputeHash(buffer, readIndex + currentReadPositionOffset, length).Reverse().ToArray();
     CRC32 crc32 = new CRC32();
     crc32.SlurpBlock(buffer, readIndex+currentReadPositionOffset, length);
     return crc32.Crc32Result;
 }
예제 #8
0
        public async Task Send(byte[] packet) {
            AsyncSocket socketToSend;
            logger.debug("transport send...");
            lock (this) {
                if (socket == null) {
                    logger.debug("socket == null");
                    throw new MTProtoTransportException("not connected");
                }
                logger.debug("socket != null");
                socketToSend = socket;
            }

            try {
                using (MemoryStream memoryStream = new MemoryStream()) {
                    using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) {
                        CRC32 crc32 = new CRC32();
                        binaryWriter.Write(packet.Length + 12);
                        binaryWriter.Write(Interlocked.Increment(ref sendCounter) - 1);
                        binaryWriter.Write(packet);
                        crc32.SlurpBlock(memoryStream.GetBuffer(), 0, 8 + packet.Length);
                        binaryWriter.Write(crc32.Crc32Result);

                        logger.debug("sending to socket: {0}", BitConverter.ToString(memoryStream.GetBuffer(), 0, (int) memoryStream.Position).Replace("-","").ToLower());
                        await socketToSend.Send(memoryStream.GetBuffer(), 0, (int) memoryStream.Position);
                    }
                }
            } catch (Exception e) {
                throw new MTProtoTransportException("unable to send packet", e);
            }
        }
예제 #9
0
        public bool TransportSend(byte[] packet) {
            //logger.debug("network send packet");
            lock (this) {
                if (state != NetworkGatewayState.ESTABLISHED) {
                    logger.warning("send error, state not established");
                    return false;
                }

                using (MemoryStream memoryStream = new MemoryStream()) {
                    using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) {
                        //Crc32 crc32 = new Crc32();
                        CRC32 crc32 = new CRC32();
                        binaryWriter.Write(packet.Length + 12);
                        binaryWriter.Write(sendCounter);
                        binaryWriter.Write(packet);
                        crc32.SlurpBlock(memoryStream.GetBuffer(), 0, 8+packet.Length);
                        binaryWriter.Write(crc32.Crc32Result);

                        byte[] transportPacket = memoryStream.ToArray();

                        //logger.info("send transport packet: {0}", BitConverter.ToString(transportPacket).Replace("-",""));

                        var args = new SocketAsyncEventArgs();
                        args.SetBuffer(transportPacket, 0, transportPacket.Length);

                        try {
                            socket.SendAsync(args);
                        }
                        catch (Exception e) {
                            logger.warning("transport packet send error: {0}", e);
                            /*
                        if(state != NetworkGatewayState.DISPOSED) {
                            state = NetworkGatewayState.INIT;
                            Connect(host, port);
                        }*/
                            TryReconnect();
                            return false;
                        }

                        sendCounter++;
                        return true;
                    }
                }
            }
        }