From 6aa29f3cf73b93797076b5bec4a220c08dc765fb Mon Sep 17 00:00:00 2001 From: Jeremy Lainé Date: Fri, 3 Sep 2010 09:37:49 +0000 Subject: rename QXmppSrvLookup to QXmppSrvInfo, and restore previous API --- src/QXmppOutgoingClient.cpp | 12 +-- src/QXmppOutgoingServer.cpp | 12 +-- src/QXmppSrvInfo.cpp | 208 ++++++++++++++++++++++++++++++++++++++++++ src/QXmppSrvInfo.h | 65 ++++++++++++++ src/QXmppSrvLookup.cpp | 215 -------------------------------------------- src/QXmppSrvLookup.h | 70 --------------- src/src.pro | 4 +- 7 files changed, 287 insertions(+), 299 deletions(-) create mode 100644 src/QXmppSrvInfo.cpp create mode 100644 src/QXmppSrvInfo.h delete mode 100644 src/QXmppSrvLookup.cpp delete mode 100644 src/QXmppSrvLookup.h (limited to 'src') diff --git a/src/QXmppOutgoingClient.cpp b/src/QXmppOutgoingClient.cpp index 0131b9a2..17a90060 100644 --- a/src/QXmppOutgoingClient.cpp +++ b/src/QXmppOutgoingClient.cpp @@ -32,7 +32,7 @@ #include "QXmppPacket.h" #include "QXmppPresence.h" #include "QXmppOutgoingClient.h" -#include "QXmppSrvLookup.h" +#include "QXmppSrvInfo.h" #include "QXmppStreamFeatures.h" #include "QXmppNonSASLAuth.h" #include "QXmppSaslAuth.h" @@ -161,15 +161,15 @@ void QXmppOutgoingClient::connectToHost() if (host.isEmpty() || !port) { debug(QString("Looking up server for domain %1").arg(domain)); - QXmppSrvLookup srvLookup; - if (srvLookup.fromNameC2S(domain)) + QXmppSrvInfo serviceInfo = QXmppSrvInfo::fromName("_xmpp-client._tcp." + domain); + if (!serviceInfo.records().isEmpty()) { // take the first returned record - host = srvLookup.records().first().hostName(); - port = srvLookup.records().first().port(); + host = serviceInfo.records().first().hostName(); + port = serviceInfo.records().first().port(); } else { // as a fallback, use domain as the host name - warning(QString("Lookup for domain %1 failed: %2").arg(domain, srvLookup.errorString())); + warning(QString("Lookup for domain %1 failed: %2").arg(domain, serviceInfo.errorString())); host = domain; } } diff --git a/src/QXmppOutgoingServer.cpp b/src/QXmppOutgoingServer.cpp index cb93434d..30d366f0 100644 --- a/src/QXmppOutgoingServer.cpp +++ b/src/QXmppOutgoingServer.cpp @@ -28,7 +28,7 @@ #include "QXmppConstants.h" #include "QXmppDialback.h" #include "QXmppOutgoingServer.h" -#include "QXmppSrvLookup.h" +#include "QXmppSrvInfo.h" #include "QXmppStreamFeatures.h" #include "QXmppUtils.h" @@ -82,15 +82,15 @@ void QXmppOutgoingServer::connectToHost(const QString &domain) // lookup server for domain debug(QString("Looking up server for domain %1").arg(domain)); - QXmppSrvLookup srvLookup; - if (srvLookup.fromNameS2S(domain)) + QXmppSrvInfo serviceInfo = QXmppSrvInfo::fromName("_xmpp-server._tcp." + domain); + if (!serviceInfo.records().isEmpty()) { // take the first returned record - host = srvLookup.records().first().hostName(); - port = srvLookup.records().first().port(); + host = serviceInfo.records().first().hostName(); + port = serviceInfo.records().first().port(); } else { // as a fallback, use domain as the host name - warning(QString("Lookup for domain %1 failed: %2").arg(domain, srvLookup.errorString())); + warning(QString("Lookup for domain %1 failed: %2").arg(domain, serviceInfo.errorString())); host = domain; port = 5269; } diff --git a/src/QXmppSrvInfo.cpp b/src/QXmppSrvInfo.cpp new file mode 100644 index 00000000..21a0a08a --- /dev/null +++ b/src/QXmppSrvInfo.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2008-2010 The QXmpp developers + * + * Author: + * Jeremy Lainé + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#include + +#include "QXmppSrvInfo.h" + +#ifdef Q_OS_WIN +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +/// Constructs an empty service record object. +/// + +QXmppSrvRecord::QXmppSrvRecord() + : host_port(0) +{ +} + +/// Returns host name for this service record. +/// + +QString QXmppSrvRecord::hostName() const +{ + return host_name; +} + +/// Sets the host name for this service record. +/// +/// \param hostName + +void QXmppSrvRecord::setHostName(const QString &hostName) +{ + host_name = hostName; +} + +/// Returns the port for this service record. +/// + +quint16 QXmppSrvRecord::port() const +{ + return host_port; +} + +/// Sets the port for this service record. +/// +/// \param port + +void QXmppSrvRecord::setPort(quint16 port) +{ + host_port = port; +} + +/// If the lookup failed, this function returns a human readable description of the error. +/// + +QString QXmppSrvInfo::errorString() const +{ + return m_errorString; +} + +/// Returns the list of records associated with this service. +/// +QList QXmppSrvInfo::records() const +{ + return m_records; +} + +/// Perform a DNS lookup for an SRV entry. +/// +/// Returns a QXmppSrvInfo object containing the found records. +/// +/// \param dname + +QXmppSrvInfo QXmppSrvInfo::fromName(const QString &dname) +{ + QXmppSrvInfo result; + +#ifdef Q_OS_WIN + PDNS_RECORD records, ptr; + + /* perform DNS query */ + if (DnsQuery_UTF8(dname.toUtf8(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &records, NULL) != ERROR_SUCCESS) + { + result.m_errorString = QLatin1String("DnsQuery_UTF8 failed"); + return result; + } + + /* extract results */ + for (ptr = records; ptr != NULL; ptr = ptr->pNext) + { + if ((ptr->wType == DNS_TYPE_SRV) && !strcmp((char*)ptr->pName, dname.toUtf8())) + { + QXmppSrvRecord record; + record.setHostName(QString::fromUtf8((char*)ptr->Data.Srv.pNameTarget)); + record.setPort(ptr->Data.Srv.wPort); + result.m_records.append(record); + } + } + + DnsRecordListFree(records, DnsFreeRecordList); +#else + unsigned char response[PACKETSZ]; + int responseLength, answerCount, answerIndex; + + /* explicitly call res_init in case config changed */ + res_init(); + + /* perform DNS query */ + memset(response, 0, sizeof(response)); + responseLength = res_query(dname.toAscii(), C_IN, T_SRV, response, sizeof(response)); + if (responseLength < int(sizeof(HEADER))) + { + result.m_errorString = QString("res_query failed: %1").arg(hstrerror(h_errno)); + return result; + } + + /* check the response header */ + HEADER *header = (HEADER*)response; + if (header->rcode != NOERROR || !(answerCount = ntohs(header->ancount))) + { + result.m_errorString = QLatin1String("res_query returned an error"); + return result; + } + + /* skip the query */ + char host[PACKETSZ], answer[PACKETSZ]; + unsigned char *p = response + sizeof(HEADER); + int status = dn_expand(response, response + responseLength, p, host, sizeof(host)); + if (status < 0) + { + result.m_errorString = QLatin1String("dn_expand failed"); + return result; + } + p += status + 4; + + /* parse answers */ + answerIndex = 0; + while ((p < response + responseLength) && (answerIndex < answerCount)) + { + int type, klass, ttl, size; + status = dn_expand(response, response + responseLength, p, host, sizeof(host)); + if (status < 0) + { + result.m_errorString = QLatin1String("dn_expand failed"); + return result; + } + + p += status; + type = (p[0] << 8) | p[1]; + p += 2; + klass = (p[0] << 8) | p[1]; + p += 2; + ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + p += 4; + size = (p[0] << 8) | p[1]; + p += 2; + + if (type == T_SRV) + { + quint16 port = (p[4] << 8) | p[5]; + status = dn_expand(response, response + responseLength, p + 6, answer, sizeof(answer)); + if (status < 0) + { + result.m_errorString = QLatin1String("dn_expand failed"); + return result; + } + QXmppSrvRecord record; + record.setHostName(answer); + record.setPort(port); + result.m_records.append(record); + } else { + qWarning("Unexpected DNS answer type"); + } + p += size; + answerIndex++; + } +#endif + return result; +} diff --git a/src/QXmppSrvInfo.h b/src/QXmppSrvInfo.h new file mode 100644 index 00000000..3c36867a --- /dev/null +++ b/src/QXmppSrvInfo.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008-2010 The QXmpp developers + * + * Author: + * Jeremy Lainé + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPSRVINFO_H +#define QXMPPSRVINFO_H + +#include +#include + +/// \brief The QXmppSrvRecord class represents a DNS SRV record. +/// + +class QXmppSrvRecord +{ +public: + QXmppSrvRecord(); + + QString hostName() const; + void setHostName(const QString &hostName); + + quint16 port() const; + void setPort(quint16 port); + +private: + QString host_name; + quint16 host_port; +}; + +/// \brief The QXmppSrvInfo class provides static methods for DNS SRV lookups. +/// + +class QXmppSrvInfo +{ +public: + QString errorString() const; + QList records() const; + + static QXmppSrvInfo fromName(const QString &dname); + +private: + QString m_errorString; + QList m_records; +}; + +#endif diff --git a/src/QXmppSrvLookup.cpp b/src/QXmppSrvLookup.cpp deleted file mode 100644 index 58f20df9..00000000 --- a/src/QXmppSrvLookup.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2008-2010 The QXmpp developers - * - * Authors: - * Jeremy Lainé - * Manjeet Dahiya - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#include - -#include "QXmppSrvLookup.h" - -#ifdef Q_OS_WIN -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif - -const QString QXmppSrvLookup::c2sPrefix = "_xmpp-client._tcp."; -const QString QXmppSrvLookup::s2sPrefix = "_xmpp-server._tcp."; - -/// Constructs an empty service record object. -/// - -QXmppSrvLookup::SrvRecord::SrvRecord() - : host_port(0) -{ -} - -/// Returns host name for this service record. -/// - -QString QXmppSrvLookup::SrvRecord::hostName() const -{ - return host_name; -} - -/// Sets the host name for this service record. -/// -/// \param hostName - -void QXmppSrvLookup::SrvRecord::setHostName(const QString &hostName) -{ - host_name = hostName; -} - -/// Returns the port for this service record. -/// - -quint16 QXmppSrvLookup::SrvRecord::port() const -{ - return host_port; -} - -/// Sets the port for this service record. -/// -/// \param port - -void QXmppSrvLookup::SrvRecord::setPort(quint16 port) -{ - host_port = port; -} - -/// If the lookup failed, this function returns a human readable description of the error. -/// - -QString QXmppSrvLookup::errorString() const -{ - return m_errorString; -} - -/// Returns the list of records associated with this service. -/// -QList QXmppSrvLookup::records() const -{ - return m_records; -} - -bool QXmppSrvLookup::fromNameC2S(const QString &domain) -{ - return fromName(c2sPrefix+domain); -} - -bool QXmppSrvLookup::fromNameS2S(const QString &domain) -{ - return fromName(s2sPrefix+domain); -} - -bool QXmppSrvLookup::fromName(const QString &dname) -{ - m_errorString.clear(); -#ifdef Q_OS_WIN - PDNS_RECORD records, ptr; - - /* perform DNS query */ - if (DnsQuery_UTF8(dname.toUtf8(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &records, NULL) != ERROR_SUCCESS) - { - m_errorString = QLatin1String("DnsQuery_UTF8 failed"); - return false; - } - - /* extract results */ - for (ptr = records; ptr != NULL; ptr = ptr->pNext) - { - if ((ptr->wType == DNS_TYPE_SRV) && !strcmp((char*)ptr->pName, dname.toUtf8())) - { - QXmppSrvLookup::SrvRecord record; - record.setHostName(QString::fromUtf8((char*)ptr->Data.Srv.pNameTarget)); - record.setPort(ptr->Data.Srv.wPort); - m_records.append(record); - } - } - - DnsRecordListFree(records, DnsFreeRecordList); -#else - unsigned char response[PACKETSZ]; - int responseLength, answerCount, answerIndex; - - /* explicitly call res_init in case config changed */ - res_init(); - - /* perform DNS query */ - memset(response, 0, sizeof(response)); - responseLength = res_query(dname.toAscii(), C_IN, T_SRV, response, sizeof(response)); - if (responseLength < int(sizeof(HEADER))) - { - m_errorString = QString("res_query failed: %1").arg(hstrerror(h_errno)); - return false; - } - - /* check the response header */ - HEADER *header = (HEADER*)response; - if (header->rcode != NOERROR || !(answerCount = ntohs(header->ancount))) - { - m_errorString = QLatin1String("res_query returned an error"); - return false; - } - - /* skip the query */ - char host[PACKETSZ], answer[PACKETSZ]; - unsigned char *p = response + sizeof(HEADER); - int status = dn_expand(response, response + responseLength, p, host, sizeof(host)); - if (status < 0) - { - m_errorString = QLatin1String("dn_expand failed"); - return false; - } - p += status + 4; - - /* parse answers */ - answerIndex = 0; - while ((p < response + responseLength) && (answerIndex < answerCount)) - { - int type, klass, ttl, size; - status = dn_expand(response, response + responseLength, p, host, sizeof(host)); - if (status < 0) - { - m_errorString = QLatin1String("dn_expand failed"); - return false; - } - - p += status; - type = (p[0] << 8) | p[1]; - p += 2; - klass = (p[0] << 8) | p[1]; - p += 2; - ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - p += 4; - size = (p[0] << 8) | p[1]; - p += 2; - - if (type == T_SRV) - { - quint16 port = (p[4] << 8) | p[5]; - status = dn_expand(response, response + responseLength, p + 6, answer, sizeof(answer)); - if (status < 0) - { - m_errorString = QLatin1String("dn_expand failed"); - return false; - } - QXmppSrvLookup::SrvRecord record; - record.setHostName(answer); - record.setPort(port); - m_records.append(record); - } else { - qWarning("Unexpected DNS answer type"); - } - p += size; - answerIndex++; - } -#endif - return true; -} diff --git a/src/QXmppSrvLookup.h b/src/QXmppSrvLookup.h deleted file mode 100644 index 9cac4f83..00000000 --- a/src/QXmppSrvLookup.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2008-2010 The QXmpp developers - * - * Authors: - * Jeremy Lainé - * Manjeet Dahiya - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#ifndef QXMPPSRVLOOKUP_H -#define QXMPPSRVLOOKUP_H - -#include -#include - -/// \brief The QXmppSrvLookup class provides static methods for DNS SRV lookups. -/// - -class QXmppSrvLookup -{ -public: - static const QString c2sPrefix; - static const QString s2sPrefix; - - /// \brief Represents a DNS SRV record - /// - class SrvRecord - { - public: - SrvRecord(); - - QString hostName() const; - void setHostName(const QString &hostName); - - quint16 port() const; - void setPort(quint16 port); - - private: - QString host_name; - quint16 host_port; - }; - - QString errorString() const; - QList records() const; - - bool fromName(const QString &name); - bool fromNameC2S(const QString &domain); - bool fromNameS2S(const QString &domain); - -private: - QString m_errorString; - QList m_records; -}; - -#endif diff --git a/src/src.pro b/src/src.pro index 71872400..f369be40 100644 --- a/src/src.pro +++ b/src/src.pro @@ -66,7 +66,7 @@ INSTALL_HEADERS = QXmppUtils.h \ QXmppServer.h \ QXmppServerExtension.h \ QXmppServerPlugin.h \ - QXmppSrvLookup.h \ + QXmppSrvInfo.h \ QXmppSessionIq.h \ QXmppSocks.h \ QXmppStanza.h \ @@ -120,7 +120,7 @@ SOURCES += QXmppUtils.cpp \ QXmppSaslAuth.cpp \ QXmppServer.cpp \ QXmppServerExtension.cpp \ - QXmppSrvLookup.cpp \ + QXmppSrvInfo.cpp \ QXmppSessionIq.cpp \ QXmppSocks.cpp \ QXmppStanza.cpp \ -- cgit v1.2.3