diff --git a/redisson/src/main/java/org/redisson/client/RedisClientConfig.java b/redisson/src/main/java/org/redisson/client/RedisClientConfig.java index a9393e433..b90f3f821 100644 --- a/redisson/src/main/java/org/redisson/client/RedisClientConfig.java +++ b/redisson/src/main/java/org/redisson/client/RedisClientConfig.java @@ -55,6 +55,7 @@ public class RedisClientConfig { private boolean keepAlive; private boolean tcpNoDelay; + private String sslHostname; private boolean sslEnableEndpointIdentification = true; private SslProvider sslProvider = SslProvider.JDK; private URI sslTruststore; @@ -89,8 +90,17 @@ public class RedisClientConfig { this.sslKeystore = config.sslKeystore; this.sslKeystorePassword = config.sslKeystorePassword; this.resolverGroup = config.resolverGroup; + this.sslHostname = config.sslHostname; } + public String getSslHostname() { + return sslHostname; + } + public RedisClientConfig setSslHostname(String sslHostname) { + this.sslHostname = sslHostname; + return this; + } + public RedisClientConfig setAddress(String host, int port) { this.address = URIBuilder.create("redis://" + host + ":" + port); return this; diff --git a/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java b/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java index 39bd51c25..9645f6249 100644 --- a/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java +++ b/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java @@ -33,6 +33,7 @@ import org.redisson.client.RedisClient; import org.redisson.client.RedisClientConfig; import org.redisson.client.RedisConnection; import org.redisson.config.SslProvider; +import org.redisson.misc.URIBuilder; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; @@ -162,7 +163,12 @@ public class RedisChannelInitializer extends ChannelInitializer { } SslContext sslContext = sslContextBuilder.build(); - SSLEngine sslEngine = sslContext.newEngine(ch.alloc(), config.getAddress().getHost(), config.getAddress().getPort()); + String hostname = config.getSslHostname(); + if (hostname == null || URIBuilder.isValidIP(hostname)) { + hostname = config.getAddress().getHost(); + } + + SSLEngine sslEngine = sslContext.newEngine(ch.alloc(), hostname, config.getAddress().getPort()); sslEngine.setSSLParameters(sslParams); SslHandler sslHandler = new SslHandler(sslEngine); diff --git a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java index de3fe9aa0..84f774545 100644 --- a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java +++ b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java @@ -82,6 +82,8 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { private RedisStrictCommand> clusterNodesCommand; + private String configEndpointHostName; + private boolean isConfigEndpoint; private AddressResolver resolver; @@ -95,7 +97,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { Throwable lastException = null; List failedMasters = new ArrayList(); for (URI addr : cfg.getNodeAddresses()) { - RFuture connectionFuture = connectToNode(cfg, addr, null); + RFuture connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); try { RedisConnection connection = connectionFuture.syncUninterruptibly().getNow(); @@ -104,6 +106,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { Future> addrsFuture = resolver.resolveAll(InetSocketAddress.createUnresolved(addr.getHost(), addr.getPort())); List allAddrs = addrsFuture.syncUninterruptibly().getNow(); if (allAddrs.size() > 1) { + configEndpointHostName = addr.getHost(); isConfigEndpoint = true; } else { resolver.close(); @@ -178,8 +181,8 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { } @Override - protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout) { - RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout); + protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { + RedisClientConfig result = super.createRedisConfig(type, address, timeout, commandTimeout, sslHostname); result.setReadOnly(type == NodeType.SLAVE && config.getReadMode() != ReadMode.MASTER); return result; } @@ -198,7 +201,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { } final RPromise>> result = new RedissonPromise>>(); - RFuture connectionFuture = connectToNode(cfg, partition.getMasterAddress(), null); + RFuture connectionFuture = connectToNode(cfg, partition.getMasterAddress(), null, configEndpointHostName); connectionFuture.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { @@ -351,7 +354,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { return; } final URI uri = iterator.next(); - RFuture connectionFuture = connectToNode(cfg, uri, null); + RFuture connectionFuture = connectToNode(cfg, uri, null, configEndpointHostName); connectionFuture.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { @@ -651,6 +654,10 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { } } } + + public String getConfigEndpointHostName() { + return configEndpointHostName; + } @Override public int calcSlot(String key) { diff --git a/redisson/src/main/java/org/redisson/connection/ConnectionManager.java b/redisson/src/main/java/org/redisson/connection/ConnectionManager.java index d6427cb24..b7ffa7c8e 100644 --- a/redisson/src/main/java/org/redisson/connection/ConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/ConnectionManager.java @@ -97,11 +97,11 @@ public interface ConnectionManager { RFuture connectionWriteOp(NodeSource source, RedisCommand command); - RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout); + RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname); - RedisClient createClient(NodeType type, InetSocketAddress address, URI uri); + RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, String sslHostname); - RedisClient createClient(NodeType type, URI address); + RedisClient createClient(NodeType type, URI address, String sslHostname); MasterSlaveEntry getEntry(RedisClient redisClient); diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 10bfdebce..d73dfbc40 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -250,7 +250,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } } - protected RFuture connectToNode(BaseMasterSlaveServersConfig cfg, final URI addr, RedisClient client) { + protected RFuture connectToNode(BaseMasterSlaveServersConfig cfg, final URI addr, RedisClient client, String sslHostname) { final Object key; if (client != null) { key = client; @@ -263,7 +263,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } if (addr != null) { - client = createClient(NodeType.MASTER, addr, cfg.getConnectTimeout(), cfg.getRetryInterval() * cfg.getRetryAttempts()); + client = createClient(NodeType.MASTER, addr, cfg.getConnectTimeout(), cfg.getRetryInterval() * cfg.getRetryAttempts(), sslHostname); } final RPromise result = new RedissonPromise(); RFuture future = client.connectAsync(); @@ -430,15 +430,15 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } @Override - public RedisClient createClient(NodeType type, URI address) { - RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts()); + public RedisClient createClient(NodeType type, URI address, String sslHostname) { + RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts(), sslHostname); clientEntries.put(client, new RedisClientEntry(client, commandExecutor, type)); return client; } @Override - public RedisClient createClient(NodeType type, InetSocketAddress address, URI uri) { - RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts()); + public RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, String sslHostname) { + RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts(), sslHostname); clientEntries.put(client, new RedisClientEntry(client, commandExecutor, type)); return client; } @@ -452,19 +452,19 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } @Override - public RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout) { - RedisClientConfig redisConfig = createRedisConfig(type, address, timeout, commandTimeout); + public RedisClient createClient(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { + RedisClientConfig redisConfig = createRedisConfig(type, address, timeout, commandTimeout, sslHostname); return RedisClient.create(redisConfig); } - private RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, int timeout, int commandTimeout) { - RedisClientConfig redisConfig = createRedisConfig(type, null, timeout, commandTimeout); + private RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, int timeout, int commandTimeout, String sslHostname) { + RedisClientConfig redisConfig = createRedisConfig(type, null, timeout, commandTimeout, sslHostname); redisConfig.setAddress(address, uri); return RedisClient.create(redisConfig); } - protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout) { + protected RedisClientConfig createRedisConfig(NodeType type, URI address, int timeout, int commandTimeout, String sslHostname) { RedisClientConfig redisConfig = new RedisClientConfig(); redisConfig.setAddress(address) .setTimer(timer) @@ -474,6 +474,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { .setSocketChannelClass(socketChannelClass) .setConnectTimeout(timeout) .setCommandTimeout(commandTimeout) + .setSslHostname(sslHostname) .setSslEnableEndpointIdentification(config.isSslEnableEndpointIdentification()) .setSslProvider(config.getSslProvider()) .setSslTruststore(config.getSslTruststore()) diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java index c2d49c4e1..c795b7a90 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java @@ -35,6 +35,7 @@ import org.redisson.client.protocol.CommandData; import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommands; import org.redisson.client.protocol.pubsub.PubSubType; +import org.redisson.cluster.ClusterConnectionManager; import org.redisson.cluster.ClusterSlotRange; import org.redisson.config.MasterSlaveServersConfig; import org.redisson.config.ReadMode; @@ -77,6 +78,8 @@ public class MasterSlaveEntry { final AtomicBoolean active = new AtomicBoolean(true); + String sslHostname; + public MasterSlaveEntry(Set slotRanges, ConnectionManager connectionManager, MasterSlaveServersConfig config) { for (ClusterSlotRange clusterSlotRange : slotRanges) { for (int i = clusterSlotRange.getStartSlot(); i < clusterSlotRange.getEndSlot() + 1; i++) { @@ -89,6 +92,10 @@ public class MasterSlaveEntry { slaveBalancer = new LoadBalancerManager(config, connectionManager, this); writeConnectionPool = new MasterConnectionPool(config, connectionManager, this); pubSubConnectionPool = new MasterPubSubConnectionPool(config, connectionManager, this); + + if (connectionManager instanceof ClusterConnectionManager) { + sslHostname = ((ClusterConnectionManager) connectionManager).getConfigEndpointHostName(); + } } public MasterSlaveServersConfig getConfig() { @@ -111,13 +118,13 @@ public class MasterSlaveEntry { } public RFuture setupMasterEntry(InetSocketAddress address, URI uri) { - RedisClient client = connectionManager.createClient(NodeType.MASTER, address, uri); + RedisClient client = connectionManager.createClient(NodeType.MASTER, address, uri, sslHostname); return setupMasterEntry(client); } public RFuture setupMasterEntry(URI address) { - RedisClient client = connectionManager.createClient(NodeType.MASTER, address); + RedisClient client = connectionManager.createClient(NodeType.MASTER, address, sslHostname); return setupMasterEntry(client); } @@ -404,12 +411,12 @@ public class MasterSlaveEntry { } private RFuture addSlave(InetSocketAddress address, URI uri, final boolean freezed, final NodeType nodeType) { - RedisClient client = connectionManager.createClient(NodeType.SLAVE, address, uri); + RedisClient client = connectionManager.createClient(NodeType.SLAVE, address, uri, sslHostname); return addSlave(client, freezed, nodeType); } private RFuture addSlave(URI address, final boolean freezed, final NodeType nodeType) { - RedisClient client = connectionManager.createClient(NodeType.SLAVE, address); + RedisClient client = connectionManager.createClient(NodeType.SLAVE, address, sslHostname); return addSlave(client, freezed, nodeType); } diff --git a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java index 9675a1683..bd0d6148f 100644 --- a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java @@ -67,7 +67,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { initTimer(this.config); for (URI addr : cfg.getNodeAddresses()) { - RFuture connectionFuture = connectToNode(cfg, addr, null); + RFuture connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); connectionFuture.awaitUninterruptibly(); RedisConnection connection = connectionFuture.getNow(); if (connection == null) { @@ -119,7 +119,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { return; } - RFuture connectionFuture = connectToNode(cfg, addr, null); + RFuture connectionFuture = connectToNode(cfg, addr, null, addr.getHost()); connectionFuture.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { diff --git a/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java b/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java index e9ca00f51..8a607da2e 100755 --- a/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java @@ -90,7 +90,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { this.sentinelResolver = resolverGroup.getResolver(getGroup().next()); for (URI addr : cfg.getSentinelAddresses()) { - RedisClient client = createClient(NodeType.SENTINEL, addr, this.config.getConnectTimeout(), this.config.getRetryInterval() * this.config.getRetryAttempts()); + RedisClient client = createClient(NodeType.SENTINEL, addr, this.config.getConnectTimeout(), this.config.getRetryInterval() * this.config.getRetryAttempts(), null); try { RedisConnection connection = client.connect(); if (!connection.isActive()) { @@ -261,7 +261,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { } RedisClient client = iterator.next(); - RFuture connectionFuture = connectToNode(null, null, client); + RFuture connectionFuture = connectToNode(null, null, client, null); connectionFuture.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { @@ -433,7 +433,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { return RedissonPromise.newSucceededFuture(null); } - client = createClient(NodeType.SENTINEL, addr, c.getConnectTimeout(), c.getRetryInterval() * c.getRetryAttempts()); + client = createClient(NodeType.SENTINEL, addr, c.getConnectTimeout(), c.getRetryInterval() * c.getRetryAttempts(), null); RedisClient oldClient = sentinels.putIfAbsent(key, client); if (oldClient != null) { return RedissonPromise.newSucceededFuture(null); diff --git a/redisson/src/main/java/org/redisson/misc/URIBuilder.java b/redisson/src/main/java/org/redisson/misc/URIBuilder.java index f25511e7d..3a9476d2f 100644 --- a/redisson/src/main/java/org/redisson/misc/URIBuilder.java +++ b/redisson/src/main/java/org/redisson/misc/URIBuilder.java @@ -17,34 +17,44 @@ package org.redisson.misc; import java.net.InetSocketAddress; import java.net.URI; +import java.util.regex.Pattern; /** * * @author Rui Gu (https://github.com/jackygurui) */ public class URIBuilder { - + + private static final Pattern ipv4Pattern = Pattern.compile("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])", Pattern.CASE_INSENSITIVE); + private static final Pattern ipv6Pattern = Pattern.compile("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}", Pattern.CASE_INSENSITIVE); + public static URI create(String uri) { URI u = URI.create(uri); - //Let's assuming most of the time it is OK. + // Let's assuming most of the time it is OK. if (u.getHost() != null) { return u; } - String s = uri.substring(0, uri.lastIndexOf(":")) - .replaceFirst("redis://", "") - .replaceFirst("rediss://", ""); - //Assuming this is an IPv6 format, other situations will be handled by - //Netty at a later stage. + String s = uri.substring(0, uri.lastIndexOf(":")).replaceFirst("redis://", "").replaceFirst("rediss://", ""); + // Assuming this is an IPv6 format, other situations will be handled by + // Netty at a later stage. return URI.create(uri.replace(s, "[" + s + "]")); } + public static boolean isValidIP(String host) { + if (ipv4Pattern.matcher(host).matches()) { + return true; + } + + return ipv6Pattern.matcher(host).matches(); + } + public static boolean compare(InetSocketAddress entryAddr, URI addr) { if (((entryAddr.getHostName() != null && entryAddr.getHostName().equals(addr.getHost())) || entryAddr.getAddress().getHostAddress().equals(addr.getHost())) - && entryAddr.getPort() == addr.getPort()) { + && entryAddr.getPort() == addr.getPort()) { return true; } return false; } - + }