Skip to content

Commit

Permalink
Consume tcnative options update
Browse files Browse the repository at this point in the history
Motivation:
tcnative has updated how constants are defined and removed some constants which are either obsolete or now set directly in tcnative.

Modifications:
- update to compile against tcnative changes.

Result:
Netty compiles with tcnative options changes.
  • Loading branch information
Scottmitch committed Feb 14, 2017
1 parent 591293b commit cd3bf3d
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 107 deletions.
1 change: 0 additions & 1 deletion handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ public final class OpenSsl {
long privateKeyBio = 0;
long certBio = 0;
try {
SSLContext.setOptions(sslCtx, SSL.SSL_OP_ALL);
SSLContext.setCipherSuite(sslCtx, "ALL");
final long ssl = SSL.newSSL(sslCtx, true);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,22 +270,19 @@ public String run() {
throw new SSLException("failed to create an SSL_CTX", e);
}

SSLContext.setOptions(ctx, SSL.SSL_OP_ALL);
SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SSLv2);
SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SSLv3);
SSLContext.setOptions(ctx, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
SSLContext.setOptions(ctx, SSL.SSL_OP_SINGLE_ECDH_USE);
SSLContext.setOptions(ctx, SSL.SSL_OP_SINGLE_DH_USE);
SSLContext.setOptions(ctx, SSL.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
SSLContext.setOptions(ctx, SSLContext.getOptions(ctx) |
SSL.SSL_OP_NO_SSLv2 |
SSL.SSL_OP_NO_SSLv3 |
SSL.SSL_OP_CIPHER_SERVER_PREFERENCE |

// We do not support compression at the moment so we should explicitly disable it.
SSLContext.setOptions(ctx, SSL.SSL_OP_NO_COMPRESSION);
SSL.SSL_OP_NO_COMPRESSION |

// Disable ticket support by default to be more inline with SSLEngineImpl of the JDK.
// This also let SSLSession.getId() work the same way for the JDK implementation and the OpenSSLEngine.
// If tickets are supported SSLSession.getId() will only return an ID on the server-side if it could
// make use of tickets.
SSLContext.setOptions(ctx, SSL.SSL_OP_NO_TICKET);
SSL.SSL_OP_NO_TICKET);

// We need to enable SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER as the memory address may change between
// calling OpenSSLEngine.wrap(...).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -581,46 +581,42 @@ public final SSLEngineResult wrap(
}
} else {
int sslError = SSL.getError(ssl, bytesWritten);
switch (sslError) {
case SSL.SSL_ERROR_ZERO_RETURN:
// This means the connection was shutdown correctly, close inbound and outbound
if (!receivedShutdown) {
closeAll();
if (sslError == SSL.SSL_ERROR_ZERO_RETURN) {
// This means the connection was shutdown correctly, close inbound and outbound
if (!receivedShutdown) {
closeAll();

bytesProduced += bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO);
bytesProduced += bioLengthBefore - SSL.bioLengthByteBuffer(networkBIO);

SSLEngineResult.HandshakeStatus hs = mayFinishHandshake(
SSLEngineResult.HandshakeStatus hs = mayFinishHandshake(
status != FINISHED ? getHandshakeStatus(SSL.bioLengthNonApplication(networkBIO))
: FINISHED);
return newResult(hs, bytesConsumed, bytesProduced);
}
: FINISHED);
return newResult(hs, bytesConsumed, bytesProduced);
}

return newResult(NOT_HANDSHAKING, bytesConsumed, bytesProduced);

case SSL.SSL_ERROR_WANT_READ:
// If there is no pending data to read from BIO we should go back to event loop and try
// to read more data [1]. It is also possible that event loop will detect the socket has
// been closed. [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
return newResult(NEED_UNWRAP, bytesConsumed, bytesProduced);

case SSL.SSL_ERROR_WANT_WRITE:
// SSL_ERROR_WANT_WRITE typically means that the underlying transport is not writable
// and we should set the "want write" flag on the selector and try again when the
// underlying transport is writable [1]. However we are not directly writing to the
// underlying transport and instead writing to a BIO buffer. The OpenSsl documentation
// says we should do the following [1]:
//
// "When using a buffering BIO, like a BIO pair, data must be written into or retrieved
// out of the BIO before being able to continue."
//
// So we attempt to drain the BIO buffer below, but if there is no data this condition
// is undefined and we assume their is a fatal error with the openssl engine and close.
// [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
return newResult(NEED_WRAP, bytesConsumed, bytesProduced);

default:
// Everything else is considered as error
throw shutdownWithError("SSL_write");
return newResult(NOT_HANDSHAKING, bytesConsumed, bytesProduced);
} else if (sslError == SSL.SSL_ERROR_WANT_READ) {
// If there is no pending data to read from BIO we should go back to event loop and try
// to read more data [1]. It is also possible that event loop will detect the socket has
// been closed. [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
return newResult(NEED_UNWRAP, bytesConsumed, bytesProduced);
} else if (sslError == SSL.SSL_ERROR_WANT_WRITE) {
// SSL_ERROR_WANT_WRITE typically means that the underlying transport is not writable
// and we should set the "want write" flag on the selector and try again when the
// underlying transport is writable [1]. However we are not directly writing to the
// underlying transport and instead writing to a BIO buffer. The OpenSsl documentation
// says we should do the following [1]:
//
// "When using a buffering BIO, like a BIO pair, data must be written into or retrieved
// out of the BIO before being able to continue."
//
// So we attempt to drain the BIO buffer below, but if there is no data this condition
// is undefined and we assume their is a fatal error with the openssl engine and close.
// [1] https://www.openssl.org/docs/manmaster/ssl/SSL_write.html
return newResult(NEED_WRAP, bytesConsumed, bytesProduced);
} else {
// Everything else is considered as error
throw shutdownWithError("SSL_write");
}
}
}
Expand Down Expand Up @@ -844,24 +840,20 @@ public final SSLEngineResult unwrap(
break;
} else {
int sslError = SSL.getError(ssl, bytesRead);
switch (sslError) {
case SSL.SSL_ERROR_WANT_WRITE:
case SSL.SSL_ERROR_WANT_READ:
// break to the outer loop as we want to read more data which means we need to
// write more to the BIO.
break readLoop;

case SSL.SSL_ERROR_ZERO_RETURN:
// This means the connection was shutdown correctly, close inbound and outbound
if (!receivedShutdown) {
closeAll();
}
return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status,
bytesConsumed, bytesProduced);

default:
return sslReadErrorResult(SSL.getLastErrorNumber(), bytesConsumed,
bytesProduced);
if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) {
// break to the outer loop as we want to read more data which means we need to
// write more to the BIO.
break readLoop;
} else if (sslError == SSL.SSL_ERROR_ZERO_RETURN) {
// This means the connection was shutdown correctly, close inbound and outbound
if (!receivedShutdown) {
closeAll();
}
return newResultMayFinishHandshake(isInboundDone() ? CLOSED : OK, status,
bytesConsumed, bytesProduced);
} else {
return sslReadErrorResult(SSL.getLastErrorNumber(), bytesConsumed,
bytesProduced);
}
}
}
Expand Down Expand Up @@ -1038,27 +1030,14 @@ public final synchronized void closeOutbound() {
int err = SSL.shutdownSSL(ssl);
if (err < 0) {
int sslErr = SSL.getError(ssl, err);
switch (sslErr) {
case SSL.SSL_ERROR_NONE:
case SSL.SSL_ERROR_WANT_ACCEPT:
case SSL.SSL_ERROR_WANT_CONNECT:
case SSL.SSL_ERROR_WANT_WRITE:
case SSL.SSL_ERROR_WANT_READ:
case SSL.SSL_ERROR_WANT_X509_LOOKUP:
case SSL.SSL_ERROR_ZERO_RETURN:
// Nothing to do here
break;
case SSL.SSL_ERROR_SYSCALL:
case SSL.SSL_ERROR_SSL:
if (logger.isDebugEnabled()) {
logger.debug("SSL_shutdown failed: OpenSSL error: {}", SSL.getLastError());
}
// There was an internal error -- shutdown
shutdown();
break;
default:
SSL.clearError();
break;
if (sslErr == SSL.SSL_ERROR_SYSCALL || sslErr == SSL.SSL_ERROR_SSL) {
if (logger.isDebugEnabled()) {
logger.debug("SSL_shutdown failed: OpenSSL error: {}", SSL.getLastError());
}
// There was an internal error -- shutdown
shutdown();
} else {
SSL.clearError();
}
}
}
Expand Down Expand Up @@ -1214,9 +1193,6 @@ public final void setEnabledProtocols(String[] protocols) {
}
synchronized (this) {
if (!isDestroyed()) {
// Enable all and then disable what we not want
SSL.setOptions(ssl, SSL.SSL_OP_ALL);

// Clear out options which disable protocols
SSL.clearOptions(ssl, SSL.SSL_OP_NO_SSLv2 | SSL.SSL_OP_NO_SSLv3 | SSL.SSL_OP_NO_TLSv1 |
SSL.SSL_OP_NO_TLSv1_1 | SSL.SSL_OP_NO_TLSv1_2);
Expand Down Expand Up @@ -1290,17 +1266,15 @@ public final synchronized void beginHandshake() throws SSLException {
int status;
if ((status = SSL.renegotiate(ssl)) != 1 || (status = SSL.doHandshake(ssl)) != 1) {
int err = SSL.getError(ssl, status);
switch (err) {
case SSL.SSL_ERROR_WANT_READ:
case SSL.SSL_ERROR_WANT_WRITE:
// If the internal SSL buffer is small it is possible that doHandshake may "fail" because
// there is not enough room to write, so we should wait until the renegotiation has been.
renegotiationPending = true;
handshakeState = HandshakeState.STARTED_EXPLICITLY;
lastAccessed = System.currentTimeMillis();
return;
default:
throw shutdownWithError("renegotiation failed");
if (err == SSL.SSL_ERROR_WANT_READ || err == SSL.SSL_ERROR_WANT_WRITE) {
// If the internal SSL buffer is small it is possible that doHandshake may "fail" because
// there is not enough room to write, so we should wait until the renegotiation has been.
renegotiationPending = true;
handshakeState = HandshakeState.STARTED_EXPLICITLY;
lastAccessed = System.currentTimeMillis();
return;
} else {
throw shutdownWithError("renegotiation failed");
}
}

Expand Down Expand Up @@ -1383,13 +1357,11 @@ private SSLEngineResult.HandshakeStatus handshake() throws SSLException {
}

int sslError = SSL.getError(ssl, code);
switch (sslError) {
case SSL.SSL_ERROR_WANT_READ:
case SSL.SSL_ERROR_WANT_WRITE:
return pendingStatus(SSL.bioLengthNonApplication(networkBIO));
default:
// Everything else is considered as error
throw shutdownWithError("SSL_do_handshake");
if (sslError == SSL.SSL_ERROR_WANT_READ || sslError == SSL.SSL_ERROR_WANT_WRITE) {
return pendingStatus(SSL.bioLengthNonApplication(networkBIO));
} else {
// Everything else is considered as error
throw shutdownWithError("SSL_do_handshake");
}
}
// if SSL_do_handshake returns > 0 or sslError == SSL.SSL_ERROR_NAME it means the handshake was finished.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
<!-- Fedora-"like" systems. This is currently only used for the netty-tcnative dependency -->
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
<tcnative.artifactId>netty-tcnative</tcnative.artifactId>
<tcnative.version>2.0.0.Beta2</tcnative.version>
<tcnative.version>2.0.0.Final-SNAPSHOT</tcnative.version>
<tcnative.classifier>${os.detected.classifier}</tcnative.classifier>
<epoll.classifier>${os.detected.name}-${os.detected.arch}</epoll.classifier>
<logging.config>${project.basedir}/../common/src/test/resources/logback-test.xml</logging.config>
Expand Down

0 comments on commit cd3bf3d

Please sign in to comment.