diff options
Diffstat (limited to 'src/network/kernel')
-rw-r--r-- | src/network/kernel/kernel.pri | 3 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 5 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.h | 3 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo.cpp | 20 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo.h | 3 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo_unix.cpp | 5 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.cpp | 12 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.h | 3 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_symbian.cpp | 242 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_win.cpp | 11 |
10 files changed, 280 insertions, 27 deletions
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 09d2acf..6145c43 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -20,7 +20,8 @@ SOURCES += kernel/qauthenticator.cpp \ kernel/qnetworkproxy.cpp \ kernel/qnetworkinterface.cpp -unix:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp +symbian: SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_symbian.cpp +unix:!symbian:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp win32:SOURCES += kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 84bfee5..5336a1e 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -523,7 +523,7 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) Constructs a copy of the given \a address. */ QHostAddress::QHostAddress(const QHostAddress &address) - : d(new QHostAddressPrivate(*address.d)) + : d(new QHostAddressPrivate(*address.d.data())) { } @@ -559,7 +559,6 @@ QHostAddress::QHostAddress(SpecialAddress address) */ QHostAddress::~QHostAddress() { - delete d; } /*! @@ -568,7 +567,7 @@ QHostAddress::~QHostAddress() */ QHostAddress &QHostAddress::operator=(const QHostAddress &address) { - *d = *address.d; + *d.data() = *address.d.data(); return *this; } diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index b2f7659..082ffaa 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -44,6 +44,7 @@ #include <QtCore/qpair.h> #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qabstractsocket.h> struct sockaddr; @@ -130,7 +131,7 @@ public: static QPair<QHostAddress, int> parseSubnet(const QString &subnet); protected: - QHostAddressPrivate *d; + QScopedPointer<QHostAddressPrivate> d; }; inline bool operator ==(QHostAddress::SpecialAddress address1, const QHostAddress &address2) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index ee1369d..c8def4a 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -42,6 +42,7 @@ #include "qhostinfo.h" #include "qhostinfo_p.h" +#include "QtCore/qscopedpointer.h" #include <qabstracteventdispatcher.h> #include <private/qunicodetables_p.h> #include <qcoreapplication.h> @@ -165,24 +166,24 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, // Support for IDNA QString lookup = QString::fromLatin1(QUrl::toAce(name)); - QHostInfoResult *result = new QHostInfoResult; - result->autoDelete = false; - QObject::connect(result, SIGNAL(resultsReady(QHostInfo)), + QScopedPointer<QHostInfoResult> result(new QHostInfoResult); + result.data()->autoDelete = false; + QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), receiver, member); - int id = result->lookupId = theIdCounter.fetchAndAddRelaxed(1); + int id = result.data()->lookupId = theIdCounter.fetchAndAddRelaxed(1); if (lookup.isEmpty()) { QHostInfo info(id); info.setError(QHostInfo::HostNotFound); info.setErrorString(QObject::tr("No host name given")); - QMetaObject::invokeMethod(result, "emitResultsReady", Qt::QueuedConnection, + QMetaObject::invokeMethod(result.data(), "emitResultsReady", Qt::QueuedConnection, Q_ARG(QHostInfo, info)); - result->autoDelete = true; + result.take()->autoDelete = true; return id; } QHostInfoAgent *agent = theAgent(); - agent->addHostName(lookup, result); + agent->addHostName(lookup, result.take()); #if !defined QT_NO_THREAD if (!agent->isRunning()) @@ -327,7 +328,7 @@ QHostInfo::QHostInfo(int id) Constructs a copy of \a other. */ QHostInfo::QHostInfo(const QHostInfo &other) - : d(new QHostInfoPrivate(*other.d)) + : d(new QHostInfoPrivate(*other.d.data())) { } @@ -337,7 +338,7 @@ QHostInfo::QHostInfo(const QHostInfo &other) */ QHostInfo &QHostInfo::operator=(const QHostInfo &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } @@ -346,7 +347,6 @@ QHostInfo &QHostInfo::operator=(const QHostInfo &other) */ QHostInfo::~QHostInfo() { - delete d; } /*! diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index 432b979..22e9f42 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -43,6 +43,7 @@ #define QHOSTINFO_H #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qhostaddress.h> QT_BEGIN_HEADER @@ -91,7 +92,7 @@ public: static QString localDomainName(); private: - QHostInfoPrivate *d; + QScopedPointer<QHostInfoPrivate> d; }; QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 4a23399..39ea72c 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -41,8 +41,6 @@ //#define QHOSTINFO_DEBUG -static const int RESOLVER_TIMEOUT = 2000; - #include "qplatformdefs.h" #include "qhostinfo_p.h" @@ -151,7 +149,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) if (address.setAddress(hostName)) { // Reverse lookup // Reverse lookups using getnameinfo are broken on darwin, use gethostbyaddr instead. -#if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN) +#if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN) && !defined (Q_OS_SYMBIAN) sockaddr_in sa4; #ifndef QT_NO_IPV6 sockaddr_in6 sa6; @@ -326,6 +324,7 @@ QString QHostInfo::localDomainName() if (local_res_ninit) { // using thread-safe version res_state_ptr state = res_state_ptr(qMalloc(sizeof(*state))); + Q_CHECK_PTR(state); memset(state, 0, sizeof(*state)); local_res_ninit(state); QString domainName = QUrl::fromAce(state->defdname); diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index d6ce745..9f4b3f8 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -128,7 +128,7 @@ QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data) for (int i = 0; i < len; ++i) { if (i) result += QLatin1Char(':'); - + char buf[3]; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400 sprintf_s(buf, 3, "%02hX", ushort(data[i])); @@ -170,7 +170,7 @@ QNetworkAddressEntry::QNetworkAddressEntry() object \a other. */ QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other) - : d(new QNetworkAddressEntryPrivate(*other.d)) + : d(new QNetworkAddressEntryPrivate(*other.d.data())) { } @@ -179,7 +179,7 @@ QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other) */ QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } @@ -188,7 +188,6 @@ QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry */ QNetworkAddressEntry::~QNetworkAddressEntry() { - delete d; } /*! @@ -604,8 +603,13 @@ QDebug operator<<(QDebug debug, const QNetworkInterface &networkInterface) << ", hardware address = " << networkInterface.hardwareAddress() << ", flags = "; flagsDebug(debug, networkInterface.flags()); +#if defined(Q_CC_RVCT) + // RVCT gets confused with << networkInterface.addressEntries(), reason unknown. + debug.nospace() << ")\n"; +#else debug.nospace() << ", entries = " << networkInterface.addressEntries() << ")\n"; +#endif return debug.space(); } #endif diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h index fd11664..a823264 100644 --- a/src/network/kernel/qnetworkinterface.h +++ b/src/network/kernel/qnetworkinterface.h @@ -43,6 +43,7 @@ #define QNETWORKINTERFACE_H #include <QtCore/qshareddata.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qhostaddress.h> #ifndef QT_NO_NETWORKINTERFACE @@ -79,7 +80,7 @@ public: void setBroadcast(const QHostAddress &newBroadcast); private: - QNetworkAddressEntryPrivate *d; + QScopedPointer<QNetworkAddressEntryPrivate> d; }; class QNetworkInterfacePrivate; diff --git a/src/network/kernel/qnetworkinterface_symbian.cpp b/src/network/kernel/qnetworkinterface_symbian.cpp new file mode 100644 index 0000000..717d80d --- /dev/null +++ b/src/network/kernel/qnetworkinterface_symbian.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//#define QNETWORKINTERFACE_DEBUG + +#include "qnetworkinterface.h" +#include "qnetworkinterface_p.h" + +#ifndef QT_NO_NETWORKINTERFACE + +#include <in_sock.h> +#include <in_iface.h> +#include <es_sock.h> + +QT_BEGIN_NAMESPACE + + +static QNetworkInterface::InterfaceFlags convertFlags(const TSoInetInterfaceInfo& aInfo) +{ + QNetworkInterface::InterfaceFlags flags = 0; + flags |= (aInfo.iState == EIfUp) ? QNetworkInterface::IsUp : QNetworkInterface::InterfaceFlag(0); + // We do not have separate flag for running in Symbian OS + flags |= (aInfo.iState == EIfUp) ? QNetworkInterface::IsRunning : QNetworkInterface::InterfaceFlag(0); + flags |= (aInfo.iFeatures & KIfCanBroadcast) ? QNetworkInterface::CanBroadcast : QNetworkInterface::InterfaceFlag(0); + flags |= (aInfo.iFeatures & KIfIsLoopback) ? QNetworkInterface::IsLoopBack : QNetworkInterface::InterfaceFlag(0); + flags |= (aInfo.iFeatures & KIfIsPointToPoint) ? QNetworkInterface::IsPointToPoint : QNetworkInterface::InterfaceFlag(0); + flags |= (aInfo.iFeatures & KIfCanMulticast) ? QNetworkInterface::CanMulticast : QNetworkInterface::InterfaceFlag(0); + return flags; +} + +QString qstringFromDesc(const TDesC& aData) +{ + return QString::fromUtf16(aData.Ptr(), aData.Length()); +} + +static QList<QNetworkInterfacePrivate *> interfaceListing() +{ + TInt err(KErrNone); + QList<QNetworkInterfacePrivate *> interfaces; + + // Connect to Native socket server + RSocketServ socketServ; + err = socketServ.Connect(); + if (err) + return interfaces; + + // Open dummy socket for interface queries + RSocket socket; + err = socket.Open(socketServ, _L("udp")); + if (err) { + socketServ.Close(); + return interfaces; + } + + // Ask socket to start enumerating interfaces + err = socket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); + if (err) { + socket.Close(); + socketServ.Close(); + return interfaces; + } + + int ifindex = 0; + TPckgBuf<TSoInetInterfaceInfo> infoPckg; + TSoInetInterfaceInfo &info = infoPckg(); + while (socket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, infoPckg) == KErrNone) { + // Do not include IPv6 addresses because netmask and broadcast address cannot be determined correctly + if (info.iName != KNullDesC && info.iAddress.IsV4Mapped()) { + TName address; + QNetworkAddressEntry entry; + QNetworkInterfacePrivate *iface = 0; + + iface = new QNetworkInterfacePrivate; + iface->index = ifindex++; + interfaces << iface; + iface->name = qstringFromDesc(info.iName); + iface->flags = convertFlags(info); + + if (/*info.iFeatures&KIfHasHardwareAddr &&*/ info.iHwAddr.Family() != KAFUnspec) { + for (TInt i = sizeof(SSockAddr); i < sizeof(SSockAddr) + info.iHwAddr.GetUserLen(); i++) { + address.AppendNumFixedWidth(info.iHwAddr[i], EHex, 2); + if ((i + 1) < sizeof(SSockAddr) + info.iHwAddr.GetUserLen()) + address.Append(_L(":")); + } + address.UpperCase(); + iface->hardwareAddress = qstringFromDesc(address); + } + + // Get the address of the interface + info.iAddress.Output(address); + entry.setIp(QHostAddress(qstringFromDesc(address))); + + // Get the interface netmask + // For some reason netmask is always 0.0.0.0 + // info.iNetMask.Output(address); + // entry.setNetmask( QHostAddress( qstringFromDesc( address ) ) ); + + // Workaround: Let Symbian determine netmask based on IP address class + // TODO: Works only for IPv4 - Task: 259128 Implement IPv6 support + TInetAddr netmask; + netmask.NetMask(info.iAddress); + netmask.Output(address); + entry.setNetmask(QHostAddress(qstringFromDesc(address))); + + // Get the interface broadcast address + if (iface->flags & QNetworkInterface::CanBroadcast) { + // For some reason broadcast address is always 0.0.0.0 + // info.iBrdAddr.Output(address); + // entry.setBroadcast( QHostAddress( qstringFromDesc( address ) ) ); + + // Workaround: Let Symbian determine broadcast address based on IP address + // TODO: Works only for IPv4 - Task: 259128 Implement IPv6 support + TInetAddr broadcast; + broadcast.NetBroadcast(info.iAddress); + broadcast.Output(address); + entry.setBroadcast(QHostAddress(qstringFromDesc(address))); + } + + // Add new entry to interface address entries + iface->addressEntries << entry; + +#if defined(QNETWORKINTERFACE_DEBUG) + printf("\n Found network interface %s, interface flags:\n\ + IsUp = %d, IsRunning = %d, CanBroadcast = %d,\n\ + IsLoopBack = %d, IsPointToPoint = %d, CanMulticast = %d, \n\ + ip = %s, netmask = %s, broadcast = %s,\n\ + hwaddress = %s", + iface->name.toLatin1().constData(), + iface->flags & QNetworkInterface::IsUp, iface->flags & QNetworkInterface::IsRunning, iface->flags & QNetworkInterface::CanBroadcast, + iface->flags & QNetworkInterface::IsLoopBack, iface->flags & QNetworkInterface::IsPointToPoint, iface->flags & QNetworkInterface::CanMulticast, + entry.ip().toString().toLatin1().constData(), entry.netmask().toString().toLatin1().constData(), entry.broadcast().toString().toLatin1().constData(), + iface->hardwareAddress.toLatin1().constData()); +#endif + } + } + + // we will try to use routing info to detect more precisely + // netmask and then ::postProcess() should calculate + // broadcast addresses + + // use dummy socket to start enumerating routes + err = socket.SetOpt(KSoInetEnumRoutes, KSolInetRtCtrl); + if (err) { + socket.Close(); + socketServ.Close(); + // return what we have + // up to this moment + return interfaces; + } + + TSoInetRouteInfo routeInfo; + TPckg<TSoInetRouteInfo> routeInfoPkg(routeInfo); + while (socket.GetOpt(KSoInetNextRoute, KSolInetRtCtrl, routeInfoPkg) == KErrNone) { + TName address; + + // get interface address + routeInfo.iIfAddr.Output(address); + QHostAddress ifAddr(qstringFromDesc(address)); + if (ifAddr.isNull()) + continue; + + routeInfo.iDstAddr.Output(address); + QHostAddress destination(qstringFromDesc(address)); + if (destination.isNull() || destination != ifAddr) + continue; + + // search interfaces + for (int ifindex = 0; ifindex < interfaces.size(); ++ifindex) { + QNetworkInterfacePrivate *iface = interfaces.at(ifindex); + for (int eindex = 0; eindex < iface->addressEntries.size(); ++eindex) { + QNetworkAddressEntry entry = iface->addressEntries.at(eindex); + if (entry.ip() != ifAddr) { + continue; + } else if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol) { + // skip if not IPv4 address (e.g. IPv6) + // as results not reliable on Symbian + continue; + } else { + routeInfo.iNetMask.Output(address); + QHostAddress netmask(qstringFromDesc(address)); + entry.setNetmask(netmask); + // NULL boradcast address for + // ::postProcess to have effect + entry.setBroadcast(QHostAddress()); + iface->addressEntries.replace(eindex, entry); + } + } + } + } + + socket.Close(); + socketServ.Close(); + + return interfaces; +} + +QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan() +{ + return interfaceListing(); +} + +QT_END_NAMESPACE + +#endif // QT_NO_NETWORKINTERFACE diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index cba931c..05d5027 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -110,6 +110,8 @@ static QHash<QHostAddress, QHostAddress> ipv4Netmasks() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); + if (!pAdapter) + return ipv4netmasks; // try again if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -151,7 +153,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_ADDRESSES *)qMalloc(bufSize); - + if (!pAdapter) + return interfaces; // try again if (ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -231,7 +234,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWin2k() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); - + if (!pAdapter) + return interfaces; // try again if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -301,7 +305,8 @@ QString QHostInfo::localDomainName() pinfo = &info; if (ptrGetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) { pinfo = (FIXED_INFO *)qMalloc(bufSize); - + if (!pinfo) + return QString(); // try again if (ptrGetNetworkParams(pinfo, &bufSize) != ERROR_SUCCESS) { qFree(pinfo); |