Fix event loop hang in SniHandler (#9933)
Motivation A bug was introduced in #9806 which looks likely to be the cause of #9919. SniHandler will enter an infinite loop if an SSL record is received with SSL major version byte != 3 (i.e. something other than TLS or SSL3.0) Modifications - Follow default path as intended for majorVersion != 3 in AbstractSniHandler#decode(...) - Add unit test to reproduce the hang Result Fixes #9919
This commit is contained in:
parent
b82258b72f
commit
41c47b41bf
@ -153,8 +153,9 @@ public abstract class AbstractSniHandler<T> extends ByteToMessageDecoder impleme
|
|||||||
select(ctx, extractSniHostname(handshakeBuffer, 0, handshakeLength));
|
select(ctx, extractSniHostname(handshakeBuffer, 0, handshakeLength));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
// fall-through
|
||||||
default:
|
default:
|
||||||
// not tls, ssl or application data, do not try sni
|
// not tls, ssl or application data, do not try sni
|
||||||
select(ctx, null);
|
select(ctx, null);
|
||||||
|
@ -320,7 +320,7 @@ public class SniHandlerTest {
|
|||||||
ch.writeInbound(Unpooled.wrappedBuffer(message));
|
ch.writeInbound(Unpooled.wrappedBuffer(message));
|
||||||
// TODO(scott): This should fail because the engine should reject zero length records during handshake.
|
// TODO(scott): This should fail because the engine should reject zero length records during handshake.
|
||||||
// See https://github.com/netty/netty/issues/6348.
|
// See https://github.com/netty/netty/issues/6348.
|
||||||
// fail();
|
fail();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
@ -344,6 +344,43 @@ public class SniHandlerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 10000)
|
||||||
|
public void testMajorVersionNot3() throws Exception {
|
||||||
|
SslContext nettyContext = makeSslContext(provider, false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DomainNameMapping<SslContext> mapping = new DomainNameMappingBuilder<SslContext>(nettyContext).build();
|
||||||
|
|
||||||
|
SniHandler handler = new SniHandler(mapping);
|
||||||
|
EmbeddedChannel ch = new EmbeddedChannel(handler);
|
||||||
|
|
||||||
|
// invalid
|
||||||
|
byte[] message = {22, 2, 0, 0, 0};
|
||||||
|
try {
|
||||||
|
// Push the handshake message.
|
||||||
|
ch.writeInbound(Unpooled.wrappedBuffer(message));
|
||||||
|
fail();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
ch.close();
|
||||||
|
|
||||||
|
// When the channel is closed the SslHandler will write an empty buffer to the channel.
|
||||||
|
ByteBuf buf = ch.readOutbound();
|
||||||
|
if (buf != null) {
|
||||||
|
assertFalse(buf.isReadable());
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(ch.finish(), is(false));
|
||||||
|
assertThat(handler.hostname(), nullValue());
|
||||||
|
assertThat(handler.sslContext(), is(nettyContext));
|
||||||
|
} finally {
|
||||||
|
releaseAll(nettyContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSniWithApnHandler() throws Exception {
|
public void testSniWithApnHandler() throws Exception {
|
||||||
SslContext nettyContext = makeSslContext(provider, true);
|
SslContext nettyContext = makeSslContext(provider, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user