This article is by Yisheng Zhu, Hui Yang and Xiao Fu from IBM Developer community. The original title is “Developing ipv6-compatible Web applications using Java”.

1, the introduction

A few days ago, a group of friends discussed with me the problem that the IM server written with MobileIMSDK wanted to support IPv6. Because of the reasons, IPv4 has long been insufficient, now the domestic from the national level are vigorously promoting the popularity of IPv6, so including public institutions, state-owned enterprises, now do information suggestions, should consider IPv6 support.

I suddenly feel that this question is very difficult to answer, because for the common network communication program developers, the real IPv6 development and testing environment is not easy to obtain, so to really clarify the Java support for IPv6, can only rely on fragmentary information and web posts, may not be complete and prepared.

In theory, Java’s support for IPv6 is transparent to programmers, requiring little code-level processing. But how exactly does it support it? To what extent? What are the requirements for JDK versions? What are the requirements for the operating system? Wait a minute. I think it’s worth doing some more research.

This article will use easy to understand text, to explain the status of Java IPv6 support, including the technical principles, can use the API, and some can run demo code snippets, hoping to make you more intuitive understanding of Java IPv6 support.

** Due to limited space, this article assumes that you already know what IPv6 technology is. If you don’t know anything about it, it is recommended to read the vernacular introduction to IPv6.

2. Recommended materials

Detailed explanation of IPv6 Technology: Basic Concepts, Application Status, Technical Practice (Part I)

Detailed explanation of IPv6 Technology: Basic Concepts, Application Status, Technical Practice (Part 2)

3. Technical background

Currently, we are using IPv4, the second generation of the Internet, and its biggest problem is that the network address resources are limited. Theoretically, it can address 16 million networks and 4 billion hosts. However, with the adoption of class A, B, and C, the number of available network and host addresses has been reduced so much that the current IP address pool is almost exhausted. The shortage of network address has seriously restricted the application and development of the global Internet.

This figure is quoted from “Network Programming Lazy Introduction (11) : An Article to Understand what IPv6 is”

On the one hand, the number of address resources is limited. On the other hand, with the development of electronic technology and network technology, computer network will enter People’s Daily life. It is possible that every thing around needs to be connected to the global Internet. In this network space scarce environment, IPv6 came into being. It not only solves the problem of the number of network address resources, but also clears the obstacles for the number of devices connected to the Internet except computers.

If only IPv4 realize man-machine dialogue, IPv6 is extended to any dialogue between things, it can not only for human services, will also serve many hardware devices, such as household appliances, sensors, remote camera, car, etc., it will be an ever-present, everywhere the thorough real broadband network in every corner of society, The economic benefits will also be huge.

Of course, IPv6 isn’t perfect or a one-size-fits-all solution to all problems. IPv6 can only be improved in the process of development, and it cannot happen overnight. The transition takes time and cost, but in the long run, IPv6 is conducive to the sustainable and long-term development of the Internet. At present, the International Internet Organization has decided to set up two special working groups to formulate corresponding international standards.

4. Java support for IPv6

With IPv6 gaining more and more attention in the industry, Java has supported IPv6 on Linux and Solaris platforms since version 1.4. Windows platform support has been added since version 1.5.

Java encapsulates both IPv4 and IPv6 variations better than C++, and legacy code can support IPv6 natively without changing with the underlying implementation.

So how does Java support IPv6?

The Java network stack prioritizes whether the underlying system supports IPv6 and which IP stack system is used. If it is a dual-stack system, it creates an IPv6 socket directly (figure 1).

Figure 1 – Dual stack structure:

For the split stack system, Java creates two IPv4/v6 sockets (figure 2) :

  • 1) In the case of a TCP client program: once a socket connection is successful, the other socket is closed, and the IP protocol type used for this socket connection is fixed.
  • 2) For TCP server applications: IPv4/v6 sockets will always be reserved because the IP protocol used by the client cannot be expected;
  • 3) For UDP applications: either client or server programs, both sockets are reserved to complete communication.

Figure 2 – Split stack structure:

5. How to verify the IPv6 address

5.1 IPv6 Address Representation

The most significant change from IPv4 to IPv6 is the length of the network address. An IPv6 address is 128 bits in length and usually contains 32 hexadecimal numbers. However, it is usually written in eight groups of four hexadecimal numbers.

The following figure shows the composition of IPv6 addresses:

This figure is quoted from “Network Programming Lazy Introduction (11) : An Article to Understand what IPv6 is”

