diff --git a/lib/native/windows-64/junbound.dll b/lib/native/windows-64/junbound.dll index 772d7a282..0a2729810 100644 Binary files a/lib/native/windows-64/junbound.dll and b/lib/native/windows-64/junbound.dll differ diff --git a/lib/native/windows/junbound.dll b/lib/native/windows/junbound.dll index 194f520a8..b1b8da8c2 100644 Binary files a/lib/native/windows/junbound.dll and b/lib/native/windows/junbound.dll differ diff --git a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java index b793e01fe..78cf98afd 100644 --- a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java +++ b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java @@ -63,17 +63,9 @@ public class ConfigurableDnssecResolver public ConfigurableDnssecResolver() { super(); - String forwarders = DnsUtilActivator.getConfigurationService() - .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS); - if(!StringUtils.isNullOrEmpty(forwarders, true)) - { - if(logger.isTraceEnabled()) - { - logger.trace("Setting DNSSEC forwarders to: " - + Arrays.toString(forwarders.split(","))); - } - super.setForwarders(forwarders.split(",")); - } + reset(); + Lookup.setDefaultResolver(this); + DnsUtilActivator.getNotificationService(). registerDefaultNotificationForEvent( ConfigurableDnssecResolver.EVENT_TYPE, @@ -290,7 +282,9 @@ private void initComponents() for(DnssecDialogResult r : DnssecDialogResult.values()) { JButton cmd = new JButton(R.getI18NString( - DnssecDialogResult.class.getName() + "." + r.name())); + "net.java.sip.communicator.util.dns." + + "ConfigurableDnssecResolver$DnssecDialogResult." + + r.name())); cmd.setActionCommand(r.name()); cmd.addActionListener(this); pnlAdvancedButtons.add(cmd); @@ -354,4 +348,34 @@ private String createPropNameUnsigned(String fqdn, String type) { return PNAME_BASE_DNSSEC_PIN + "." + fqdn.replace(".", "__"); } + + /** + * Reloads the configuration of forwarders and trust anchors. + */ + public void reset() + { + String forwarders = DnsUtilActivator.getConfigurationService() + .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS); + if(!StringUtils.isNullOrEmpty(forwarders, true)) + { + if(logger.isTraceEnabled()) + { + logger.trace("Setting DNSSEC forwarders to: " + + Arrays.toString(forwarders.split(","))); + } + super.setForwarders(forwarders.split(",")); + } + + for(int i = 1;;i++) + { + String anchor = DnsUtilActivator.getResources().getSettingsString( + "net.java.sip.communicator.util.dns.DS_ROOT." + i); + if(anchor == null) + break; + clearTrustAnchors(); + addTrustAnchor(anchor); + if(logger.isTraceEnabled()) + logger.trace("Loaded trust anchor " + anchor); + } + } } diff --git a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java index fd086c526..2eb8c75ea 100644 --- a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java +++ b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java @@ -8,6 +8,8 @@ import net.java.sip.communicator.impl.dns.dnsconfig.*; import net.java.sip.communicator.service.dns.*; +import net.java.sip.communicator.service.netaddr.*; +import net.java.sip.communicator.service.netaddr.event.*; import net.java.sip.communicator.service.notification.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; @@ -24,8 +26,13 @@ * @author Ingo Bauersachs */ public class DnsUtilActivator - implements BundleActivator + implements BundleActivator, + ServiceListener { + /** Class logger */ + private static final Logger logger + = Logger.getLogger(DnsUtilActivator.class); + /** * The name of the property that sets custom nameservers to use for all DNS * lookups when DNSSEC is enabled. Multiple servers are separated by a comma @@ -34,20 +41,53 @@ public class DnsUtilActivator public static final String PNAME_DNSSEC_NAMESERVERS = "net.java.sip.communicator.util.dns.DNSSEC_NAMESERVERS"; - /** - * The Logger used by the UtilActivator class and its - * instances for logging output. - */ - private static final Logger logger - = Logger.getLogger(DnsUtilActivator.class); - private static ConfigurationService configurationService; private static NotificationService notificationService; private static ResourceManagementService resourceService; private static BundleContext bundleContext; - private static DnsConfigActivator dnsConfigActivator; + /** + * The address of the backup resolver we would use by default. + */ + public static final String DEFAULT_BACKUP_RESOLVER + = "backup-resolver.jitsi.net"; + + /** + * The name of the property that users may use to override the port + * of our backup DNS resolver. + */ + public static final String PNAME_BACKUP_RESOLVER_PORT + = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_PORT"; + + /** + * The name of the property that users may use to override the + * IP address of our backup DNS resolver. This is only used when the + * backup resolver name cannot be determined. + */ + public static final String PNAME_BACKUP_RESOLVER_FALLBACK_IP + = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_FALLBACK_IP"; + + /** + * The default of the property that users may use to disable + * our backup DNS resolver. + */ + public static final boolean PDEFAULT_BACKUP_RESOLVER_ENABLED = true; + + /** + * The name of the property that users may use to disable + * our backup DNS resolver. + */ + public static final String PNAME_BACKUP_RESOLVER_ENABLED + = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_ENABLED"; + + /** + * The name of the property that users may use to override the + * address of our backup DNS resolver. + */ + public static final String PNAME_BACKUP_RESOLVER + = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER"; + /** * Calls Thread.setUncaughtExceptionHandler() * @@ -62,56 +102,82 @@ public void start(BundleContext context) throws Exception { bundleContext = context; + context.addServiceListener(this); - bundleContext.registerService( - ParallelResolver.class.getName(), - new ParallelResolverImpl(), - null); + if(UtilActivator.getConfigurationService().getBoolean( + DnsUtilActivator.PNAME_BACKUP_RESOLVER_ENABLED, + DnsUtilActivator.PDEFAULT_BACKUP_RESOLVER_ENABLED) + && !getConfigurationService().getBoolean( + CustomResolver.PNAME_DNSSEC_RESOLVER_ENABLED, + CustomResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED)) + { + bundleContext.registerService( + CustomResolver.class.getName(), + new ParallelResolverImpl(), + null); + } if(getConfigurationService().getBoolean( - ParallelResolverImpl.PNAME_DNSSEC_RESOLVER_ENABLED, - ParallelResolverImpl.PDEFAULT_DNSSEC_RESOLVER_ENABLED)) + CustomResolver.PNAME_DNSSEC_RESOLVER_ENABLED, + CustomResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED)) { - getNotificationService(). - registerDefaultNotificationForEvent( - ConfigurableDnssecResolver.EVENT_TYPE, - NotificationAction.ACTION_POPUP_MESSAGE, - null, null); + bundleContext.registerService( + CustomResolver.class.getName(), + new ConfigurableDnssecResolver(), + null); } - refreshResolver(); dnsConfigActivator = new DnsConfigActivator(); dnsConfigActivator.start(context); } /** - * Sets a DNSSEC resolver as default resolver on lookup when DNSSEC is - * enabled; creates a standard lookup otherwise. + * Listens when network is going from down to up and + * resets dns configuration. */ - public static void refreshResolver() + private static class NetworkListener + implements NetworkConfigurationChangeListener { - if(getConfigurationService().getBoolean( - ParallelResolverImpl.PNAME_DNSSEC_RESOLVER_ENABLED, - ParallelResolverImpl.PDEFAULT_DNSSEC_RESOLVER_ENABLED)) + /** + * Fired when a change has occurred in the + * computer network configuration. + * + * @param event the change event. + */ + public void configurationChanged(ChangeEvent event) { - logger.trace("DNSSEC is enabled"); - ConfigurableDnssecResolver res = new ConfigurableDnssecResolver(); - for(int i = 1;;i++) + if((event.getType() == ChangeEvent.IFACE_UP + || event.getType() == ChangeEvent.DNS_CHANGE) + && !event.isInitial()) { - String anchor = getResources().getSettingsString( - "net.java.sip.communicator.util.dns.DS_ROOT." + i); - if(anchor == null) - break; - res.addTrustAnchor(anchor); - if(logger.isTraceEnabled()) - logger.trace("Loaded trust anchor " + anchor); + reloadDnsResolverConfig(); } - Lookup.setDefaultResolver(res); } - else + } + + /** + * Reloads dns server configuration in the resolver. + */ + public static void reloadDnsResolverConfig() + { + // reread system dns configuration + ResolverConfig.refresh(); + if(logger.isTraceEnabled()) { - logger.trace("DNSSEC is disabled, refresh default config"); - Lookup.refreshDefault(); + StringBuilder sb = new StringBuilder(); + sb.append("Reloaded resolver config, default DNS servers are: "); + for(String s : ResolverConfig.getCurrentConfig().servers()) + { + sb.append(s); + sb.append(", "); + } + logger.trace(sb.toString()); + } + + // now reset an eventually present custom resolver + if(Lookup.getDefaultResolver() instanceof CustomResolver) + { + ((CustomResolver)Lookup.getDefaultResolver()).reset(); } } @@ -180,4 +246,25 @@ public static ResourceManagementService getResources() } return resourceService; } + + /** + * Listens on OSGi service changes and registers a listener for network + * changes as soon as the change-notification service is available + */ + public void serviceChanged(ServiceEvent event) + { + if (event.getType() != ServiceEvent.REGISTERED) + { + return; + } + + Object service = bundleContext.getService(event.getServiceReference()); + if (!(service instanceof NetworkAddressManagerService)) + { + return; + } + + ((NetworkAddressManagerService)service) + .addNetworkConfigurationChangeListener(new NetworkListener()); + } } diff --git a/src/net/java/sip/communicator/impl/dns/ParallelResolverImpl.java b/src/net/java/sip/communicator/impl/dns/ParallelResolverImpl.java index bd317b3d0..054a6e402 100644 --- a/src/net/java/sip/communicator/impl/dns/ParallelResolverImpl.java +++ b/src/net/java/sip/communicator/impl/dns/ParallelResolverImpl.java @@ -6,6 +6,7 @@ */ package net.java.sip.communicator.impl.dns; +import java.beans.*; import java.io.*; import java.net.*; import java.util.*; @@ -35,7 +36,7 @@ * @author Emil Ivov */ public class ParallelResolverImpl - implements ParallelResolver + implements CustomResolver, PropertyChangeListener { /** * The Logger used by the ParallelResolver @@ -50,39 +51,12 @@ public class ParallelResolverImpl */ private static boolean redundantMode = false; - /** - * The default number of milliseconds it takes us to get into redundant - * mode while waiting for a DNS query response. - */ - public static final int DNS_PATIENCE = 1500; - - /** - * The name of the property that allows us to override the default - * DNS_PATIENCE value. - */ - public static final String PNAME_DNS_PATIENCE - = "net.java.sip.communicator.util.dns.DNS_PATIENCE"; - /** * The currently configured number of milliseconds that we need to wait * before entering redundant mode. */ private static long currentDnsPatience = DNS_PATIENCE; - /** - * The default number of times that the primary DNS would have to provide a - * faster response than the backup resolver before we consider it safe - * enough to exit redundant mode. - */ - public static final int DNS_REDEMPTION = 3; - - /** - * The name of the property that allows us to override the default - * DNS_REDEMPTION value. - */ - public static final String PNAME_DNS_REDEMPTION - = "net.java.sip.communicator.util.dns.DNS_REDEMPTION"; - /** * The currently configured number of times that the primary DNS would have * to provide a faster response than the backup resolver before we consider @@ -106,9 +80,17 @@ public class ParallelResolverImpl /** * The default resolver that we use if everything works properly. */ - private static Resolver defaultResolver; + private Resolver defaultResolver; + + /** + * An extended resolver that would be encapsulating all backup resolvers. + */ + private ExtendedResolver backupResolver; - static + /** + * Creates a new instance of this class. + */ + ParallelResolverImpl() { try { @@ -120,57 +102,67 @@ public class ParallelResolverImpl throw new RuntimeException("Failed to initialize resolver"); } + DnsUtilActivator.getConfigurationService() + .addPropertyChangeListener(this); initProperties(); + Lookup.setDefaultResolver(this); } - /** - * Default resolver property initialisation - */ - private static void initProperties() + private void initProperties() { + String rslvrAddrStr + = UtilActivator.getConfigurationService().getString( + DnsUtilActivator.PNAME_BACKUP_RESOLVER, + DnsUtilActivator.DEFAULT_BACKUP_RESOLVER); + String customResolverIP + = UtilActivator.getConfigurationService().getString( + DnsUtilActivator.PNAME_BACKUP_RESOLVER_FALLBACK_IP, + UtilActivator.getResources().getSettingsString( + DnsUtilActivator.PNAME_BACKUP_RESOLVER_FALLBACK_IP)); + + InetAddress resolverAddress = null; try { - currentDnsPatience = DnsUtilActivator.getConfigurationService() - .getLong(PNAME_DNS_PATIENCE, DNS_PATIENCE); - currentDnsRedemption - = DnsUtilActivator.getConfigurationService() - .getInt(PNAME_DNS_REDEMPTION, DNS_REDEMPTION); + resolverAddress = NetworkUtils.getInetAddress(rslvrAddrStr); } - catch(Throwable t) + catch(UnknownHostException exc) { - //we don't want messed up properties to screw up DNS resolution - //so we just log. - logger.info("Failed to initialize DNS resolver properties", t); + logger.warn("Oh! Seems like our primary DNS is down!" + + "Don't panic! We'll try to fall back to " + + customResolverIP); } - } + if(resolverAddress == null) + { + // name resolution failed for backup DNS resolver, + // try with the IP address of the default backup resolver + try + { + resolverAddress = NetworkUtils.getInetAddress(customResolverIP); + } + catch (UnknownHostException e) + { + // this shouldn't happen, but log anyway + logger.error(e); + } + } - /** - * Replaces the default resolver used by this class. Mostly meant for - * debugging. - * - * @param resolver the resolver we'd like to use by default from now on. - */ - public void setDefaultResolver(Resolver resolver) - { - defaultResolver = resolver; - } + int resolverPort = UtilActivator.getConfigurationService().getInt( + DnsUtilActivator.PNAME_BACKUP_RESOLVER_PORT, + SimpleResolver.DEFAULT_PORT); - /** - * Returns the default resolver used by this class. Mostly meant for - * debugging. - * - * @return the resolver this class consults first. - */ - public Resolver getDefaultResolver() - { - return defaultResolver; - } + InetSocketAddress resolverSockAddr + = new InetSocketAddress(resolverAddress, resolverPort); - /** - * An extended resolver that would be encapsulating all backup resolvers. - */ - private ExtendedResolver backupResolver; + setBackupServers(new InetSocketAddress[]{ resolverSockAddr }); + + currentDnsPatience = DnsUtilActivator.getConfigurationService() + .getLong(PNAME_DNS_PATIENCE, DNS_PATIENCE); + + currentDnsRedemption + = DnsUtilActivator.getConfigurationService() + .getInt(PNAME_DNS_REDEMPTION, DNS_REDEMPTION); + } /** * Sets the specified array of backupServers used if the default @@ -179,7 +171,7 @@ public Resolver getDefaultResolver() * @param backupServers the list of backup DNS servers that we should use * if, and only if, the default servers don't seem to work that well. */ - public void setBackupServers(InetSocketAddress[] backupServers) + private void setBackupServers(InetSocketAddress[] backupServers) { try { @@ -188,7 +180,6 @@ public void setBackupServers(InetSocketAddress[] backupServers) { SimpleResolver sr = new SimpleResolver(); sr.setAddress(backupServer); - backupResolver.addResolver(sr); } } @@ -393,6 +384,7 @@ public void setTimeout(int secs) */ public void reset() { + Lookup.refreshDefault(); ExtendedResolver resolver = (ExtendedResolver)defaultResolver; // remove old ones @@ -415,7 +407,9 @@ public void reset() } } else + { resolver.addResolver(new SimpleResolver()); + } } catch (UnknownHostException e) { @@ -692,12 +686,23 @@ else if (exception instanceof Error) } } - /** - * Sets a DNSSEC resolver as default resolver on lookup when DNSSEC is - * enabled; creates a standard lookup otherwise. - */ - public void refreshResolver() + @SuppressWarnings("serial") + private final Set configNames = new HashSet(5) + {{ + add(DnsUtilActivator.PNAME_BACKUP_RESOLVER); + add(DnsUtilActivator.PNAME_BACKUP_RESOLVER_FALLBACK_IP); + add(DnsUtilActivator.PNAME_BACKUP_RESOLVER_PORT); + add(CustomResolver.PNAME_DNS_PATIENCE); + add(CustomResolver.PNAME_DNS_REDEMPTION); + }}; + + public void propertyChange(PropertyChangeEvent evt) { - DnsUtilActivator.refreshResolver(); + if (!configNames.contains(evt.getPropertyName())) + { + return; + } + + initProperties(); } } diff --git a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java b/src/net/java/sip/communicator/impl/dns/UnboundResolver.java index 0f2979533..92ab06ba6 100644 --- a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java +++ b/src/net/java/sip/communicator/impl/dns/UnboundResolver.java @@ -23,7 +23,7 @@ * @author Ingo Bauersachs */ public class UnboundResolver - implements Resolver + implements CustomResolver { private final static Logger logger = Logger.getLogger(UnboundResolver.class); @@ -93,6 +93,14 @@ public void setForwarders(String[] forwarders) this.forwarders = forwarders; } + /** + * Clears any existing trust anchors previously added. + */ + public void clearTrustAnchors() + { + trustAnchors.clear(); + } + /** * Adds a DNSSEC trust anchor validation of the DNSKEYs. * @@ -136,7 +144,7 @@ public SecureMessage call() throws Exception if(logger.isDebugEnabled() && secureMessage != null) logger.debug(secureMessage); } - + return secureMessage; } }); @@ -381,4 +389,11 @@ public void setTimeout(int secs, int msecs) { timeout = secs * 1000 + msecs; } + + /** + * Does nothing. + */ + public void reset() + { + } } diff --git a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf index 3157e6ef4..619c311cb 100644 --- a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf +++ b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf @@ -15,6 +15,8 @@ Import-Package: org.jitsi.util, net.java.sip.communicator.service.notification, net.java.sip.communicator.service.dns, net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.netaddr, + net.java.sip.communicator.service.netaddr.event, org.jitsi.service.configuration, sun.net.dns, org.xbill.DNS, diff --git a/src/net/java/sip/communicator/impl/dns/dnsconfig/DnssecPanel.java b/src/net/java/sip/communicator/impl/dns/dnsconfig/DnssecPanel.java index e7f88d451..8e7928f56 100644 --- a/src/net/java/sip/communicator/impl/dns/dnsconfig/DnssecPanel.java +++ b/src/net/java/sip/communicator/impl/dns/dnsconfig/DnssecPanel.java @@ -203,8 +203,8 @@ private void loadData() ) ); chkEnabled.setSelected(config.getBoolean( - ParallelResolver.PNAME_DNSSEC_RESOLVER_ENABLED, - ParallelResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED + CustomResolver.PNAME_DNSSEC_RESOLVER_ENABLED, + CustomResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED )); chkAbsolute.setSelected(config.getBoolean( NetworkUtils.PNAME_DNS_ALWAYS_ABSOLUTE, @@ -262,7 +262,7 @@ public void actionPerformed(ActionEvent e) chkEnabled.setSelected(true); } config.setProperty( - ParallelResolver.PNAME_DNSSEC_RESOLVER_ENABLED, + CustomResolver.PNAME_DNSSEC_RESOLVER_ENABLED, chkEnabled.isSelected()); } catch (Exception ex) @@ -341,7 +341,7 @@ public void focusLost(FocusEvent e) config.setProperty( DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS, txtNameservers.getText()); - NetworkUtils.reloadDnsResolverConfig(); + DnsUtilActivator.reloadDnsResolverConfig(); } } diff --git a/src/net/java/sip/communicator/impl/dns/dnsconfig/ParallelDnsPanel.java b/src/net/java/sip/communicator/impl/dns/dnsconfig/ParallelDnsPanel.java index 0059d1128..0506e96d5 100644 --- a/src/net/java/sip/communicator/impl/dns/dnsconfig/ParallelDnsPanel.java +++ b/src/net/java/sip/communicator/impl/dns/dnsconfig/ParallelDnsPanel.java @@ -6,19 +6,9 @@ */ package net.java.sip.communicator.impl.dns.dnsconfig; -import static net.java.sip.communicator.util.NetworkUtils.DEFAULT_BACKUP_RESOLVER; -import static net.java.sip.communicator.util.NetworkUtils.PDEFAULT_BACKUP_RESOLVER_ENABLED; -import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER; -import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_ENABLED; -import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_FALLBACK_IP; -import static net.java.sip.communicator.util.NetworkUtils.PNAME_BACKUP_RESOLVER_PORT; -import static net.java.sip.communicator.util.NetworkUtils.getDefaultDnsPort; -import static net.java.sip.communicator.util.NetworkUtils.isIPv4Address; -import static net.java.sip.communicator.util.NetworkUtils.isIPv6Address; -import static net.java.sip.communicator.service.dns.ParallelResolver.DNS_PATIENCE; -import static net.java.sip.communicator.service.dns.ParallelResolver.DNS_REDEMPTION; -import static net.java.sip.communicator.service.dns.ParallelResolver.PNAME_DNS_PATIENCE; -import static net.java.sip.communicator.service.dns.ParallelResolver.PNAME_DNS_REDEMPTION; +import static net.java.sip.communicator.util.NetworkUtils.*; +import static net.java.sip.communicator.service.dns.CustomResolver.*; +import static net.java.sip.communicator.impl.dns.DnsUtilActivator.*; import java.awt.*; import java.awt.event.*; @@ -29,6 +19,7 @@ import javax.swing.event.*; import javax.swing.text.*; +import net.java.sip.communicator.impl.dns.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.dns.*; import net.java.sip.communicator.util.*; @@ -36,6 +27,7 @@ import org.jitsi.service.configuration.*; import org.jitsi.service.resources.*; import org.osgi.framework.*; +import org.xbill.DNS.*; /** * Page inside the advanced configuration options that allow the user to @@ -208,8 +200,8 @@ private void initComponents() public void updateDnssecState() { boolean isDnssec = configService.getBoolean( - ParallelResolver.PNAME_DNSSEC_RESOLVER_ENABLED, - ParallelResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED); + CustomResolver.PNAME_DNSSEC_RESOLVER_ENABLED, + CustomResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED); if(isDnssec) chkBackupDnsEnabled.setSelected(false); chkBackupDnsEnabled.setEnabled(!isDnssec); @@ -376,7 +368,7 @@ private void loadData() PNAME_BACKUP_RESOLVER_FALLBACK_IP, R.getSettingsString(PNAME_BACKUP_RESOLVER_FALLBACK_IP))); spnBackupResolverPort.setValue(configService.getInt( - PNAME_BACKUP_RESOLVER_PORT, getDefaultDnsPort())); + PNAME_BACKUP_RESOLVER_PORT, SimpleResolver.DEFAULT_PORT)); spnDnsTimeout.setValue(configService.getInt( PNAME_DNS_PATIENCE, DNS_PATIENCE)); spnDnsRedemption.setValue(configService.getInt( diff --git a/src/net/java/sip/communicator/service/dns/CustomResolver.java b/src/net/java/sip/communicator/service/dns/CustomResolver.java new file mode 100644 index 000000000..ef51594de --- /dev/null +++ b/src/net/java/sip/communicator/service/dns/CustomResolver.java @@ -0,0 +1,84 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.service.dns; + +import org.xbill.DNS.*; + +/** + * The purpose of this class is to help avoid the significant delays that occur + * in networks where DNS servers would ignore SRV, NAPTR, and sometimes even + * A/AAAA queries (i.e. without even sending an error response). We also try to + * handle cases where DNS servers may return empty responses to some records. + *

+ * We achieve this by entering a redundant mode whenever we detect an abnormal + * delay (longer than DNS_PATIENCE) while waiting for a DNS resonse, + * or when that response is not considered satisfying. + *

+ * Once we enter redundant mode, we start duplicating all queries and sending + * them to both our primary and backup resolvers (in case we have any). We then + * always return the first response we get, regardless of who sent it. + *

+ * We exit redundant mode after receiving DNS_REDEMPTION consecutive + * timely and correct responses from our primary resolver. + * + * @author Emil Ivov + */ +public interface CustomResolver + extends Resolver +{ + /** + * The default number of milliseconds it takes us to get into redundant + * mode while waiting for a DNS query response. + */ + public static final int DNS_PATIENCE = 1500; + + /** + * The name of the property that allows us to override the default + * DNS_PATIENCE value. + */ + public static final String PNAME_DNS_PATIENCE + = "net.java.sip.communicator.util.dns.DNS_PATIENCE"; + + /** + * The default number of times that the primary DNS would have to provide a + * faster response than the backup resolver before we consider it safe + * enough to exit redundant mode. + */ + public static final int DNS_REDEMPTION = 3; + + /** + * The name of the property that allows us to override the default + * DNS_REDEMPTION value. + */ + public static final String PNAME_DNS_REDEMPTION + = "net.java.sip.communicator.util.dns.DNS_REDEMPTION"; + + /** + * The currently configured number of times that the primary DNS would have + * to provide a faster response than the backup resolver before we consider + * it safe enough to exit redundant mode. + */ + public static int currentDnsRedemption = DNS_REDEMPTION; + + /** + * The name of the property that enables or disables the DNSSEC resolver + * (instead of a normal, non-validating local resolver). + */ + public static final String PNAME_DNSSEC_RESOLVER_ENABLED + = "net.java.sip.communicator.util.dns.DNSSEC_ENABLED"; + + /** + * Default value of @see PNAME_DNSSEC_RESOLVER_ENABLED. + */ + public static final boolean PDEFAULT_DNSSEC_RESOLVER_ENABLED = false; + + /** + * Resets resolver configuration and populate our default resolver + * with the newly configured servers. + */ + public void reset(); +} diff --git a/src/net/java/sip/communicator/service/dns/ParallelResolver.java b/src/net/java/sip/communicator/service/dns/ParallelResolver.java deleted file mode 100644 index 7c172d4b0..000000000 --- a/src/net/java/sip/communicator/service/dns/ParallelResolver.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.service.dns; - -import java.io.*; -import java.net.*; -import java.util.*; - -import org.xbill.DNS.*; - -/** - * The purpose of this class is to help avoid the significant delays that occur - * in networks where DNS servers would ignore SRV, NAPTR, and sometimes even - * A/AAAA queries (i.e. without even sending an error response). We also try to - * handle cases where DNS servers may return empty responses to some records. - *

- * We achieve this by entering a redundant mode whenever we detect an abnormal - * delay (longer than DNS_PATIENCE) while waiting for a DNS resonse, - * or when that response is not considered satisfying. - *

- * Once we enter redundant mode, we start duplicating all queries and sending - * them to both our primary and backup resolvers (in case we have any). We then - * always return the first response we get, regardless of who sent it. - *

- * We exit redundant mode after receiving DNS_REDEMPTION consecutive - * timely and correct responses from our primary resolver. - * - * @author Emil Ivov - */ -public interface ParallelResolver - extends Resolver -{ - /** - * The default number of milliseconds it takes us to get into redundant - * mode while waiting for a DNS query response. - */ - public static final int DNS_PATIENCE = 1500; - - /** - * The name of the property that allows us to override the default - * DNS_PATIENCE value. - */ - public static final String PNAME_DNS_PATIENCE - = "net.java.sip.communicator.util.dns.DNS_PATIENCE"; - - /** - * The default number of times that the primary DNS would have to provide a - * faster response than the backup resolver before we consider it safe - * enough to exit redundant mode. - */ - public static final int DNS_REDEMPTION = 3; - - /** - * The name of the property that allows us to override the default - * DNS_REDEMPTION value. - */ - public static final String PNAME_DNS_REDEMPTION - = "net.java.sip.communicator.util.dns.DNS_REDEMPTION"; - - /** - * The currently configured number of times that the primary DNS would have - * to provide a faster response than the backup resolver before we consider - * it safe enough to exit redundant mode. - */ - public static int currentDnsRedemption = DNS_REDEMPTION; - - /** - * The name of the property that enables or disables the DNSSEC resolver - * (instead of a normal, non-validating local resolver). - */ - public static final String PNAME_DNSSEC_RESOLVER_ENABLED - = "net.java.sip.communicator.util.dns.DNSSEC_ENABLED"; - - /** - * Default value of @see PNAME_DNSSEC_RESOLVER_ENABLED. - */ - public static final boolean PDEFAULT_DNSSEC_RESOLVER_ENABLED = false; - - /** - * Replaces the default resolver used by this class. Mostly meant for - * debugging. - * - * @param resolver the resolver we'd like to use by default from now on. - */ - public void setDefaultResolver(Resolver resolver); - - /** - * Returns the default resolver used by this class. Mostly meant for - * debugging. - * - * @return the resolver this class consults first. - */ - public Resolver getDefaultResolver(); - - /** - * Creates a ParallelResolver that would use the specified array - * of backupServers if the default DNS doesn't seem to be doing - * that well. - * - * @param backupServers the list of backup DNS servers that we should use - * if, and only if, the default servers don't seem to work that well. - */ - public void setBackupServers(InetSocketAddress[] backupServers); - - /** - * Sends a message and waits for a response. - * - * @param query The query to send. - * @return The response - * - * @throws IOException An error occurred while sending or receiving. - */ - public Message send(Message query) - throws IOException; - /** - * Supposed to asynchronously send messages but not currently implemented. - * - * @param query The query to send - * @param listener The object containing the callbacks. - * @return An identifier, which is also a parameter in the callback - */ - public Object sendAsync(final Message query, - final ResolverListener listener); - - /** - * Sets the port to communicate on with the default servers. - * - * @param port The port to send messages to - */ - public void setPort(int port); - - /** - * Sets whether TCP connections will be sent by default with the default - * resolver. Backup servers would always be contacted the same way. - * - * @param flag Indicates whether TCP connections are made - */ - public void setTCP(boolean flag); - - /** - * Sets whether truncated responses will be ignored. If not, a truncated - * response over UDP will cause a retransmission over TCP. Backup servers - * would always be contacted the same way. - * - * @param flag Indicates whether truncated responses should be ignored. - */ - public void setIgnoreTruncation(boolean flag); - - /** - * Sets the EDNS version used on outgoing messages. - * - * @param level The EDNS level to use. 0 indicates EDNS0 and -1 indicates no - * EDNS. - * @throws IllegalArgumentException An invalid level was indicated. - */ - public void setEDNS(int level); - - /** - * Sets the EDNS information on outgoing messages. - * - * @param level The EDNS level to use. 0 indicates EDNS0 and -1 indicates no - * EDNS. - * @param payloadSize The maximum DNS packet size that this host is capable - * of receiving over UDP. If 0 is specified, the default (1280) is used. - * @param flags EDNS extended flags to be set in the OPT record. - * @param options EDNS options to be set in the OPT record, specified as a - * List of OPTRecord.Option elements. - * - * @throws IllegalArgumentException An invalid field was specified. - * @see OPTRecord - */ - @SuppressWarnings("rawtypes") // that's the way it is in dnsjava - public void setEDNS(int level, int payloadSize, int flags, List options); - - /** - * Specifies the TSIG key that messages will be signed with - * @param key The key - */ - public void setTSIGKey(TSIG key); - - /** - * Sets the amount of time to wait for a response before giving up. - * - * @param secs The number of seconds to wait. - * @param msecs The number of milliseconds to wait. - */ - public void setTimeout(int secs, int msecs); - - /** - * Sets the amount of time to wait for a response before giving up. - * - * @param secs The number of seconds to wait. - */ - public void setTimeout(int secs); - - /** - * Resets resolver configuration and populate our default resolver - * with the newly configured servers. - */ - public void reset(); - - /** - * Sets a DNSSEC resolver as default resolver on lookup when DNSSEC is - * enabled; creates a standard lookup otherwise. - */ - public void refreshResolver(); -} diff --git a/src/net/java/sip/communicator/util/NetworkUtils.java b/src/net/java/sip/communicator/util/NetworkUtils.java index 1099b861c..fe481ea71 100644 --- a/src/net/java/sip/communicator/util/NetworkUtils.java +++ b/src/net/java/sip/communicator/util/NetworkUtils.java @@ -6,14 +6,11 @@ */ package net.java.sip.communicator.util; -import java.beans.*; import java.net.*; import java.text.*; import java.util.*; -import java.util.concurrent.atomic.*; import net.java.sip.communicator.service.dns.*; -import net.java.sip.communicator.service.netaddr.event.*; import net.java.sip.communicator.util.SRVRecord; @@ -82,47 +79,6 @@ public class NetworkUtils */ private static Random portNumberGenerator = new Random(); - /** - * The name of the property that users may use to override the - * address of our backup DNS resolver. - */ - public static final String PNAME_BACKUP_RESOLVER - = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER"; - - /** - * The name of the property that users may use to disable - * our backup DNS resolver. - */ - public static final String PNAME_BACKUP_RESOLVER_ENABLED - = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_ENABLED"; - - /** - * The default of the property that users may use to disable - * our backup DNS resolver. - */ - public static final boolean PDEFAULT_BACKUP_RESOLVER_ENABLED = true; - - /** - * The name of the property that users may use to override the port - * of our backup DNS resolver. - */ - public static final String PNAME_BACKUP_RESOLVER_PORT - = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_PORT"; - - /** - * The address of the backup resolver we would use by default. - */ - public static final String DEFAULT_BACKUP_RESOLVER - = "backup-resolver.jitsi.net"; - - /** - * The name of the property that users may use to override the - * IP address of our backup DNS resolver. This is only used when the - * backup resolver name cannot be determined. - */ - public static final String PNAME_BACKUP_RESOLVER_FALLBACK_IP - = "net.java.sip.communicator.util.dns.BACKUP_RESOLVER_FALLBACK_IP"; - /** * The name of the boolean property that defines whether all domain names * looked up from Jitsi should be treated as absolute. @@ -135,27 +91,6 @@ public class NetworkUtils */ public static final boolean PDEFAULT_DNS_ALWAYS_ABSOLUTE = false; - /** - * The DNSjava resolver that we use with SRV and NAPTR queries in order to - * try and smooth the problem of DNS servers that silently drop them. - */ - private static Resolver parallelResolver = null; - - /** - * Monitor object to set or reset the parallel resolver. - */ - private final static Object parallelResolverLock = new Object(); - - /** - * Initialization flag for {@link #netListener} - */ - private static final AtomicBoolean netListenerAdded = new AtomicBoolean(); - - /** - * Listener for network change events to reset the DNS resolvers. - */ - private static final NetworkListener netListener = new NetworkListener(); - /** * A random number generator. */ @@ -1269,17 +1204,6 @@ private static boolean isMappedIPv4Addr(byte[] address) private static Lookup createLookup(String domain, int type) throws TextParseException { - // listens for network changes up/down so we can reset - // dns configuration - if(netListenerAdded.compareAndSet(false, true)) - { - if(logger.isDebugEnabled()) - logger.debug("NetConfigChange listener added: " - + netListener.hashCode()); - UtilActivator.getNetworkAddressManagerService() - .addNetworkConfigurationChangeListener(netListener); - } - // make domain name absolute if requested if(UtilActivator.getConfigurationService().getBoolean( PNAME_DNS_ALWAYS_ABSOLUTE, @@ -1303,198 +1227,9 @@ private static Lookup createLookup(String domain, int type) logger.trace(sb.toString()); } - if(!UtilActivator.getConfigurationService() - .getBoolean(PNAME_BACKUP_RESOLVER_ENABLED, - PDEFAULT_BACKUP_RESOLVER_ENABLED) - || UtilActivator.getConfigurationService().getBoolean( - ParallelResolver.PNAME_DNSSEC_RESOLVER_ENABLED, - ParallelResolver.PDEFAULT_DNSSEC_RESOLVER_ENABLED - )) - { - return lookup; - } - - //Initiate our global parallel resolver if this is our first ever - //DNS query. The lock here is heavy but necessary as a) the config - //form can cause an intermittent reset and b) multiple accounts signing - //in at the same time could cause multiple ParallelResolver instances - synchronized(parallelResolverLock) - { - if(parallelResolver == null) - { - try - { - String rslvrAddrStr - = UtilActivator.getConfigurationService() - .getString(PNAME_BACKUP_RESOLVER, - DEFAULT_BACKUP_RESOLVER); - String customRslvrIP - = UtilActivator.getConfigurationService().getString( - PNAME_BACKUP_RESOLVER_FALLBACK_IP, - UtilActivator.getResources().getSettingsString( - PNAME_BACKUP_RESOLVER_FALLBACK_IP)); - - InetAddress resolverAddress = null; - - try - { - resolverAddress = getInetAddress(rslvrAddrStr); - } - catch(UnknownHostException exc) - { - logger.warn("Oh! Seems like our primary DNS is down!" - + "Don't panic! We'll try to fall back to " - + customRslvrIP); - } - - if(resolverAddress == null) - { - /* name resolution failed for backup DNS resolver, - * try with the IP address of the default backup resolver - */ - resolverAddress = getInetAddress(customRslvrIP); - } - - int rslvrPort = UtilActivator.getConfigurationService().getInt( - PNAME_BACKUP_RESOLVER_PORT, SimpleResolver.DEFAULT_PORT); - - InetSocketAddress resolverSockAddr - = new InetSocketAddress(resolverAddress, rslvrPort); - - parallelResolver = UtilActivator.getParallelResolver(); - if (parallelResolver != null - && parallelResolver instanceof ParallelResolver) - { - ((ParallelResolver) parallelResolver).setBackupServers( - new InetSocketAddress[]{resolverSockAddr}); - } - - //listens for changes on the parallel DNS settings - UtilActivator.getConfigurationService() - .addPropertyChangeListener( - new DnsConfigurationChangeListener()); - } - catch(Throwable t) - { - //We don't want to a problem with our parallel resolver to - //make our entire DNS resolution to fail so in case something - //goes wrong during initialization so we default to the - //dns java default resolver - logger.info("failed to initialize parallel resolver. we will " - +"be using dnsjava's default one instead"); - - if(logger.isDebugEnabled()) - logger.debug("exception was: ", t); - - parallelResolver = Lookup.getDefaultResolver(); - } - } - - lookup.setResolver(parallelResolver); - } - return lookup; } - /** - * Gets the default port used by DNS servers obtained through - * SimpleResolver.DEFAULT_PORT. - * @return The default DNS server port - */ - public static short getDefaultDnsPort() - { - return SimpleResolver.DEFAULT_PORT; - } - - /** - * Listens when network is going from down to up and - * resets dns configuration. - */ - private static class NetworkListener - implements NetworkConfigurationChangeListener - { - /** - * Fired when a change has occurred in the - * computer network configuration. - * - * @param event the change event. - */ - public void configurationChanged(ChangeEvent event) - { - if((event.getType() == ChangeEvent.IFACE_UP - || event.getType() == ChangeEvent.DNS_CHANGE) - && !event.isInitial()) - { - reloadDnsResolverConfig(); - } - } - } - - /** - * Listens for changes in the DNS configuration and resets - * the parallelResolver when necessary - */ - private static class DnsConfigurationChangeListener - implements PropertyChangeListener - { - @SuppressWarnings("serial") - private final Set configNames = new HashSet(5){{ - add(PNAME_BACKUP_RESOLVER); - add(PNAME_BACKUP_RESOLVER_FALLBACK_IP); - add(PNAME_BACKUP_RESOLVER_PORT); - add(ParallelResolver.PNAME_DNS_PATIENCE); - add(ParallelResolver.PNAME_DNS_REDEMPTION); - }}; - - public void propertyChange(PropertyChangeEvent evt) - { - if(configNames.contains(evt.getPropertyName()) && - parallelResolver != null) - { - parallelResolver = null; - logger.info("Parallel DNS resolver reset"); - } - } - } - - /** - * Reloads dns server configuration in the resolver. - */ - public static void reloadDnsResolverConfig() - { - // reread system dns configuration - ResolverConfig.refresh(); - try - { - ((ParallelResolver) parallelResolver).refreshResolver(); - } - catch(Throwable t) - { - logger.error("Error reloading dns util activator"); - } - if(parallelResolver instanceof ParallelResolver) - { - //needs a separate lock object because the parallelResolver could - //be set to null in between - synchronized(parallelResolverLock) - { - ((ParallelResolver)parallelResolver).reset(); - } - } - - if(logger.isTraceEnabled()) - { - StringBuilder sb = new StringBuilder(); - sb.append("Reloaded resolver config, active DNS servers are: "); - for(String s : ResolverConfig.getCurrentConfig().servers()) - { - sb.append(s); - sb.append(", "); - } - logger.trace(sb.toString()); - } - } - /** * Compares two DNS names against each other. Helper method to avoid the * export of DNSJava. diff --git a/src/net/java/sip/communicator/util/UtilActivator.java b/src/net/java/sip/communicator/util/UtilActivator.java index 0bafaca5c..328d2f6d5 100644 --- a/src/net/java/sip/communicator/util/UtilActivator.java +++ b/src/net/java/sip/communicator/util/UtilActivator.java @@ -9,9 +9,7 @@ //import java.awt.image.*; import java.util.*; -import net.java.sip.communicator.service.dns.*; import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.netaddr.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.resources.*; @@ -50,20 +48,12 @@ public class UtilActivator private static MediaService mediaService; - private static ParallelResolver parallelResolver; - public static BundleContext bundleContext; private static AccountManager accountManager; private static AlertUIService alertUIService; - /** - * Network address manager service will inform us for changes in - * network configuration. - */ - private static NetworkAddressManagerService networkAddressManagerService; - /** * Calls Thread.setUncaughtExceptionHandler() * @@ -151,22 +141,6 @@ public static ResourceManagementService getResources() return resourceService; } - /** - * Returns the service giving access to current network configuration. - * - * @return the service giving access to current network configuration. - */ - public static NetworkAddressManagerService getNetworkAddressManagerService() - { - if (networkAddressManagerService == null) - { - networkAddressManagerService = - ServiceUtils.getService(bundleContext, - NetworkAddressManagerService.class); - } - return networkAddressManagerService; - } - /** * Gets the UIService instance registered in the * BundleContext of the UtilActivator. @@ -270,21 +244,6 @@ public static MediaConfigurationService getMediaConfiguration() return providerFactoriesMap; } - /** - * - * @return - */ - public static ParallelResolver getParallelResolver() - { - if (parallelResolver == null) - { - parallelResolver - = ServiceUtils.getService( bundleContext, - ParallelResolver.class); - } - return parallelResolver; - } - /** * Returns the AccountManager obtained from the bundle context. * @return the AccountManager obtained from the bundle context @@ -299,7 +258,6 @@ public static AccountManager getAccountManager() return accountManager; } - /** * Returns the MetaContactListService obtained from the bundle * context. diff --git a/src/net/java/sip/communicator/util/util.manifest.mf b/src/net/java/sip/communicator/util/util.manifest.mf index 54512ed30..11b391a8b 100644 --- a/src/net/java/sip/communicator/util/util.manifest.mf +++ b/src/net/java/sip/communicator/util/util.manifest.mf @@ -33,8 +33,6 @@ Import-Package: com.sun.awt, net.java.sip.communicator.service.resources, net.java.sip.communicator.service.keybindings, net.java.sip.communicator.service.msghistory, - net.java.sip.communicator.service.netaddr, - net.java.sip.communicator.service.netaddr.event, net.java.sip.communicator.service.contactlist, net.java.sip.communicator.service.browserlauncher, net.java.sip.communicator.service.protocol,