Changeset 160
- Timestamp:
- Sep 5, 2009, 2:57:17 AM (16 years ago)
- Location:
- trunk/src/network
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/network/kernel/kernel.pri ¶
r2 r160 23 23 unix:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp 24 24 win32:SOURCES += kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp 25 os2:SOURCES += kernel/qhostinfo_os2.cpp kernel/qnetworkinterface_os2.cpp 25 26 26 27 mac:LIBS+= -framework SystemConfiguration -
TabularUnified trunk/src/network/kernel/qhostinfo_os2.cpp ¶
r158 r160 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** Contact: Qt Software Information (qt-info@nokia.com) 5 ** 6 ** Copyright (C) 2009 netlabs.org. OS/2 parts. 5 7 ** 6 8 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 44 46 static const int RESOLVER_TIMEOUT = 2000; 45 47 48 #include "qt_os2.h" 46 49 #include "qplatformdefs.h" 47 50 … … 52 55 #include <qurl.h> 53 56 #include <qfile.h> 54 #include <private/qmutexpool_p.h>55 57 56 58 extern "C" { … … 61 63 } 62 64 63 #if defined (QT_NO_GETADDRINFO)64 65 #include <qmutex.h> 65 66 QT_BEGIN_NAMESPACE 66 67 Q_GLOBAL_STATIC(QMutex, getHostByNameMutex) 67 68 QT_END_NAMESPACE 68 #endif69 69 70 70 QT_BEGIN_NAMESPACE … … 75 75 #endif 76 76 77 // HP-UXi has a bug in getaddrinfo(3) that makes it thread-unsafe78 // with this flag. So disable it in that platform.79 #if defined(AI_ADDRCONFIG) && !defined(Q_OS_HPUX)80 # define Q_ADDRCONFIG AI_ADDRCONFIG81 #endif82 83 typedef struct __res_state *res_state_ptr;84 85 typedef int (*res_init_proto)(void);86 static res_init_proto local_res_init = 0;87 typedef int (*res_ninit_proto)(res_state_ptr);88 static res_ninit_proto local_res_ninit = 0;89 typedef void (*res_nclose_proto)(res_state_ptr);90 static res_nclose_proto local_res_nclose = 0;91 static res_state_ptr local_res = 0;92 93 static void resolveLibrary()94 {95 #ifndef QT_NO_LIBRARY96 QLibrary lib(QLatin1String("resolv"));97 if (!lib.load())98 return;99 100 local_res_init = res_init_proto(lib.resolve("__res_init"));101 if (!local_res_init)102 local_res_init = res_init_proto(lib.resolve("res_init"));103 104 local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit"));105 if (!local_res_ninit)106 local_res_ninit = res_ninit_proto(lib.resolve("res_ninit"));107 108 if (!local_res_ninit) {109 // if we can't get a thread-safe context, we have to use the global _res state110 local_res = res_state_ptr(lib.resolve("_res"));111 } else {112 local_res_nclose = res_nclose_proto(lib.resolve("res_nclose"));113 if (!local_res_nclose)114 local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose"));115 if (!local_res_nclose)116 local_res_ninit = 0;117 }118 #endif119 }120 121 77 QHostInfo QHostInfoAgent::fromName(const QString &hostName) 122 78 { … … 129 85 #endif 130 86 131 // Load res_init on demand.132 static volatile bool triedResolve = false;133 if (!triedResolve) {134 #ifndef QT_NO_THREAD135 QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_init));136 #endif137 if (!triedResolve) {138 resolveLibrary();139 triedResolve = true;140 }141 }142 143 // If res_init is available, poll it.144 if (local_res_init)145 local_res_init();146 147 87 QHostAddress address; 148 88 if (address.setAddress(hostName)) { 149 89 // Reverse lookup 150 // Reverse lookups using getnameinfo are broken on darwin, use gethostbyaddr instead.151 #if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN)152 sockaddr_in sa4;153 #ifndef QT_NO_IPV6154 sockaddr_in6 sa6;155 #endif156 sockaddr *sa = 0;157 QT_SOCKLEN_T saSize = 0;158 if (address.protocol() == QAbstractSocket::IPv4Protocol) {159 sa = (sockaddr *)&sa4;160 saSize = sizeof(sa4);161 memset(&sa4, 0, sizeof(sa4));162 sa4.sin_family = AF_INET;163 sa4.sin_addr.s_addr = htonl(address.toIPv4Address());164 }165 #ifndef QT_NO_IPV6166 else {167 sa = (sockaddr *)&sa6;168 saSize = sizeof(sa6);169 memset(&sa6, 0, sizeof(sa6));170 sa6.sin6_family = AF_INET6;171 memcpy(sa6.sin6_addr.s6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr.s6_addr));172 }173 #endif174 175 char hbuf[NI_MAXHOST];176 if (!sa || getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) != 0) {177 results.setError(QHostInfo::HostNotFound);178 results.setErrorString(tr("Host not found"));179 return results;180 }181 results.setHostName(QString::fromLatin1(hbuf));182 #else183 90 in_addr_t inetaddr = inet_addr(hostName.toLatin1().constData()); 184 91 struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET); … … 189 96 } 190 97 results.setHostName(QString::fromLatin1(ent->h_name)); 191 #endif 192 } 193 194 #if !defined (QT_NO_GETADDRINFO) 195 // Call getaddrinfo, and place all IPv4 addresses at the start and 196 // the IPv6 addresses at the end of the address list in results. 197 addrinfo *res = 0; 198 struct addrinfo hints; 199 memset(&hints, 0, sizeof(hints)); 200 hints.ai_family = PF_UNSPEC; 201 #ifdef Q_ADDRCONFIG 202 hints.ai_flags = Q_ADDRCONFIG; 203 #endif 204 205 int result = getaddrinfo(hostName.toLatin1().constData(), 0, &hints, &res); 206 # ifdef Q_ADDRCONFIG 207 if (result == EAI_BADFLAGS) { 208 // if the lookup failed with AI_ADDRCONFIG set, try again without it 209 hints.ai_flags = 0; 210 result = getaddrinfo(hostName.toLatin1().constData(), 0, &hints, &res); 211 } 212 # endif 213 214 if (result == 0) { 215 addrinfo *node = res; 216 QList<QHostAddress> addresses; 217 while (node) { 218 if (node->ai_family == AF_INET) { 219 QHostAddress addr; 220 addr.setAddress(ntohl(((sockaddr_in *) node->ai_addr)->sin_addr.s_addr)); 221 if (!addresses.contains(addr)) 222 addresses.append(addr); 223 } 224 #ifndef QT_NO_IPV6 225 else if (node->ai_family == AF_INET6) { 226 QHostAddress addr; 227 addr.setAddress(((sockaddr_in6 *) node->ai_addr)->sin6_addr.s6_addr); 228 if (!addresses.contains(addr)) 229 addresses.append(addr); 230 } 231 #endif 232 node = node->ai_next; 233 } 234 if (addresses.isEmpty() && node == 0) { 235 // Reached the end of the list, but no addresses were found; this 236 // means the list contains one or more unknown address types. 237 results.setError(QHostInfo::UnknownError); 238 results.setErrorString(tr("Unknown address type")); 239 } 240 241 results.setAddresses(addresses); 242 freeaddrinfo(res); 243 } else if (result == EAI_NONAME 244 || result == EAI_FAIL 245 #ifdef EAI_NODATA 246 // EAI_NODATA is deprecated in RFC 3493 247 || result == EAI_NODATA 248 #endif 249 ) { 250 results.setError(QHostInfo::HostNotFound); 251 results.setErrorString(tr("Host not found")); 252 } else { 253 results.setError(QHostInfo::UnknownError); 254 results.setErrorString(QString::fromLocal8Bit(gai_strerror(result))); 255 } 256 257 #else 98 } 99 258 100 // Fall back to gethostbyname for platforms that don't define 259 101 // getaddrinfo. gethostbyname does not support IPv6, and it's not … … 285 127 results.setErrorString(tr("Unknown error")); 286 128 } 287 #endif // !defined (QT_NO_GETADDRINFO)288 129 289 130 #if defined(QHOSTINFO_DEBUG) … … 317 158 QString QHostInfo::localDomainName() 318 159 { 319 resolveLibrary(); 320 if (local_res_ninit) { 321 // using thread-safe version 322 res_state_ptr state = res_state_ptr(qMalloc(sizeof(*state))); 323 memset(state, 0, sizeof(*state)); 324 local_res_ninit(state); 325 QString domainName = QUrl::fromAce(state->defdname); 326 if (domainName.isEmpty()) 327 domainName = QUrl::fromAce(state->dnsrch[0]); 328 local_res_nclose(state); 329 qFree(state); 330 331 return domainName; 332 } 333 334 if (local_res_init && local_res) { 335 // using thread-unsafe version 336 337 #if defined(QT_NO_GETADDRINFO) 338 // We have to call res_init to be sure that _res was initialized 339 // So, for systems without getaddrinfo (which is thread-safe), we lock the mutex too 160 // We have to call res_init to be sure that _res was initialized 161 // So, for systems without getaddrinfo (which is thread-safe), we lock the mutex too 162 { 340 163 QMutexLocker locker(::getHostByNameMutex()); 341 #endif 342 local_res_init();343 QString domainName = QUrl::fromAce(local_res->defdname);344 if (domainName.isEmpty())345 domainName = QUrl::fromAce(local_res->dnsrch[0]);346 return domainName;164 if ((_res.options & RES_INIT) || res_init() == 0) { 165 QString domainName = QUrl::fromAce(_res.defdname); 166 if (domainName.isEmpty()) 167 domainName = QUrl::fromAce(_res.dnsrch[0]); 168 return domainName; 169 } 347 170 } 348 171 349 172 // nothing worked, try doing it by ourselves: 350 173 QFile resolvconf; 351 #if defined(_PATH_RESCONF) 352 resolvconf.setFileName(QFile::decodeName(_PATH_RESCONF)); 353 #else 354 resolvconf.setFileName(QLatin1String("/etc/resolv.conf")); 355 #endif 174 QByteArray etc = qgetenv("ETC"); 175 if (etc.isEmpty()) { 176 etc = "x:\\MPTN\\ETC"; 177 ULONG boot = 0; 178 DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)boot, sizeof(boot)); 179 etc[0] = (char)(boot + 'A' - 1); 180 } 181 // currently, resolv takes precedence over resolv2 assuming that resolv 182 // is created for PPP connections and therefore should override resolv2 183 // which is created for permanent LAN connections. 184 resolvconf.setFileName(QFile::decodeName(etc) + QLatin1String("\\resolv")); 185 if (!resolvconf.exists()) 186 resolvconf.setFileName(QFile::decodeName(etc)+ QLatin1String("\\resolv2")); 187 356 188 if (!resolvconf.open(QIODevice::ReadOnly)) 357 189 return QString(); // failure -
TabularUnified trunk/src/network/kernel/qnetworkinterface_os2.cpp ¶
r158 r160 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** Contact: Qt Software Information (qt-info@nokia.com) 5 ** 6 ** Copyright (C) 2009 netlabs.org. OS/2 parts. 5 7 ** 6 8 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 47 49 #ifndef QT_NO_NETWORKINTERFACE 48 50 49 #define IP_MULTICAST // make AIX happy and define IFF_MULTICAST50 51 51 #include <sys/types.h> 52 52 #include <sys/socket.h> 53 53 54 #ifdef Q_OS_SOLARIS 55 # include <sys/sockio.h> 56 #endif 54 #include <sys/sockio.h> 57 55 #include <net/if.h> 58 59 #ifndef QT_NO_GETIFADDRS60 # include <ifaddrs.h>61 #endif62 63 #ifdef QT_LINUXBASE64 # include <arpa/inet.h>65 # ifndef SIOCGIFBRDADDR66 # define SIOCGIFBRDADDR 0x891967 # endif68 #endif // QT_LINUXBASE69 56 70 57 #include <qplatformdefs.h> … … 80 67 if (sa->sa_family == AF_INET) 81 68 address.setAddress(htonl(((sockaddr_in *)sa)->sin_addr.s_addr)); 82 #ifndef QT_NO_IPV683 else if (sa->sa_family == AF_INET6)84 address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);85 #endif86 69 return address; 87 70 … … 105 88 } 106 89 107 #ifdef QT_NO_GETIFADDRS108 // getifaddrs not available109 110 90 static const int STORAGEBUFFER_GROWTH = 256; 111 91 … … 113 93 { 114 94 QSet<QByteArray> result; 115 #ifdef QT_NO_IPV6IFNAME116 95 QByteArray storageBuffer; 117 96 struct ifconf interfaceList; … … 148 127 149 128 return result; 150 #else151 Q_UNUSED(socket);152 153 // use if_nameindex154 struct if_nameindex *interfaceList = ::if_nameindex();155 for (struct if_nameindex *ptr = interfaceList; ptr && ptr->if_name; ++ptr)156 result << ptr->if_name;157 158 if_freenameindex(interfaceList);159 return result;160 #endif161 129 } 162 130 … … 167 135 int ifindex = 0; 168 136 169 #ifndef QT_NO_IPV6IFNAME170 // Get the interface index171 ifindex = if_nametoindex(req.ifr_name);172 173 // find the interface data174 QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();175 for ( ; if_it != interfaces.end(); ++if_it)176 if ((*if_it)->index == ifindex) {177 // existing interface178 iface = *if_it;179 break;180 }181 #else182 137 // Search by name 183 138 QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin(); … … 188 143 break; 189 144 } 190 #endif191 145 192 146 if (!iface) { … … 274 228 } 275 229 276 #else277 // use getifaddrs278 279 // platform-specific defs:280 # ifdef Q_OS_LINUX281 QT_BEGIN_INCLUDE_NAMESPACE282 # include <features.h>283 QT_END_INCLUDE_NAMESPACE284 # endif285 286 # if defined(Q_OS_LINUX) && __GLIBC__ - 0 >= 2 && __GLIBC_MINOR__ - 0 >= 1287 # include <netpacket/packet.h>288 289 static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)290 {291 QList<QNetworkInterfacePrivate *> interfaces;292 293 for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) {294 if ( !ptr->ifa_addr )295 continue;296 297 // Get the interface index298 int ifindex = if_nametoindex(ptr->ifa_name);299 300 // on Linux we use AF_PACKET and sockaddr_ll to obtain hHwAddress301 QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();302 for ( ; if_it != interfaces.end(); ++if_it)303 if ((*if_it)->index == ifindex) {304 // this one has been added already305 if ( ptr->ifa_addr->sa_family == AF_PACKET306 && (*if_it)->hardwareAddress.isEmpty()) {307 sockaddr_ll *sll = (sockaddr_ll *)ptr->ifa_addr;308 (*if_it)->hardwareAddress = (*if_it)->makeHwAddress(sll->sll_halen, (uchar*)sll->sll_addr);309 }310 break;311 }312 if ( if_it != interfaces.end() )313 continue;314 315 QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;316 interfaces << iface;317 iface->index = ifindex;318 iface->name = QString::fromLatin1(ptr->ifa_name);319 iface->flags = convertFlags(ptr->ifa_flags);320 321 if ( ptr->ifa_addr->sa_family == AF_PACKET ) {322 sockaddr_ll *sll = (sockaddr_ll *)ptr->ifa_addr;323 iface->hardwareAddress = iface->makeHwAddress(sll->sll_halen, (uchar*)sll->sll_addr);324 }325 }326 327 return interfaces;328 }329 330 # elif defined(Q_OS_BSD4)331 QT_BEGIN_INCLUDE_NAMESPACE332 # include <net/if_dl.h>333 QT_END_INCLUDE_NAMESPACE334 335 static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)336 {337 QList<QNetworkInterfacePrivate *> interfaces;338 339 // on NetBSD we use AF_LINK and sockaddr_dl340 // scan the list for that family341 for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next)342 if (ptr->ifa_addr && ptr->ifa_addr->sa_family == AF_LINK) {343 QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;344 interfaces << iface;345 346 sockaddr_dl *sdl = (sockaddr_dl *)ptr->ifa_addr;347 iface->index = sdl->sdl_index;348 iface->name = QString::fromLatin1(ptr->ifa_name);349 iface->flags = convertFlags(ptr->ifa_flags);350 iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl));351 }352 353 return interfaces;354 }355 356 # else // Generic version357 358 static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)359 {360 QList<QNetworkInterfacePrivate *> interfaces;361 362 // make sure there's one entry for each interface363 for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next) {364 // Get the interface index365 int ifindex = if_nametoindex(ptr->ifa_name);366 367 QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();368 for ( ; if_it != interfaces.end(); ++if_it)369 if ((*if_it)->index == ifindex)370 // this one has been added already371 break;372 373 if (if_it == interfaces.end()) {374 // none found, create375 QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;376 interfaces << iface;377 378 iface->index = ifindex;379 iface->name = QString::fromLatin1(ptr->ifa_name);380 iface->flags = convertFlags(ptr->ifa_flags);381 }382 }383 384 return interfaces;385 }386 387 # endif388 389 390 static QList<QNetworkInterfacePrivate *> interfaceListing()391 {392 QList<QNetworkInterfacePrivate *> interfaces;393 394 int socket;395 if ((socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)396 return interfaces; // error397 398 ifaddrs *interfaceListing;399 if (getifaddrs(&interfaceListing) == -1) {400 // error401 ::close(socket);402 return interfaces;403 }404 405 interfaces = createInterfaces(interfaceListing);406 for (ifaddrs *ptr = interfaceListing; ptr; ptr = ptr->ifa_next) {407 // Get the interface index408 int ifindex = if_nametoindex(ptr->ifa_name);409 QNetworkInterfacePrivate *iface = 0;410 QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();411 for ( ; if_it != interfaces.end(); ++if_it)412 if ((*if_it)->index == ifindex) {413 // found this interface already414 iface = *if_it;415 break;416 }417 if (!iface) {418 // skip all non-IP interfaces419 continue;420 }421 422 QNetworkAddressEntry entry;423 entry.setIp(addressFromSockaddr(ptr->ifa_addr));424 if (entry.ip().isNull())425 // could not parse the address426 continue;427 428 entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask));429 if (iface->flags & QNetworkInterface::CanBroadcast)430 entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr));431 432 iface->addressEntries << entry;433 }434 435 freeifaddrs(interfaceListing);436 ::close(socket);437 return interfaces;438 }439 #endif440 441 230 QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan() 442 231 { -
TabularUnified trunk/src/network/network.pro ¶
r2 r160 2 2 3 3 TARGET = QtNetwork 4 5 os2:TARGET_SHORT = QtNet 6 4 7 QPRO_PWD = $$PWD 5 8 DEFINES += QT_BUILD_NETWORK_LIB QT_NO_USING_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.