meszibalu commented on a change in pull request #4125:
URL: https://github.com/apache/hbase/pull/4125#discussion_r823399398



##########
File path: 
hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
##########
@@ -297,11 +295,10 @@ public void operationComplete(ChannelFuture future) 
throws Exception {
             established(ch);
           }
         }
-      }).channel();
+      }).sync().channel();

Review comment:
       Why do we have `sync()` here? It converts the asynchronous connection to 
synchronous.

##########
File path: 
hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
##########
@@ -181,4 +204,80 @@ public int getNumOpenConnections() {
     // allChannels also contains the server channel, so exclude that from the 
count.
     return channelsCount > 0 ? channelsCount - 1 : channelsCount;
   }
+
+  private synchronized void initSSL(ChannelPipeline p, boolean 
supportPlaintext) throws
+    X509Exception {
+    SslContext nettySslContext;
+
+    SSLContextAndOptions sslContextAndOptions = 
x509Util.getDefaultSSLContextAndOptions();
+    nettySslContext = sslContextAndOptions
+      .createNettyJdkSslContext(sslContextAndOptions.getSSLContext(), false);
+
+    if (supportPlaintext) {
+      p.addLast("ssl", new NettyRpcServer.DualModeSslHandler(nettySslContext));
+      LOG.debug("Dual mode SSL handler added for channel: {}", p.channel());
+    } else {
+      p.addLast("ssl", nettySslContext.newHandler(p.channel().alloc()));
+      LOG.debug("SSL handler added for channel: {}", p.channel());
+    }
+  }
+
+  /**
+   * A handler that detects whether the client would like to use
+   * TLS or not and responds in kind. The first bytes are examined
+   * for the static TLS headers to make the determination and
+   * placed back in the stream with the correct ChannelHandler
+   * instantiated.
+   */
+  class DualModeSslHandler extends OptionalSslHandler {
+
+    DualModeSslHandler(SslContext sslContext) {
+      super(sslContext);
+    }
+
+    @Override
+    protected void decode(ChannelHandlerContext context, ByteBuf in, 
List<Object> out)
+      throws Exception {
+      if (in.readableBytes() >= 5) {
+        super.decode(context, in, out);
+      } else if (in.readableBytes() > 0) {
+        // It requires 5 bytes to detect a proper ssl connection. In the
+        // case that the server receives fewer, check if we can fail to 
plaintext.
+        // This will occur when for any four letter work commands.
+        if (TLS_HANDSHAKE_RECORD_TYPE != in.getByte(0)) {
+          LOG.debug("first byte {} does not match TLS handshake, failing to 
plaintext",
+            in.getByte(0));
+          handleNonSsl(context);

Review comment:
       It reconfigures the pipeline once if we have only 1-4 incoming bytes. So 
if at some point of time we receive only 2 bytes of data for example, it will 
remove itself and the ssl handler if I understand it correctly.
   
   I think we should check the **first** X bytes of incoming data and make the 
decision to keep or remove ssl handler.

##########
File path: 
hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcConnection.java
##########
@@ -321,14 +319,22 @@ public void run(boolean cancelled) throws IOException {
         if (cancelled) {
           setCancelled(call);
         } else {
+          Channel channel = channelRef.get();
           if (channel == null) {
-            connect();
+            try {
+              channelRef.compareAndSet(null, connect());
+              channel = channelRef.get();

Review comment:
       You discarded the return value of `compareAndSet`. If there are multiple 
connection attempts at the same time, one of it is leaked.

##########
File path: 
hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/NettyRpcServer.java
##########
@@ -181,4 +204,80 @@ public int getNumOpenConnections() {
     // allChannels also contains the server channel, so exclude that from the 
count.
     return channelsCount > 0 ? channelsCount - 1 : channelsCount;
   }
+
+  private synchronized void initSSL(ChannelPipeline p, boolean 
supportPlaintext) throws
+    X509Exception {
+    SslContext nettySslContext;
+
+    SSLContextAndOptions sslContextAndOptions = 
x509Util.getDefaultSSLContextAndOptions();
+    nettySslContext = sslContextAndOptions
+      .createNettyJdkSslContext(sslContextAndOptions.getSSLContext(), false);
+
+    if (supportPlaintext) {
+      p.addLast("ssl", new NettyRpcServer.DualModeSslHandler(nettySslContext));
+      LOG.debug("Dual mode SSL handler added for channel: {}", p.channel());
+    } else {
+      p.addLast("ssl", nettySslContext.newHandler(p.channel().alloc()));
+      LOG.debug("SSL handler added for channel: {}", p.channel());
+    }
+  }
+
+  /**
+   * A handler that detects whether the client would like to use
+   * TLS or not and responds in kind. The first bytes are examined
+   * for the static TLS headers to make the determination and
+   * placed back in the stream with the correct ChannelHandler
+   * instantiated.
+   */
+  class DualModeSslHandler extends OptionalSslHandler {
+
+    DualModeSslHandler(SslContext sslContext) {
+      super(sslContext);
+    }
+
+    @Override
+    protected void decode(ChannelHandlerContext context, ByteBuf in, 
List<Object> out)
+      throws Exception {
+      if (in.readableBytes() >= 5) {
+        super.decode(context, in, out);
+      } else if (in.readableBytes() > 0) {
+        // It requires 5 bytes to detect a proper ssl connection. In the

Review comment:
       If 5 bytes are required why `>= 5` in the previous if? 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to