You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by aw...@apache.org on 2022/10/06 18:03:00 UTC

[cassandra] 01/01: Update StorageService.getNativeaddress to handle IPv6 addresses

This is an automated email from the ASF dual-hosted git repository.

aweisberg pushed a commit to branch cassandra-17945-4.0-guest
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit c50ab514114415973cb6edc7a5c7e914528e812f
Author: Andy Tolbert <68...@users.noreply.github.com>
AuthorDate: Tue Oct 4 12:02:26 2022 -0500

    Update StorageService.getNativeaddress to handle IPv6 addresses
    
    StorageService.getNativeaddress does not currently correctly handle
    IPv6 addresses correctly when NATIVE_ADDRESS_AND_PORT are not present in
    that it simply concatenates the IP address with the default native port,
    e.g.:
    
    0:0:0:0:0:0:5a:3:9042
    
    This does not parse into an InetSocketAddress as the address and port
    can't be disambiguated.
    
    Such a case would usually be present when there are 3.x nodes present in a
    cluster with 4.0 nodes.
    
    Change updates RPC_ADDRESS and else case to create InetAddressAndPort instances
    with DatabaseDescriptor.getNativeTransportPort and returns the
    getHostAddress(withPort) which properly bracket encodes the address,
    e.g.:
    
    [0:0:0:0:0:0:5a:3]:9042
    
    which can be parsed as an InetSocketAddress.
---
 .../apache/cassandra/service/StorageService.java   | 27 +++++++++++++++++++---
 .../service/StorageServiceServerTest.java          | 22 ++++++++++++++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index 7e70e4ce20..b70347a301 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -1975,10 +1975,31 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
                 throw new RuntimeException(e);
             }
         }
-        else if (Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RPC_ADDRESS) == null)
-            return endpoint.address.getHostAddress() + ":" + DatabaseDescriptor.getNativeTransportPort();
         else
-            return Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RPC_ADDRESS).value + ":" + DatabaseDescriptor.getNativeTransportPort();
+        {
+             final String ipAddress;
+             // If RPC_ADDRESS present in gossip for this endpoint use it.  This is expected for 3.x nodes.
+             if (Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RPC_ADDRESS) != null)
+             {
+                 ipAddress = Gossiper.instance.getEndpointStateForEndpoint(endpoint).getApplicationState(ApplicationState.RPC_ADDRESS).value;
+             }
+             else
+             {
+                 // otherwise just use the IP of the endpoint itself.
+                 ipAddress = endpoint.getHostAddress(false);
+             }
+
+             // include the configured native_transport_port.
+             try
+             {
+                 InetAddressAndPort address = InetAddressAndPort.getByNameOverrideDefaults(ipAddress, DatabaseDescriptor.getNativeTransportPort());
+                 return address.getHostAddress(withPort);
+             }
+             catch (UnknownHostException e)
+             {
+                 throw new RuntimeException(e);
+             }
+         }
     }
 
     public Map<List<String>, List<String>> getRangeToRpcaddressMap(String keyspace)
diff --git a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java
index b5ddd35514..60bed4c64d 100644
--- a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java
+++ b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java
@@ -641,6 +641,28 @@ public class StorageServiceServerTest
         assertEquals("127.0.0.3:666", StorageService.instance.getNativeaddress(internalAddress, true));
     }
 
+    @Test
+    public void testGetNativeAddressIPV6() throws Exception
+    {
+        // Ensure IPv6 addresses are properly bracketed in RFC2732 (https://datatracker.ietf.org/doc/html/rfc2732) format when including ports.
+        // See https://issues.apache.org/jira/browse/CASSANDRA-17945 for more context.
+        String internalAddressIPV6String = "[0:0:0:0:0:0:0:3]:666";
+        InetAddressAndPort internalAddressIPV6 = InetAddressAndPort.getByName(internalAddressIPV6String);
+        Gossiper.instance.addSavedEndpoint(internalAddressIPV6);
+
+        //Default to using the provided address with the configured port
+        assertEquals("[0:0:0:0:0:0:0:3]:" + DatabaseDescriptor.getNativeTransportPort(), StorageService.instance.getNativeaddress(internalAddressIPV6, true));
+
+        VersionedValue.VersionedValueFactory valueFactory =  new VersionedValue.VersionedValueFactory(Murmur3Partitioner.instance);
+        //If RPC_ADDRESS is present with an IPv6 address, we should properly bracket encode the IP with the configured port.
+        Gossiper.instance.getEndpointStateForEndpoint(internalAddressIPV6).addApplicationState(ApplicationState.RPC_ADDRESS, valueFactory.rpcaddress(InetAddress.getByName("0:0:0:0:0:0:5a:3")));
+        assertEquals("[0:0:0:0:0:0:5a:3]:" + DatabaseDescriptor.getNativeTransportPort(), StorageService.instance.getNativeaddress(internalAddressIPV6, true));
+
+        //If we have the address and port in gossip use that
+        Gossiper.instance.getEndpointStateForEndpoint(internalAddressIPV6).addApplicationState(ApplicationState.NATIVE_ADDRESS_AND_PORT, valueFactory.nativeaddressAndPort(InetAddressAndPort.getByName("[0:0:0:0:0:0:5c:3]:8675")));
+        assertEquals("[0:0:0:0:0:0:5c:3]:8675", StorageService.instance.getNativeaddress(internalAddressIPV6, true));
+    }
+
     @Test
     public void testAuditLogEnableLoggerNotFound() throws Exception
     {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org