protected void createSession()
            throws UnauthorizedException, XmlPullParserException, IOException {
        XmlPullParser xpp = reader.getXPPParser();
        for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
            eventType = xpp.next();
        }

        // Check that the TO attribute of the stream header matches the server name or a valid
        // subdomain. If the value of the 'to' attribute is not valid then return a host-unknown
        // error and close the underlying connection.
        String host = reader.getXPPParser().getAttributeValue("", "to");
        if (validateHost() && isHostUnknown(host)) {
            final Element stream = DocumentHelper.createElement(QName.get("stream", "stream", xpp.getNamespace("stream")));
            final Document document = DocumentHelper.createDocument(stream);
            document.setXMLEncoding(StandardCharsets.UTF_8.toString());
            stream.add(Namespace.get("", xpp.getNamespace(null)));
            stream.addAttribute("from", host);
            stream.addAttribute("id", STREAM_ID_FACTORY.createStreamID().getID());
            stream.addAttribute("version", "1.0");

            connection.deliverRawText(StringUtils.asUnclosedStream(document));

            // Send the host_unknown error and close the underlying connection
            connection.close(new StreamError(StreamError.Condition.host_unknown, "The 'to' attribute does not specify an XMPP domain entity served by this service."));
            // Log a warning so that admins can track this cases from the server side
            Log.warn("Closing session due to incorrect hostname in stream header. Host: {}. Connection: {}", host, connection);
        }

        // Create the correct session based on the sent namespace. At this point the server
        // may offer the client to encrypt the connection. If the client decides to encrypt
        // the connection then a <starttls> stanza should be received
        else if (!createSession(xpp.getNamespace(null))) {
            // No session was created because of an invalid namespace prefix so answer a stream
            // error and close the underlying connection
            final Element stream = DocumentHelper.createElement(QName.get("stream", "stream", xpp.getNamespace("stream")));
            final Document document = DocumentHelper.createDocument(stream);
            document.setXMLEncoding(StandardCharsets.UTF_8.toString());
            stream.add(Namespace.get("", xpp.getNamespace(null)));
            stream.addAttribute("from", host);
            stream.addAttribute("id", STREAM_ID_FACTORY.createStreamID().getID());
            stream.addAttribute("version", "1.0");

            connection.deliverRawText(StringUtils.asUnclosedStream(document));

            // Include the bad-namespace-prefix in the response and close the underlying connection.
            connection.close(new StreamError(StreamError.Condition.bad_namespace_prefix, "The namespace used in the request does not identify functionality that can be provided by this endpoint."));
            // Log a warning so that admins can track this cases from the server side
            Log.warn("Closing session due to bad_namespace_prefix in stream header. Prefix: {}. Connection: {}", xpp.getNamespace(null), connection);
        }
    }
Uses the XPP to grab the opening stream tag and create an active session
object. The session to create will depend on the sent namespace. In all
cases, the method obtains the opening stream tag, checks for errors, and
either creates a session or returns an error and kills the connection.
If the connection remains open, the XPP will be set to be ready for the
first packet. A call to next() should result in an START_TAG state with
the first packet in the stream.

@throws UnauthorizedException if the connection required encryption but was not encrypted.
@throws XmlPullParserException if there was an XML error while creating the session.
@throws IOException if an IO error occurred while creating the session.
xmppserver/src/main/java/org/jivesoftware/openfire/net/SocketReader.java