28#include <sys/socket.h>
30#include <netinet/in.h>
48#include "tdestandarddirs.h"
49#include "tdeapplication.h"
52#include "tdesocketaddress.h"
53#include "kresolverstandardworkers_p.h"
59using namespace KNetwork::Internal;
66 if (getenv(
"TDE_NO_IPV6") != 0L)
69 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
79static TQMutex blacklistMutex;
80TQStringList KBlacklistWorker::blacklist;
82void KBlacklistWorker::init()
87 if (!TDEGlobal::_instance)
90 static bool beenhere =
false;
99void 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());
134bool KBlacklistWorker::isBlacklisted(
const TQString& host)
136 KBlacklistWorker::init();
143 TQString ascii = TQString::fromLatin1(KResolver::domainToAscii(host));
145 TQMutexLocker locker(&blacklistMutex);
148 TQStringList::ConstIterator it = blacklist.constBegin(),
149 end = blacklist.constEnd();
150 for ( ; it !=
end; ++it)
151 if (ascii.endsWith(*it))
158bool KBlacklistWorker::preprocess()
160 if (isBlacklisted(nodeName()))
162 results.setError(KResolver::NoName);
169bool 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;
361 TQString canon = KResolver::domainToUnicode(TQString::fromLatin1(he->h_name));
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));
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;
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))
524 canon = KResolver::domainToUnicode(TQString::fromAscii(p->ai_canonname));
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;
543bool 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);
558 m_encodedName = KResolver::domainToAscii(node);
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);
583bool 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());
609bool 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())
628 protoname = KResolver::protocolName(protocol()).first();
631 if (protoname.isEmpty())
634 setError(KResolver::NoName);
642 int result = KResolver::servicePort(serviceName().latin1(), protoname);
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;
694bool 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)
757 sa.
setHost(KIpAddress::anyhostV6);
763 sa.
setHost(KIpAddress::anyhostV4);
771 sa.
setHost(KIpAddress::localhostV6);
777 sa.
setHost(KIpAddress::localhostV4);
789 setError(KResolver::BadFlags);
793 return ok || (flags() & KResolver::NoResolve);
796bool 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)
844bool 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);
903bool 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
939KGetAddrinfoWorker::~KGetAddrinfoWorker()
943bool KGetAddrinfoWorker::preprocess()
949 if (flags() & KResolver::NoResolve)
956bool 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);
998bool 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)
1020void KNetwork::Internal::initStandardWorkers()
1023 KResolverWorkerFactoryBase::registerNewWorker(
new KResolverWorkerFactory<TDEStandardWorker>);
1025#ifdef HAVE_GETADDRINFO
1026 KResolverWorkerFactoryBase::registerNewWorker(
new KResolverWorkerFactory<KGetAddrinfoWorker>);
an Internet socket address
KInetSocketAddress & setPort(TQ_UINT16 port)
Sets the port number.
KInetSocketAddress & setScopeId(int scopeid)
Sets the scope id for this IPv6 object.
int ipVersion() const
Returns the IP version of the address this object holds.
KInetSocketAddress & setHost(const KIpAddress &addr)
Sets the IP address to the given raw address.
Name and service resolution results.
int systemError() const
Retrieves the system error code, if any.
int error() const
Retrieves the error code associated with this resolution.
void setError(int errorcode, int systemerror=0)
Sets the error codes.
SocketFamilies
Address family selection types.
A Unix (local) socket address.
TQ_UINT16 length() const
Returns the length of this socket address structure.
static TDEStandardDirs * dirs()
Returns the application standard dirs object.
TQStringList findAllResources(const char *type, const TQString &filter=TQString::null, bool recursive=false, bool unique=false) const
Tries to find all resources with the specified type.
A namespace to store all networking-related (socket) classes.
const TDEShortcut & end()
Goto end of the document.