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
}