Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 Cluster connection errors #1422

Open
lewisvive opened this issue Apr 6, 2020 · 9 comments
Open

IPv6 Cluster connection errors #1422

lewisvive opened this issue Apr 6, 2020 · 9 comments

Comments

@lewisvive
Copy link

lewisvive commented Apr 6, 2020

I've got an IPv6 only Redis cluster. The client connects fine to any hash slots on the existing node, but if it needs to go to another node it fails. Have proven the network is fine as another client will connect fine not in .Net code. Odd how the port is in the endpoint.

Connection string was "[abcd:1234:3:a::a]:7000,[abcd:1234:3:a::b]:7000"

The GetEndpoints has 8 endpoints when there is only 6 in the cluster (3 master, 3 slave).

'Endpoint [abcd:1234:3:a::c:7000]:0 serving hashslot 6438 is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. IOCP:

@lewisvive
Copy link
Author

Have worked out issue. It's to do with cluster nodes and the IPv6 Addresses not having braces around in Redis.

So our cluster list is

abcd:1234:3:a::a:7000@17000
abcd:1234:3:a::b:7000@17000
abcd:1234:3:a::c:7000@17000
abcd:1234:3:a::a:7001@17001
abcd:1234:3:a::b:7001@17001
abcd:1234:3:a::c:7001@17001

And it's parsing in TryEndpoint that as [abcd:1234:3:a::c:7001]:0

I've done a temp fix for my issue to get working by adjusting TryEndpoint

if (firstColonIndex != lastColonIndex)
                    {
                        // IPv6 ::1
                        //addressPart = addressWithPort;
                        portPart = addressWithPort.Substring(lastColonIndex + 1);
                        addressPart = addressWithPort.Substring(0, lastColonIndex);
                    }

@mgravell
Copy link
Collaborator

mgravell commented Apr 6, 2020

You're right, this is a plain ol' bug.

Needs attention in both TryParseEndPoint and ToString(EndPoint) (with tests); marking up-for-grabs, but if nobody jumps on it I'll try and give it a go at some point. You're welcome to jump in yourself :)

@lewisvive
Copy link
Author

Are we happy to say that Redis cluster nodes will always return the port?

@lewisvive
Copy link
Author

Have adjusted it now :). ToString was OK as the Endpoint returned is in the correct form.

@mgravell
Copy link
Collaborator

mgravell commented Apr 6, 2020

where are those strings coming from? I may have been incorrect in my earlier statement; I'm concerned that we need to ensure that the strings are all entirely valid. Where are the strings coming from, exactly?

@lewisvive
Copy link
Author

lewisvive commented Apr 6, 2020

If you are running a v6 cluster. See below.

598b4e6db6c64e3ba7c149b3b2642ac3894863b8 2a06:4e80:3:a::a:7000@17000 master - 0 1586176873933 11 connected 0-5460
09fb56f110e72b2fb2569557ce89bc9f4836a9a0 2a06:4e80:3:a::c:7001@17001 slave 8891890bcd55303e6e678f60e996665be4ac3919 0 1586176874435 6 connected
c6d69a74b760f6b05552a4f47d94467a9d21feff 2a06:4e80:3:a::b:7001@17001 slave 598b4e6db6c64e3ba7c149b3b2642ac3894863b8 0 1586176874000 11 connected
8891890bcd55303e6e678f60e996665be4ac3919 2a06:4e80:3:a::b:7000@17000 master - 0 1586176873430 2 connected 5461-10922
f7c0914720764c18649719a7fff9dbdb85fa284c 2a06:4e80:3:a::a:7001@17001 slave 9b6a14db9e4d927937fb28b8ca4db6f19ed4e6d0 0 1586176873000 13 connected
9b6a14db9e4d927937fb28b8ca4db6f19ed4e6d0 2a06:4e80:3:a::c:7000@17000 myself,master - 0 1586176873000 13 connected 10923-16383

@mgravell
Copy link
Collaborator

mgravell commented Apr 6, 2020

OK; my thought here is that we should not consider this as a standard IP plus port syntax, as that is not a valid ip plus port syntax. Under RFC 3986, that should be [2a06:4e80:3:a::a]:7000, so: I propose that we don't treat it as that. I would not want to confuse our normal endpoint handling with this atypical case.

The cluster nodes documentation indicates that the format is ip:port@cport; as such, I propose that in this case we need different handling, i.e. strip this into ip, port and cport before trying to parse anything, taking the last colon into account, so in the case of 2a06:4e80:3:a::a:7000@17000, this would be:

  • ip = "2a06:4e80:3:a::a"
  • port = "7000"
  • cport = "17000"

and parse ip in isolation; to emphasize, we should absolutely not attempt to parse 2a06:4e80:3:a::a:7000 using any standard ip+port code, but something that is unique to this scenario.

/cc @antirez, just in case you want to think about whether the output of cluster nodes is wrong and it should be outputting "[2a06:4e80:3:a::a]:7000:17000" - however, I imagine that ship has sailed already.

@lewisvive
Copy link
Author

Ok, Let me have a re-jig and think differently about it.

@NiKiZe
Copy link

NiKiZe commented May 3, 2023

Think I'm seeing a similar issue
Calling ClientList gives clients with similar Raw data where we can see addr not having braces:
id=8897064 addr=fd40:8017:11:7032:7011:600:ac18:bc:54265 fd=60 name=i-230510-t age=1548 idle=40 flags=P db=0 sub=2 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=0 omem=0 tot-mem=20496 ow=0 owmem=0 events=r cmd=ping user=default numops=31

Here addr goes into Format.TryParseEndPoint and comes back empty/null

This is def. a Redis bug, however it is in production (Azure redis cache)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants