Skip to content

Commit

Permalink
Motivation
Browse files Browse the repository at this point in the history
[netty#4958]: OpenSslContext retains native resources that get released by the
Garbage Collector via object finalization. This works fine for traditonal SSL
deployments with static working sets of SslContext(s). We intend to load large
sets of [Open]SslContext(s) on a per connection basis.

Having OpenSslContext implement the ReferenceCounted interface would
facilitate efficient sharing and timely relase of all native resources once all
client disconnected that used the same context.

Modifications

Let OpenSslContext implement the ReferenceCounted and delegate all calls
to an inner AbstractReferenceCounted field that calls OpenSslContext's destroy()
method once the reference count reaches 0.

Result

It's possible to release OpenSslContext's native resources as soon as it's
no longer in use.
  • Loading branch information
Roger Kapsi committed Mar 11, 2016
1 parent 6536c7c commit 04ded69
Showing 1 changed file with 64 additions and 1 deletion.
65 changes: 64 additions & 1 deletion handler/src/main/java/io/netty/handler/ssl/OpenSslContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.base64.Base64;
import io.netty.util.AbstractReferenceCounted;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCounted;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
Expand Down Expand Up @@ -51,7 +53,7 @@
import static io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import static io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;

public abstract class OpenSslContext extends SslContext {
public abstract class OpenSslContext extends SslContext implements ReferenceCounted {
private static final byte[] BEGIN_CERT = "-----BEGIN CERTIFICATE-----\n".getBytes(CharsetUtil.US_ASCII);
private static final byte[] END_CERT = "\n-----END CERTIFICATE-----\n".getBytes(CharsetUtil.US_ASCII);
private static final byte[] BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n".getBytes(CharsetUtil.US_ASCII);
Expand All @@ -73,6 +75,28 @@ public abstract class OpenSslContext extends SslContext {
// TODO: Maybe make configurable ?
protected static final int VERIFY_DEPTH = 10;

/**
* [4958]: This reference counter provides an optimization that allows the
* user to efficiently share a context and also eagerly release its native
* resources once it's no longer in use instead of relaying on the Garbage
* Collector and object finalization.
*/
private final ReferenceCounted refCnt = new AbstractReferenceCounted() {
@SuppressWarnings("unused")
private Object hint;

@Override
public ReferenceCounted touch(Object hint) {
this.hint = hint;
return this;
}

@Override
protected void deallocate() {
destroy();
}
};

/** The OpenSSL SSL_CTX object */
protected volatile long ctx;
long aprPool;
Expand Down Expand Up @@ -387,6 +411,45 @@ protected final void destroy() {
}
}

@Override
public int refCnt() {
return refCnt.refCnt();
}

@Override
public OpenSslContext retain() {
refCnt.retain();
return this;
}

@Override
public OpenSslContext retain(int increment) {
refCnt.retain(increment);
return this;
}

@Override
public OpenSslContext touch() {
refCnt.touch();
return this;
}

@Override
public OpenSslContext touch(Object hint) {
refCnt.touch(hint);
return this;
}

@Override
public boolean release() {
return refCnt.release();
}

@Override
public boolean release(int decrement) {
return refCnt.release(decrement);
}

protected static X509Certificate[] certificates(byte[][] chain) {
X509Certificate[] peerCerts = new X509Certificate[chain.length];
for (int i = 0; i < peerCerts.length; i++) {
Expand Down

0 comments on commit 04ded69

Please sign in to comment.