public LocalIncomingServerSession createIncomingSession(XMPPPacketReader reader) throws IOException,
            XmlPullParserException {

        if (!ServerDialback.isEnabled() && !ServerDialback.isEnabledForSelfSigned()) {
            Log.info("Server Dialback: disallowing functionality as it has been disabled by configuration.");
            return null;
        }

        XmlPullParser xpp = reader.getXPPParser();
        StringBuilder sb;
        if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) {
            Log.debug("ServerDialback: Processing incoming session.");

            StreamID streamID = sessionManager.nextStreamID();

            sb = new StringBuilder();
            sb.append("<stream:stream");
            sb.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
            sb.append(" xmlns=\"jabber:server\" xmlns:db=\"jabber:server:dialback\"");
            sb.append(" id=\"");
            sb.append(streamID.toString());
            sb.append("\">");
            connection.deliverRawText(sb.toString());

            try {
                Element doc = reader.parseDocument().getRootElement();
                if ("db".equals(doc.getNamespacePrefix()) && "result".equals(doc.getName())) {
                    String hostname = doc.attributeValue("from");
                    String recipient = doc.attributeValue("to");
                    Log.debug("ServerDialback: RS - Validating remote domain for incoming session from {} to {}", hostname, recipient);
                    try {
                        validateRemoteDomain(doc, streamID);
                        Log.debug("ServerDialback: RS - Validation of remote domain for incoming session from {} to {} was successful.", hostname, recipient);
                        // Create a server Session for the remote server
                        LocalIncomingServerSession session = sessionManager.
                            createIncomingServerSession(connection, streamID, hostname);
                        // Add the validated domain as a valid domain
                        session.addValidatedDomain(hostname);
                        session.setAuthenticationMethod(ServerSession.AuthenticationMethod.DIALBACK);
                        // Set the domain or subdomain of the local server used when
                        // validating the session
                        session.setLocalDomain(recipient);
                        // After the session has been created, inform all listeners as well.
                        ServerSessionEventDispatcher.dispatchEvent(session, ServerSessionEventDispatcher.EventType.session_created);
                        return session;
                    } catch (StreamErrorException e) {
                        Log.debug("ServerDialback: RS - Validation of remote domain for incoming session from {} to {} was not successful.", hostname, recipient, e);
                        connection.close(e.getStreamError());
                        return null;
                    } catch (Exception e) {
                        Log.debug("ServerDialback: RS - Validation of remote domain for incoming session from {} to {} was not successful.", hostname, recipient, e);
                        connection.close();
                        return null;
                    }
                }
                else if ("db".equals(doc.getNamespacePrefix()) && "verify".equals(doc.getName())) {
                    // When acting as an Authoritative Server the Receiving Server will send a
                    // db:verify packet for verifying a key that was previously sent by this
                    // server when acting as the Originating Server
                    verifyReceivedKey(doc, connection);
                    // Close the underlying connection
                    connection.close();
                    String verifyFROM = doc.attributeValue("from");
                    String id = doc.attributeValue("id");
                    Log.debug("ServerDialback: AS - Connection closed for host: " + verifyFROM + " id: " + id);
                    return null;
                }
                else {
                    Log.debug("ServerDialback: Received an invalid/unknown packet while trying to process an incoming session: {}", doc.asXML());
                    // The remote server sent an invalid/unknown packet
                    connection.deliverRawText(
                            new StreamError(StreamError.Condition.invalid_xml).toXML());
                    // Close the underlying connection
                    connection.close();
                    return null;
                }
            }
            catch (Exception e) {
                Log.error("An error occurred while creating a server session", e);
                // Close the underlying connection
                connection.close();
                return null;
            }

        }
        else {
            Log.debug("ServerDialback: Received a stanza in an invalid namespace while trying to process an incoming session: {}", xpp.getNamespace("db"));
            connection.deliverRawText(
                    new StreamError(StreamError.Condition.invalid_namespace, "Invalid namespace: " + xpp.getNamespace("db")).toXML());
            // Close the underlying connection
            connection.close();
            return null;
        }
    }
Returns a new {@link IncomingServerSession} with a domain validated by the Authoritative
Server. New domains may be added to the returned IncomingServerSession after they have
been validated. See
{@link LocalIncomingServerSession#validateSubsequentDomain(org.dom4j.Element)}. The remote
server will be able to send packets through this session whose domains were previously
validated.<p>

When acting as an Authoritative Server this method will verify the requested key
and will return null since the underlying TCP connection will be closed after sending the
response to the Receiving Server.<p>

@param reader reader of DOM documents on the connection to the remote server.
@return an IncomingServerSession that was previously validated against the remote server.
@throws IOException if an I/O error occurs while communicating with the remote server.
@throws XmlPullParserException if an error occurs while parsing XML packets.
xmppserver/src/main/java/org/jivesoftware/openfire/server/ServerDialback.java