Such as:

  • 1) 2001:0 db8:85 a3:08 d3:1319:8 a2e: 0370:7344 is a valid IPv6 address. If all four digits are zero, they can be omitted;
  • 2) 2001:0 db8:85 a3:0000-1319:8 a2e: 0370-7344 is equivalent to 2001:0 db8:85 a3: : 1319:8 a2e: 0370-7344.

Following these rules, if more than two colons are omitted, they can be compressed to one, but this zero compression can occur only once in an address.

Therefore:

2001:0DB8:0000:0000:0000:0000:1428:57ab

2001:0DB8:0000:0000:0000::1428:57ab

2001:0DB8:0:0:0:0:1428:57ab

2001:0DB8:0::0:1428:57ab

2001:0DB8::1428:57ab

Both are valid addresses, and they are equivalent. But 2001:25 DE: : cade

Is illegal (because it makes it unclear how many all-zeros there are in each compression). The leading zeros can also be omitted, so: 2001:0db8:02de ::0e13 is equal to 2001:db8:2de ::e13.

5.2 IPv6 Address Verification

IPv4 addresses can be easily converted to IPv6 format.

For example: if the IPv4 an address for 135.75.43.52 (hex 0 x874b2b34), it can be converted into 0000:0000-0000:0000-0000:0000-874 b: 2 b34

Or :874B:2B34. You can also use a mixed ipv4-compatible address, so the address can be: :135.75.43.52.

IPv6 network address authentication is a necessary step for developing Java applications in IPv6 or migrating Java applications from an existing IPv4 environment to IPv6, especially for Java applications that provide a UI (user interface).

Fortunately, Java has added support for IPv6 network address verification since Java 1.5. The programmer can simply by call methods sun.net.util.IPAddressUtil.isIPv6LiteralAddress ()

To verify that a String input is a valid IPv6 network address.

In order to more deeply understand IPv6 network address step by step the specification, and verify the algorithm, the author refer to some of the material, including methods mentioned above sun.net.util.IPAddressUtil.isIPv6LiteralAddress () of the source code, As well as the regular expressions of some IPv6 network addresses circulating on the network, it is found that:

  • 1) There are many network address formats allowed by IPv6 protocol, with loose specifications (such as zero compression address, IPv4 mapped address, etc.), so the format of IPv6 network address changes greatly;
  • 2) Java validates IPv6 network addresses by cyclic matching of input characters, rather than using regular expressions. The matching process also relies on other Java methods.
  • 3) At present, the regular expressions for IPv6 network address verification circulating on the network can only cover part of the address format, and the expressions are long and difficult to read, which is very difficult to understand.

In order to make the verification method simple and easy to read, the author tries to use multiple regular expressions to verify the IPv6 network address after simply classifying the format.

This approach strikes a balance between generality (based on regular expressions, which makes it easy to implement in a variety of programming languages) and readability (each individual regular expression is relatively short). According to the test, all IPv6 network address formats are supported, and no exception has been found.

The following is the author of Java for IPv6 network address authentication method. This algorithm can be easily rewritten in other programming languages.

Demo Code 1 – Verify address:

//IPv6 address validator matches these IPv6 formats

. / / : : FFFF: when 8.9.221 | 2001:0 db8:85 a3:08 d3:1319:8 a2e: 0370-7344

/ / | : : 8 a2e: 70-7344 | 2001:0:03 0 db8:85 a3:08 d3:1319:8 a2e: 100.22.44.55

/ / | 2001:0 db8: : 8 a2e: 100.22.44.55 | : : 100.22.44.55 | FFFF: :

//And such addresses are invalid

/ / : : 8 a2e: 0:03 70:7344.4 | 2001: idb8: : 111:7.8.9.111 | : 2001:100. A2.44.55

/ / | : 2001: : 100.22.44.55

