aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/felix.unit.test.properties8
-rw-r--r--lib/installer-exclude/cglib-nodep.osgi-2.1_3.jarbin0 -> 334368 bytes
-rw-r--r--lib/installer-exclude/easymock-3.1.jarbin0 -> 113786 bytes
-rw-r--r--lib/installer-exclude/objenesis-1.2.jarbin0 -> 36089 bytes
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java812
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/AutoProxyConnection.java384
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java114
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java163
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java3
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf1
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java3
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java427
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetPresence.java6
-rw-r--r--test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf6
16 files changed, 1173 insertions, 758 deletions
diff --git a/lib/felix.unit.test.properties b/lib/felix.unit.test.properties
index fabf3dc..4ff1686 100644
--- a/lib/felix.unit.test.properties
+++ b/lib/felix.unit.test.properties
@@ -28,7 +28,8 @@ org.osgi.framework.system.packages.extra= \
sun.net.util; \
sun.net.dns; \
sun.security.action; \
- sun.security.pkcs11;
+ sun.security.pkcs11; \
+ sun.reflect;
#
@@ -41,7 +42,10 @@ org.osgi.framework.system.packages.extra= \
#
felix.auto.start.10= \
- file:lib/bundle/junit.jar
+ reference:file:lib/bundle/junit.jar \
+ reference:file:lib/installer-exclude/easymock-3.1.jar \
+ reference:file:lib/installer-exclude/objenesis-1.2.jar \
+ reference:file:lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar
# file:lib/bundle/shell.jar \
# file:lib/bundle/bundlerepository.jar \
# file:lib/bundle/servicebinder.jar \
diff --git a/lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar b/lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar
new file mode 100644
index 0000000..3064d35
--- /dev/null
+++ b/lib/installer-exclude/cglib-nodep.osgi-2.1_3.jar
Binary files differ
diff --git a/lib/installer-exclude/easymock-3.1.jar b/lib/installer-exclude/easymock-3.1.jar
new file mode 100644
index 0000000..d8232ab
--- /dev/null
+++ b/lib/installer-exclude/easymock-3.1.jar
Binary files differ
diff --git a/lib/installer-exclude/objenesis-1.2.jar b/lib/installer-exclude/objenesis-1.2.jar
new file mode 100644
index 0000000..759b623
--- /dev/null
+++ b/lib/installer-exclude/objenesis-1.2.jar
Binary files differ
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 1c782e5..6cff570 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
@@ -9,6 +9,7 @@ package net.java.sip.communicator.impl.protocol.sip;
import gov.nist.javax.sip.address.*;
import gov.nist.javax.sip.header.*;
import gov.nist.javax.sip.message.*;
+import net.java.sip.communicator.impl.protocol.sip.net.*;
import net.java.sip.communicator.impl.protocol.sip.security.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
@@ -155,31 +156,9 @@ public class ProtocolProviderServiceSipImpl
private SipSecurityManager sipSecurityManager = null;
/**
- * The address and port of an outbound proxy if we have one (remains null
- * if we are not using a proxy).
+ * Address resolver for the outbound proxy connection.
*/
- private InetSocketAddress outboundProxySocketAddress = null;
-
- /**
- * The transport used by our outbound proxy (remains null
- * if we are not using a proxy).
- */
- private String outboundProxyTransport = null;
-
- /**
- * Array of ordered addresses to try when connecting.
- */
- private InetSocketAddress[] connectionAddresses = null;
-
- /**
- * Array of ordered addresses transports to try when connecting.
- */
- private String[] connectionTransports = null;
-
- /**
- * The InetAddress we are connecting to, outbound proxy.
- */
- private InetSocketAddress currentConnectionAddress = null;
+ private ProxyConnection connection;
/**
* The logo corresponding to the jabber protocol.
@@ -320,11 +299,17 @@ public class ProtocolProviderServiceSipImpl
sipSecurityManager.setSecurityAuthority(authority);
initRegistrarConnection();
- initOutboundProxy(0);
-
//connect to the Registrar.
- if (sipRegistrarConnection != null)
- sipRegistrarConnection.register();
+ connection = ProxyConnection.create(this);
+ if(!registerUsingNextAddress())
+ {
+ logger.error("No address found for " + this);
+ fireRegistrationStateChanged(
+ RegistrationState.UNREGISTERED,
+ RegistrationState.CONNECTION_FAILED,
+ RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND,
+ "Invalid or inaccessible server address.");
+ }
}
/**
@@ -340,7 +325,7 @@ public class ProtocolProviderServiceSipImpl
{
if(getRegistrationState().equals(RegistrationState.UNREGISTERED)
|| getRegistrationState().equals(RegistrationState.UNREGISTERING)
- || getRegistrationState().equals(RegistrationState.CONNECTION_FAILED))
+ || getRegistrationState().equals(RegistrationState.CONNECTION_FAILED))
{
return;
}
@@ -1013,9 +998,7 @@ public class ProtocolProviderServiceSipImpl
addressFactory = null;
sipSecurityManager = null;
- connectionAddresses = null;
- connectionTransports = null;
- currentConnectionAddress = null;
+ connection = null;
methodProcessors.clear();
@@ -1386,18 +1369,14 @@ public class ProtocolProviderServiceSipImpl
logger.trace("Query for a " + transport + " listening point");
//override the transport in case we have an outbound proxy.
- if(outboundProxySocketAddress != null)
+ if(connection.getAddress() != null)
{
if (logger.isTraceEnabled())
logger.trace("Will use proxy address");
- transport = outboundProxyTransport;
+ transport = connection.getTransport();
}
- if( transport == null
- || transport.trim().length() == 0
- || ( ! transport.trim().equalsIgnoreCase(ListeningPoint.TCP)
- && ! transport.trim().equalsIgnoreCase(ListeningPoint.UDP)
- && ! transport.trim().equalsIgnoreCase(ListeningPoint.TLS)))
+ if(!isValidTransport(transport))
{
transport = getDefaultTransport();
}
@@ -1435,26 +1414,9 @@ public class ProtocolProviderServiceSipImpl
* @return the listening point that we should use to contact the
* intended destination.
*/
- public ListeningPoint getListeningPoint(Address intendedDestination)
- {
- return getListeningPoint((SipURI)intendedDestination.getURI());
- }
-
- /**
- * Returns the default listening point that we should use to contact the
- * intended destination.
- *
- * @param intendedDestination the address that we will be trying to contact
- * through the listening point we are trying to obtain.
- *
- * @return the listening point that we should use to contact the
- * intended destination.
- */
public ListeningPoint getListeningPoint(SipURI intendedDestination)
{
- String transport = intendedDestination.getTransportParam();
-
- return getListeningPoint(transport);
+ return getListeningPoint(intendedDestination.getTransportParam());
}
/**
@@ -1652,48 +1614,9 @@ public class ProtocolProviderServiceSipImpl
}
}
- /**
- * In case we are using an outbound proxy this method returns
- * a suitable string for use with Router.
- * The method returns <tt>null</tt> otherwise.
- *
- * @return the string of our outbound proxy if we are using one and
- * <tt>null</tt> otherwise.
- */
- public String getOutboundProxyString()
+ public ProxyConnection getConnection()
{
- InetAddress proxyAddress = outboundProxySocketAddress.getAddress();
- StringBuilder proxyStringBuffer
- = new StringBuilder(proxyAddress.getHostAddress());
-
- if(proxyAddress instanceof Inet6Address)
- {
- proxyStringBuffer.insert(0, '[');
- proxyStringBuffer.append(']');
- }
-
- proxyStringBuffer.append(':');
- proxyStringBuffer.append(outboundProxySocketAddress.getPort());
- proxyStringBuffer.append('/');
- proxyStringBuffer.append(outboundProxyTransport);
-
- return proxyStringBuffer.toString();
- }
-
- /**
- * Compares an InetAddress against the active outbound proxy. The comparison
- * is by reference, not equals.
- *
- * @param addressToTest The addres to test.
- * @return True when the InetAddress is the same as the outbound proxy.
- */
- public boolean matchesInetAddress(InetAddress addressToTest)
- {
- // if the proxy is not yet initialized then this is not the provider that
- // caused this comparison
- if(outboundProxySocketAddress == null)
- return false;
- return addressToTest == outboundProxySocketAddress.getAddress();
+ return connection;
}
/**
@@ -1704,259 +1627,7 @@ public class ProtocolProviderServiceSipImpl
*/
public boolean isSignalingTransportSecure()
{
- return ListeningPoint.TLS.equalsIgnoreCase(outboundProxyTransport);
- }
-
- /**
- * Extracts all properties concerning the usage of an outbound proxy for
- * this account.
- * @param ix index of the address to use.
- */
- private void initOutboundProxy(int ix)
- {
- //First init the proxy address
- String proxyAddressStr =
- accountID
- .getAccountPropertyString(ProtocolProviderFactory.
- PROXY_ADDRESS);
- boolean proxyAddressAndPortEntered = false;
-
- if(proxyAddressStr == null || proxyAddressStr.trim().length() == 0
- || accountID.getAccountPropertyBoolean(
- ProtocolProviderFactory.PROXY_AUTO_CONFIG, false))
- {
- String userID = accountID.getAccountPropertyString(
- ProtocolProviderFactory.USER_ID);
-
- int domainIx = userID.indexOf("@");
-
- if(domainIx > 0)
- {
- proxyAddressStr = userID.substring(domainIx + 1);
- }
- else
- {
- proxyAddressStr = accountID
- .getAccountPropertyString(ProtocolProviderFactory.
- SERVER_ADDRESS);
-
- if(proxyAddressStr == null || proxyAddressStr.trim().length() == 0)
- {
- /* registrarless account */
- return;
- }
- }
- }
- else
- {
- if(accountID.getAccountProperty(ProtocolProviderFactory.PROXY_PORT)
- != null)
- {
- proxyAddressAndPortEntered = true;
- }
- }
-
- //init proxy port
- int proxyPort = ListeningPoint.PORT_5060;
-
- //proxy transport
- String proxyTransport = accountID.getAccountPropertyString(
- ProtocolProviderFactory.PREFERRED_TRANSPORT);
-
- if (proxyTransport != null && proxyTransport.length() > 0)
- {
- if (!proxyTransport.equals(ListeningPoint.UDP)
- && !proxyTransport.equals(ListeningPoint.TCP)
- && !proxyTransport.equals(ListeningPoint.TLS))
- {
- throw new IllegalArgumentException(proxyTransport
- + " is not a valid transport protocol. Transport must be "
- + "left blank or set to TCP, UDP or TLS.");
- }
- }
- else
- {
- proxyTransport = getDefaultTransport();
- }
-
- InetSocketAddress proxySocketAddress = null;
- try
- {
- //check if user has overridden proxy port.
- proxyPort = accountID.getAccountPropertyInt(
- ProtocolProviderFactory.PROXY_PORT,
- proxyPort);
- if (proxyPort > NetworkUtils.MAX_PORT_NUMBER)
- {
- throw new IllegalArgumentException(proxyPort + " is larger than "
- + NetworkUtils.MAX_PORT_NUMBER
- + " and does not therefore represent a valid port number.");
- }
-
- if(accountID.getAccountPropertyBoolean(
- ProtocolProviderFactory.PROXY_AUTO_CONFIG, false))
- {
- if(connectionAddresses == null)
- {
- ArrayList<InetSocketAddress> proxySocketAddressesList
- = new ArrayList<InetSocketAddress>();
- ArrayList<String> proxyTransportsList
- = new ArrayList<String>();
-
- resolveSipAddress(
- proxyAddressStr,
- proxyTransport,
- proxySocketAddressesList,
- proxyTransportsList,
- true);
-
- connectionTransports = proxyTransportsList.toArray(
- new String[proxyTransportsList.size()]);
- connectionAddresses = proxySocketAddressesList.toArray(
- new InetSocketAddress[proxySocketAddressesList.size()]);
- }
-
- proxyTransport = connectionTransports[ix];
- proxySocketAddress = connectionAddresses[ix];
- }
- else
- {
- // according rfc3263 if proxy address and port are
- // explicitly entered don't make SRV queries
- if(proxyAddressAndPortEntered)
- {
- if(connectionAddresses == null)
- {
- ArrayList<InetSocketAddress> addresses
- = new ArrayList<InetSocketAddress>();
-
- resolveAddresses(
- proxyAddressStr,
- addresses,
- proxyPort);
-
- connectionAddresses = addresses.toArray(
- new InetSocketAddress[addresses.size()]);
-
- // we have transport, use it for all addresses
- connectionTransports = new String[addresses.size()];
- Arrays.fill(connectionTransports, proxyTransport);
- }
- // only set if enough results found
- if(connectionAddresses.length > ix)
- proxySocketAddress = connectionAddresses[ix];
- }
- else
- {
- if(connectionAddresses == null)
- {
- ArrayList<InetSocketAddress> proxySocketAddressesList
- = new ArrayList<InetSocketAddress>();
- ArrayList<String> proxyTransportsList
- = new ArrayList<String>();
-
- resolveSipAddress(
- proxyAddressStr,
- proxyTransport,
- proxySocketAddressesList,
- proxyTransportsList,
- false);
-
- connectionTransports = proxyTransportsList.toArray(
- new String[proxyTransportsList.size()]);
- connectionAddresses =
- proxySocketAddressesList.toArray(
- new InetSocketAddress[
- proxySocketAddressesList.size()]);
- }
-
- proxyTransport = connectionTransports[ix];
- proxySocketAddress = connectionAddresses[ix];
- }
- }
-
- if(proxySocketAddress == null)
- throw new UnknownHostException();
-
- if(this.currentConnectionAddress == null)
- this.currentConnectionAddress = proxySocketAddress;
-
- proxyPort = proxySocketAddress.getPort();
-
- if (logger.isTraceEnabled())
- logger.trace("Setting proxy address = " + proxyAddressStr);
-
- // We should set here the property to indicate that the proxy
- // address is validated. When we load stored accounts we check
- // this property in order to prevent checking again the proxy
- // address. this is needed because in the case we don't have
- // network while loading the application we still want to have
- // our accounts loaded.
- accountID.putAccountProperty(
- ProtocolProviderFactory.PROXY_ADDRESS_VALIDATED,
- Boolean.toString(true));
- }
- catch (UnknownHostException ex)
- {
- logger.error(proxyAddressStr
- + " appears to be an either invalid"
- + " or inaccessible address.",
- ex);
-
- boolean isProxyValidated =
- accountID.getAccountPropertyBoolean(
- ProtocolProviderFactory.PROXY_ADDRESS_VALIDATED, false);
-
- // We should check here if the proxy address was already validated.
- // When we load stored accounts we want to prevent checking again the
- // proxy address. This is needed because in the case we don't have
- // network while loading the application we still want to have our
- // accounts loaded.
- if (!isProxyValidated)
- {
- throw new IllegalArgumentException(
- proxyAddressStr
- + " appears to be an either invalid or"
- + " inaccessible address.",
- ex);
- }
- }
-
- if(connectionAddresses == null
- || connectionAddresses.length == 0)
- {
- sipRegistrarConnection = null;
- // no addresses, maybe network down, lets try
- // resolving them later
- connectionAddresses = null;
- connectionTransports = null;
-
- fireRegistrationStateChanged(
- RegistrationState.UNREGISTERED,
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_SERVER_NOT_FOUND,
- "Invalid or inaccessible server address.");
-
- return;
- }
-
- // Return if no proxy is specified or if the proxyAddress is null.
- if(proxySocketAddress == null)
- {
- return;
- }
-
- // lets change registrar connections transport
- // make sure it reflects the transport we choose from DNS records
- // registrar connection can be null while creating accounts
- if(sipRegistrarConnection != null)
- sipRegistrarConnection.setTransport(proxyTransport);
-
- //store a reference to our sip proxy so that we can use it when
- //constructing via and contact headers.
- this.outboundProxySocketAddress
- = new InetSocketAddress(proxySocketAddress.getAddress(), proxyPort);
- this.outboundProxyTransport = proxyTransport;
+ return ListeningPoint.TLS.equalsIgnoreCase(connection.getTransport());
}
/**
@@ -2057,20 +1728,13 @@ public class ProtocolProviderServiceSipImpl
*/
public String getDefaultTransport()
{
- if( sipRegistrarConnection != null)
- {
- String registrarTransport = sipRegistrarConnection.getTransport();
- if( registrarTransport != null
- && registrarTransport.length() > 0)
- {
- return registrarTransport;
- }
- }
-
- if(outboundProxySocketAddress != null
- && outboundProxyTransport != null)
+ if(sipRegistrarConnection != null
+ && !sipRegistrarConnection.isRegistrarless()
+ && connection != null
+ && connection.getAddress() != null
+ && connection.getTransport() != null)
{
- return outboundProxyTransport;
+ return connection.getTransport();
}
else
{
@@ -2109,19 +1773,6 @@ public class ProtocolProviderServiceSipImpl
}
/**
- * Returns the listening point that corresponds to the transport returned by
- * getDefaultTransport(). Equivalent to calling
- * getListeningPoint(getDefaultTransport())
- *
- * @return the Jain SipProvider that corresponds to the transport returned
- * by getDefaultTransport().
- */
- public ListeningPoint getDefaultListeningPoint()
- {
- return getListeningPoint(getDefaultTransport());
- }
-
- /**
* Returns the display name string that the user has set as a display name
* for this account.
*
@@ -2518,320 +2169,6 @@ public class ProtocolProviderServiceSipImpl
}
/**
- * Tries to resolve <tt>address</tt> into a valid InetSocketAddress using
- * an <tt>SRV</tt> 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 <tt>address</tt>, 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
- * address.
- * @param resultAddresses the list that will be filled with the result
- * addresses. An <tt>InetSocketAddress</tt> instances containing the
- * <tt>SRV</tt> record for <tt>address</tt> if one has been defined and the
- * A/AAAA record where it hasn't.
- * @param resultTransports the transports for the <tt>resultAddresses</tt>.
- * @param resolveProtocol if the protocol should be resolved
- * @return the transports that is used, when the <tt>transport</tt> is with
- * value Auto we resolve the address with NAPTR query, if no NAPTR record
- * we will use the default one.
- *
- * @throws UnknownHostException if <tt>address</tt> is not a valid host
- * address.
- */
- public void resolveSipAddress(
- String address, String transport,
- List<InetSocketAddress> resultAddresses,
- List<String> resultTransports,
- boolean resolveProtocol)
- throws UnknownHostException
- {
- //we need to resolve the address only if its a hostname.
- if(NetworkUtils.isValidIPAddress(address))
- {
- InetAddress addressObj = NetworkUtils.getInetAddress(address);
-
- //this is an ip address so we need to return default ports since
- //we can't get them from a DNS.
- int port = ListeningPoint.PORT_5060;
- if(transport.equalsIgnoreCase(ListeningPoint.TLS))
- port = ListeningPoint.PORT_5061;
-
- resultTransports.add(transport);
- resultAddresses.add(new InetSocketAddress(addressObj, port));
-
- // as its ip address return, no dns is needed.
- return;
- }
-
- // first make NAPTR resolve to get protocol, if needed
- if(resolveProtocol)
- {
- try
- {
- String[][] naptrRecords = NetworkUtils.getNAPTRRecords(address);
-
- if(naptrRecords != null && naptrRecords.length > 0)
- {
- for(String[] rec : naptrRecords)
- {
- resolveSRV(
- rec[2],
- rec[1],
- resultAddresses,
- resultTransports,
- true);
- }
-
- // NAPTR found use only it
- if(logger.isInfoEnabled())
- logger.info("Found NAPTR record and using it:"
- + resultAddresses);
-
- // return only if found something
- if(resultAddresses.size() > 0
- && resultTransports.size() > 0)
- return;
- }
- }
- catch (ParseException e)
- {
- logger.error("Error parsing dns record.", e);
- }
- }
-
- //try to obtain SRV mappings from the DNS
- try
- {
- if(resolveProtocol)
- {
- String[] transports = new String[]{
- ListeningPoint.TLS,
- ListeningPoint.TCP,
- ListeningPoint.UDP
- };
- for(String tp : transports)
- {
- resolveSRV(
- address,
- tp,
- resultAddresses,
- resultTransports,
- false);
- if(!resultAddresses.isEmpty())
- {
- transport = tp;
- break;
- }
- }
- }
- else
- {
- resolveSRV(
- address,
- transport,
- resultAddresses,
- resultTransports,
- false);
- }
- }
- catch (ParseException e)
- {
- logger.error("Error parsing dns record.", e);
- }
-
- //no SRV means default ports
- int defaultPort = ListeningPoint.PORT_5060;
- if(transport.equalsIgnoreCase(ListeningPoint.TLS))
- defaultPort = ListeningPoint.PORT_5061;
-
- ArrayList<InetSocketAddress> tempResultAddresses
- = new ArrayList<InetSocketAddress>();
-
- // after checking SRVs, lets add and AAAA and A records
- resolveAddresses(
- address,
- tempResultAddresses,
- defaultPort);
- for(InetSocketAddress a : tempResultAddresses)
- {
- if(!resultAddresses.contains(a))
- {
- resultAddresses.add(a);
- resultTransports.add(transport);
- }
- }
-
- // make sure we don't return empty array
- if(resultAddresses.size() == 0)
- {
- resultAddresses.add(new InetSocketAddress(address, defaultPort));
- resultTransports.add(transport);
-
- // 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.
- @SuppressWarnings("unused")
- InetAddress addressObj = InetAddress.getByName(address);
- }
- }
-
- /**
- * Resolves the given address. Resolves A and AAAA records and returns
- * them in <tt>resultAddresses</tt> ordered according
- * <tt>preferIPv6Addresses</tt> option.
- * @param address the address to resolve.
- * @param resultAddresses the List in which we provide the result.
- * @param defaultPort the port to use for the result address.
- * @throws UnknownHostException its not supposed to be thrown, cause
- * the address we use is an ip address.
- */
- private void resolveAddresses(
- String address, List<InetSocketAddress> resultAddresses,
- int defaultPort)
- throws UnknownHostException
- {
- //we need to resolve the address only if its a hostname.
- if(NetworkUtils.isValidIPAddress(address))
- {
- InetAddress addressObj = NetworkUtils.getInetAddress(address);
-
- resultAddresses.add(new InetSocketAddress(addressObj, defaultPort));
-
- // as its ip address return, no dns is needed.
- return;
- }
-
- try
- {
- for(InetSocketAddress a :
- NetworkUtils.getAandAAAARecords(address, defaultPort))
- {
- resultAddresses.add(a);
- }
- }
- catch (ParseException ex)
- {
- logger.error("Error parsing dns record.", ex);
- }
-
- if(resultAddresses.size() == 0)
- logger.warn("No AAAA and A record found for " + address);
- }
-
- /**
- * Tries to resolve <tt>address</tt> into a valid InetSocketAddress using
- * an <tt>SRV</tt> query where it exists and A/AAAA where it doesn't. The
- * method assumes that the transport that we'll be using when connecting to
- * address is the one that has been defined as default for this provider.
- *
- * @param address the address we'd like to resolve.
- *
- * @return an <tt>InetSocketAddress</tt> instance containing the
- * <tt>SRV</tt> record for <tt>address</tt> if one has been defined and the
- * A/AAAA record where it hasn't.
- *
- * @throws UnknownHostException if <tt>address</tt> is not a valid host
- * address.
- */
- public InetSocketAddress resolveSipAddress(String address)
- throws UnknownHostException
- {
- ArrayList<InetSocketAddress> socketAddressesList =
- new ArrayList<InetSocketAddress>();
-
- resolveSipAddress(address, getDefaultTransport(), socketAddressesList,
- new ArrayList<String>(),
- getAccountID().getAccountPropertyBoolean(
- ProtocolProviderFactory.PROXY_AUTO_CONFIG, false));
-
- return socketAddressesList.get(0);
- }
-
- /**
- * Resolves the SRV records add their corresponding AAAA and A records
- * in the <tt>resultAddresses</tt> ordered by the preference
- * <tt>preferIPv6Addresses</tt> and their corresponding <tt>transport</tt>
- * in the <tt>resultTransports</tt>.
- * @param address the address to resolve.
- * @param transport the transport to use
- * @param resultAddresses the result address after resolve.
- * @param resultTransports and the addresses transports.
- * @param srvQueryString is the supplied address is of type
- * _sip(s)._protocol.address, a string ready for srv queries, used
- * when we have a NAPTR returned records with value <tt>true</tt>.
- * @throws ParseException exception when parsing dns address
- */
- private void resolveSRV(String address,
- String transport,
- List<InetSocketAddress> resultAddresses,
- List<String> resultTransports,
- boolean srvQueryString)
- throws ParseException
- {
- SRVRecord srvRecords[] = null;
-
- if(srvQueryString)
- {
- srvRecords = NetworkUtils.getSRVRecords(address);
- }
- else
- {
- srvRecords = NetworkUtils.getSRVRecords(
- transport.equalsIgnoreCase(ListeningPoint.TLS)
- ? "sips" : "sip",
- transport.equalsIgnoreCase(ListeningPoint.UDP)
- ? ListeningPoint.UDP : ListeningPoint.TCP,
- address);
- }
-
- if(srvRecords != null)
- {
- ArrayList<InetSocketAddress> tempResultAddresses
- = new ArrayList<InetSocketAddress>();
-
- for(SRVRecord s : srvRecords)
- {
- // add corresponding A and AAAA records
- // to the host address from SRV records
- try
- {
- // as these are already resolved addresses (the SRV res.)
- // lets get it without triggering a PTR
- resolveAddresses(
- s.getTarget(),
- tempResultAddresses,
- s.getPort());
- }
- catch(UnknownHostException e)
- {
- logger.warn("Address unknown:" + s.getTarget(), e);
- }
-
- /* add and every SRV address itself if not already there
- if(!tempResultAddresses.contains(s))
- tempResultAddresses.add(s);
- */
-
- if (logger.isTraceEnabled())
- logger.trace("Returned SRV " + s);
- }
-
- for(InetSocketAddress a : tempResultAddresses)
- {
- if(!resultAddresses.contains(a))
- {
- resultAddresses.add(a);
- resultTransports.add(transport);
- }
- }
- }
- }
-
- /**
* Returns the <tt>InetAddress</tt> that is most likely to be to be used
* as a next hop when contacting the specified <tt>destination</tt>. This is
* an utility method that is used whenever we have to choose one of our
@@ -2854,7 +2191,6 @@ public class ProtocolProviderServiceSipImpl
return getIntendedDestination((SipURI)destination.getURI());
}
-
/**
* Returns the <tt>InetAddress</tt> that is most likely to be to be used
* as a next hop when contacting the specified <tt>destination</tt>. This is
@@ -2905,7 +2241,7 @@ public class ProtocolProviderServiceSipImpl
//but the destination could only be known to our outbound proxy
//if we have one. If this is the case replace the destination
//address with that of the proxy.(report by Dan Bogos)
- InetSocketAddress outboundProxy = outboundProxySocketAddress;
+ InetSocketAddress outboundProxy = connection.getAddress();
if(outboundProxy != null)
{
@@ -2915,16 +2251,11 @@ public class ProtocolProviderServiceSipImpl
}
else
{
- try
- {
- destinationInetAddress = resolveSipAddress(host);
- }
- catch (UnknownHostException ex)
- {
- throw new IllegalArgumentException(
- host + " is not a valid internet address.",
- ex);
- }
+ ProxyConnection tempConn = new AutoProxyConnection(
+ (SipAccountID)getAccountID(),
+ host,
+ getDefaultTransport());
+ destinationInetAddress = tempConn.getAddress();
}
if(logger.isDebugEnabled())
@@ -3046,66 +2377,42 @@ public class ProtocolProviderServiceSipImpl
*/
boolean registerUsingNextAddress()
{
- // means no connection
- if(connectionAddresses == null)
+ if(connection == null)
return false;
- int i = 0;
- for (; i < connectionAddresses.length; i++)
- {
- if(connectionAddresses[i].equals(currentConnectionAddress))
- break;
- }
-
- if(i + 1 < connectionAddresses.length)
+ try
{
- changeAddress(i + 1);
-
- try
+ if(sipRegistrarConnection.isRegistrarless())
{
+ sipRegistrarConnection.setTransport(getDefaultTransport());
sipRegistrarConnection.register();
+ return true;
+
}
- catch (Throwable e)
+ else if(connection.getNextAddress())
{
- logger.error("Cannot send register!", e);
- sipRegistrarConnection.setRegistrationState(
- RegistrationState.CONNECTION_FAILED,
- RegistrationStateChangeEvent.REASON_NOT_SPECIFIED,
- "A timeout occurred while trying to connect to the server.");
+ sipRegistrarConnection.setTransport(connection.getTransport());
+ sipRegistrarConnection.register();
+ return true;
}
-
- return true;
+ }
+ catch (Throwable e)
+ {
+ logger.error("Cannot send register!", e);
+ sipRegistrarConnection.setRegistrationState(
+ RegistrationState.CONNECTION_FAILED,
+ RegistrationStateChangeEvent.REASON_NOT_SPECIFIED,
+ "A timeout occurred while trying to connect to the server.");
}
// as we reached the last address lets change it to the first one
// so we don't get stuck to the last one forever, and the next time
// use again the first one
- changeAddress(0);
-
+ connection.reset();
return false;
}
/**
- * Change the current address used to register to ix one.
- * @param ix the index of the new address to assign.
- */
- private void changeAddress(int ix)
- {
- if(ix >= connectionAddresses.length)
- return;
-
- this.currentConnectionAddress = connectionAddresses[ix];
- sipRegistrarConnection.setTransport(connectionTransports[ix]);
-
- initOutboundProxy(ix);
- }
-
- protected InetSocketAddress getCurrentConnectionAddress()
- {
- return currentConnectionAddress;
- }
-
- /**
* If somewhere we got for example timeout of receiving answer to our
* requests we consider problem with network and notify the provider.
*/
@@ -3130,4 +2437,17 @@ public class ProtocolProviderServiceSipImpl
"A timeout occurred while trying to connect to the server.");
}
}
+
+ /**
+ * Determines whether the supplied transport is a known SIP transport method
+ *
+ * @param transport the SIP transport to check
+ * @return True when transport is one of UDP, TCP or TLS.
+ */
+ public static boolean isValidTransport(String transport)
+ {
+ return ListeningPoint.UDP.equalsIgnoreCase(transport)
+ || ListeningPoint.TLS.equalsIgnoreCase(transport)
+ || ListeningPoint.TCP.equalsIgnoreCase(transport);
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java b/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
index 75b6f2c..555eb98 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProxyRouter.java
@@ -126,7 +126,7 @@ public class ProxyRouter
ProtocolProviderServiceSipImpl sipProvider
= ((ProtocolProviderServiceSipImpl) service);
- String proxy = sipProvider.getOutboundProxyString();
+ String proxy = sipProvider.getConnection().getOutboundProxyString();
boolean forceLooseRouting = Boolean.valueOf((String)
sipProvider.getAccountID().getAccountProperty(
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java
index ad6de0f..3748718 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ServerStoredContactListXivoImpl.java
@@ -173,7 +173,7 @@ public class ServerStoredContactListXivoImpl
connection = new Socket(serverAddress, 5003);
else // lets try using our sip connected address
connection = new Socket(
- sipProvider.getCurrentConnectionAddress().getAddress(), 5003);
+ sipProvider.getConnection().getAddress().getAddress(), 5003);
connectionWriter = new PrintStream(connection.getOutputStream());
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/AutoProxyConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/net/AutoProxyConnection.java
new file mode 100644
index 0000000..0f84e67
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/AutoProxyConnection.java
@@ -0,0 +1,384 @@
+/*
+ * 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.impl.protocol.sip.net;
+
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.*;
+
+import java.net.*;
+import java.text.*;
+
+import javax.sip.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.util.*;
+import static javax.sip.ListeningPoint.*;
+
+/**
+ * Implementation of the autodetect proxy connection. Tries to resolve a SIP-
+ * server by querying DNS in this order: NAPTR-SRV-A; SRV-A; A.
+ *
+ * @author Ingo Bauersachs
+ */
+public class AutoProxyConnection
+ extends ProxyConnection
+{
+ private enum State
+ {
+ New,
+ Naptr,
+ NaptrSrv,
+ NaptrSrvHosts,
+ NaptrSrvHostIPs,
+ Srv,
+ SrvHosts,
+ SrvHostIPs,
+ Hosts,
+ IP
+ }
+
+ /**
+ * Wrapper around {@link NetworkUtils} to support Unit Tests.
+ */
+ protected static class LocalNetworkUtils
+ {
+ public InetAddress getInetAddress(String address)
+ throws UnknownHostException
+ {
+ return NetworkUtils.getInetAddress(address);
+ }
+
+ public String[][] getNAPTRRecords(String address)
+ throws ParseException
+ {
+ return NetworkUtils.getNAPTRRecords(address);
+ }
+
+ public SRVRecord[] getSRVRecords(String service, String proto,
+ String address) throws ParseException
+ {
+ return NetworkUtils.getSRVRecords(service, proto, address);
+ }
+
+ public InetSocketAddress[] getAandAAAARecords(String target, int port)
+ throws ParseException
+ {
+ return NetworkUtils.getAandAAAARecords(target, port);
+ }
+
+ public boolean isValidIPAddress(String address)
+ {
+ return NetworkUtils.isValidIPAddress(address);
+ }
+
+ public SRVRecord[] getSRVRecords(String domain)
+ throws ParseException
+ {
+ return NetworkUtils.getSRVRecords(domain);
+ }
+ }
+
+ private final static Logger logger
+ = Logger.getLogger(AutoProxyConnection.class);
+
+ private State state;
+ private String address;
+ private final String defaultTransport;
+ private LocalNetworkUtils nu = new LocalNetworkUtils();
+
+ private final static String[] transports = new String[]
+ {
+ ListeningPoint.TLS,
+ ListeningPoint.TCP,
+ ListeningPoint.UDP
+ };
+ private boolean hadSrvResults;
+ private String[][] naptrRecords;
+ private int naptrIndex;
+ private SRVRecord[] srvRecords;
+ private int srvRecordsIndex;
+ private int srvTransportIndex;
+ private InetSocketAddress socketAddresses[];
+ private int socketAddressIndex;
+
+ /**
+ * Creates a new instance of this class. Uses the server from the account.
+ *
+ * @param account the account of this SIP protocol instance
+ * @param defaultTransport the default transport to use when DNS does not
+ * provide a protocol through NAPTR or SRV
+ */
+ public AutoProxyConnection(SipAccountID account, String defaultTransport)
+ {
+ super(account);
+ this.defaultTransport = defaultTransport;
+ reset();
+ }
+
+ /**
+ * Creates a new instance of this class. Uses the supplied address instead
+ * of the server address from the account.
+ *
+ * @param account the account of this SIP protocol instance
+ * @param address the domain on which to perform autodetection
+ * @param defaultTransport the default transport to use when DNS does not
+ * provide a protocol through NAPTR or SRV
+ */
+ public AutoProxyConnection(SipAccountID account, String address,
+ String defaultTransport)
+ {
+ super(account);
+ this.defaultTransport = defaultTransport;
+ reset();
+ this.address = address;
+ }
+
+ /**
+ * Sets the NetworkUtils wrapper. Used for Unit-Testing.
+ * @param nu the the NetworkUtils wrapper.
+ */
+ protected void setNetworkUtils(LocalNetworkUtils nu)
+ {
+ this.nu = nu;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#
+ * getNextAddressFromDns()
+ */
+ protected boolean getNextAddressFromDns()
+ {
+ try
+ {
+ return getNextAddressInternal();
+ }
+ catch(ParseException ex)
+ {
+ logger.error("Unable to get DNS data for <" + address
+ + "> in state" + state, ex);
+ }
+ return false;
+ }
+
+ /**
+ * Gets the next address from DNS.
+ */
+ private boolean getNextAddressInternal()
+ throws ParseException
+ {
+ switch(state)
+ {
+ case New:
+ state = State.Naptr;
+ return getNextAddressFromDns();
+ case IP:
+ if(socketAddressIndex == 0)
+ {
+ socketAddressIndex++;
+ try
+ {
+ socketAddress = new InetSocketAddress(
+ nu.getInetAddress(address),
+ ListeningPoint.TLS.equalsIgnoreCase(transport)
+ ? ListeningPoint.PORT_5061
+ : ListeningPoint.PORT_5060
+ );
+ }
+ catch (UnknownHostException e)
+ {
+ //this is not supposed to happen
+ logger.error("invalid IP address: " + address, e);
+ return false;
+ }
+ transport = defaultTransport;
+ return true;
+ }
+ return false;
+ case Naptr:
+ naptrRecords = nu.getNAPTRRecords(address);
+ if(naptrRecords != null && naptrRecords.length > 0)
+ {
+ state = State.NaptrSrv;
+ naptrIndex = 0;
+ }
+ else
+ {
+ hadSrvResults = false;
+ state = State.Srv;
+ srvTransportIndex = 0;
+ }
+
+ return getNextAddressFromDns();
+ case NaptrSrv:
+ for(; naptrIndex < naptrRecords.length; naptrIndex++)
+ {
+ srvRecords = nu.getSRVRecords(
+ naptrRecords[naptrIndex][2]);
+ if(srvRecords != null && srvRecords.length > 0)
+ {
+ state = State.NaptrSrvHosts;
+ if(TLS.equalsIgnoreCase(naptrRecords[naptrIndex][1]))
+ transport = TLS;
+ else if(TCP.equalsIgnoreCase(naptrRecords[naptrIndex][1]))
+ transport = TCP;
+ else
+ transport = UDP;
+ srvRecordsIndex = 0;
+ if(getNextAddressFromDns())
+ {
+ naptrIndex++;
+ return true;
+ }
+ }
+ }
+ return false; //no more naptr's
+ case NaptrSrvHosts:
+ for(; srvRecordsIndex < srvRecords.length; srvRecordsIndex++)
+ {
+ socketAddresses = nu.getAandAAAARecords(
+ srvRecords[srvRecordsIndex].getTarget(),
+ srvRecords[srvRecordsIndex].getPort());
+ if(socketAddresses != null && socketAddresses.length > 0)
+ {
+ state = State.NaptrSrvHostIPs;
+ socketAddressIndex = 0;
+ if(getNextAddressFromDns())
+ {
+ srvRecordsIndex++;
+ return true;
+ }
+ }
+ }
+ state = State.NaptrSrv;
+ return getNextAddressFromDns(); //backtrack to next naptr
+ case NaptrSrvHostIPs:
+ if(socketAddressIndex >= socketAddresses.length)
+ {
+ state = State.NaptrSrvHosts;
+ return getNextAddressFromDns(); //backtrack to next srv
+ }
+ socketAddress = socketAddresses[socketAddressIndex];
+ socketAddressIndex++;
+ return true;
+ case Srv:
+ for(;srvTransportIndex < transports.length; srvTransportIndex++)
+ {
+ srvRecords = nu.getSRVRecords(
+ (TLS.equals(transports[srvTransportIndex])
+ ? "sips"
+ : "sip"),
+ (UDP.equalsIgnoreCase(transports[srvTransportIndex])
+ ? UDP
+ : TCP),
+ address);
+ if(srvRecords != null && srvRecords.length > 0)
+ {
+ hadSrvResults = true;
+ state = State.SrvHosts;
+ srvRecordsIndex = 0;
+ transport = transports[srvTransportIndex];
+ if(getNextAddressFromDns())
+ {
+ srvTransportIndex++;
+ return true;
+ }
+ }
+ }
+ if(!hadSrvResults)
+ {
+ state = State.Hosts;
+ socketAddressIndex = 0;
+ return getNextAddressFromDns();
+ }
+ return false;
+ case SrvHosts:
+ for(; srvRecordsIndex < srvRecords.length; srvRecordsIndex++)
+ {
+ socketAddresses = nu.getAandAAAARecords(
+ srvRecords[srvRecordsIndex].getTarget(),
+ srvRecords[srvRecordsIndex].getPort());
+ if(socketAddresses != null && socketAddresses.length > 0)
+ {
+ state = State.SrvHostIPs;
+ socketAddressIndex = 0;
+ if(getNextAddressFromDns())
+ {
+ srvRecordsIndex++;
+ return true;
+ }
+ }
+ }
+ state = State.Srv;
+ return getNextAddressFromDns(); //backtrack to next srv record
+ case SrvHostIPs:
+ if(socketAddressIndex >= socketAddresses.length)
+ {
+ state = State.SrvHosts;
+ return getNextAddressFromDns();
+ }
+ socketAddress = socketAddresses[socketAddressIndex];
+ socketAddressIndex++;
+ return true;
+ case Hosts:
+ transport = defaultTransport;
+
+ if(socketAddresses == null)
+ {
+ socketAddresses = nu.getAandAAAARecords(
+ address,
+ ListeningPoint.PORT_5060);
+ }
+
+ if(socketAddresses != null && socketAddresses.length > 0
+ && socketAddressIndex < socketAddresses.length)
+ {
+ socketAddress = socketAddresses[socketAddressIndex++];
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#reset()
+ */
+ @Override
+ public void reset()
+ {
+ super.reset();
+ state = State.New;
+
+ //determine the hostname of the proxy for autodetection:
+ //1) server part of the user ID
+ //2) name of the registrar when the user ID contains no domain
+ String userID = account.getAccountPropertyString(USER_ID);
+ int domainIx = userID.indexOf("@");
+ if(domainIx > 0)
+ {
+ address = userID.substring(domainIx + 1);
+ }
+ else
+ {
+ address = account.getAccountPropertyString(SERVER_ADDRESS);
+ if(address == null || address.trim().length() == 0)
+ {
+ //registrarless account
+ return;
+ }
+ }
+ if(nu.isValidIPAddress(address))
+ {
+ state = State.IP;
+ socketAddressIndex = 0;
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java
new file mode 100644
index 0000000..93a3e42
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/ManualProxyConnection.java
@@ -0,0 +1,114 @@
+/*
+ * 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.impl.protocol.sip.net;
+
+import static javax.sip.ListeningPoint.*;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.*;
+
+import java.net.*;
+import java.text.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Implementation of the manually configured SIP proxy connection. IP Address
+ * lookups are performed using the account's proxy address.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ManualProxyConnection
+ extends ProxyConnection
+{
+ private final static Logger logger
+ = Logger.getLogger(ManualProxyConnection.class);
+
+ private String address;
+ private int port;
+
+ private InetSocketAddress[] lookups;
+ private int lookupIndex;
+
+ /**
+ * Creates a new instance of this class. Uses the server from the account.
+ *
+ * @param account the account of this SIP protocol instance
+ */
+ public ManualProxyConnection(SipAccountID account)
+ {
+ super(account);
+ reset();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#
+ * getNextAddress()
+ */
+ @Override
+ public boolean getNextAddressFromDns()
+ {
+ if(lookups == null)
+ {
+ try
+ {
+ lookupIndex = 0;
+ lookups = NetworkUtils.getAandAAAARecords(address, port);
+
+ //no result found, reset state and indicate "out of addresses"
+ if(lookups.length == 0)
+ {
+ lookups = null;
+ return false;
+ }
+ }
+ catch (ParseException e)
+ {
+ logger.error("Invalid address <" + address + ">", e);
+ return false;
+ }
+ }
+
+ //check if the available addresses are exhausted
+ if(lookupIndex >= lookups.length)
+ {
+ if(logger.isDebugEnabled())
+ logger.debug("No more addresses for " + account);
+ lookups = null;
+ return false;
+ }
+
+ //assign the next address and return lookup success
+ if(logger.isDebugEnabled())
+ logger.debug("Returning <" + socketAddress
+ + "> as next address for " + account);
+ socketAddress = lookups[lookupIndex];
+ lookupIndex++;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * net.java.sip.communicator.impl.protocol.sip.net.ProxyConnection#reset()
+ */
+ @Override
+ public void reset()
+ {
+ super.reset();
+ address = account.getAccountPropertyString(PROXY_ADDRESS);
+ port = account.getAccountPropertyInt(PROXY_PORT, PORT_5060);
+ transport = account.getAccountPropertyString(PREFERRED_TRANSPORT);
+
+ //check property sanity
+ if(!ProtocolProviderServiceSipImpl.isValidTransport(transport))
+ throw new IllegalArgumentException(
+ transport + " is not a valid SIP transport");
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java b/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java
new file mode 100644
index 0000000..4de0685
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/ProxyConnection.java
@@ -0,0 +1,163 @@
+package net.java.sip.communicator.impl.protocol.sip.net;
+
+import java.net.*;
+import java.util.*;
+
+import net.java.sip.communicator.impl.protocol.sip.*;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.*;
+
+/**
+ * Abstract class for the determining the address for the SIP proxy.
+ *
+ * @author Ingo Bauersachs
+ */
+public abstract class ProxyConnection
+{
+ private List<String> returnedAddresses = new LinkedList<String>();
+
+ protected String transport;
+ protected InetSocketAddress socketAddress;
+ protected final SipAccountID account;
+
+ /**
+ * Creates a new instance of this class.
+ * @param account the account of this SIP protocol instance
+ */
+ protected ProxyConnection(SipAccountID account)
+ {
+ this.account = account;
+ }
+
+ /**
+ * Gets the address to use for the next connection attempt.
+ * @return the address of the last lookup.
+ */
+ public final InetSocketAddress getAddress()
+ {
+ if(socketAddress == null)
+ getNextAddress();
+ return socketAddress;
+ }
+
+ /**
+ * Gets the transport to use for the next connection attempt.
+ * @return the transport of the last lookup.
+ */
+ public final String getTransport()
+ {
+ if(transport == null)
+ getNextAddress();
+ return transport;
+ }
+
+ /**
+ * In case we are using an outbound proxy this method returns
+ * a suitable string for use with Router.
+ * The method returns <tt>null</tt> otherwise.
+ *
+ * @return the string of our outbound proxy if we are using one and
+ * <tt>null</tt> otherwise.
+ */
+ public final String getOutboundProxyString()
+ {
+ if(socketAddress == null)
+ if(!getNextAddress())
+ return null;
+
+ InetAddress proxyAddress = socketAddress.getAddress();
+ StringBuilder proxyStringBuffer
+ = new StringBuilder(proxyAddress.getHostAddress());
+
+ if(proxyAddress instanceof Inet6Address)
+ {
+ proxyStringBuffer.insert(0, '[');
+ proxyStringBuffer.append(']');
+ }
+
+ proxyStringBuffer.append(':');
+ proxyStringBuffer.append(socketAddress.getPort());
+ proxyStringBuffer.append('/');
+ proxyStringBuffer.append(transport);
+
+ return proxyStringBuffer.toString();
+ }
+
+ /**
+ * Compares an InetAddress against the active outbound proxy. The comparison
+ * is by reference, not equals.
+ *
+ * @param addressToTest The addres to test.
+ * @return True when the InetAddress is the same as the outbound proxy.
+ */
+ public final boolean isSameInetAddress(InetAddress addressToTest)
+ {
+ // if the proxy is not yet initialized then this is not the provider
+ // that caused this comparison
+ if(socketAddress == null)
+ return false;
+ return addressToTest == socketAddress.getAddress();
+ }
+
+ /**
+ * Retrieves the next address to use from DNS. Duplicate results are
+ * suppressed.
+ *
+ * @return True if a new address is available through {@link #getAddress()},
+ * false if the last address was reached. A new lookup from scratch
+ * can be started by calling {@link #reset()}.
+ */
+ public final boolean getNextAddress()
+ {
+ boolean result;
+ String key = null;
+ do
+ {
+ result = getNextAddressFromDns();
+ if(result && socketAddress != null)
+ {
+ key = getOutboundProxyString();
+ if(!returnedAddresses.contains(key))
+ {
+ returnedAddresses.add(key);
+ break;
+ }
+ }
+ }
+ while(result && returnedAddresses.contains(key));
+ return result;
+ }
+
+ /**
+ * Implementations must use this method to get the next address, but do not
+ * have to care about duplicate addresses.
+ *
+ * @return True when a further address was available.
+ */
+ protected abstract boolean getNextAddressFromDns();
+
+ /**
+ * Resets the lookup to it's initial state. Overriders methods have to call
+ * this method through a super-call.
+ */
+ public void reset()
+ {
+ returnedAddresses.clear();
+ }
+
+ /**
+ * Factory method to create a proxy connection based on the account settings
+ * of the protocol provider.
+ *
+ * @param pps the protocol provider that needs a SIP server connection.
+ * @return An instance of a derived class.
+ */
+ public static ProxyConnection create(ProtocolProviderServiceSipImpl pps)
+ {
+ if (pps.getAccountID().getAccountPropertyBoolean(PROXY_AUTO_CONFIG,
+ true))
+ return new AutoProxyConnection((SipAccountID) pps.getAccountID(),
+ pps.getDefaultTransport());
+ else
+ return new ManualProxyConnection((SipAccountID) pps.getAccountID());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
index 243350d..f5aa540 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/net/SslNetworkLayer.java
@@ -190,7 +190,8 @@ public class SslNetworkLayer
for (ProtocolProviderServiceSipImpl pps : ProtocolProviderServiceSipImpl
.getAllInstances())
{
- if (pps.matchesInetAddress(address))
+ if (pps.getConnection() != null
+ && pps.getConnection().isSameInetAddress(address))
{
provider = pps;
break;
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
index 6373236..9ebb963 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
+++ b/src/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf
@@ -65,6 +65,7 @@ Import-Package: org.apache.log4j,
javax.xml.transform.dom,
javax.xml.transform.stream,
Export-Package: net.java.sip.communicator.impl.protocol.sip,
+ net.java.sip.communicator.impl.protocol.sip.net,
net.java.sip.communicator.impl.protocol.sip.xcap,
net.java.sip.communicator.impl.protocol.sip.xcap.utils,
net.java.sip.communicator.impl.protocol.sip.xcap.model,
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java b/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
index 77af005..4e07318 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
+++ b/test/net/java/sip/communicator/slick/protocol/sip/SipProtocolProviderServiceLick.java
@@ -79,6 +79,9 @@ public class SipProtocolProviderServiceLick
// xcap parsing tests
addTest(TestXCapParse.suite());
+ //proxy detection tests
+ addTestSuite(TestAutoProxyDetection.class);
+
//First test account installation so that the service that has
//been installed by it gets tested by the rest of the tests.
addTestSuite(TestAccountInstallation.class);
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java b/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java
new file mode 100644
index 0000000..3b1b76f
--- /dev/null
+++ b/test/net/java/sip/communicator/slick/protocol/sip/TestAutoProxyDetection.java
@@ -0,0 +1,427 @@
+/*
+ * 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.slick.protocol.sip;
+
+import static org.easymock.EasyMock.*;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+
+import net.java.sip.communicator.impl.protocol.sip.SipAccountID;
+import net.java.sip.communicator.impl.protocol.sip.net.AutoProxyConnection;
+import net.java.sip.communicator.util.SRVRecord;
+import static net.java.sip.communicator.service.protocol.ProtocolProviderFactory.*;
+import junit.framework.TestCase;
+
+/**
+ * Tests all variations of automatic proxy detection through (simulated) DNS.
+ *
+ * @author Ingo Bauersachs
+ */
+public class TestAutoProxyDetection
+ extends TestCase
+{
+ private static class TestedAutoProxyDetection extends AutoProxyConnection
+ {
+ public TestedAutoProxyDetection(SipAccountID account,
+ String defaultTransport)
+ {
+ super(account, defaultTransport);
+ }
+
+ @Override
+ public void setNetworkUtils(LocalNetworkUtils nu)
+ {
+ super.setNetworkUtils(nu);
+ }
+
+ public static class NetworkUtils extends LocalNetworkUtils
+ {
+ }
+ }
+
+ private SipAccountID account;
+ private TestedAutoProxyDetection.NetworkUtils nu;
+ private SRVRecord srv1;
+ private SRVRecord srv2;
+ private SRVRecord srv3;
+ private InetSocketAddress a1;
+ private InetSocketAddress a2;
+ private InetSocketAddress a3;
+ private InetSocketAddress a4;
+ private final static String DOMAIN = "example.com";
+ private InetAddress ia1;
+ private InetAddress ia2;
+ private InetAddress ia3;
+ private InetAddress ia4;
+ private TestedAutoProxyDetection apd;
+
+ public void setUp()
+ {
+ account = createMock(SipAccountID.class);
+ expect(account.getAccountPropertyString(USER_ID))
+ .andReturn("unit@" + DOMAIN);
+ replay(account);
+
+ nu = createMock(TestedAutoProxyDetection.NetworkUtils.class);
+ apd = new TestedAutoProxyDetection(account, "UDP");
+ apd.setNetworkUtils(nu);
+
+ srv1 = createMock(SRVRecord.class);
+ expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
+ expect(srv1.getPort()).andReturn(5060);
+ srv2 = createMock(SRVRecord.class);
+ expect(srv2.getTarget()).andReturn("proxy2."+DOMAIN);
+ expect(srv2.getPort()).andReturn(5061);
+ srv3 = createMock(SRVRecord.class);
+ expect(srv3.getTarget()).andReturn("proxy3."+DOMAIN);
+ expect(srv3.getPort()).andReturn(5062);
+ try
+ {
+ ia1 = InetAddress.getByAddress("proxy1." + DOMAIN,
+ new byte[]{0x7f,0,0,1});
+ ia2 = InetAddress.getByAddress("proxy2." + DOMAIN,
+ new byte[]{0x7f,0,0,2});
+ ia3 = InetAddress.getByAddress("proxy3." + DOMAIN,
+ new byte[]{0x7f,0,0,3});
+ ia4 = InetAddress.getByAddress("proxy4." + DOMAIN,
+ new byte[]{0x7f,0,0,4});
+ }
+ catch (UnknownHostException e)
+ {
+ fail("unable to initialize: " + e.getMessage());
+ }
+ a1 = new InetSocketAddress(ia1, 5060);
+ a2 = new InetSocketAddress(ia2, 5061);
+ a3 = new InetSocketAddress(ia3, 5062);
+ a4 = new InetSocketAddress(ia4, 5063);
+ }
+
+ private void prepareOneNaptrOneSrv() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1 });
+ }
+
+ private void prepareOneNaptrTwoSrv() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1, srv2 });
+ }
+
+ public void testOneNaptrNoSrv() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp." + DOMAIN)).andReturn(null);
+ replay(nu);
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneNaptrOneSrvOneA() throws ParseException
+ {
+ prepareOneNaptrOneSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ replay(nu, srv1);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testOneNaptrOneSrvTwoA() throws ParseException
+ {
+ prepareOneNaptrOneSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+ replay(nu, srv1);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ //-----------------------
+
+ public void testOneNaptrTwoSrvOneA() throws ParseException
+ {
+ prepareOneNaptrTwoSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a2});
+ replay(nu, srv1, srv2);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ public void testOneNaptrTwoSrvTwoA() throws ParseException
+ {
+ prepareOneNaptrTwoSrv();
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a3, a4});
+ replay(nu, srv1, srv2);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a3, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a4, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ //-------------------
+
+ public void testThreeNaptrOneSrvEachOneAEach() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN},
+ {"0", "tcp", "_sip._tcp." + DOMAIN},
+ {"0", "tls", "_sips._tcp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv1 });
+ expect(nu.getSRVRecords("_sip._tcp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv2 });
+ expect(nu.getSRVRecords("_sips._tcp."+DOMAIN))
+ .andReturn(new SRVRecord[]{ srv3 });
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy3." + DOMAIN, 5062))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1, srv2, srv3);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("TCP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2, srv3);
+ }
+
+ //-----------------------
+
+ public void testNoSrvOneA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneSrvOneA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testOneSrvTwoA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+
+ replay(nu, srv1);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+
+ public void testTwoSrvOneA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv2});
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN))
+ .andReturn(new SRVRecord[]{srv1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy2." + DOMAIN, 5061))
+ .andReturn(new InetSocketAddress[]{a2});
+
+ replay(nu, srv1, srv2);
+
+ assertEquals(a2, apd.getAddress());
+ assertEquals("TLS", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1, srv2);
+ }
+
+ //----------------------
+
+ public void testNoA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{});
+
+ replay(nu);
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testOneA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testTwoA() throws ParseException
+ {
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{});
+ expect(nu.getSRVRecords("sips", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "TCP", DOMAIN)).andReturn(null);
+ expect(nu.getSRVRecords("sip", "UDP", DOMAIN)).andReturn(null);
+ expect(nu.getAandAAAARecords(DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1, a2});
+
+ replay(nu);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertTrue(apd.getNextAddress());
+ assertEquals(a2, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu);
+ }
+
+ public void testNotReturningSameAddressTwice() throws ParseException
+ {
+ expect(srv1.getTarget()).andReturn("proxy1."+DOMAIN);
+ expect(srv1.getPort()).andReturn(5060);
+ expect(nu.getNAPTRRecords(DOMAIN)).andReturn(new String[][]{
+ {"0", "udp", "_sip._udp." + DOMAIN},
+ {"1", "udp", "_sip._udp." + DOMAIN}
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
+ srv1
+ });
+ expect(nu.getSRVRecords("_sip._udp."+DOMAIN)).andReturn(new SRVRecord[]{
+ srv1
+ });
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+ expect(nu.getAandAAAARecords("proxy1." + DOMAIN, 5060))
+ .andReturn(new InetSocketAddress[]{a1});
+
+ replay(nu, srv1);
+
+ assertEquals(a1, apd.getAddress());
+ assertEquals("UDP", apd.getTransport());
+
+ assertFalse(apd.getNextAddress());
+ verify(account, nu, srv1);
+ }
+}
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetPresence.java b/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetPresence.java
index ca723d7..1fe4f26 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetPresence.java
+++ b/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetPresence.java
@@ -118,11 +118,7 @@ public class TestOperationSetPresence
if(SipSlickFixture.onlineTestingDisabled)
{
TestSuite suite = new TestSuite();
- //the only test around here that we could run without net
- //connectivity
- suite.addTest(
- new TestOperationSetPresence(
- "testSupportedStatusSetForCompleteness"));
+ //currently no tests without online connection
return suite;
}
diff --git a/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf b/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf
index 57320fb..e5a7495 100644
--- a/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf
+++ b/test/net/java/sip/communicator/slick/protocol/sip/sip.provider.slick.manifest.mf
@@ -7,13 +7,15 @@ System-Bundle: yes
Import-Package: net.java.sip.communicator.service.configuration,
junit.framework,
org.osgi.framework,
- org.w3c.dom;
- javax.xml.namespace;
+ org.w3c.dom,
+ org.easymock,
+ javax.xml.namespace,
net.java.sip.communicator.util,
net.java.sip.communicator.util.xml,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.impl.protocol.sip,
+ net.java.sip.communicator.impl.protocol.sip.net,
net.java.sip.communicator.impl.protocol.sip.xcap,
net.java.sip.communicator.impl.protocol.sip.xcap.utils,
net.java.sip.communicator.impl.protocol.sip.xcap.model,