?

Log in

No account? Create an account

IPV6, MySQL, yet more...

« previous entry | next entry »
Dec. 30th, 2007 | 02:24 am

I've refactored mysql so that I can enable IPV6 support. After some good feedback on the last release I modified everything to make dual stack support work (and got rid of the resolve locks in the process).

The tree is now public:
http://mysql.bkbits.net:8080/mysql-6.0-ipv6/

There are some issues with Windows that I need to resolve (which has more to do with broken Windows setups then problems in the code).

Instructions on how to build from Bitkeeper from here:
http://dev.mysql.com/doc/refman/6.0/en/installing-source-tree.html

I still need to change the family defines to allow the IPV6 pieces to work, but that is just a couple of lines. I wanted to get the refactoring out of the way before I did that.

The tree is an Alpha, so don't even think about putting this into production environment (as always, I recommend people stick to GA releases for production usage).

Link | Leave a comment | Share

Comments {6}

(no subject)

from: arekm
date: Jan. 3rd, 2008 02:20 pm (UTC)
Link

netinet/in.h provided IN6_ARE_ADDR_EQUAL() macro is probably nicer than doing memcmp()


"/* We only look at the first item (something to think about changing in the future) */"
Just loop over all addressess returned by getaddrinfo() until some success. Thing about case when there is mysql-server.somewhere.org which has both AAAA and A addresses but you are trying to connect to it from ipv4-only host. getaddrinfo() will still return both, AAAA and A addresses and you won't be able to connect.

I see the same problem for binding. Always do the for() loop iterating over getaddrinfo() returned stuff. There is also one getaddrinfo flag which could help: AI_ADDRCONFIG but there are some problems with it (not perfect, not implemented everywhere).

To make world even more complicated there is a socket option: IPV6_V6ONLY. Newer Linux and BSD systems support it. Linux has it off by default, not sure about BSD. Older Linux system don't support this option at all.

I don't see v4-mapped handling (so 127.0.0.1 isn't equal to ::ffff:127.0.0.1 in server ACLs etc)?
The other thing needed is CIDR prefix handling for ipv6 (+ special cases for v4-mapped addresses).

(In existing v6 apps v4-mapped are usually converted to pure v4 addresses by stripping ::ffff: internally to avoid 127.0.0.1 != ::ffff:127.0.0.1 problem)

Reply | Thread

Brian "Krow" Aker

(no subject)

from: krow
date: Jan. 4th, 2008 01:50 am (UTC)
Link

Thank you for the feedback.

Your message pushed me over the edge on whether to map ::ffff:127.0.0.1 to 127.0.0.1. I've just unpulled in the repository and rolled back. I will commit a change in a little while which will do exactly that.

On two platforms I found that IN6_ARE_ADDR_EQUAL is just mapped to memcmp(). Windows also lacks the Macro for it (Windows also lacks AI_ADDRCONFIG in most cases).

On the for() loop, I am going to fix that with another commit.


Reply | Parent | Thread

(no subject)

from: arekm
date: Jan. 4th, 2008 02:30 pm (UTC)
Link

hints.ai_family = AF_UNSPEC instead of leaving it 0-initialized (on Linux AF_UNSPEC is zero but not sure if this is the case on other platforms).

About that v4-mapped crap. I usually handle that by adding little helper convert_v4mapped(struct sockaddr_storage * ss) which basically does if (IN6_IS_ADDR_V4MAPPED(ss) then convert struct from AF_INET6 to pure AF_INET and using it when needed.

ps.
::ffff:127.0.0.1
can be also written as
0:0:0:0:0:ffff:7f00:1
and so on so string based handling needs normalization function, too (like getaddrinfo+getnameinfo NI_NUM..). Adding CIDR handling to that makes things very messy.

Reply | Parent | Thread

Brian "Krow" Aker

(no subject)

from: krow
date: Jan. 4th, 2008 07:16 pm (UTC)
Link

What does your convert_v4mapped() do? It modifies the structure in place? Not worried about the structure being different, on different platforms?

Leaving ai.family null seems to be the portable solution. I found comments on it by Ulrich, and when running the code within the MySQL build farm, it has been the only portable way to get things going.

I still have a bug on getnameinfo() for Solaris. It constantly returns "non-recoverable name resolution failure".

Reply | Parent | Thread

(no subject)

from: arekm
date: Jan. 4th, 2008 07:35 pm (UTC)
Link

Yes, it converted struct (address + port). in_addr and in6_addr are well defined (rfc2553 for in6_addr) so it should work fine unless there is some crazy implementation that does things by ignoring rfc.

Relying on ai_family zero == AF_UNSPEC isn't "portable". It's just a luck. What if some platform has AF_UNSPEC 999 ? ;-) (Don't know that Urlich comment anyway).

Can't help with solaris problem but that getaddrinfo() source code is available so it should be easy to track down why this happens.

Reply | Parent | Thread

Brian "Krow" Aker

(no subject)

from: krow
date: Jan. 4th, 2008 09:24 pm (UTC)
Link

Apache has this snip of code:

    if (sockaddr->family == AF_INET6 &&
        IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
        struct sockaddr_in tmpsa;
        tmpsa.sin_family = AF_INET;
        tmpsa.sin_port = 0;
        tmpsa.sin_addr.s_addr = ((apr_uint32_t *)sockaddr->ipaddr_ptr)[3];
#ifdef SIN6_LEN
        tmpsa.sin_len = sizeof(tmpsa);



Alignment/structures seem to be platform dependent. At least OSX and Solaris are different.

Reply | Parent | Thread