public static boolean isIPV6Format(String ip) {

ip = ip.trim();

//in many cases such as URLs, IPv6 addresses are wrapped by []

if(ip.substring(0, 1).equals(“[“) && ip.substring(ip.length()-1).equals(“]”))

ip = ip.substring(1, ip.length()-1);

return(1< Pattern.compile(“:”).split(ip).length)

//a valid IPv6 address should contains no less than 1,

// And no more than 7 “: “As separators

&& (Pattern.compile(“:”).split(ip).length <= 8)

// The address can be compressed, but “:: “can appear only once

&& (Pattern.compile(“::”).split(ip).length <= 2)

//if a compressed address

&& (Pattern.compile(“::”).split(ip).length == 2)

//if starts with “:: “– leading zeros are compressed

? (((ip.substring(0, 2).equals(“::”))

? The Pattern matches (” ^ : : [[\ \ da – f] {1, 4} {0, 4} (:)) (([\ \ da – f] {1, 4} (:) [\ \ da – f] {1, 4})

[\ \ | (da – f] {1, 4}) | ((\ \ d {1, 3}. {3} \ \ d {1, 3})), IP)”

: the Pattern matches (” ^ ([\ \ da – f] {1, 4} {1, 5} (: | : :))

(([\ \ da – f] {1, 4} (: | : 🙂 [\ \ da – f] {1, 4}) | ([\ \ da – f] {1, 4})

| ((\ \ d {1, 3}. {3} \ \ d {1, 3}, IP)))))”

//if ends with “::” – ending zeros are compressed

: ((ip.substring(ip.length()-2).equals(“::”))

? The Pattern matches (” ^ ([\ \ da – f] {1, 4} (: | : :)) {1, 7}, IP)”

: the Pattern matches (” ^ ([\ \ da – f] {1, 4} {6}) (([\ \ da – f] {1, 4}

: [\ \ da – f] {1, 4}) | ((\ \ d {1, 3}. {3} \ \ d {1, 3})) “, IP));

}}

6. How to normalize IPv6 addresses

In network program development, IP address is often used to identify a host, for example, to record the access records of end users. IPv6 has multiple representations such as zero-compressed addresses. Therefore, using IPv6 addresses as identifiers may cause some problems.

To avoid these problems, it is necessary to formalize IPv6 addresses before using them.

In addition to regular expressions, which we are familiar with, I found that the same effect can be achieved using a simple Java API.

Demo code 2 – Normalizing addresses:

InetAddress inetAddr = InetAddress.getByName(ipAddr);

ipAddr = inetAddr.getHostAddress();

System.out.println(ipAddr);

The inetaddress.getByName (String) method takes either a host name or an IP address String.

The address string ipAddr has been converted to its full form when we enter a valid IPv6 address for any information and fetch the host IP through the getHostAddress() method.

B: 2002-97 for example input e7aa: : 97 b: e7aa, after the above code execution, zero compression section will be restored, ipAddr into 2002:97 b: e7aa: 0:0:0:97 b: e7aa.

7. How do I obtain the local IPv6 address

Sometimes, in order to register a listener, a developer needs to use the native IPv6 address, which cannot be obtained simply by inetaddress.getLocalhost (). Because it’s possible to get special addresses like 0:0:0:0:0:0:0:1. With such an address, other servers will not be able to send notifications to the machine, so you must first filter out the addresses that are actually available. The following code does this by iterating through the addresses of the network interface until it finds one that matches the requirements.

Demo code 3 – Get the local IP address:

public static String getLocalIPv6Address() throws IOException {

InetAddress inetAddress = null;

Enumeration networkInterfaces = NetworkInterface

.getNetworkInterfaces();

outer:

while(networkInterfaces.hasMoreElements()) {

Enumeration inetAds = networkInterfaces.nextElement()

.getInetAddresses();

while(inetAds.hasMoreElements()) {

inetAddress = inetAds.nextElement();

//Check if it’s ipv6 address and reserved address

if(inetAddress instanceofInet6Address

&& !isReservedAddr(inetAddress)) {

break outer;

}

}

}

String ipAddr = inetAddress.getHostAddress();

// Filter network card No

int index = ipAddr.indexOf(‘%’);

if(index > 0) {

ipAddr = ipAddr.substring(0, index);

}

return ipAddr;

}

/ * *

* Check if it’s “local address” or “link local address” or “loopbackaddress”

* @param ip address

* @return result

* /

private static boolean isReservedAddr(InetAddress inetAddr) {

if(inetAddr.isAnyLocalAddress() || inetAddr.isLinkLocalAddress()

|| inetAddr.isLoopbackAddress()) {

return true;

}

return false;

}

To support IPv6, Java has added two subclasses of InetAddress: Inet4Address and Inet6Address.

These two subclasses are not normally used, but are useful when we need to deal with different IP protocols separately, where we filter addresses based on Inet6Address.

The isReservedAddr() method filters local special IP addresses, including “LocalAddress”, “LinkLocalAddress”, and “LoopbackAddress”. Readers can modify the filter criteria according to their own needs.

Another thing to note is that on Windows, the obtained IPv6 address may be followed by a percent sign plus a number. The number here is the number of the local network adapter. This suffix is not part of the IPv6 standard address and can be removed.

8, IPv4/IPv6 dual environment, network selection and testing

Let’s take a look at my IPv4/IPv6 development test environment and its configuration.

The IPv4/IPv6 dual environment I live in is a typical “6to4” dual stack network, where there is a mapping mechanism from IPv6 to IPv4. Any IPv6 address 2002:92 a: 8 f7a: 100: a: b: c: d would be the default mapping in routing for IPv4 addresses A.B.C.D, so only a routing table.

In this environment, the one-to-one correspondence between IPv4 and IPv6 addresses is manually guaranteed. If a client uses both IPv4 and IPv6 addresses that do not match, or uses both DHCPv4 and DHCPv6 (which may cause a mismatch between IPv4 and IPv6 addresses), IPv6 routing addressing will fail.

Because of this, in order to configure a dual address environment, we generally use DHCPv4 to automatically obtain IPv4 addresses and then manually configure the corresponding IPv6 addresses.

Windows:

1) Windows 2000 and below: does not support IPv6

2) Windows 2003 and Windows XP: Use the Netsh command line to add IPv6 addresses and DNS, for example: C: > netsh interface ipv6 add to address “Local Area Connection”, 2002:92 a: 8 f7a: 100:10:13:1:2 and C: > netsh interface ipv6 add DNS “Local Area Connection”, 2002, 92 a: 8 f7a: 100:10: : 250

3) Windows 2008 and Windows Vista: Can be configured either using the Windows Network Properties page or using the Netsh command line similar to Windows 2003 and Windows XP

