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 |
return | void |
/// <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); }
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; } } }
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); } } }
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)); }
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); }
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; }
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); } }
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; } } } }