public void validateRemoteDomain(Element doc, StreamID streamID) throws StreamErrorException, ServerDialbackErrorException, ServerDialbackKeyInvalidException
    {
        StringBuilder sb;
        String recipient = doc.attributeValue("to");
        String remoteDomain = doc.attributeValue("from");

        final Logger log = LoggerFactory.getLogger( Log.getName() + "[Acting as Receiving Server: Validate domain: " + recipient + "(id " + streamID + ") for OS: " + remoteDomain + "]" );

        log.debug( "Validating domain...");

        if (!ServerDialback.isEnabled() && !ServerDialback.isEnabledForSelfSigned()) {
            throw new StreamErrorException(new StreamError(StreamError.Condition.policy_violation, "Dialback has been disabled by configuration."));
        }

        if (connection.getConfiguration().getTlsPolicy() == Connection.TLSPolicy.required && !connection.isEncrypted()) {
            throw new StreamErrorException(new StreamError(StreamError.Condition.policy_violation, "Local server configuration dictates that Server Dialback can be negotiated only after the connection has been encrypted."));
        }

        if (!RemoteServerManager.canAccess(remoteDomain)) {
            throw new StreamErrorException(new StreamError(StreamError.Condition.policy_violation, "Remote domain is not allowed to establish a connection to this server."));
        }
        else if (isHostUnknown(recipient)) {
            throw new ServerDialbackErrorException(recipient, remoteDomain, new PacketError(PacketError.Condition.item_not_found, PacketError.Type.cancel, "Service not hosted here"));
        }
        else {
            log.debug( "Check if the remote domain already has a connection to the target domain/subdomain" );
            boolean alreadyExists = false;
            for (IncomingServerSession session : sessionManager.getIncomingServerSessions(remoteDomain)) {
                if (recipient.equals(session.getLocalDomain())) {
                    alreadyExists = true;
                }
            }
            if (alreadyExists && !sessionManager.isMultipleServerConnectionsAllowed()) {
                throw new ServerDialbackErrorException(recipient, remoteDomain, new PacketError(PacketError.Condition.resource_constraint, PacketError.Type.cancel, "Incoming session already exists"));
            }
            else {
                log.debug( "Checking to see if the remote server provides stronger authentication based on SASL. If that's the case, dialback-based authentication can be skipped." );
                if (SASLAuthentication.verifyCertificates(connection.getPeerCertificates(), remoteDomain, true)) {
                    log.debug( "Host authenticated based on SASL. Weaker dialback-based authentication is skipped." );
                    log.debug( "Domain validated successfully!" );
                    return;
                }

                log.debug( "Unable to authenticate host based on stronger SASL. Proceeding with dialback..." );

                String key = doc.getTextTrim();

                final Map.Entry<Socket, Boolean> socketToXmppDomain = SocketUtil.createSocketToXmppDomain( remoteDomain, RemoteServerManager.getPortForServer(remoteDomain) );

                if ( socketToXmppDomain == null )
                {
                    throw new ServerDialbackErrorException(recipient, remoteDomain, new PacketError(PacketError.Condition.remote_server_not_found, PacketError.Type.cancel, "No server available for verifying key of remote server."));
                }

                Socket socket = socketToXmppDomain.getKey();
                boolean directTLS = socketToXmppDomain.getValue();

                VerifyResult result;
                try {
                    log.debug( "Verifying dialback key..." );
                    final SocketAddress socketAddress = socket.getRemoteSocketAddress();
                    log.debug( "Opening a new connection to {} {}.", socketAddress, directTLS ? "using directTLS" : "that is initially not encrypted" );
                    try {
                        result = verifyKey( key, streamID, recipient, remoteDomain, socket, directTLS, directTLS );
                    }
                    catch (SSLHandshakeException e)
                    {
                        result = VerifyResult.error;
                        log.debug( "Verification of dialback key failed due to TLS failure.", e );

                        // The receiving entity is expected to close the socket *without* sending any more data (<failure/> nor </stream>).
                        // It is probably (see OF-794) best if we, as the initiating entity, therefor don't send any data either.
                        final SocketAddress oldAddress = socket.getRemoteSocketAddress();
                        socket.close();

                        if ( !directTLS )
                        {
                            log.debug( "Retry without StartTLS... Re-opening socket (with the same remote peer)..." );

                            // Retry, without TLS.
                            socket = new Socket();
                            socket.connect( oldAddress, RemoteServerManager.getSocketTimeout() );
                            log.debug( "Successfully re-opened socket! Try to validate dialback key again (without TLS this time)..." );

                            result = verifyKey( key, streamID, recipient, remoteDomain, socket, true, directTLS );
                        }
                    } catch ( SSLException ex ) {
                        if ( JiveGlobals.getBooleanProperty(ConnectionSettings.Server.TLS_ON_PLAIN_DETECTION_ALLOW_NONDIRECTTLS_FALLBACK, true) && ex.getMessage().contains( "plaintext connection?" ) ) {
                            Log.warn( "Plaintext detected on a new connection that is was started in DirectTLS mode (socket address: {}). Attempting to restart the connection in non-DirectTLS mode.", socketAddress );
                            try {
                                // Close old socket
                                socket.close();
                            } catch ( Exception e ) {
                                Log.debug( "An exception occurred (and is ignored) while trying to close a socket that was already in an error state.", e );
                            }
                            socket = new Socket();
                            socket.connect( socketAddress, RemoteServerManager.getSocketTimeout() );
                            result = verifyKey( key, streamID, recipient, remoteDomain, socket, false, false );
                            directTLS = false; // No error this time? directTLS apparently is 'false'. Change it's value for future usage (if any)
                            Log.info( "Re-established connection to {}. Proceeding without directTLS.", socketAddress );
                        } else {
                            // Do not retry as non-DirectTLS, rethrow the exception.
                            throw ex;
                        }
                    }

                    switch(result) {
                        case valid:
                            log.debug( "Successfully validated domain!" );
                            return;

                        case invalid:
                            throw new ServerDialbackKeyInvalidException(recipient, remoteDomain);

                        default:
                            break;
                    }
                    throw new ServerDialbackErrorException(recipient, remoteDomain, new PacketError( PacketError.Condition.remote_server_timeout, PacketError.Type.cancel, "Key verification did not complete (the Authoritative Server likely returned an error or a time out occurred)."));
                }
                catch (ServerDialbackKeyInvalidException | ServerDialbackErrorException e) {
                    throw e;
                }
                catch (Exception e) {
                    throw new ServerDialbackErrorException(recipient, remoteDomain, new PacketError(PacketError.Condition.remote_server_timeout, PacketError.Type.cancel, "Authoritative server failed"), e);
                }
            }
        }
    }
Returns true if the domain requested by the remote server was validated by the Authoritative
Server. To validate the domain a new TCP connection will be established to the
Authoritative Server. The Authoritative Server may be the same Originating Server or
some other machine in the Originating Server's network.<p>

If the domain was not valid or some error occurred while validating the domain then the
underlying TCP connection may be closed.

@param doc the request for validating the new domain.
@param streamID the stream id generated by this server for the Originating Server.
@throws StreamErrorException when validation did not succeed.
xmppserver/src/main/java/org/jivesoftware/openfire/server/ServerDialback.java