Problemas al migrar el cliente ssl netty de la versión 3.7 a 4, el tiempo de espera del protocolo

Tengo un cliente netty que espera awaitIninterrumpidamente para que el servidor envíe algo. Esto parece funcionar bien en la versión 3.7. He intentado migrarlo al 4.0 pero sigo recibiendo la excepción:

    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.

Tengo este código en la versión netty 3.7:



    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;
        }

Y he cambiado en esto para adaptarse a la versión 4.0:





       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;
        }   
    }

¿Alguien tiene alguna idea de lo que estoy haciendo mal? Gracias de antemano!

Respuestas a la pregunta(0)

Su respuesta a la pregunta