public AwaitableWrapper <Msg> RecvMsgR(BytesView buf) { if (_RecvMsgR_ra == null) { _RecvMsgR_ra = new ReusableAwaiter <Msg>(); _RecvMsgR_cont = () => { if (!_RecvMsgR_awaiter.TryGetResult(out var r, out var ex)) { _RecvMsgR_ra.SetException(ex); } else { _RecvMsgR_ra.SetResult(new Msg(r.bv)); } }; } _RecvMsgR_ra.Reset(); var awaiter = _RecvMsgR_awaiter = _readAsyncR(new BytesSegment(buf?.bytes, buf?.offset ?? 0, buf?.len ?? 0)); if (awaiter.IsCompleted) { _RecvMsgR_cont(); } else { awaiter.OnCompleted(_RecvMsgR_cont); } return(new AwaitableWrapper <Msg>(_RecvMsgR_ra)); }
public void Reset() { this.bytes = null; this.offset = 0; this.len = 0; this.nextNode = null; }
public static AwaitableWrapper <Msg> RecvMsgR(this IMsgStream ms, BytesView bv) { if (ms is IMsgStreamReadR r) { return(r.RecvMsgR(bv)); } return(new AwaitableWrapper <Msg>(ms.RecvMsg(bv))); }
public void OnWrite(BytesView bv) { if (WriteFilters?.Count > 0) { lock (WriteFilters) foreach (var item in WriteFilters) { item(bv); } } }
public static Action <BytesView> GetAesFilter(bool isEncrypt, byte[] iv, byte[] key) { int keySize = key.Length * 8, blockSize = iv.Length * 8; int blockBytesSize = blockSize / 8; byte[] buf = new byte[blockSize / 8]; BytesView bvBuf = new BytesView(buf); var aesalg = Aes.Create(); aesalg.Padding = PaddingMode.PKCS7; aesalg.KeySize = keySize; aesalg.BlockSize = blockSize; aesalg.IV = iv; aesalg.Key = key; return((bv) => { if (bv.len == 0) { return; } var pos = 0; if (isEncrypt) { using (var ms = new MemoryStream(bv.bytes, bv.offset, bv.len)) using (var cryStream = new CryptoStream(ms, aesalg.CreateEncryptor(), CryptoStreamMode.Read)) { int read; int oldbytesSize = bv.len - (bv.len % blockBytesSize); bv.len = oldbytesSize; bv.nextNode = bvBuf; while ((read = cryStream.Read(bv.bytes, bv.offset + pos, oldbytesSize - pos)) > 0) { pos += read; } while ((read = cryStream.Read(buf, pos - oldbytesSize, buf.Length - (pos - oldbytesSize))) > 0) { pos += read; } } } else { using (var cryStream = new CryptoStream(new MemoryStream(bv.bytes, bv.offset, bv.len), aesalg.CreateDecryptor(), CryptoStreamMode.Read)) { int read; while ((read = cryStream.Read(buf, 0, blockBytesSize)) > 0) { for (int i = 0; i < read; i++) { bv.bytes[bv.offset + pos++] = buf[i]; } } bv.len = pos; } } }); }
public void OnRead(BytesView bv) { if (ReadFilters?.Count > 0) { lock (ReadFilters) for (int i = ReadFilters.Count - 1; i >= 0; i--) { Action <BytesView> item = ReadFilters[i]; item(bv); } } }
public void TryRecycle() { if (Data == null) { return; } if (Data.nextNode != null) { Logging.logWithStackTrace("lastMsg.nextNode != null", Logging.Level.Warning); } BufferPool.GlobalPut(Data.bytes); Data = null; }
public void Set(BytesView bv) { this.bytes = bv.bytes; this.offset = bv.offset; this.len = bv.len; }
public static Action <BytesView> GetAesStreamFilter(bool isEncrypt, byte[] key) // is actually AES OFB { uint keySize = (uint)key.Length * 8, blockSize = 128; uint blockBytesSize = blockSize / 8; uint encryptedZerosSize = blockBytesSize; byte[] buf = new byte[blockSize / 8]; BytesView bvBuf = new BytesView(buf); var aesalg = new AesCryptoServiceProvider(); aesalg.Mode = CipherMode.CBC; // to generate OFB keystream, use CBC with all zeros byte array as input. aesalg.KeySize = (int)keySize; aesalg.BlockSize = (int)blockSize; aesalg.Key = key; ICryptoTransform enc = null; byte[] keystreamBuffer = null; uint keystreamBufferPos = 0; return(bv => { if (enc == null) { if (isEncrypt) { bv.nextNode = bv.Clone(); bv.Set(aesalg.IV); bv = bv.nextNode; } else { aesalg.IV = bv.GetBytes(0, (int)blockBytesSize); for (uint i = 0; i < bv.len - blockBytesSize; i++) { bv[i] = bv[i + blockBytesSize]; } bv.len -= (int)blockBytesSize; } enc = aesalg.CreateEncryptor(); if (enc.CanTransformMultipleBlocks) { encryptedZerosSize *= blocksPerPass; } keystreamBuffer = new byte[encryptedZerosSize]; keystreamBufferPos = encryptedZerosSize; } unsafe { fixed(byte *ksBuf = keystreamBuffer) do { var pos = (uint)bv.offset; var end = pos + (uint)bv.len; if (bv.bytes == null) { throw new ArgumentNullException("bv.bytes"); } if (bv.bytes.Length < end) throw new ArgumentException("bv.bytes.Length < offset + len"); fixed(byte *bytes = bv.bytes) while (pos < end) { var remainningTmp = (uint)encryptedZerosSize - keystreamBufferPos; if (remainningTmp == 0) { remainningTmp = encryptedZerosSize; keystreamBufferPos = 0; enc.TransformBlock(zeroesBytes, 0, (int)encryptedZerosSize, keystreamBuffer, 0); } var tmpEnd = pos + remainningTmp; var thisEnd = end < tmpEnd ? end : tmpEnd; var thisCount = thisEnd - pos; NaiveUtils.XorBytesUnsafe(ksBuf + keystreamBufferPos, bytes + pos, (uint)thisCount); keystreamBufferPos += thisCount; pos += thisCount; } bv = bv.nextNode; }while (bv != null); } }); }
public static Action <BytesView> GetAesFilter2(bool isEncrypting, byte[] key) { int keySize = key.Length * 8, blockSize = 128; int blockBytesSize = blockSize / 8; byte[] buf = new byte[blockSize / 8]; BytesView bvBuf = new BytesView(buf); var aesalg = new AesCryptoServiceProvider(); aesalg.Padding = PaddingMode.PKCS7; //aesalg.Mode = CipherMode.CBC; aesalg.KeySize = keySize; aesalg.BlockSize = blockSize; aesalg.Key = key; bool firstPacket = true; if (isEncrypting) { return((bv) => { if (firstPacket) { firstPacket = false; aesalg.GenerateIV(); var tmp = bv.Clone(); bv.Set(aesalg.IV); bv.nextNode = tmp; bv = tmp; } if (bv.len == 0) { return; } var pos = 0; using (var ms = new MemoryStream(bv.bytes, bv.offset, bv.len)) using (var cryStream = new CryptoStream(ms, aesalg.CreateEncryptor(), CryptoStreamMode.Read)) { int read; int oldbytesSize = bv.len - (bv.len % blockBytesSize); bv.len = oldbytesSize; bv.nextNode = bvBuf; while ((read = cryStream.Read(bv.bytes, bv.offset + pos, oldbytesSize - pos)) > 0) { pos += read; } while ((read = cryStream.Read(buf, pos - oldbytesSize, buf.Length - (pos - oldbytesSize))) > 0) { pos += read; } aesalg.IV = buf; } }); } else { return((bv) => { if (firstPacket) { firstPacket = false; aesalg.IV = bv.GetBytes(0, blockBytesSize); //bv.offset += blockBytesSize; for (int i = 0; i < bv.len - blockBytesSize; i++) { bv[i] = bv[i + blockBytesSize]; } bv.len -= blockBytesSize; } if (bv.len == 0) { return; } var pos = 0; using (var cryStream = new CryptoStream(new MemoryStream(bv.bytes, bv.offset, bv.len), aesalg.CreateDecryptor(), CryptoStreamMode.Read)) { int read; int lastBlockPos = bv.len - blockBytesSize; for (int i = 0; i < blockBytesSize; i++) { buf[i] = bv[lastBlockPos + i]; } aesalg.IV = buf; while ((read = cryStream.Read(bv.bytes, bv.offset + pos, bv.len - pos)) > 0) { pos += read; } bv.len = pos; } }); } }
public async Task <Msg> RecvMsg(BytesView buf) { var frame = await _readAsyncR(new BytesSegment(buf?.bytes, buf?.offset ?? 0, buf?.len ?? 0)); return(new Msg(frame.bv)); }
public Msg(BytesView data) { this.Data = data; }
public BytesSegment(BytesView bv) { this.Bytes = bv.bytes; this.Offset = bv.offset; this.Len = bv.len; }