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