opendj-core/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
@@ -546,6 +546,6 @@ if (!isRunning) { throw new IllegalStateException("Server is not running"); } return (InetSocketAddress) listener.getSocketAddresses().iterator().next(); return listener.firstSocketAddress(); } } opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferReader.java
@@ -150,6 +150,7 @@ ASN1BufferReader(final int maxElementSize, final Buffer buffer) { this.readLimiter = new RootSequenceLimiter(); this.buffer = buffer; this.buffer.allowBufferDispose(false); this.maxElementSize = maxElementSize; } opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/ASN1BufferWriter.java
@@ -139,19 +139,19 @@ /** Default maximum size for cached protocol/entry encoding buffers. */ private static final int DEFAULT_MAX_INTERNAL_BUFFER_SIZE = 32 * 1024; private final MemoryManager<Buffer> memoryManager; private MemoryManager<Buffer> memoryManager; private SequenceBuffer sequenceBuffer; private Buffer outBuffer; private final RootSequenceBuffer rootBuffer; /** Creates a new ASN.1 writer that writes to a StreamWriter. */ ASN1BufferWriter(MemoryManager memoryManager) { ASN1BufferWriter() { this.rootBuffer = new RootSequenceBuffer(); this.memoryManager = memoryManager; } /** Reset the writer. */ void reset() { void reset(final MemoryManager memoryManager) { this.memoryManager = memoryManager; sequenceBuffer = rootBuffer; outBuffer = memoryManager.allocate(BUFFER_INIT_SIZE); } @@ -189,6 +189,7 @@ /** Recycle the writer to allow re-use. */ @Override public void recycle() { memoryManager = null; sequenceBuffer = null; outBuffer = null; } opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/GrizzlyUtils.java
@@ -165,9 +165,9 @@ ? ThreadCache.takeFromCache(WRITER_INDEX) : ThreadCache.takeFromCache(WRITER_INDEX_V2); if (writer == null) { writer = LDAP.getWriter(new ASN1BufferWriter(memoryManager), protocolVersion); writer = LDAP.getWriter(new ASN1BufferWriter(), protocolVersion); } writer.getASN1Writer().reset(); writer.getASN1Writer().reset(memoryManager); return writer; } opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LDAPClientFilter.java
@@ -422,16 +422,26 @@ final Buffer buffer = (Buffer) ctx.getMessage(); try (final ASN1BufferReader reader = new ASN1BufferReader(maxASN1ElementSize, buffer)) { final LDAPReader<? extends ASN1Reader> ldapReader = LDAP.getReader(reader, decodeOptions); while (ldapReader.hasMessageAvailable()) { ldapReader.readMessage(handler); buffer.mark(); if (!reader.elementAvailable()) { buffer.reset(); return ctx.getStopAction(buffer); } buffer.shrink(); final int length = reader.peekLength(); final Buffer remainder = buffer.remaining() > length ? buffer.split(buffer.position() + length) : null; buffer.reset(); try (final ASN1BufferReader packetReader = new ASN1BufferReader(maxASN1ElementSize, buffer)) { final LDAPReader<? extends ASN1Reader> ldapReader = LDAP.getReader(packetReader, decodeOptions); ctx.setMessage(null); ldapReader.readMessage(handler); } finally { buffer.tryDispose(); } return ctx.getInvokeAction(remainder); } catch (IOException e) { handleReadException(ctx, e); throw e; } return ctx.getStopAction(buffer.hasRemaining() ? buffer : null); } private final void handleReadException(FilterChainContext ctx, IOException e) { opendj-grizzly/src/main/java/org/forgerock/opendj/grizzly/LdapCodec.java
@@ -36,7 +36,6 @@ import org.forgerock.opendj.ldap.spi.LdapMessages.LdapRequestEnvelope; import org.forgerock.opendj.ldap.spi.LdapMessages.LdapResponseMessage; import org.glassfish.grizzly.Buffer; import org.glassfish.grizzly.attributes.AttributeStorage; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; @@ -57,14 +56,26 @@ public NextAction handleRead(final FilterChainContext ctx) throws IOException { try { final Buffer buffer = ctx.getMessage(); final LdapRequestEnvelope message; message = readMessage(buffer, ctx.getConnection()); if (message != null) { ctx.setMessage(message); return ctx.getInvokeAction(getRemainingBuffer(buffer)); try (final ASN1BufferReader reader = new ASN1BufferReader(maxASN1ElementSize, buffer)) { buffer.mark(); if (!reader.elementAvailable()) { buffer.reset(); return ctx.getStopAction(buffer); } final int length = reader.peekLength(); if (length > maxASN1ElementSize) { buffer.reset(); throw DecodeException.fatalError( ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED.get(length, maxASN1ElementSize)); } final Buffer remainder = (buffer.remaining() > length) ? buffer.split(buffer.position() + length) : null; buffer.reset(); ctx.setMessage(decodePacket(new ASN1BufferReader(maxASN1ElementSize, buffer))); buffer.tryDispose(); return ctx.getInvokeAction(remainder); } return ctx.getStopAction(getRemainingBuffer(buffer)); } catch (Exception e) { onLdapCodecError(ctx, e); ctx.getConnection().closeSilently(); @@ -76,29 +87,7 @@ protected abstract void onLdapCodecError(FilterChainContext ctx, Throwable error); private LdapRequestEnvelope readMessage(final Buffer buffer, final AttributeStorage attributeStorage) throws IOException { try (final ASN1BufferReader reader = new ASN1BufferReader(maxASN1ElementSize, buffer)) { final int packetStart = buffer.position(); if (!reader.elementAvailable()) { buffer.position(packetStart); return null; } final int length = reader.peekLength(); if (length > maxASN1ElementSize) { buffer.position(packetStart); throw DecodeException.fatalError( ERR_LDAP_CLIENT_DECODE_MAX_REQUEST_SIZE_EXCEEDED.get(length, maxASN1ElementSize)); } final Buffer packet = buffer.slice(packetStart, buffer.position() + length); buffer.position(buffer.position() + length); return decodePacket(new ASN1BufferReader(maxASN1ElementSize, packet), attributeStorage); } } private LdapRequestEnvelope decodePacket(final ASN1BufferReader reader, final AttributeStorage attributeStorage) private LdapRequestEnvelope decodePacket(final ASN1BufferReader reader) throws IOException { reader.mark(); try { @@ -138,10 +127,6 @@ } } private Buffer getRemainingBuffer(final Buffer buffer) { return buffer.hasRemaining() ? buffer : null; } @Override public NextAction handleWrite(final FilterChainContext ctx) throws IOException { final LdapResponseMessage response = ctx.<LdapResponseMessage>getMessage(); opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ASN1BufferWriterTestCase.java
@@ -35,7 +35,7 @@ @Test public class ASN1BufferWriterTestCase extends ASN1WriterTestCase { private final ASN1BufferWriter writer = new ASN1BufferWriter(MemoryManager.DEFAULT_MEMORY_MANAGER); private final ASN1BufferWriter writer = new ASN1BufferWriter(); @Override protected byte[] getEncodedBytes() throws IOException, DecodeException { @@ -53,7 +53,7 @@ @Override protected ASN1Writer getWriter() throws IOException { writer.flush(); writer.reset(); writer.reset(MemoryManager.DEFAULT_MEMORY_MANAGER); return writer; } }