private async Task WriteAsync(Socket socket, PipeReader reader, Func <LdapRequestMessage, LdapRequestMessage> packetCallback, Action <LdapException> errorCallback, CancellationToken cancellationToken) { try { while (socket.Connected) { var result = await reader.ReadAsync(cancellationToken); var buffer = result.Buffer; bool success; do { success = false; if (TryReadTagAndLength(buffer, out var tagLength)) { if (buffer.Length >= tagLength) { var ldap = ReadLdapMessage(buffer.Slice(0, tagLength)); ldap = packetCallback(ldap); await WriteLdapMessage(socket, ldap, cancellationToken).ConfigureAwait(false); buffer = buffer.Slice(tagLength); success = true; } else if (tagLength > MaxMessageSize) { //maybe increase pipe size https://github.com/dotnet/corefx/issues/30689 throw new LdapException(ResultCode.UnwillingToPerform, "MaxMessageSize exceeded"); } } } while (success && buffer.Length > 2); if (result.IsCompleted) { break; } reader.AdvanceTo(buffer.Start, buffer.End); } reader.Complete(); } catch (LdapException ex) { errorCallback(ex); socket.Close(); reader.Complete(ex); } catch (SocketException ex) { socket.Close(); reader.Complete(ex); } catch (OperationCanceledException ex) { socket.Close(); reader.Complete(ex); } catch (ObjectDisposedException ex) { if (ex.ObjectName != socket.GetType().FullName) { socket.Close(); } if (ex.ObjectName != reader.GetType().FullName) { reader.Complete(ex); } } }