private VerifyResult sendVerifyKey(String key, StreamID streamID, String recipient, String remoteDomain, Writer writer, XMPPPacketReader reader, Socket socket, boolean skipTLS, boolean directTLS) throws IOException, XmlPullParserException, RemoteConnectionFailedException {
        final Logger log = LoggerFactory.getLogger( Log.getName() + "[Acting as Receiving Server: Verify key with AS: " + remoteDomain + " for OS: " + recipient + " (id " + streamID + ")]" );

        VerifyResult result = VerifyResult.error;

        final ConnectionManager connectionManager = XMPPServer.getInstance().getConnectionManager();
        final TLSStreamHandler tlsStreamHandler = new TLSStreamHandler( socket, connectionManager.getListener( ConnectionType.SOCKET_S2S, directTLS ).generateConnectionConfiguration(), true );

        if ( directTLS ) {
            // Start handshake
            log.debug( "Starting Direct TLS handshake." );
            tlsStreamHandler.start();

            // Use new wrapped writers
            writer = new BufferedWriter( new OutputStreamWriter( tlsStreamHandler.getOutputStream(), StandardCharsets.UTF_8 ) );
            reader.getXPPParser().setInput( new InputStreamReader( tlsStreamHandler.getInputStream(), StandardCharsets.UTF_8 ) );
        }

        log.debug( "Send the Authoritative Server a stream header and wait for answer." );
        final Element stream = DocumentHelper.createElement(QName.get("stream", "stream", "http://etherx.jabber.org/streams"));
        final Document document = DocumentHelper.createDocument(stream);
        document.setXMLEncoding(StandardCharsets.UTF_8.toString());
        stream.add(Namespace.get("", "jabber:server"));
        stream.add(Namespace.get("db", "jabber:server:dialback"));
        stream.addAttribute("to", remoteDomain);
        stream.addAttribute("from", recipient);
        stream.addAttribute("version", "1.0");

        final String docTxt = document.asXML(); // Strip closing element.
        final String withoutClosing = docTxt.substring(0, docTxt.lastIndexOf("</stream:stream>"));

        writer.write(withoutClosing);
        writer.flush();

        // Get the answer from the Authoritative Server
        XmlPullParser xpp = reader.getXPPParser();
        for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
            eventType = xpp.next();
        }

        log.debug( "Got a response." ); // TODO there's code duplication here with LocalOutgoingServerSession.
        if ((xpp.getAttributeValue("", "version") != null) && (xpp.getAttributeValue("", "version").equals("1.0"))) {
            log.debug( "The remote server is XMPP 1.0 compliant (or at least reports to be).");
            Document doc;
            try {
                doc = reader.parseDocument();
            } catch (DocumentException e) {
                log.warn("Unable to verify key: XML Error!", e);
                // Close the stream
                writer.write("</stream:stream>");
                writer.flush();
                return VerifyResult.error;
            }
            Element features = doc.getRootElement();
            Element starttls = features.element("starttls");
            if (!directTLS && !skipTLS && starttls != null) {
                writer.write("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
                writer.flush();
                try {
                    doc = reader.parseDocument();
                } catch (DocumentException e) {
                    log.warn("Unable to verify key: XML Error!", e);
                    // Close the stream
                    writer.write("</stream:stream>");
                    writer.flush();
                    return VerifyResult.error;
                }
                if (!doc.getRootElement().getName().equals("proceed")) {
                    log.warn("Unable to verify key: Got {} instead of proceed for starttls", doc.getRootElement().getName());
                    log.debug("Like this: {}", doc.asXML());
                    // Close the stream
                    writer.write("</stream:stream>");
                    writer.flush();
                    return VerifyResult.error;
                }

                log.debug( "Negotiating StartTLS with AS... " );
                // Start handshake
                tlsStreamHandler.start();
                // Use new wrapped writers
                writer = new BufferedWriter( new OutputStreamWriter( tlsStreamHandler.getOutputStream(), StandardCharsets.UTF_8 ) );
                reader.getXPPParser().setInput( new InputStreamReader( tlsStreamHandler.getInputStream(), StandardCharsets.UTF_8 ) );
                log.debug( "Successfully negotiated StartTLS with AS... " );
                /// Recurses!
                return sendVerifyKey( key, streamID, recipient, remoteDomain, writer, reader, socket, skipTLS, directTLS );
            }
        }
        if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) {
            log.debug("Request for verification of the key and wait for response");
            final Element verify = DocumentHelper.createElement(QName.get("verify", "db", "jabber:server:dialback"));
            document.getRootElement().add(verify);

            verify.addAttribute("from", recipient);
            verify.addAttribute("to", remoteDomain);
            verify.addAttribute("id", streamID.getID());
            verify.addText(key);

            writer.write(verify.asXML());
            writer.flush();

            try {
                Element doc = reader.parseDocument().getRootElement();
                if ("db".equals(doc.getNamespacePrefix()) && "verify".equals(doc.getName())) {
                    if (doc.attributeValue("id") == null || !streamID.equals(BasicStreamIDFactory.createStreamID( doc.attributeValue("id") ))) {
                        // Include the invalid-id stream error condition in the response
                        writer.write(new StreamError(StreamError.Condition.invalid_id).toXML());
                        writer.write("</stream:stream>");
                        writer.flush();
                        // Thrown an error so <remote-connection-failed/> stream error
                        // condition is sent to the Originating Server
                        throw new RemoteConnectionFailedException("Invalid ID");
                    }
                    else if (isHostUnknown( doc.attributeValue( "to" ) )) {
                        // Include the host-unknown stream error condition in the response
                        writer.write(new StreamError(StreamError.Condition.host_unknown).toXML());
                        writer.write("</stream:stream>");
                        writer.flush();
                        // Thrown an error so <remote-connection-failed/> stream error
                        // condition is sent to the Originating Server
                        throw new RemoteConnectionFailedException("Host unknown");
                    }
                    else if (!remoteDomain.equals(doc.attributeValue("from"))) {
                        // Include the invalid-from stream error condition in the response
                        writer.write(new StreamError(StreamError.Condition.invalid_from).toXML());
                        writer.write("</stream:stream>");
                        writer.flush();
                        // Thrown an error so <remote-connection-failed/> stream error
                        // condition is sent to the Originating Server
                        throw new RemoteConnectionFailedException("Invalid From");
                    }
                    else if ("valid".equals(doc.attributeValue("type"))){
                        log.debug("Key was VERIFIED by the Authoritative Server.");
                        result = VerifyResult.valid;
                    }
                    else if ("invalid".equals(doc.attributeValue("type"))){
                        log.debug("Key was NOT VERIFIED by the Authoritative Server.");
                        result = VerifyResult.invalid;
                    }
                    else {
                        log.debug("Key was ERRORED by the Authoritative Server.");
                        result = VerifyResult.error;
                    }
                }
                else {
                    log.debug("db:verify answer was: " + doc.asXML());
                }
            }
            catch (DocumentException | RuntimeException e) {
                log.error("An error occurred while connecting to the Authoritative Server: ", e);
                // Thrown an error so <remote-connection-failed/> stream error condition is
                // sent to the Originating Server
                writer.write("</stream:stream>");
                writer.flush();
                throw new RemoteConnectionFailedException("Error connecting to the Authoritative Server");
            }

        }
        else {
            // Include the invalid-namespace stream error condition in the response
            writer.write(new StreamError(StreamError.Condition.invalid_namespace).toXML());
            writer.write("</stream:stream>");
            writer.flush();
            // Thrown an error so <remote-connection-failed/> stream error condition is
            // sent to the Originating Server
            throw new RemoteConnectionFailedException("Invalid namespace");
        }
        writer.write("</stream:stream>");
        writer.flush();
        return result;
    }
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