2

just yesterday while debugging my android app i figured out that whenever reverse dns lookup is not possible my connection takes bunch loads of time to initiate (roughly about 20-30 seconds).

i managed to narrow down the source to InetAddress.getHostName() call (that's where it takes so much time) but i am (unfortunately) clueless on how i could work it around. I understand that SSL connections with no DNS verification are more prone to MITM attacks; in such cases i would prefer to notify the user about issues rather than make him wait forever for the application to load and connect. i've been browsing the web back and forth looking for the answer, i could find ways to fix that in java, but none of them applies to android (at least i couldn't cache inetaddress nor use alternative classes to resolve my host names with impl property).

is there any way i could limit the timeout to some reasonable timeouts (say: 2-3 seconds)? i would like to save the time i'd need to spend re-writing ssl sockets as android native code.

thanks!

Man of One Way
  • 3,904
  • 1
  • 26
  • 41
Tomasz W
  • 1,841
  • 1
  • 16
  • 25
  • Can you clarify what's connecting to what? Where does the /reverse/ DNS come into play? (Note that the verification of the identity for the certificate is based on the forward DNS, the one the client is trying to connect to, not the reverse DNS entry.) – Bruno Jul 26 '11 at 12:46
  • it's a trivial attempt to establish point-to-point connection between server and client being two linux devices (ok, linux & android). my android application creates a TLS context, and later utilizes SSLSocketFactory to build a secure socket. the problem, however, shows when i call _sock.connect_ using Inet4Address (built with InetSocketAddress). i separated this call (sock.connect) to two consecutive calls being: inet4address.getHostName(), which lags 20 seconds, and socket.connect, which ever since started working quickly, which, i believe, may be accelerated due to previous call – Tomasz W Jul 26 '11 at 12:48
  • Any reason why you choose to deal with the InetAddress explicitly? Why not use `SSLSocketFactory.createSocket(String host, int port)`? – Bruno Jul 26 '11 at 13:08
  • @Bruno, I did that just to isolate the source of the problem. The call you proposed takes exactly as much time due to reverse dns resolution (ip -> host name). – Tomasz W Jul 26 '11 at 13:36
  • I'm just surprised there's a *reverse* DNS lookup. Looking at the `sun.security.ssl.SSLSocketImpl` (in OpenJDK 7), it stores the requested host name (`rawHostname`), whereas Harmony/Android doesn't seem to, but a quick look through the code seems to suggest that it should keep hold of the name initially supplied in `InetAddress`. By the way, are you supplying it with an IP address or a host name initially? – Bruno Jul 26 '11 at 14:21
  • reverse dns lookup is, iirc, one of the _host verification methods_. it may fail either way (because usual use case is connecting your phone to your computer, which won't be authenticated by dns). to answer your question - i'm supplying server address in canonical form (say, "192.168.1.2"), i thought it should save plenty of time, but it doesn't – Tomasz W Jul 26 '11 at 14:27
  • No, reverse DNS lookup is a bad and insecure way of tying the identity of the destination server to the certificate. The host name in the certificate (CN or subject Alt Name) should match the *intended* name, not one that may be obtained by a (possibly spoofed) reverse DNS lookup. In addition, as you've noticed, supplying the IP address directly doesn't save you any time. – Bruno Jul 26 '11 at 14:34

1 Answers1

1

this is (was) related to a bug in GLIBC trying to reverse lookup ipv6 host names even if no ipv6 interfaces were configured.

the problem and fix are discussed here:

https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/417757

it should work if /etc/hosts file is updated to cover particular IP address

Tomasz W
  • 1,841
  • 1
  • 16
  • 25