【发布时间】:2018-01-25 22:58:14
【问题描述】:
似乎服务器拒绝了来自 wireshark 输出的 tls 协商,但我无法从代码中看出原因。它基于有效的代码,只是它已被弃用,因此我使用新的 API 进行更新。代码是开始。需要使用真实的证书。有谁知道为什么服务器会发送 tcp FIN, ACK?
我有这个服务器代码:
ServerBootstrap sbssl = new ServerBootstrap();
bossGroupSsl = new NioEventLoopGroup(1);
workerGroupSsl = new NioEventLoopGroup();
sbssl.group(bossGroupSsl, workerGroupSsl).option(ChannelOption.SO_RCVBUF, 8192).handler(new LoggingHandler(LogLevel.DEBUG))
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(8192))
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline cp = ch.pipeline();
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext cont2 = SslContextBuilder.forServer(cert.privateKey(), cert.certificate()).build();
SSLEngine engine = cont2.newEngine(ch.alloc());
cp.addLast("ssl", new SslHandler(engine));
还有这个客户端代码:
Bootstrap b = new Bootstrap();
group = new NioEventLoopGroup();
Log.d(RegisterAttemptSSL.class.getName(), "connecting");
InetSocketAddress ria = new InetSocketAddress(toHostname, portDestination);
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.IP_TOS, 24)
.remoteAddress(ria).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
SslContext cont2 = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
SSLEngine engine = cont2.newEngine(ch.alloc(), toHostname, portDestination);
engine.setEnabledProtocols(new String[] {"TLSv1.2"});
ch.pipeline().addLast(new SslHandler(engine, false));
导致这个wireshark:
21 16.840654 10.1.10.100 10.1.10.203 TCP 74 4683 → 5061 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=62567382 TSecr=0 WS=256
22 16.840931 IntelCor_25:1d:fc 广播 ARP 42 谁有 10.1.10.100?告诉 10.1.10.203
23 16.856111 SonyMobi_7f:55:af IntelCor_25:1d:fc ARP 42 10.1.10.100 位于 84:c7:ea:7f:55:af
24 16.856198 10.1.10.203 10.1.10.100 TCP 74 5061 → 4683 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1 TSval=46199014 TSecr=62567382
25 16.859326 10.1.10.100 10.1.10.203 TCP 66 4683 → 5061 [ACK] Seq=1 Ack=1 Win=87808 Len=0 TSval=62567385 TSecr=46199014
26 16.872274 10.1.10.100 10.1.10.203 TLSv1 179 客户端问候
27 16.964375 10.1.10.203 10.1.10.100 TCP 66 5061 → 4683 [FIN, ACK] Seq=1 Ack=114 Win=66560 Len=0 TSval=46199026 TSecr=62567387
28 16.965112 10.1.10.203 10.1.10.100 TCP 54 5061 → 4683 [RST, ACK] Seq=2 Ack=114 Win=0 Len=0
netty 4.1.18.Final 赢 7 JDK 8
在服务器端使用此代码,除了触发了 channelReadComplete 蜜蜂之外,没有下一个处理程序蜜蜂的 channelRead0 触发第一个额外时间。相同的处理程序用于常规 tcp 并且没有这个怪癖可以正常工作。在客户端有一个空指针,但业务逻辑不受影响。
ServerBootstrap sbssl = new ServerBootstrap();
bossGroupSsl = new NioEventLoopGroup(1);
workerGroupSsl = new NioEventLoopGroup();
sbssl.group(bossGroupSsl, workerGroupSsl).option(ChannelOption.SO_RCVBUF, 8192)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(8192))
.channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline cp = ch.pipeline();
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext cont = SslContext.newServerContext(cert.certificate(), cert.privateKey());
cp.addLast("ssl", cont.newHandler(ch.alloc()));
01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: io.netty.handler.codec.DecoderException: java.lang.NullPointerException: ssl == null 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459) 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) 01-26 15:34:34.546 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: at java.lang.Thread.run(Thread.java:764) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 由: java.lang.NullPointerException: ssl == null 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err:在 com.android.org.conscrypt.NativeCrypto.SSL_pending_readable_bytes(本机方法) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 com.android.org.conscrypt.OpenSSLEngineImpl.pendingInboundCleartextBytes(OpenSSLEngineImpl.java:491) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:679) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:630) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:596) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:292) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1248) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1159) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1194) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: 在 io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) 01-26 15:34:34.547 31823-31856/no.tobiassenit.sipclient W/System.err: ... 16 更多
似乎即使没有使用新的 api 也会出现问题 - 只需激活类就足够了。所以这行得通:即使没有使用新的 api,似乎也会出现问题 - 只需激活类就足够了。所以这行得通:
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext cont = SslContext.newServerContext(cert.certificate(), cert.privateKey());
//SslContext cont2 = SslContextBuilder.forServer(cert.privateKey(), cert.certificate()).build();
//SSLEngine engine = cont2.newEngine(ch.alloc());
//engine.setUseClientMode(true);;
//cp.addFirst("ssl", new SslHandler(engine));
cp.addFirst("ssl", cont.newHandler(ch.alloc()));
虽然没有(tcp fin, ack):
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext cont = SslContext.newServerContext(cert.certificate(), cert.privateKey());
SslContext cont2 = SslContextBuilder.forServer(cert.privateKey(), cert.certificate()).build();
SSLEngine engine = cont2.newEngine(ch.alloc());
//cp.addFirst("ssl", new SslHandler(engine));
cp.addFirst("ssl", cont.newHandler(ch.alloc()));
【问题讨论】:
-
好像有一个 NullPointerException。我会在那里调查。
-
请注意,当服务器端配置了已弃用的方法 SslContext.newServerContext 时会出现空指针。
-
另请注意,openssl 由 Android/客户端和服务器端的 JSSE 使用。
标签: netty