00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "k3resolverstandardworkers_p.h"
00026
00027 #include <config.h>
00028 #include <config-network.h>
00029
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <sys/un.h>
00033 #include <netinet/in.h>
00034 #include <netdb.h>
00035 #include <errno.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039
00040 #ifdef HAVE_NET_IF_H
00041 #include <net/if.h>
00042 #endif
00043
00044 #include <QFile>
00045 #include <QList>
00046 #include <QMutex>
00047 #include <QTextStream>
00048 #include <QThread>
00049 #ifdef Q_WS_WIN
00050 #include <winsock2.h>
00051 #endif
00052
00053 #include "kdebug.h"
00054 #include "kglobal.h"
00055 #include "kstandarddirs.h"
00056
00057 #include "k3resolver.h"
00058 #include "k3socketaddress.h"
00059
00060 struct hostent;
00061 struct addrinfo;
00062
00063 using namespace KNetwork;
00064 using namespace KNetwork::Internal;
00065
00066 static bool hasIPv6()
00067 {
00068 #ifdef Q_WS_WIN
00069 extern void KNetwork_initSocket();
00070 KNetwork_initSocket();
00071 #endif
00072 #ifdef AF_INET6
00073 if (!qgetenv("KDE_NO_IPV6").isEmpty())
00074 return false;
00075
00076 # ifdef Q_WS_WIN
00077 SOCKET s = ::socket(AF_INET6, SOCK_STREAM, 0);
00078 if (s == INVALID_SOCKET)
00079 return false;
00080 ::closesocket(s);
00081 # else
00082 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
00083 if (fd == -1)
00084 return false;
00085 ::close(fd);
00086 # endif
00087 return true;
00088 #else
00089 return false;
00090 #endif
00091 }
00092
00093
00094 static QMutex blacklistMutex;
00095 QStringList KBlacklistWorker::blacklist;
00096
00097 void KBlacklistWorker::init()
00098 {
00099 if (!KGlobal::hasMainComponent())
00100 return;
00101
00102 static bool beenhere = false;
00103
00104 if (beenhere)
00105 return;
00106
00107 beenhere = true;
00108 loadBlacklist();
00109 }
00110
00111 void KBlacklistWorker::loadBlacklist()
00112 {
00113 QMutexLocker locker(&blacklistMutex);
00114 QStringList filelist = KGlobal::dirs()->findAllResources("config", "ipv6blacklist");
00115
00116 QStringList::ConstIterator it = filelist.constBegin(),
00117 end = filelist.constEnd();
00118 for ( ; it != end; ++it)
00119 {
00120
00121 QFile f(*it);
00122 if (!f.open(QIODevice::ReadOnly))
00123 continue;
00124
00125 QTextStream stream(&f);
00126 stream.setCodec("latin1");
00127 for (QString line = stream.readLine(); !line.isNull();
00128 line = stream.readLine())
00129 {
00130 if (line.isEmpty())
00131 continue;
00132
00133
00134
00135 line = line.trimmed();
00136 if (line[0] != '.')
00137 line.prepend(QChar( '.') );
00138
00139 blacklist.append(line.toLower());
00140 }
00141 }
00142 }
00143
00144
00145
00146 bool KBlacklistWorker::isBlacklisted(const QString& host)
00147 {
00148 KBlacklistWorker::init();
00149
00150
00151 if (host.isEmpty())
00152 return false;
00153
00154 QString ascii = QLatin1String(KResolver::domainToAscii(host));
00155
00156 QMutexLocker locker(&blacklistMutex);
00157
00158
00159 QStringList::ConstIterator it = blacklist.constBegin(),
00160 end = blacklist.constEnd();
00161 for ( ; it != end; ++it)
00162 if (ascii.endsWith(*it))
00163 return true;
00164
00165
00166 return false;
00167 }
00168
00169 bool KBlacklistWorker::preprocess()
00170 {
00171 if (isBlacklisted(nodeName()))
00172 {
00173 results.setError(KResolver::NoName);
00174 finished();
00175 return true;
00176 }
00177 return false;
00178 }
00179
00180 bool KBlacklistWorker::run()
00181 {
00182 results.setError(KResolver::NoName);
00183 finished();
00184 return false;
00185 }
00186
00187 namespace
00188 {
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 #ifndef HAVE_GETADDRINFO
00207
00208 # if defined(HAVE_GETHOSTBYNAME2_R)
00209 # define USE_GETHOSTBYNAME2_R
00210 # elif defined(HAVE_GETHOSTBYNAME_R) && (!defined(AF_INET6) || !defined(HAVE_GETHOSTBYNAME2))
00211 # define USE_GETHOSTBYNAME_R
00212 # elif defined(HAVE_GETHOSTBYNAME2)
00213 # define USE_GETHOSTBYNAME2)
00214 # else
00215 # define USE_GETHOSTBYNAME
00216 # endif
00217
00218 class GetHostByNameThread: public KResolverWorkerBase
00219 {
00220 public:
00221 QByteArray m_hostname;
00222 quint16 m_port;
00223 int m_scopeid;
00224 int m_af;
00225 KResolverResults& results;
00226
00227 GetHostByNameThread(const char * hostname, quint16 port,
00228 int scopeid, int af, KResolverResults* res) :
00229 m_hostname(hostname), m_port(port), m_scopeid(scopeid), m_af(af),
00230 results(*res)
00231 { }
00232
00233 ~GetHostByNameThread()
00234 { }
00235
00236 virtual bool preprocess()
00237 { return true; }
00238
00239 virtual bool run();
00240
00241 void processResults(hostent* he, int my_h_errno);
00242 };
00243
00244 bool GetHostByNameThread::run()
00245 {
00246
00247 hostent *resultptr;
00248 hostent my_results;
00249 unsigned buflen = 1024;
00250 int res;
00251 int my_h_errno;
00252 char *buf = 0L;
00253
00254
00255
00256
00257 ResolverLocker resLock( this );
00258 do
00259 {
00260 res = 0;
00261 my_h_errno = HOST_NOT_FOUND;
00262
00263
00264 if (m_af != AF_INET &&
00265 KBlacklistWorker::isBlacklisted(QLatin1String(m_hostname)))
00266 break;
00267
00268 # ifdef USE_GETHOSTBYNAME2_R
00269 buf = new char[buflen];
00270 res = gethostbyname2_r(m_hostname, m_af, &my_results, buf, buflen,
00271 &resultptr, &my_h_errno);
00272
00273 # elif defined(USE_GETHOSTBYNAME_R)
00274 if (m_af == AF_INET)
00275 {
00276 buf = new char[buflen];
00277 res = gethostbyname_r(m_hostname, &my_results, buf, buflen,
00278 &resultptr, &my_h_errno);
00279 }
00280 else
00281 resultptr = 0;
00282
00283 # elif defined(USE_GETHOSTBYNAME2)
00284
00285 resultptr = gethostbyname2(m_hostname, m_af);
00286 my_h_errno = h_errno;
00287
00288 # else
00289 if (m_af == AF_INET)
00290 {
00291
00292 resultptr = gethostbyname(m_hostname);
00293 my_h_errno = h_errno;
00294 }
00295 else
00296 resultptr = 0;
00297 # endif
00298
00299 if (resultptr != 0L)
00300 my_h_errno = 0;
00301
00302
00303
00304 if (res == ERANGE)
00305 {
00306
00307 buflen += 1024;
00308 delete [] buf;
00309 buf = new char[buflen];
00310 }
00311
00312 if ((res == ERANGE || my_h_errno != 0) && checkResolver())
00313 {
00314
00315 resLock.openClose();
00316 }
00317 }
00318 while (res == ERANGE);
00319 processResults(resultptr, my_h_errno);
00320
00321 delete [] buf;
00322
00323 finished();
00324 return results.error() == KResolver::NoError;
00325 }
00326
00327 void GetHostByNameThread::processResults(hostent *he, int herrno)
00328 {
00329 if (herrno)
00330 {
00331 qDebug("KStandardWorker::processResults: got error %d", herrno);
00332 switch (herrno)
00333 {
00334 case HOST_NOT_FOUND:
00335 results.setError(KResolver::NoName);
00336 return;
00337
00338 case TRY_AGAIN:
00339 results.setError(KResolver::TryAgain);
00340 return;
00341
00342 case NO_RECOVERY:
00343 results.setError(KResolver::NonRecoverable);
00344 return;
00345
00346 case NO_ADDRESS:
00347 results.setError(KResolver::NoName);
00348 return;
00349
00350 default:
00351 results.setError(KResolver::UnknownError);
00352 return;
00353 }
00354 }
00355 else if (he == 0L)
00356 {
00357 results.setError(KResolver::NoName);
00358 return;
00359 }
00360
00361
00362 setError(KResolver::NoError);
00363 results.setError(KResolver::NoError);
00364
00365
00366
00367 int proto = protocol();
00368 int socktype = socketType();
00369 if (socktype == 0)
00370 socktype = SOCK_STREAM;
00371
00372 QString canon = KResolver::domainToUnicode(QLatin1String(he->h_name));
00373 KInetSocketAddress sa;
00374 sa.setPort(m_port);
00375 if (he->h_addrtype != AF_INET)
00376 sa.setScopeId(m_scopeid);
00377
00378 for (int i = 0; he->h_addr_list[i]; i++)
00379 {
00380 sa.setHost(KIpAddress(he->h_addr_list[i], he->h_addrtype == AF_INET ? 4 : 6));
00381 results.prepend(KResolverEntry(sa, socktype, proto, canon, m_hostname));
00382
00383 }
00384
00385 }
00386
00387 #else // HAVE_GETADDRINFO
00388
00389 class GetAddrInfoThread: public KResolverWorkerBase
00390 {
00391 public:
00392 QByteArray m_node;
00393 QByteArray m_serv;
00394 int m_af;
00395 int m_flags;
00396 KResolverResults& results;
00397
00398 GetAddrInfoThread(const char* node, const char* serv, int af, int flags,
00399 KResolverResults* res) :
00400 m_node(node), m_serv(serv), m_af(af), m_flags(flags), results(*res)
00401 { }
00402
00403 ~GetAddrInfoThread()
00404 { }
00405
00406 virtual bool preprocess()
00407 { return true; }
00408
00409 virtual bool run();
00410
00411 void processResults(addrinfo* ai, int ret_code, KResolverResults& rr);
00412 };
00413
00414 bool GetAddrInfoThread::run()
00415 {
00416
00417 if ((m_af != AF_INET && m_af != AF_UNSPEC) &&
00418 KBlacklistWorker::isBlacklisted(QLatin1String(m_node)))
00419 {
00420 results.setError(KResolver::NoName);
00421 finished();
00422 return false;
00423 }
00424
00425 do
00426 {
00427 ResolverLocker resLock( this );
00428
00429
00430 addrinfo hint;
00431 memset(&hint, 0, sizeof(hint));
00432 hint.ai_family = m_af;
00433 hint.ai_socktype = socketType();
00434 hint.ai_protocol = protocol();
00435
00436 if (hint.ai_socktype == 0)
00437 hint.ai_socktype = SOCK_STREAM;
00438
00439 if (m_flags & KResolver::Passive)
00440 hint.ai_flags |= AI_PASSIVE;
00441 if (m_flags & KResolver::CanonName)
00442 hint.ai_flags |= AI_CANONNAME;
00443 # ifdef AI_NUMERICHOST
00444 if (m_flags & KResolver::NoResolve)
00445 hint.ai_flags |= AI_NUMERICHOST;
00446 # endif
00447 # ifdef AI_ADDRCONFIG
00448 hint.ai_flags |= AI_ADDRCONFIG;
00449 # endif
00450
00451
00452 if (m_node.isEmpty())
00453 m_node = "*";
00454
00455 addrinfo *result;
00456 int res = getaddrinfo(m_node, m_serv, &hint, &result);
00457
00458
00459
00460
00461 if (res != 0)
00462 {
00463 if (checkResolver())
00464 {
00465
00466 resLock.openClose();
00467 continue;
00468 }
00469
00470 switch (res)
00471 {
00472 case EAI_BADFLAGS:
00473 results.setError(KResolver::BadFlags);
00474 break;
00475
00476 #ifdef EAI_NODATA
00477
00478 #if EAI_NODATA != EAI_NONAME
00479 case EAI_NODATA:
00480 #endif
00481 #endif
00482 case EAI_NONAME:
00483 results.setError(KResolver::NoName);
00484 break;
00485
00486 case EAI_AGAIN:
00487 results.setError(KResolver::TryAgain);
00488 break;
00489
00490 case EAI_FAIL:
00491 results.setError(KResolver::NonRecoverable);
00492 break;
00493
00494 case EAI_FAMILY:
00495 results.setError(KResolver::UnsupportedFamily);
00496 break;
00497
00498 case EAI_SOCKTYPE:
00499 results.setError(KResolver::UnsupportedSocketType);
00500 break;
00501
00502 case EAI_SERVICE:
00503 results.setError(KResolver::UnsupportedService);
00504 break;
00505
00506 case EAI_MEMORY:
00507 results.setError(KResolver::Memory);
00508 break;
00509
00510 #ifdef EAI_SYSTEM // not available on windows
00511 case EAI_SYSTEM:
00512 results.setError(KResolver::SystemError, errno);
00513 break;
00514 #endif
00515 default:
00516 results.setError(KResolver::UnknownError, errno);
00517 break;
00518 }
00519
00520 finished();
00521 return false;
00522 }
00523
00524
00525 QString canon;
00526 const char *previous_canon = 0L;
00527
00528 for (addrinfo* p = result; p; p = p->ai_next)
00529 {
00530
00531 if ((previous_canon && !p->ai_canonname) ||
00532 (!previous_canon && p->ai_canonname) ||
00533 (p->ai_canonname != previous_canon &&
00534 strcmp(p->ai_canonname, previous_canon) != 0))
00535 {
00536 canon = KResolver::domainToUnicode(QString::fromAscii(p->ai_canonname));
00537 previous_canon = p->ai_canonname;
00538 }
00539
00540 results.append(KResolverEntry(p->ai_addr, p->ai_addrlen, p->ai_socktype,
00541 p->ai_protocol, canon, m_node));
00542 }
00543
00544 freeaddrinfo(result);
00545 results.setError(KResolver::NoError);
00546 finished();
00547 return results.error() == KResolver::NoError;
00548 }
00549 while (true);
00550 }
00551
00552 #endif // HAVE_GETADDRINFO
00553 }
00554
00555 KStandardWorker::~KStandardWorker()
00556 {
00557 qDeleteAll(resultList);
00558 }
00559
00560 bool KStandardWorker::sanityCheck()
00561 {
00562
00563
00564 if (!nodeName().isEmpty())
00565 {
00566 QString node = nodeName();
00567 if (node.indexOf('%') != -1)
00568 node.truncate(node.indexOf('%'));
00569
00570 if (node.isEmpty() || node == QLatin1String("*") ||
00571 node == QLatin1String("localhost"))
00572 m_encodedName.truncate(0);
00573 else
00574 {
00575 m_encodedName = KResolver::domainToAscii(node);
00576
00577 if (m_encodedName.isNull())
00578 {
00579 qDebug("could not encode hostname '%s' (UTF-8)", node.toUtf8().data());
00580 setError(KResolver::NoName);
00581 return false;
00582 }
00583
00584
00585
00586 }
00587 }
00588 else
00589 m_encodedName.truncate(0);
00590
00591 if (protocol() == -1)
00592 {
00593 setError(KResolver::NonRecoverable);
00594 return false;
00595 }
00596
00597 return true;
00598 }
00599
00600 bool KStandardWorker::resolveScopeId()
00601 {
00602
00603 scopeid = 0;
00604 int pos = nodeName().lastIndexOf('%');
00605 if (pos == -1)
00606 return true;
00607
00608 QString scopename = nodeName().mid(pos + 1);
00609
00610 bool ok;
00611 scopeid = scopename.toInt(&ok);
00612 if (!ok)
00613 {
00614
00615
00616 #ifdef HAVE_IF_NAMETOINDEX
00617 scopeid = if_nametoindex(scopename.toLatin1());
00618 #else
00619 scopeid = 0;
00620 #endif
00621 }
00622
00623 return true;
00624 }
00625
00626 bool KStandardWorker::resolveService()
00627 {
00628
00629 bool ok;
00630 port = serviceName().toUInt(&ok);
00631 if (!ok)
00632 {
00633
00634
00635
00636 if (serviceName().isEmpty() || serviceName().compare(QLatin1String("*")) == 0)
00637 port = 0;
00638 else
00639 {
00640
00641 QByteArray protoname = protocolName();
00642
00643 if (protoname.isEmpty() && protocol())
00644 {
00645 protoname = KResolver::protocolName(protocol()).first();
00646
00647
00648 if (protoname.isEmpty())
00649 {
00650
00651 setError(KResolver::NoName);
00652 return false;
00653 }
00654 }
00655 else
00656 protoname = "tcp";
00657
00658
00659 int result = KResolver::servicePort(serviceName().toLatin1(), protoname);
00660 if (result == -1)
00661 {
00662
00663 setError(KResolver::NoName);
00664 return false;
00665 }
00666
00667
00668 port = (quint16)result;
00669 }
00670 }
00671
00672
00673 return true;
00674 }
00675
00676 KResolver::ErrorCodes KStandardWorker::addUnix()
00677 {
00678
00679 if ((familyMask() & KResolver::UnixFamily) == 0)
00680
00681 return KResolver::UnsupportedFamily;
00682
00683
00684 if (!m_encodedName.isEmpty())
00685 return KResolver::AddrFamily;
00686
00687 if (protocol() || !protocolName().isNull())
00688 return KResolver::BadFlags;
00689
00690 QString pathname = serviceName();
00691 if (pathname.isEmpty())
00692 return KResolver::NoName;;
00693
00694 if (pathname[0] != '/')
00695
00696
00697 pathname.prepend("/tmp/");
00698
00699
00700 KUnixSocketAddress sa(pathname);
00701 int socktype = socketType();
00702 if (socktype == 0)
00703 socktype = SOCK_STREAM;
00704
00705 results.append(KResolverEntry(sa, socktype, 0));
00706 setError(KResolver::NoError);
00707
00708 return KResolver::NoError;
00709 }
00710
00711 bool KStandardWorker::resolveNumerically()
00712 {
00713
00714
00715
00716
00717 bool wantV4 = familyMask() & KResolver::IPv4Family,
00718 wantV6 = familyMask() & KResolver::IPv6Family;
00719
00720 if (!wantV6 && !wantV4)
00721
00722 return (flags() & KResolver::NoResolve);
00723
00724
00725 if (!resolveScopeId() || !resolveService())
00726 return (flags() & KResolver::NoResolve);
00727
00728
00729
00730 KInetSocketAddress sa;
00731 setError(KResolver::NoError);
00732 sa.setHost(KIpAddress(QLatin1String(m_encodedName)));
00733
00734
00735 bool ok = sa.length() != 0;
00736
00737 sa.setPort(port);
00738 if (sa.ipVersion() == 6)
00739 sa.setScopeId(scopeid);
00740 int proto = protocol();
00741 int socktype = socketType();
00742 if (socktype == 0)
00743 socktype = SOCK_STREAM;
00744
00745 if (ok)
00746 {
00747
00748
00749
00750 if ((sa.ipVersion() == 4 && wantV4) ||
00751 (sa.ipVersion() == 6 && wantV6))
00752 results.append(KResolverEntry(sa, socktype, proto));
00753 else
00754 {
00755
00756
00757
00758
00759
00760
00761
00762
00763 setError(KResolver::AddrFamily);
00764 return true;
00765 }
00766 }
00767 else if (m_encodedName.isEmpty())
00768 {
00769
00770 if (flags() & KResolver::Passive)
00771 {
00772 if (wantV6)
00773 {
00774 sa.setHost(KIpAddress::anyhostV6);
00775 results.append(KResolverEntry(sa, socktype, proto));
00776 }
00777
00778 if (wantV4)
00779 {
00780 sa.setHost(KIpAddress::anyhostV4);
00781 results.append(KResolverEntry(sa, socktype, proto));
00782 }
00783 }
00784 else
00785 {
00786 if (wantV6)
00787 {
00788 sa.setHost(KIpAddress::localhostV6);
00789 results.append(KResolverEntry(sa, socktype, proto));
00790 }
00791
00792 if (wantV4)
00793 {
00794 sa.setHost(KIpAddress::localhostV4);
00795 results.append(KResolverEntry(sa, socktype, proto));
00796 }
00797 }
00798
00799 ok = true;
00800 }
00801 else
00802 {
00803
00804
00805
00806 setError(KResolver::BadFlags);
00807 ok = false;
00808 }
00809
00810 return ok || (flags() & KResolver::NoResolve);
00811 }
00812
00813 bool KStandardWorker::preprocess()
00814 {
00815
00816 if (!sanityCheck())
00817 return false;
00818
00819
00820 if (familyMask() & KResolver::UnknownFamily)
00821 {
00822 setError(KResolver::UnsupportedFamily);
00823 return false;
00824 }
00825
00826
00827 if (socketType() != SOCK_STREAM && socketType() != SOCK_DGRAM && socketType() != 0)
00828 {
00829 setError(KResolver::UnsupportedSocketType);
00830 return false;
00831 }
00832
00833
00834
00835 if (resolveNumerically() || m_encodedName.isEmpty())
00836 {
00837
00838 setError(addUnix());
00839 if (results.count())
00840 setError(KResolver::NoError);
00841 finished();
00842 return true;
00843 }
00844
00845
00846 #ifdef AF_INET6
00847 # define mask (KResolver::IPv6Family | KResolver::IPv4Family | KResolver::UnixFamily)
00848 #else
00849 # define mask (KResolver::IPv4Family | KResolver::UnixFamily)
00850 #endif
00851
00852 if ((familyMask() & mask) == 0)
00853
00854 return false;
00855
00856 #undef mask
00857
00858 return true;
00859 }
00860
00861 bool KStandardWorker::run()
00862 {
00863 #ifndef HAVE_GETADDRINFO
00864
00865
00866
00867 if (!resolveScopeId())
00868 return false;
00869
00870
00871 if (!resolveService())
00872 return false;
00873 #endif
00874
00875
00876
00877 setError(KResolver::NoName);
00878
00879
00880 struct
00881 {
00882 KResolver::SocketFamilies mask;
00883 int af;
00884 } families[] = { { KResolver::IPv4Family, AF_INET }
00885 #ifdef AF_INET6
00886 , { KResolver::IPv6Family, AF_INET6 }
00887 #endif
00888 };
00889 int familyCount = sizeof(families)/sizeof(families[0]);
00890 bool skipIPv6 = !hasIPv6();
00891
00892 for (int i = 0; i < familyCount; i++)
00893 if (familyMask() & families[i].mask)
00894 {
00895 #ifdef AF_INET6
00896 if (skipIPv6 && families[i].af == AF_INET6)
00897 continue;
00898 #endif
00899
00900 KResolverWorkerBase *worker;
00901 KResolverResults *res = new KResolverResults;
00902 resultList.append(res);
00903 #ifdef HAVE_GETADDRINFO
00904 worker = new GetAddrInfoThread(m_encodedName,
00905 serviceName().toLatin1(),
00906 families[i].af, flags(), res);
00907 #else
00908 worker = new GetHostByNameThread(m_encodedName, port, scopeid,
00909 families[i].af, res);
00910 #endif
00911
00912 enqueue(worker);
00913 }
00914
00915
00916 return true;
00917 }
00918
00919 bool KStandardWorker::postprocess()
00920 {
00921 if (results.count())
00922 return true;
00923
00924
00925
00926 if (resultList.isEmpty())
00927 {
00928 results.setError(KResolver::NoName);
00929 return true;
00930 }
00931
00932 for (int i = resultList.size(); i > 0; --i)
00933 {
00934 KResolverResults* rr = resultList.at(i - 1);
00935 if (!rr->isEmpty())
00936 {
00937 results.setError(KResolver::NoError);
00938 KResolverResults::Iterator it = rr->begin();
00939 for ( ; it != rr->end(); ++it)
00940 results.append(*it);
00941 }
00942 else if (results.isEmpty())
00943
00944
00945 setError(rr->error(), rr->systemError());
00946
00947 delete rr;
00948 resultList[i - 1] = 0L;
00949 }
00950
00951 resultList.clear();
00952 return true;
00953 }
00954
00955 #ifdef HAVE_GETADDRINFO
00956 KGetAddrinfoWorker::~KGetAddrinfoWorker()
00957 {
00958 }
00959
00960 bool KGetAddrinfoWorker::preprocess()
00961 {
00962
00963 if (!sanityCheck())
00964 return false;
00965
00966 if (flags() & KResolver::NoResolve)
00967
00968 return run();
00969
00970 return true;
00971 }
00972
00973 bool KGetAddrinfoWorker::run()
00974 {
00975
00976 GetAddrInfoThread worker(m_encodedName, serviceName().toLatin1(),
00977 AF_UNSPEC, flags(), &results);
00978
00979 if (!worker.run())
00980 {
00981 if (wantThis(AF_UNIX))
00982 {
00983 if (addUnix() == KResolver::NoError)
00984 setError(KResolver::NoError);
00985 }
00986 else
00987 setError(worker.results.error(), worker.results.systemError());
00988
00989 return false;
00990 }
00991
00992
00993
00994
00995
00996 bool seen_unix = false;
00997 int i = 0;
00998 while ( i < results.count() )
00999 {
01000 const KResolverEntry& res = results[i];
01001 if (res.family() == AF_UNIX)
01002 seen_unix = true;
01003 if (!wantThis(res.family()))
01004 results.removeAt(i);
01005 else
01006 ++i;
01007 }
01008
01009 if (!seen_unix)
01010 addUnix();
01011
01012 finished();
01013 return true;
01014 }
01015
01016 bool KGetAddrinfoWorker::wantThis(int family)
01017 {
01018
01019
01020 #ifdef AF_INET6
01021 if (family == AF_INET6 && familyMask() & KResolver::IPv6Family)
01022 return true;
01023 #endif
01024 if (family == AF_INET && familyMask() & KResolver::IPv4Family)
01025 return true;
01026 if (family == AF_UNIX && familyMask() & KResolver::UnixFamily)
01027 return true;
01028
01029
01030 if (familyMask() & KResolver::UnknownFamily)
01031 return true;
01032
01033 return false;
01034 }
01035
01036 #endif
01037
01038 void KNetwork::Internal::initStandardWorkers()
01039 {
01040
01041 KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KStandardWorker>);
01042
01043 #ifdef HAVE_GETADDRINFO
01044 KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KGetAddrinfoWorker>);
01045 #endif
01046 }