1

I'm trying to go through the SSL example and EchoServer example in Netty and for some reason, when I add my sslContext on the client side, I keep getting, an established connection was aborted by the software in your host machine.

EchoServerBootstrap

public class EchoServerBootstrap {
    private final int port;

    public EchoServerBootstrap(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        new EchoServerBootstrap(3000).start();
    }

    public void start() throws Exception {
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        final SslContext sslContext = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();

        EventLoopGroup group = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
            .channel(NioServerSocketChannel.class)
            .localAddress(new InetSocketAddress(port))
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(sslContext.newHandler(ch.alloc()));
                    ch.pipeline().addLast(new EchoServerHandler());
                }
            });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

EchoServerHandler

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
        @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("Received: " + in.toString(CharsetUtil.UTF_8));
        ctx.write(in);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channel read complete");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

EchoClientHandler

public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks", CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
        System.out.println("Client receive: " + in.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

EchoClientBootstrap

public class EchoClientBootstrap {
    private final String host;
    private final int port;

    public EchoClientBootstrap(String host, int port) {
        this.port = port;
        this.host = host;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();

        final SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
            .channel(NioSocketChannel.class)
            .remoteAddress(new InetSocketAddress(host, port))
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(sslContext.newHandler(ch.alloc(), host, port)); // WHEN I ADD THIS LINE IT FAILS WITH I/O EXCEPTION 'an established connection was aborted...'
                    ch.pipeline().addLast(new EchoClientHandler());
                }
            });
            ChannelFuture f = b.connect(host, port).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {

        new EchoClientBootstrap("localhost", 3000).start();
    }
}

Is there something obvious I'm missing? I tried following this example and altering it a bit (http://netty.io/4.1/xref/io/netty/example/securechat/package-summary.html), but I keep getting that exception when I add the sslContext to the client channel. Any thoughts?

halfer
  • 19,824
  • 17
  • 99
  • 186
Crystal
  • 28,460
  • 62
  • 219
  • 393

1 Answers1

0

I added some logging to figure out what was going on, and without encryption, EchoClient sends over the "Netty rocks" message and the server reads the message and closes the channel. But for some reason if SSL is enabled, the EchoServerHandler calls channelReadComplete before the EchoClient can send "Netty rocks" which is essentially this method

@Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channel read complete");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

which was closing my channel. I am not sure why there is that discrepancy when using SSL.

halfer
  • 19,824
  • 17
  • 99
  • 186
Crystal
  • 28,460
  • 62
  • 219
  • 393