From ce3c005eb5eac0cc12328758a87782b9fa441b6b Mon Sep 17 00:00:00 2001 From: Damian Minkov Date: Mon, 13 Sep 2010 11:49:13 +0000 Subject: Update dns resolution for sip addresses when connecting, added and the initial address as backup (the way we were connecting before introducing the reconnection mechanism for ipv6 and ipv4 services). --- .../sip/ProtocolProviderServiceSipImpl.java | 94 ++++++++++++++++------ .../java/sip/communicator/util/NetworkUtils.java | 2 + 2 files changed, 70 insertions(+), 26 deletions(-) (limited to 'src/net/java') diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java index 7e0fff4..07ae898 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -494,7 +494,8 @@ public class ProtocolProviderServiceSipImpl this.sipStatusEnum = new SipStatusEnum(protocolIconPath); - //init the proxy + //init the proxy, we had to have at least one address configured + // so use it, if it fails later we will use next one initOutboundProxy(accountID, 0); //init proxy port @@ -2516,6 +2517,9 @@ public class ProtocolProviderServiceSipImpl /** * Tries to resolve address into a valid InetSocketAddress using * an SRV query where it exists and A/AAAA where it doesn't. + * If there is no SRV,A or AAAA records return the socket address created + * with the supplied address, so we can keep old behaviour. + * When letting underling libs and java to resolve the address. * * @param address the address we'd like to resolve. * @param transport the protocol that we'd like to use when accessing @@ -2535,8 +2539,6 @@ public class ProtocolProviderServiceSipImpl ArrayList resultAddresses = new ArrayList(); - InetSocketAddress sockAddr = null; - //we need to resolve the address only if its a hostname. if(NetworkUtils.isValidIPAddress(address)) { @@ -2549,43 +2551,85 @@ public class ProtocolProviderServiceSipImpl port = ListeningPoint.PORT_5061; resultAddresses.add(new InetSocketAddress(addressObj, port)); + + // as its ip address return, no dns is needed. + return resultAddresses.toArray(new InetSocketAddress[]{}); } + boolean preferIPv6Addresses = + Boolean.getBoolean("java.net.preferIPv6Addresses"); + //try to obtain SRV mappings from the DNS try { - if(transport.equalsIgnoreCase(ListeningPoint.TLS)) - { - sockAddr = NetworkUtils.getSRVRecord( - "sips", ListeningPoint.TCP, address); - } - else + InetSocketAddress[] sockAddrs = + NetworkUtils.getSRVRecords( + transport.equalsIgnoreCase(ListeningPoint.TLS) ? + "sips" : "sip", + ListeningPoint.TCP, address); + for(InetSocketAddress s : sockAddrs) { - sockAddr = NetworkUtils.getSRVRecord("sip", transport, address); + // add corresponding A and AAAA records to the host address + // from SRV records + resolveAddresses( + s.getHostName(), + resultAddresses, + preferIPv6Addresses, + s.getPort()); + + // add and every SRV address itself + resultAddresses.add(s); + + if (logger.isTraceEnabled()) + logger.trace("Returned SRV " + s); } - if (logger.isTraceEnabled()) - logger.trace("Returned SRV " + sockAddr); } catch (ParseException e) { - throw new UnknownHostException(address); + logger.error("Error parsing dns record.", e); } - if(sockAddr != null) - resultAddresses.add(sockAddr); - - //there were no SRV mappings so we only need to A/AAAA resolve the - //address. Do this before we instantiate the resulting InetSocketAddress - //because its constructor suprresses UnknownHostException-s and we want - //to know if something goes wrong. - //no SRV means default ports int defaultPort = ListeningPoint.PORT_5060; if(transport.equalsIgnoreCase(ListeningPoint.TLS)) defaultPort = ListeningPoint.PORT_5061; // after checking SRVs, lets add and AAAA and A records - // in order corresponding java preferences. + resolveAddresses( + address, + resultAddresses, + preferIPv6Addresses, + defaultPort); + + // make sure we don't return empty array + if(resultAddresses.size() == 0) + { + resultAddresses.add(new InetSocketAddress(address, defaultPort)); + + // there were no SRV mappings so we only need to A/AAAA resolve the + // address. Do this before we instantiate the + // resulting InetSocketAddress because its constructor + // suppresses UnknownHostException-s and we want to know if + // something goes wrong. + InetAddress addressObj = InetAddress.getByName(address); + } + + return resultAddresses.toArray(new InetSocketAddress[]{}); + } + + /** + * Resolves the given address. Resolves A and AAAA records and returns + * them in resultAddresses ordered according + * preferIPv6Addresses option. + * @param address the address to resolve. + * @param resultAddresses the List in which we provide the result. + * @param preferIPv6Addresses whether ipv6 address should go before ipv4. + * @param defaultPort the port to use for the result address. + */ + private void resolveAddresses( + String address, List resultAddresses, + boolean preferIPv6Addresses, int defaultPort) + { InetSocketAddress addressObj4 = null; InetSocketAddress addressObj6 = null; try @@ -2602,8 +2646,8 @@ public class ProtocolProviderServiceSipImpl { logger.error("Error parsing dns record.", ex); } - - if(Boolean.getBoolean("java.net.preferIPv6Addresses")) + + if(preferIPv6Addresses) { if(addressObj6 != null) resultAddresses.add(addressObj6); @@ -2619,8 +2663,6 @@ public class ProtocolProviderServiceSipImpl if(addressObj6 != null) resultAddresses.add(addressObj6); } - - return resultAddresses.toArray(new InetSocketAddress[]{}); } /** diff --git a/src/net/java/sip/communicator/util/NetworkUtils.java b/src/net/java/sip/communicator/util/NetworkUtils.java index 9a09d1b..36fbb66 100644 --- a/src/net/java/sip/communicator/util/NetworkUtils.java +++ b/src/net/java/sip/communicator/util/NetworkUtils.java @@ -466,6 +466,7 @@ public class NetworkUtils } else { + logger.warn("No A record found for: " + domain); return null; } } @@ -502,6 +503,7 @@ public class NetworkUtils } else { + logger.warn("No AAAA record found for: " + domain); return null; } } -- cgit v1.1