org.jivesoftware.openfire.net.SocketUtil Maven / Gradle / Ivy
The newest version!
package org.jivesoftware.openfire.net;
import org.jivesoftware.openfire.server.RemoteServerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.List;
/**
* Utility class to generate Socket instances.
*
* @author Guus der Kinderen, [email protected]
*/
public class SocketUtil
{
private final static Logger Log = LoggerFactory.getLogger( SocketUtil.class );
/**
* Creates a socket connection to an XMPP domain.
*
* This implementation uses DNS SRV records to find a list of remote hosts for the XMPP domain (as implemented by
* {@link DNSUtil#resolveXMPPDomain(String, int)}. It then iteratively tries to create a socket connection to each
* of them, until one socket connection succeeds.
*
* Either the connected Socket instance is returned, or null if no connection could be established.
*
* Note that this method blocks while performing network IO. The timeout as defined by
* {@link RemoteServerManager#getSocketTimeout()} is observed.
*
* @param xmppDomain The XMPP domain to connect to.
* @param port The port to connect to when DNS resolution fails.
* @return a Socket instance that is connected, or null.
* @see DNSUtil#resolveXMPPDomain(String, int)
*/
public static Socket createSocketToXmppDomain( String xmppDomain, int port )
{
Log.debug( "Creating a socket connection to XMPP domain '{}' ...", xmppDomain );
Log.debug( "Use DNS to resolve remote hosts for the provided XMPP domain '{}' (default port: {}) ...", xmppDomain, port );
final List remoteHosts = DNSUtil.resolveXMPPDomain( xmppDomain, port );
Log.debug( "Found {} host(s) for XMPP domain '{}'.", remoteHosts.size(), xmppDomain );
Socket socket = null;
final int socketTimeout = RemoteServerManager.getSocketTimeout();
for ( DNSUtil.HostAddress remoteHost : remoteHosts )
{
final String realHostname = remoteHost.getHost();
final int realPort = remoteHost.getPort();
try
{
// (re)initialize the socket.
socket = new Socket();
Log.debug( "Trying to create socket connection to XMPP domain '{}' using remote host: {}:{} (blocks up to {} ms) ...", xmppDomain, realHostname, realPort, socketTimeout );
socket.connect( new InetSocketAddress( realHostname, realPort ), socketTimeout );
Log.debug( "Successfully created socket connection to XMPP domain '{}' using remote host: {}:{}!", xmppDomain, realHostname, realPort );
return socket;
}
catch ( Exception e )
{
Log.debug( "An exception occurred while trying to create a socket connection to XMPP domain '{}' using remote host {}:{}", xmppDomain, realHostname, realPort, e );
Log.warn( "Unable to create a socket connection to XMPP domain '{}' using remote host: {}:{}. Cause: {} (a full stacktrace is logged on debug level)", xmppDomain, realHostname, realPort, e.getMessage() );
try
{
if ( socket != null )
{
socket.close();
socket = null;
}
}
catch ( IOException ex )
{
Log.debug( "An additional exception occurred while trying to close a socket when creating a connection to {}:{} failed.", realHostname, realPort, ex );
}
}
}
Log.warn( "Unable to create a socket connection to XMPP domain '{}': Unable to connect to any of its remote hosts.", xmppDomain );
return null;
}
}