Bug #46336 | Backport IPv6 bug fixes to cluster-7.0 | ||
---|---|---|---|
Submitted: | 22 Jul 2009 9:39 | Modified: | 28 Aug 2009 13:36 |
Reporter: | Frazer Clement | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Cluster: Cluster (NDB) storage engine | Severity: | S2 (Serious) |
Version: | mysql-5.1-telco-7.0 | OS: | Any |
Assigned to: | Frazer Clement | CPU Architecture: | Any |
[22 Jul 2009 9:39]
Frazer Clement
[24 Jul 2009 0:18]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/79208 2946 Frazer Clement 2009-07-23 Bug#46336 Backport IPv6 bug fixes to cluster-7.0 This patch contains the fixes to the mysql-5.4 bugs mentioned in the bug report, plus a couple of other fixes. Passes MTR testcases and manual testing including replication. Appears to resolve issues with skip_name_resolve. Appears to resolve issues with V4MAPPED addresses in ACLs Extra fix information available in bug report. modified: configure.in include/config-win.h scripts/mysql_system_tables_data.sql sql/hostname.cc sql/mysql_priv.h sql/sql_acl.cc sql/sql_connect.cc vio/viosocket.c
[24 Jul 2009 9:41]
Frazer Clement
Extra patches to original bug fixes : --- /home/frazer/saved_diffs/hostname.cc-alik 2009-07-22 17:26:02.000000000 +0100 +++ sql/hostname.cc 2009-07-22 17:30:12.000000000 +0100 @@ -418,6 +418,12 @@ static inline bool is_ip_loopback(const { /* Check for IPv6 ::1. */ struct in6_addr *ip6_addr= &((struct sockaddr_in6 *) ip)->sin6_addr; + if (IN6_IS_ADDR_V4MAPPED(ip6_addr)) + { + /* Check for ::ffff:127.0.0.1 */ + uint32 relevantWord= *(((uint32*)(&ip6_addr->s6_addr))+ 3); + return (ntohl(relevantWord) == INADDR_LOOPBACK); + } return IN6_IS_ADDR_LOOPBACK(ip6_addr); } #endif /* HAVE_STRUCT_IN6_ADDR */ --- /home/frazer/tmp/hostname.cc 2009-07-23 11:04:07.000000000 +0100 +++ sql/hostname.cc 2009-07-23 11:08:53.000000000 +0100 @@ -102,7 +102,12 @@ static void get_ip_string(const struct s #endif /* HAVE_STRUCT_IN6_ADDR */ default: - DBUG_ASSERT(FALSE); + /* In some cases, the socket address is unset - in this + * case we output an empty pseudo-IPv4 address + */ + DBUG_ASSERT(sizeof("0.0.0.0") < ip_str_size); + my_snprintf(ip_str, ip_str_size, "0.0.0.0"); + break; } } @@ -225,7 +230,9 @@ static void hostname_cache_get_key(const } default: - DBUG_ASSERT(FALSE); + /* In some cases, the sockaddr is not set, for those we return + * an 'empty' key + */ break; }
[28 Jul 2009 11:43]
Frazer Clement
New patch for bug#45584 - fix to this bug will be reapplied...
[29 Jul 2009 5:56]
Sveta Smirnova
Bug #46440 was marked as duplicate of this one.
[29 Jul 2009 12:09]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/79520 2954 Frazer Clement 2009-07-29 Bug#46336 Backport IPv6 bug fixes to cluster-7.0 This patch contains the fixes to the mysql-5.4 bugs mentioned in the bug report. Passes MTR testcases and manual testing including replication. Appears to resolve issues with skip_name_resolve. Appears to resolve issues with V4MAPPED addresses in ACLs Extra fix information available in bug report. modified: configure.in include/config-win.h scripts/mysql_system_tables_data.sql sql/hostname.cc sql/mysql_priv.h sql/sql_acl.cc sql/sql_connect.cc vio/viosocket.c
[30 Jul 2009 18:54]
Will Murnane
I submitted bug #46440, and was pointed in the direction of this thread. I applied the first patch listed here (not having seen the other patch), and things still weren't working. I added the following code to diagnose what was going on, and recompiled with debugging enabled: diff -ru mysql-cluster-gpl-7.0.6-orig/sql/sql_connect.cc mysql-cluster-gpl-7.0.6-new/sql/sql_connect.cc --- mysql-cluster-gpl-7.0.6-orig/sql/sql_connect.cc Thu Jul 30 14:47:24 2009 +++ mysql-cluster-gpl-7.0.6-new/sql/sql_connect.cc Wed Jul 29 17:54:54 2009 @@ -655,6 +655,7 @@ /* The value to which 'ip' is set here, is useless */ if (vio_peer_addr(net->vio, ip, &thd->peer_port, NI_MAXHOST)) { +DBUG_PRINT("info", ("one")); my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); return 1; } @@ -663,6 +664,7 @@ if (get_client_ip_address((const struct sockaddr *) &net->vio->remote, net->vio->addrLen, ip, sizeof (ip))) { +DBUG_PRINT("info", ("two")); my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); return 1; } @@ -677,6 +679,7 @@ if (ip_to_hostname(&net->vio->remote, &thd->main_security_ctx.host, &connect_errors)) { +DBUG_PRINT("info", ("three")); my_error(ER_BAD_HOST_ERROR, MYF(0), ip); return 1; } Then I saw output like this from "mysql --user=mysql -#d": login_connection: info: two So I added the following additional code: diff -ru mysql-cluster-gpl-7.0.6-orig/sql/hostname.cc mysql-cluster-gpl-7.0.6-new/sql/hostname.cc --- mysql-cluster-gpl-7.0.6-orig/sql/hostname.cc Thu Jul 30 14:47:24 2009 +++ mysql-cluster-gpl-7.0.6-new/sql/hostname.cc Wed Jul 29 18:15:23 2009 @@ -143,9 +143,32 @@ } #endif /* HAVE_STRUCT_IN6_ADDR */ - return getnameinfo(resolving_addr, resolving_addr_length, + int rval = getnameinfo(resolving_addr, resolving_addr_length, ip_buffer, ip_buffer_size, NULL, 0, - NI_NUMERICHOST) != 0; + NI_NUMERICHOST); +int e = errno; + + char foo[1000]; + switch (rval){ +case EAI_AGAIN: + strcpy(foo, "The name could not be resolved at this time. Future attempts may succeed."); +case EAI_BADFLAGS: + strcpy(foo, "The flags had an invalid value."); +case EAI_FAIL: + strcpy(foo, "A non-recoverable error occurred."); +case EAI_FAMILY: + strcpy(foo, "The address family was not recognized or the address length was invalid for the specified family."); +case EAI_MEMORY: + strcpy(foo, "There was a memory allocation failure."); +case EAI_NONAME: + strcpy(foo, "The name does not resolve for the supplied parameters. NI_NAMEREQD is set and the host's name cannot be located, or both nodename and servname were null."); +case EAI_OVERFLOW: + strcpy(foo, "An argument buffer overflowed. The buffer pointed to by the node argument or the service argument was too small."); +case EAI_SYSTEM: + sprintf(foo, "A system error occurred. The error code can be found in errno: %s. ", strerror(e)); + } + DBUG_PRINT("info", ("Return val is %d (%s)", rval, foo)); + return rval != 0; } /** Now, when I make a connection, I see this: login_connection: info: New connection received on TCP/IP (22) vio_peer_addr: enter: sd: 22 vio_peer_addr: exit: addr: ::ffff:130.85.95.252 login_connection: info: Return val is 4 (A system error occurred. The error code can be found in errno: Error 0. ) login_connection: info: two I'm going to try with the second patchset mentioned here, but I wanted to point out that this doesn't seem to be solved on Solaris.
[30 Jul 2009 20:57]
Sveta Smirnova
Bug #46476 was marked as duplicate of this one.
[31 Jul 2009 8:37]
Kaloyan Kovachev
I have applied _only_ the changes from http://lists.mysql.com/commits/76095 (skipping the windows part which is ifdef-ed in either case) and can confirm that the problem is resolved. As a side note: IPv6 is disabled in the kernel, so i am unable to test with IPv6.
[5 Aug 2009 14:38]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/80170 2961 Frazer Clement 2009-08-05 Bug#46336 Backport IPv6 bug fixes to cluster 7.0 modified: configure.in include/config-win.h scripts/mysql_system_tables_data.sql sql/hostname.cc sql/mysql_priv.h sql/sql_acl.cc sql/sql_connect.cc vio/viosocket.c
[5 Aug 2009 15:42]
Frazer Clement
Patch pushed to 7.0.7 and 7.1.0
[5 Aug 2009 17:56]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/80205 2962 Frazer Clement 2009-08-05 Bug#46336 - fix compiler warnings modified: sql/hostname.cc
[5 Aug 2009 18:06]
Will Murnane
I've found the problem on Solaris. getnameinfo() *requires* that the salen argument match the actual size of the struct sockaddr_storage passed to it. Thus, one needs to check if the argument to ip_to_hostname is AF_INET or AF_INET6 and set the addrLen appropriately. The patch that I proposed to bug #46440 must thus be changed to this: diff -ru mysql-cluster-gpl-7.0.6/sql/hostname.cc mysql-cluster-gpl-7.0.6-mod//sql/hostname.cc --- mysql-cluster-gpl-7.0.6/sql/hostname.cc Tue May 26 10:34:43 2009 +++ mysql-cluster-gpl-7.0.6-mod//sql/hostname.cc Tue Jul 28 17:22:14 2009 @@ -137,6 +149,19 @@ char * ip_to_hostname(struct sockaddr_storage *in, int addrLen, uint *errors) { char *name= NULL; + if (in->ss_family == AF_INET6) + { + if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6*)in)->sin6_addr)) + { + struct sockaddr_in foo; + bzero(&foo, sizeof(struct sockaddr)); + foo.sin_family = AF_INET; + foo.sin_port = ((struct sockaddr_in6*)in)->sin6_port; + memcpy(&foo.sin_addr.s_addr, &((struct sockaddr_in6*)in)->sin6_addr.s6_addr[12], 4); + in = (struct sockaddr_storage*)&foo; + addrLen = sizeof(struct sockaddr); + } + } struct addrinfo hints,*res_lst= NULL,*t_res; int gxi_error; @@ -149,7 +172,7 @@ /* Historical comparison for 127.0.0.1 */ gxi_error= getnameinfo((struct sockaddr *)in, addrLen, hostname_buff, NI_MAXHOST, - NULL, 0, NI_NUMERICHOST); + NULL, 0, 0); if (gxi_error) { DBUG_PRINT("error",("getnameinfo returned %d", gxi_error)); @@ -242,8 +265,16 @@ /* Check that 'getaddrinfo' returned the used ip */ for (t_res= res_lst; t_res; t_res=t_res->ai_next) { - if (!memcmp(&(t_res->ai_addr), in, - sizeof(struct sockaddr_storage) ) ) + if ((in->ss_family == t_res->ai_addr->sa_family) && + (((in->ss_family == AF_INET) && + (((struct sockaddr_in*)in)->sin_addr.s_addr == + ((struct sockaddr_in*)t_res->ai_addr)->sin_addr.s_addr)) + || + ((in->ss_family == AF_INET6) && + (!memcmp( + (void*)&((struct sockaddr_in6*)in)->sin6_addr, + (void*)&((struct sockaddr_in6*)t_res->ai_addr)->sin6_addr, + sizeof(struct in6_addr)))))) { add_hostname(in,name); freeaddrinfo(res_lst); I am now using this modified patch and have noticed no problems with it. We don't have ipv6 connectivity, though, so it's very possible that it fails with ipv6 enabled. More testing is required. The notable change is that addrLen is set to sizeof(struct sockaddr) inside the first pair of if statements. Failure to do this gives EAI_SYSTEM with errno set to 0, as seen in the debug statements I printed earlier in this thread: login_connection: info: Return val is 4 (A system error occurred. The error code can be found in errno: Error 0. ) This behavior can be seen in the OpenSolaris code cross-reference at http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libsocket/inet/getnamein... line 129. This is the OpenSolaris rather than the Solaris codebase, but the behavior appears to be the same. Frazer Clement pointed out to me that I omitted the "break" statements from my debugging code, but since the last case is the one that is printed, the output is in fact still correct. I also tried the second patch in this thread (from 29 July), but found the same EAI_SYSTEM with errno==0 behavior. I'm not sure why, as it looks like everything is done right. In any case, it seems that 7.0.6 plus the patch listed above does the right thing for me. I'll re-test with 7.0.7 when it becomes available and report back.
[11 Aug 2009 15:59]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/80599 2953 Frazer Clement 2009-08-11 Bug#46336 Backport IPv6 bug fixes to cluster-7.0 - Patch back of 'official' IPv6 fixes from mysql-azalea e.g. fixes for bugs 45584, 43006 and 45606 - Minor modification to get_peername call to match different Windows-specific code in mysql-5.1-telco-7.0 - Includes fix for Solaris getnameinfo() address length issue. modified: CMakeLists.txt configure.in include/violite.h mysql-test/t/skip_name_resolve.test sql/hostname.cc sql/mysql_priv.h sql/sql_connect.cc vio/viosocket.c
[12 Aug 2009 9:10]
Frazer Clement
Patch fixes ACL issue whereby IPv4 addresses in GRANT tables have to be entered in IPV4 mapped form (e.g. x.y.z.a has to be entered as ::ffff:x.y.z.a).
[28 Aug 2009 13:36]
Jon Stephens
Thank you for your bug report. This issue has already been fixed in the latest released version of that product, which you can download at http://www.mysql.com/downloads/ Since this Bug report serves only as a 'wrapper' for others, see the following bug reports for documentation info: BUG#38247 BUG#43006 BUG#45283 BUG#45584 BUG#45606