# HG changeset patch # User michaelm # Date 1429623417 -3600 # Node ID 2a735486f81288c62a99edb801f7395009f4a47e # Parent ad35f9986f75657b88b9200e09a9abfbbf62b8a8 6991580: IPv6 Nameservers in resolv.conf throws NumberFormatException Reviewed-by: michaelm, andrew Contributed-by: sgehwolf@redhat.com diff -r ad35f9986f75 -r 2a735486f812 jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java --- a/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java Tue Apr 21 14:23:58 2015 +0100 +++ b/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java Tue Apr 21 14:36:57 2015 +0100 @@ -85,6 +85,15 @@ if (val.charAt(0) == '#' || val.charAt(0) == ';') { break; } + if ("nameserver".equals(keyword)) { + if (val.indexOf(':') >= 0 && + val.indexOf('.') < 0 && // skip for IPv4 literals with port + val.indexOf('[') < 0 && + val.indexOf(']') < 0 ) { + // IPv6 literal, in non-BSD-style. + val = "[" + val + "]"; + } + } ll.add(val); if (--maxvalues == 0) { break; diff -r ad35f9986f75 -r 2a735486f812 jdk/test/javax/naming/dns/IPv6NameserverPlatformParsingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/naming/dns/IPv6NameserverPlatformParsingTest.java Tue Apr 21 14:36:57 2015 +0100 @@ -0,0 +1,81 @@ +import java.lang.reflect.Field; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.NamingManager; + +import com.sun.jndi.dns.DnsContext; + +/** + * @test + * @bug 6991580 + * @summary IPv6 Nameservers in resolv.conf throws NumberFormatException + * @run main/manual IPv6NameserverPlatformParsingTest + * + * In order to run this test be sure to place, for example, the following + * snippet into your platform's {@code /etc/resolv.conf}: + *
+ * nameserver 127.0.0.1
+ * nameserver 2001:4860:4860::8888
+ * nameserver [::1]:5353
+ * nameserver 127.0.0.1:5353
+ * 
+ * + * Then, run this test as manual jtreg test. + * + * @author Severin Gehwolf + * + */ +public class IPv6NameserverPlatformParsingTest { + + private static boolean foundIPv6 = false; + + public static void main(String[] args) { + Hashtable env = new Hashtable<>(); + env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.dns.DnsContextFactory.class.getName()); + + String[] servers; + try { + Context ctx = NamingManager.getInitialContext(env); + if (!com.sun.jndi.dns.DnsContextFactory.platformServersAvailable()) { + throw new RuntimeException("FAIL: no platform servers available, test does not make sense"); + } + DnsContext context = (DnsContext)ctx; + servers = getServersFromContext(context); + } catch (NamingException e) { + throw new RuntimeException(e); + } + for (String server: servers) { + System.out.println("DEBUG: 'nameserver = " + server + "'"); + if (server.indexOf(':') >= 0 && server.indexOf('.') < 0) { + System.out.println("DEBUG: ==> Found IPv6 address in servers list: " + server); + foundIPv6 = true; + } + } + try { + new com.sun.jndi.dns.DnsClient(servers, 100, 1); + } catch (NumberFormatException e) { + throw new RuntimeException("FAIL: Tried to parse non-[]-encapsulated IPv6 address.", e); + } catch (Exception e) { + throw new RuntimeException("ERROR: Something unexpected happened."); + } + if (!foundIPv6) { + // This is a manual test, since it requires changing /etc/resolv.conf on Linux/Unix + // platforms. See comment as to how to run this test. + throw new RuntimeException("ERROR: No IPv6 address returned from platform."); + } + System.out.println("PASS: Found IPv6 address and DnsClient parsed it correctly."); + } + + private static String[] getServersFromContext(DnsContext context) { + try { + Field serversField = DnsContext.class.getDeclaredField("servers"); + serversField.setAccessible(true); + return (String[])serversField.get(context); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +}