bool QXmppServerPrivate::routeData(const QString &to, const QByteArray &data) { // refuse to route packets to empty destination, own domain or sub-domains const QString toDomain = QXmppUtils::jidToDomain(to); if (to.isEmpty() || to == domain || toDomain.endsWith("." + domain)) return false; if (toDomain == domain) { // look for a client connection QList<QXmppIncomingClient*> found; if (QXmppUtils::jidToResource(to).isEmpty()) { foreach (QXmppIncomingClient *conn, incomingClientsByBareJid.value(to)) found << conn; } else { QXmppIncomingClient *conn = incomingClientsByJid.value(to); if (conn) found << conn; } // send data foreach (QXmppStream *conn, found) QMetaObject::invokeMethod(conn, "sendData", Q_ARG(QByteArray, data)); return !found.isEmpty(); } else if (!serversForServers.isEmpty()) { bool check; Q_UNUSED(check); // look for an outgoing S2S connection foreach (QXmppOutgoingServer *conn, outgoingServers) { if (conn->remoteDomain() == toDomain) { // send or queue data QMetaObject::invokeMethod(conn, "queueData", Q_ARG(QByteArray, data)); return true; } } // if we did not find an outgoing server, // we need to establish the S2S connection QXmppOutgoingServer *conn = new QXmppOutgoingServer(domain, 0); conn->setLocalStreamKey(QXmppUtils::generateStanzaHash().toLatin1()); conn->moveToThread(q->thread()); conn->setParent(q); check = QObject::connect(conn, SIGNAL(disconnected()), q, SLOT(_q_outgoingServerDisconnected())); Q_UNUSED(check); // add stream outgoingServers.insert(conn); q->setGauge("outgoing-server.count", outgoingServers.size()); // queue data and connect to remote server QMetaObject::invokeMethod(conn, "queueData", Q_ARG(QByteArray, data)); QMetaObject::invokeMethod(conn, "connectToHost", Q_ARG(QString, toDomain)); return true; } else {
void tst_QXmppServer::testConnect() { QFETCH(QString, username); QFETCH(QString, password); QFETCH(QString, mechanism); QFETCH(bool, connected); const QString testDomain("localhost"); const QHostAddress testHost(QHostAddress::LocalHost); const quint16 testPort = 12345; QXmppLogger logger; //logger.setLoggingType(QXmppLogger::StdoutLogging); // prepare server TestPasswordChecker passwordChecker; passwordChecker.addCredentials("testuser", "testpwd"); QXmppServer server; server.setDomain(testDomain); server.setLogger(&logger); server.setPasswordChecker(&passwordChecker); server.listenForClients(testHost, testPort); // prepare client QXmppClient client; client.setLogger(&logger); QEventLoop loop; connect(&client, SIGNAL(connected()), &loop, SLOT(quit())); connect(&client, SIGNAL(disconnected()), &loop, SLOT(quit())); QXmppConfiguration config; config.setDomain(testDomain); config.setHost(testHost.toString()); config.setPort(testPort); config.setUser(username); config.setPassword(password); config.setSaslAuthMechanism(mechanism); client.connectToServer(config); loop.exec(); QCOMPARE(client.isConnected(), connected); }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // we want one argument : the domain to serve if (argc != 2) { fprintf(stderr, "Usage: xmppServer <domain>\n"); return EXIT_FAILURE; } const QString domain = QString::fromLocal8Bit(argv[1]); QXmppLogger logger; logger.setLoggingType(QXmppLogger::StdoutLogging); passwordChecker checker; QXmppServer server; server.setDomain(domain); server.setLogger(&logger); server.setPasswordChecker(&checker); server.listenForClients(); server.listenForServers(); return a.exec(); }