27 #include <sys/types.h>
28 #include <sys/socket.h>
30 #include <netinet/in.h>
43 #include <tqstrlist.h>
47 #include "tdeglobal.h"
48 #include "tdestandarddirs.h"
49 #include "tdeapplication.h"
51 #include "kresolver.h"
52 #include "tdesocketaddress.h"
53 #include "kresolverstandardworkers_p.h"
59 using namespace KNetwork::Internal;
66 if (getenv(
"TDE_NO_IPV6") != 0L)
69 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
79 static TQMutex blacklistMutex;
80 TQStringList KBlacklistWorker::blacklist;
82 void KBlacklistWorker::init()
87 if (!TDEGlobal::_instance)
90 static bool beenhere =
false;
99 void KBlacklistWorker::loadBlacklist()
101 TQMutexLocker locker(&blacklistMutex);
104 TQStringList::ConstIterator it = filelist.constBegin(),
105 end = filelist.constEnd();
106 for ( ; it !=
end; ++it)
110 if (!f.open(IO_ReadOnly))
113 TQTextStream stream(&f);
114 stream.setEncoding(TQTextStream::Latin1);
115 for (TQString line = stream.readLine(); !line.isNull();
116 line = stream.readLine())
123 line = line.stripWhiteSpace();
127 blacklist.append(line.lower());
134 bool KBlacklistWorker::isBlacklisted(
const TQString& host)
136 KBlacklistWorker::init();
145 TQMutexLocker locker(&blacklistMutex);
148 TQStringList::ConstIterator it = blacklist.constBegin(),
149 end = blacklist.constEnd();
150 for ( ; it !=
end; ++it)
151 if (ascii.endsWith(*it))
158 bool KBlacklistWorker::preprocess()
160 if (isBlacklisted(nodeName()))
162 results.setError(KResolver::NoName);
169 bool KBlacklistWorker::run()
171 results.setError(KResolver::NoName);
195 #ifndef HAVE_GETADDRINFO
197 # if defined(HAVE_GETHOSTBYNAME2_R)
198 # define USE_GETHOSTBYNAME2_R
199 # elif defined(HAVE_GETHOSTBYNAME_R) && (!defined(AF_INET6) || !defined(HAVE_GETHOSTBYNAME2))
200 # define USE_GETHOSTBYNAME_R
201 # elif defined(HAVE_GETHOSTBYNAME2)
202 # define USE_GETHOSTBYNAME2
204 # define USE_GETHOSTBYNAME
207 class GetHostByNameThread:
public KResolverWorkerBase
210 TQCString m_hostname;
216 GetHostByNameThread(
const char * hostname, TQ_UINT16 port,
218 m_hostname(hostname), m_port(port), m_scopeid(scopeid), m_af(af),
222 ~GetHostByNameThread()
225 virtual bool preprocess()
230 void processResults(hostent* he,
int my_h_errno);
233 bool GetHostByNameThread::run()
238 unsigned buflen = 1024;
246 ResolverLocker resLock(
this );
250 my_h_errno = HOST_NOT_FOUND;
253 if (m_af != AF_INET &&
254 KBlacklistWorker::isBlacklisted(TQString::fromLatin1(m_hostname)))
257 # ifdef USE_GETHOSTBYNAME2_R
258 buf =
new char[buflen];
259 res = gethostbyname2_r(m_hostname, m_af, &my_results, buf, buflen,
260 &resultptr, &my_h_errno);
262 # elif defined(USE_GETHOSTBYNAME_R)
265 buf =
new char[buflen];
266 res = gethostbyname_r(m_hostname, &my_results, buf, buflen,
267 &resultptr, &my_h_errno);
272 # elif defined(USE_GETHOSTBYNAME2)
274 resultptr = gethostbyname2(m_hostname, m_af);
275 my_h_errno = h_errno;
281 resultptr = gethostbyname(m_hostname);
282 my_h_errno = h_errno;
298 buf =
new char[buflen];
301 if ((res == ERANGE || my_h_errno != 0) && checkResolver())
307 while (res == ERANGE);
308 processResults(resultptr, my_h_errno);
313 return results.error() == KResolver::NoError;
316 void GetHostByNameThread::processResults(hostent *he,
int herrno)
320 tqDebug(
"TDEStandardWorker::processResults: got error %d", herrno);
324 results.setError(KResolver::NoName);
328 results.setError(KResolver::TryAgain);
332 results.setError(KResolver::NonRecoverable);
336 results.setError(KResolver::NoName);
340 results.setError(KResolver::UnknownError);
346 results.setError(KResolver::NoName);
351 setError(KResolver::NoError);
352 results.setError(KResolver::NoError);
356 int proto = protocol();
357 int socktype = socketType();
359 socktype = SOCK_STREAM;
364 if (he->h_addrtype != AF_INET)
367 for (
int i = 0; he->h_addr_list[i]; i++)
370 results.prepend(
KResolverEntry(sa, socktype, proto, canon, m_hostname));
376 #else // HAVE_GETADDRINFO
378 class GetAddrInfoThread:
public KResolverWorkerBase
387 GetAddrInfoThread(
const char* node,
const char* serv,
int af,
int flags,
389 m_node(node), m_serv(serv), m_af(af), m_flags(flags), results(*res)
395 virtual bool preprocess()
403 bool GetAddrInfoThread::run()
406 if ((m_af != AF_INET && m_af != AF_UNSPEC) &&
407 KBlacklistWorker::isBlacklisted(TQString::fromLatin1(m_node)))
409 results.setError(KResolver::NoName);
416 ResolverLocker resLock(
this );
420 memset(&hint, 0,
sizeof(hint));
421 hint.ai_family = m_af;
422 hint.ai_socktype = socketType();
423 hint.ai_protocol = protocol();
425 if (hint.ai_socktype == 0)
426 hint.ai_socktype = SOCK_STREAM;
428 if (m_flags & KResolver::Passive)
429 hint.ai_flags |= AI_PASSIVE;
430 if (m_flags & KResolver::CanonName)
431 hint.ai_flags |= AI_CANONNAME;
432 # ifdef AI_NUMERICHOST
433 if (m_flags & KResolver::NoResolve)
434 hint.ai_flags |= AI_NUMERICHOST;
436 # ifdef AI_ADDRCONFIG
437 hint.ai_flags |= AI_ADDRCONFIG;
441 if (m_node.isEmpty())
445 int res = getaddrinfo(m_node, m_serv, &hint, &result);
462 results.setError(KResolver::BadFlags);
467 #if EAI_NODATA != EAI_NONAME
472 results.setError(KResolver::NoName);
476 results.setError(KResolver::TryAgain);
480 results.setError(KResolver::NonRecoverable);
484 results.setError(KResolver::UnsupportedFamily);
488 results.setError(KResolver::UnsupportedSocketType);
492 results.setError(KResolver::UnsupportedService);
496 results.setError(KResolver::Memory);
500 results.setError(KResolver::SystemError, errno);
504 results.setError(KResolver::UnknownError, errno);
514 const char *previous_canon = 0L;
516 for (addrinfo* p = result; p; p = p->ai_next)
519 if ((previous_canon && !p->ai_canonname) ||
520 (!previous_canon && p->ai_canonname) ||
521 (p->ai_canonname != previous_canon &&
522 strcmp(p->ai_canonname, previous_canon) != 0))
525 previous_canon = p->ai_canonname;
528 results.append(
KResolverEntry(p->ai_addr, p->ai_addrlen, p->ai_socktype,
529 p->ai_protocol, canon, m_node));
532 freeaddrinfo(result);
533 results.setError(KResolver::NoError);
535 return results.error() == KResolver::NoError;
540 #endif // HAVE_GETADDRINFO
543 bool TDEStandardWorker::sanityCheck()
547 if (!nodeName().isEmpty())
549 TQString node = nodeName();
550 if (node.find(
'%') != -1)
551 node.truncate(node.find(
'%'));
553 if (node.isEmpty() || node == TQString::fromLatin1(
"*") ||
554 node == TQString::fromLatin1(
"localhost"))
555 m_encodedName.truncate(0);
560 if (m_encodedName.isNull())
562 tqDebug(
"could not encode hostname '%s' (UTF-8)", node.utf8().data());
563 setError(KResolver::NoName);
572 m_encodedName.truncate(0);
574 if (protocol() == -1)
576 setError(KResolver::NonRecoverable);
583 bool TDEStandardWorker::resolveScopeId()
587 int pos = nodeName().findRev(
'%');
591 TQString scopename = nodeName().mid(pos + 1);
594 scopeid = scopename.toInt(&ok);
599 #ifdef HAVE_IF_NAMETOINDEX
600 scopeid = if_nametoindex(scopename.latin1());
609 bool TDEStandardWorker::resolveService()
613 port = serviceName().toUInt(&ok);
619 if (serviceName().isEmpty() || serviceName().compare(TQString::fromLatin1(
"*")) == 0)
624 TQCString protoname = protocolName();
626 if (protoname.isEmpty() && protocol())
631 if (protoname.isEmpty())
634 setError(KResolver::NoName);
646 setError(KResolver::NoName);
651 port = (TQ_UINT16)result;
662 if ((familyMask() & KResolver::UnixFamily) == 0)
664 return KResolver::UnsupportedFamily;
667 if (!m_encodedName.isEmpty())
668 return KResolver::AddrFamily;
670 if (protocol() || !protocolName().isEmpty())
671 return KResolver::BadFlags;
673 TQString pathname = serviceName();
674 if (pathname.isEmpty())
675 return KResolver::NoName;;
677 if (pathname[0] !=
'/')
680 pathname.prepend(
"/tmp/");
684 int socktype = socketType();
686 socktype = SOCK_STREAM;
689 setError(KResolver::NoError);
691 return KResolver::NoError;
694 bool TDEStandardWorker::resolveNumerically()
700 bool wantV4 = familyMask() & KResolver::IPv4Family,
701 wantV6 = familyMask() & KResolver::IPv6Family;
703 if (!wantV6 && !wantV4)
705 return (flags() & KResolver::NoResolve);
708 if (!resolveScopeId() || !resolveService())
709 return (flags() & KResolver::NoResolve);
714 setError(KResolver::NoError);
718 bool ok = sa.
length() != 0;
723 int proto = protocol();
724 int socktype = socketType();
726 socktype = SOCK_STREAM;
746 setError(KResolver::AddrFamily);
750 else if (m_encodedName.isEmpty())
753 if (flags() & KResolver::Passive)
789 setError(KResolver::BadFlags);
793 return ok || (flags() & KResolver::NoResolve);
796 bool TDEStandardWorker::preprocess()
803 if (familyMask() & KResolver::UnknownFamily)
805 setError(KResolver::UnsupportedFamily);
810 if (socketType() != SOCK_STREAM && socketType() != SOCK_DGRAM && socketType() != 0)
812 setError(KResolver::UnsupportedSocketType);
818 if (resolveNumerically() || m_encodedName.isEmpty())
823 setError(KResolver::NoError);
830 # define mask (KResolver::IPv6Family | KResolver::IPv4Family | KResolver::UnixFamily)
832 # define mask (KResolver::IPv4Family | KResolver::UnixFamily)
835 if ((familyMask() & mask) == 0)
844 bool TDEStandardWorker::run()
846 #ifndef HAVE_GETADDRINFO
850 if (!resolveScopeId())
854 if (!resolveService())
860 setError(KResolver::NoName);
867 } families[] = { { KResolver::IPv4Family, AF_INET }
869 , { KResolver::IPv6Family, AF_INET6 }
872 int familyCount =
sizeof(families)/
sizeof(families[0]);
873 bool skipIPv6 = !hasIPv6();
874 resultList.setAutoDelete(
true);
876 for (
int i = 0; i < familyCount; i++)
877 if (familyMask() & families[i].mask)
880 if (skipIPv6 && families[i].af == AF_INET6)
884 KResolverWorkerBase *worker;
886 resultList.append(res);
887 #ifdef HAVE_GETADDRINFO
888 worker =
new GetAddrInfoThread(m_encodedName,
889 serviceName().latin1(),
890 families[i].af, flags(), res);
892 worker =
new GetHostByNameThread(m_encodedName, port, scopeid,
893 families[i].af, res);
903 bool TDEStandardWorker::postprocess()
910 if (resultList.isEmpty())
912 results.setError(KResolver::NoName);
921 results.
setError(KResolver::NoError);
922 KResolverResults::Iterator it = rr->begin();
923 for ( ; it != rr->end(); ++it)
926 else if (results.isEmpty())
931 rr = resultList.prev();
938 #ifdef HAVE_GETADDRINFO
939 KGetAddrinfoWorker::~KGetAddrinfoWorker()
943 bool KGetAddrinfoWorker::preprocess()
949 if (flags() & KResolver::NoResolve)
956 bool KGetAddrinfoWorker::run()
959 GetAddrInfoThread worker(m_encodedName, serviceName().latin1(),
960 AF_UNSPEC, flags(), &results);
964 if (wantThis(AF_UNIX))
966 if (addUnix() == KResolver::NoError)
967 setError(KResolver::NoError);
970 setError(worker.results.error(), worker.results.systemError());
979 bool seen_unix =
false;
980 KResolverResults::Iterator it = results.begin();
981 for ( ; it != results.end(); )
983 if ((*it).family() == AF_UNIX)
985 if (!wantThis((*it).family()))
986 it = results.remove(it);
998 bool KGetAddrinfoWorker::wantThis(
int family)
1003 if (family == AF_INET6 && familyMask() & KResolver::IPv6Family)
1006 if (family == AF_INET && familyMask() & KResolver::IPv4Family)
1008 if (family == AF_UNIX && familyMask() & KResolver::UnixFamily)
1012 if (familyMask() & KResolver::UnknownFamily)
1020 void KNetwork::Internal::initStandardWorkers()
1023 KResolverWorkerFactoryBase::registerNewWorker(
new KResolverWorkerFactory<TDEStandardWorker>);
1025 #ifdef HAVE_GETADDRINFO
1026 KResolverWorkerFactoryBase::registerNewWorker(
new KResolverWorkerFactory<KGetAddrinfoWorker>);