Monday, January 21, 2013

Ready for IPv6 addresses to visit your web app?

In a java servlet you lookup the client’s IP address by calling request.getRemoteAddr(), which returns a String. But are you expecting a dotted decimal IP address in that String? Your code should be prepared to see IPv6 addresses too.
I recommend looking at Google’s Guava library, a useful collection of commonly useful Java Stuff, i.e. “collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth”. Specific to reading Inet addresses is the class InetAddresses.

With InetAddresses.forString(ipAddr) you can pass in a raw internet address string (whether IPv4 or IPv6) and get back an InetAddress, which you can test to see which type you were returned, either Inet4Address or Inet6Address.

Here’s an example where I am only calling a library if I have an IPv4 address. (Until the lib will lookup IPv6 too.)

  1: import java.net.Inet4Address;
  2: import java.net.InetAddress;
  3: 
  4: import com.google.common.net.InetAddresses;
  5: 
  6: 
  7: String ipAddr = request.getRemoteAddr();
  8: Location loc = null;
  9: try {
 10:     InetAddress ia = InetAddresses.forString(ipAddr);
 11:     // TODO fix geo library to handle IPv6 addresses
 12:     if ( ia instanceof Inet4Address ) {
 13:         loc = Geo.DB.lookup(ipAddr);
 14:     }
 15: }
 16: catch ( IllegalArgumentException e ) {
 17:     // the string was not a valid IPv4 or IPv6 address
 18:     loc = null;
 19: }

Another thing I am interested in from the Guava library is a means to produce a canonical form of an IPv6 address. There is a recommendation proposed (IETF RFC5952) for a canonical form of IPv6, and it calls out some good reasons why we should care. The actual proposal itself is very simple, having only five concerns and are what you’d expect.
I have not thoroughly examined yet what Guava does to format IPv6 addresses. That’s next.


Update 1/22/2013:  The function InetAddresses.toAddrString(InetAddress ip) returns the string representation of the IP address, and for IPv6 addresses, it adheres to RFC 5952. Hat tip to +Paul Marks for pointing me to the right version of the API.