Linux (the following is the temporary IPv6 configuration method, that is, the configuration file is not modified, and the configuration becomes invalid after the computer restarts) :

1) Redhat Linux: the easiest way is to use the ifconfig command line add IPv6 address, for example: ifconfig eth0 inet6 add 2002:92 a: 8 f7a: 100:10:14:24:106/96.

2) SUSE Linux: same as above.

In practice, the object-oriented nature of Java and the encapsulation of IP addresses by the Java.NET package make it extremely easy to migrate Java applications from IPv4 to IPv4/IPv6 dual or pure IPv6 environments. Usually all we need to do is check the code and remove the IPv4 address written in explicit code, replacing it with the host name.

** For some special needs, Java also provides two extended classes for InetAddress: Inet4Address and Inet6Address, which encapsulate special properties and behaviors for both IPv4 and IPv6.

However, due to the polymorphic nature of Java, programmers generally only need to use the parent class InetAddress, and the Java VIRTUAL machine can choose the correct behavior logic at run time depending on the type of IP address encapsulated. So in most cases, the programmer does not need to have precise control over the types used and their behavior, leaving it to the Java virtual machine.

For details about the new types and methods, please refer to the Java API documentation.

** Also: ** In a dual IPv4/IPv6 environment, it is worth noting the following two ipv6-related Java virtual machine system attributes for web applications developed using Java.

java.net.preferIPv4Stack=<true|false>

java.net.preferIPv6Addresses=<true|false>

PreferIPv4Stack (default false) indicates whether the Java program uses the IPv4 socket preferentially if the IPv4 and IPv6 dual stacks exist. By default, IPv6 sockets are preferred because IPv6 sockets can talk to corresponding IPv4 or IPv6 hosts. In contrast, if IPv4 is preferentially used, only IPv6 hosts cannot communicate with each other.

PreferIPv6Addresses (default false) Indicates whether the Java program returns the IPv6 address preferentially when querying the local or remote IP address if both IPv4 and IPv6 addresses exist. Java returns IPv4 addresses by default primarily for backward compatibility to support older IPv4 authentication logic and older IPv4 address-only services.

9. Write at the end

This paper introduces some basic introduction of IPv6 address, focuses on how to use Java to develop ipv6-compatible network applications, including how to verify IPv6 address, how to normalize the representation of IPv6 address, how to obtain the local IPv6 address. And network selection and testing in IPv4/IPv6 dual address environment.

At the same time, the author combined with the Java code snippet used in daily work, hoping to present a comprehensive and practical text introduction to readers, and also hope that this article can bring some help to readers in the process of developing IPv6 compatible programs using Java in the future.

10. Reference materials

[1] IPv6 address technology architecture

[2] IPv6 protocol technical document

[3] Networking IPv6 User Guide for JDK/JRE 5.0

(This article is simultaneously published at: www.52im.net/thread-3236…)