private int TryFillAndReadInternalBuffer(BytesSegment bs) { var readBufferSize = this.ReadaheadBufferSize; if (EnableReadaheadBuffer && (socketAvailable > bs.Len & bs.Len < readBufferSize)) { if (readaheadScore > 0) { readaheadScore--; } if (readaheadBuffer.Bytes == null) { if (readaheadScore > 0) { return(0); } readaheadBuffer.Bytes = new byte[readBufferSize]; } else if (readaheadBuffer.Bytes.Length < readBufferSize) { readaheadBuffer.Bytes = new byte[readBufferSize]; } Interlocked.Increment(ref ctr.Rsync); readaheadBuffer.Offset = 0; readaheadBuffer.Len = readBufferSize; var read = ReadSocketDirectSync(readaheadBuffer); readaheadBuffer.Len = read; if (read <= 0) { throw new Exception($"{this} should not happen: Socket.Receive() returns {read} when Socket.Available > 0."); } read = Math.Min(read, bs.Len); readaheadBuffer.CopyTo(bs, read); readaheadBuffer.SubSelf(read); return(read); } else { if (readaheadScore < readaheadScoreMax) { if (++readaheadScore == readaheadScoreMax) { // There are many large reading opearations, so the internal buffer can be released now. readaheadBuffer.Bytes = null; } } return(0); } }
public async Task <int> ReadAsync(BytesSegment bs) { lock (_syncRoot) { if (tcsNewBuffer?.IsCompleted == false) { throw new Exception("another recv task is running."); } if (buffer.Len == 0 & !recvEOF) { tcsNewBuffer.Reset(); } } if (tcsNewBuffer != null) { await tcsNewBuffer; } lock (_syncRoot) { if (recvEOF && buffer.Len == 0) { return(0); } int read = Math.Min(bs.Len, buffer.Len); buffer.CopyTo(bs, 0, read); buffer.SubSelf(read); if (buffer.Len == 0) { buffer = new BytesSegment(); tcsBufferEmptied.SetResult(0); } return(read); } }
private void Dequeue(BytesSegment bs, int len) { Queue.CopyTo(bs, len); Queue.SubSelf(len); if (Queue.Len == 0) { Queue.ResetSelf(); } }
public void ServerData(object sender, BytesSegment bs) { if (serverDone || bs.Len == 0) { return; } serverDone = true; if (sBuf != null) { bs.CopyTo(sBuf, 0, bs.Len, sProg); sProg += bs.Len; if (sProg < sBuf.Length) { goto CONTINUE_READ; } else { bs = new BytesSegment(sBuf, 0, sProg); } } if (Tls.Version != 0) { var hello = new TlsStream.ServerHello(); try { TlsStream.ParseServerHelloRecord(bs, ref hello, out var size); if (size > bs.Len) { if (sBuf != null) { throw new Exception("sBuf != null"); } sBuf = new byte[size]; bs.CopyTo(sBuf); sProg = bs.Len; goto CONTINUE_READ; } } catch (Exception e) { if (hello.Version != 0) { TlsError = true; Logging.exception(e, Logging.Level.Warning, "parsing tls server hello from " + sender); } } Tls.Version = Math.Min(Tls.Version, hello.Version); Tls.Alpn = hello.Alpn; } sBuf = null; return; CONTINUE_READ: serverDone = false; return; }
public async Task <ClientHello> ReadClientHello() { var recordHeader = new BytesSegment(new byte[5]); await RealBaseStream.ReadFullAsyncR(recordHeader); MyStreamWrapper.Queue = recordHeader; ushort ver = 0; int recordPayloadLength = GetRecordPayloadLength(recordHeader, ref ver); var record = new BytesSegment(new byte[5 + recordPayloadLength]); recordHeader.CopyTo(record); var msg = record.Sub(5); await RealBaseStream.ReadFullAsyncR(msg); MyStreamWrapper.Queue = record; var ch = new ClientHello(); ParseClientHello(msg, ref ch); return(ch); }