Make the ParallelResolver and the DnssecResolver two distinct DNS service implementations

cusax-fix
Ingo Bauersachs 14 years ago
parent 07a34a3f13
commit 30363404e8

Binary file not shown.

@ -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);
}
}
}

@ -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 <tt>Logger</tt> used by the <tt>UtilActivator</tt> 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 <tt>Thread.setUncaughtExceptionHandler()</tt>
*
@ -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());
}
}

@ -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 <tt>Logger</tt> used by the <tt>ParallelResolver</tt>
@ -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
* <tt>DNS_PATIENCE</tt> 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
* <tt>DNS_REDEMPTION</tt> 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 <tt>backupServers</tt> 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<String> configNames = new HashSet<String>(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();
}
}

@ -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()
{
}
}

@ -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,

@ -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();
}
}

@ -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(

@ -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.
* <p>
* We achieve this by entering a redundant mode whenever we detect an abnormal
* delay (longer than <tt>DNS_PATIENCE</tt>) while waiting for a DNS resonse,
* or when that response is not considered satisfying.
* <p>
* 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.
* <p>
* We exit redundant mode after receiving <tt>DNS_REDEMPTION</tt> 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
* <tt>DNS_PATIENCE</tt> 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
* <tt>DNS_REDEMPTION</tt> 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();
}

@ -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.
* <p>
* We achieve this by entering a redundant mode whenever we detect an abnormal
* delay (longer than <tt>DNS_PATIENCE</tt>) while waiting for a DNS resonse,
* or when that response is not considered satisfying.
* <p>
* 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.
* <p>
* We exit redundant mode after receiving <tt>DNS_REDEMPTION</tt> 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
* <tt>DNS_PATIENCE</tt> 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
* <tt>DNS_REDEMPTION</tt> 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 <tt>ParallelResolver</tt> that would use the specified array
* of <tt>backupServers</tt> 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();
}

@ -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<String> configNames = new HashSet<String>(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.

@ -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 <tt>Thread.setUncaughtExceptionHandler()</tt>
*
@ -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 <tt>UIService</tt> instance registered in the
* <tt>BundleContext</tt> of the <tt>UtilActivator</tt>.
@ -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 <tt>AccountManager</tt> obtained from the bundle context.
* @return the <tt>AccountManager</tt> obtained from the bundle context
@ -299,7 +258,6 @@ public static AccountManager getAccountManager()
return accountManager;
}
/**
* Returns the <tt>MetaContactListService</tt> obtained from the bundle
* context.

@ -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,

Loading…
Cancel
Save