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:13 UTC

[cassandra] branch cassandra-17945-trunk-guest created (now 833de7bb94)

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

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


      at 833de7bb94 Update StorageService.getNativeaddress to handle IPv6 addresses

This branch includes the following new commits:

     new 833de7bb94 Update StorageService.getNativeaddress to handle IPv6 addresses

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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


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

Posted by aw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 833de7bb9460c1de2e678cd1bddd315ef8b40cfb
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 a8b27bfc22..965d19509b 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -2158,10 +2158,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.getAddress().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 c8739ae1bc..119b8104d4 100644
--- a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java
+++ b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java
@@ -572,6 +572,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