问题
I have a netty client that waits awaitUninterruptibly for the server to send something. This seems to work fine in the version 3.7. I have tried to migrate it to the 4.0 but I keep getting the excepcion:
javax.net.ssl.SSLException: handshake timed out nioEventLoopGroup-2-1, called closeOutbound() nioEventLoopGroup-2-1, closeOutboundInternal() nioEventLoopGroup-2-1, SEND TLSv1 ALERT: warning, description = close_notify nioEventLoopGroup-2-1, WRITE: TLSv1 Alert, length = 2 nioEventLoopGroup-2-1, called closeInbound() nioEventLoopGroup-2-1, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack? javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack? nioEventLoopGroup-2-1, SEND TLSv1 ALERT: fatal, description = internal_error nioEventLoopGroup-2-1, Exception sending alert: java.io.IOException: writer side was already closed.
I have this code in the 3.7 netty version:
public class CtraderClient {
private final String host;
private final int port;
Channel channel = null;
public CtraderClient(String host, int port) {
this.host = host;
this.port = port;
}
public void run() {
// Configure the client.
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootstrap.setOption("keepAlive", true);
HashedWheelTimer timer = new HashedWheelTimer();
// Configure the pipeline factory.
bootstrap.setPipelineFactory(new SecurePipelineFactory(timer));
// Start the connection attempt.
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,
port));
// Wait until the connection attempt succeeds or fails.
channel = future.awaitUninterruptibly().getChannel();
if (!future.isSuccess()) {
future.getCause().printStackTrace();
bootstrap.releaseExternalResources();
return;
}
}
}
public class SecurePipelineFactory implements ChannelPipelineFactory {
private final ChannelHandler idleStateHandler;
private Timer timer;
public SecurePipelineFactory(Timer timer) {
this.timer = timer;
this.idleStateHandler = new IdleStateHandler(timer, 0, 20, 0); // timer must be shared.
}
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = pipeline();
SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, null, null);
SSLEngine engine = sslcontext.createSSLEngine();
engine.setUseClientMode(true);
SslHandler sslHandler = new SslHandler(engine);
pipeline.addLast("ssl", sslHandler);
pipeline.addLast(
"frameDecoder",
new LengthFieldBasedFrameDecoder(
1048576, 0, 4, 0, 4));
pipeline.addLast("protobufDecoder",
new ProtobufDecoder(
ProtoMessage.getDefaultInstance()));
pipeline.addLast("frameEncoder",
new LengthFieldPrepender(4));
pipeline.addLast("protobufEncoder",
new ProtobufEncoder());
// pipeline.addLast("handler", new SecureHandler());
pipeline.addLast("protoHandler", new ProtoMessageHandler());
pipeline.addLast("idleStateHandler", idleStateHandler);
pipeline.addLast("heartHandler", new HeartbeatHandler());
return pipeline;
}
And I've changed into this to fit the 4.0 version:
public class CtraderClient {
private final String host;
private final int port;
Channel channel = null;
private static final Logger LOGGER = LoggerFactory
.getLogger(CtraderClient.class);
public CtraderClient(String host, int port) {
this.host = host;
this.port = port;
}
public void run() throws InterruptedException {
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new MyChannelInitializer ());
// Start the connection attempt.
ChannelFuture future = b.connect(new InetSocketAddress(host, port))
.sync();
channel = future.awaitUninterruptibly().channel();
if (!future.isSuccess()) {
future.cause().printStackTrace();
//bootstrap.releaseExternalResources();
return;
}
}
}
public class MyChannelInitializer extends ChannelInitializer {
private static final String PROTOCOL = "SSL";
@Override
public void initChannel(SocketChannel channel) throws Exception {
SslHandler sslHandler = createSSLHandler();
channel.pipeline().addLast("ssl", sslHandler);
channel.pipeline().addLast(
"frameDecoder",
new LengthFieldBasedFrameDecoder(
1048576, 0, 4, 0, 4));
channel.pipeline().addLast("protobufDecoder",
new ProtobufDecoder(
ProtoMessage.getDefaultInstance()));
channel.pipeline().addLast("frameEncoder",
new LengthFieldPrepender(4));
channel.pipeline().addLast("protobufEncoder",
new ProtobufEncoder());
channel.pipeline().addLast("protoHandler", new ProtoMessageHandler());
channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(0, 20, 0));
channel.pipeline().addLast("heartHandler", new HeartbeatHandler());
}
private SslHandler createSSLHandler() throws NoSuchAlgorithmException,
KeyManagementException {
SSLEngine engine = createSSLEngine();
engine.setUseClientMode(true);
SslHandler sslHandler = new SslHandler(engine);
return sslHandler;
}
private SSLEngine createSSLEngine() throws NoSuchAlgorithmException,
KeyManagementException {
SSLContext sslcontext = SSLContext.getInstance(PROTOCOL);
sslcontext.init(null, null, null); //SecureTrustManagerFactory.getTrustManagers() --- I tried it with a dummy
// x09Trustmanager that returns new X509Certificate[0] in getAcceptedIssuers(),
//but I get the same exception
SSLEngine engine = sslcontext.createSSLEngine();
return engine;
}
}
Has anyone any idea of what I'm doing wrong? Thanx in advance!
来源:https://stackoverflow.com/questions/19443786/problems-when-migrating-ssl-netty-client-from-version-3-7-to-4-handshake-timeou