kresolverstandardworkers.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,029 行 · 第 1/2 页
CPP
1,029 行
for (addrinfo* p = result; p; p = p->ai_next) { // cache the last canon name to avoid doing the ToUnicode processing unnecessarily if ((previous_canon && !p->ai_canonname) || (!previous_canon && p->ai_canonname) || (p->ai_canonname != previous_canon && strcmp(p->ai_canonname, previous_canon) != 0)) { canon = KResolver::domainToUnicode(QString::fromAscii(p->ai_canonname)); previous_canon = p->ai_canonname; } results.append(KResolverEntry(p->ai_addr, p->ai_addrlen, p->ai_socktype, p->ai_protocol, canon, m_node)); } freeaddrinfo(result); results.setError(KResolver::NoError); finished(); return results.error() == KResolver::NoError; } while (true); }#endif // HAVE_GETADDRINFO} // namespacebool KStandardWorker::sanityCheck(){ // check that the requested values are sensible if (!nodeName().isEmpty()) { QString node = nodeName(); if (node.find('%') != -1) node.truncate(node.find('%')); if (node.isEmpty() || node == QString::fromLatin1("*") || node == QString::fromLatin1("localhost")) m_encodedName.truncate(0); else { m_encodedName = KResolver::domainToAscii(node); if (m_encodedName.isNull()) { qDebug("could not encode hostname '%s' (UTF-8)", node.utf8().data()); setError(KResolver::NoName); return false; // invalid hostname! } // qDebug("Using encoded hostname '%s' for '%s' (UTF-8)", m_encodedName.data(), // node.utf8().data()); } } else m_encodedName.truncate(0); // just to be sure, but it should be clear already if (protocol() == -1) { setError(KResolver::NonRecoverable); return false; // user passed invalid protocol name } return true; // it's sane}bool KStandardWorker::resolveScopeId(){ // we must test the original name, not the encoded one scopeid = 0; int pos = nodeName().findRev('%'); if (pos == -1) return true; QString scopename = nodeName().mid(pos + 1); bool ok; scopeid = scopename.toInt(&ok); if (!ok) { // it's not a number // therefore, it's an interface name#ifdef HAVE_IF_NAMETOINDEX scopeid = if_nametoindex(scopename.latin1());#else scopeid = 0;#endif } return true;}bool KStandardWorker::resolveService(){ // find the service first bool ok; port = serviceName().toUInt(&ok); if (!ok) { // service name does not contain a port number // must be a name if (serviceName().isEmpty() || serviceName().compare(QString::fromLatin1("*")) == 0) port = 0; else { // it's a name. We need the protocol name in order to lookup. QCString protoname = protocolName(); if (protoname.isEmpty() && protocol()) { protoname = KResolver::protocolName(protocol()).first(); // if it's still empty... if (protoname.isEmpty()) { // lookup failed! setError(KResolver::NoName); return false; } } else protoname = "tcp"; // it's not, so we can do a port lookup int result = KResolver::servicePort(serviceName().latin1(), protoname); if (result == -1) { // lookup failed! setError(KResolver::NoName); return false; } // it worked, we have a port number port = (Q_UINT16)result; } } // we found a port return true;}KResolver::ErrorCodes KStandardWorker::addUnix(){ // before trying to add, see if the user wants Unix sockets if ((familyMask() & KResolver::UnixFamily) == 0) // no, Unix sockets are not wanted return KResolver::UnsupportedFamily; // now check if the requested data are good for a Unix socket if (!m_encodedName.isEmpty()) return KResolver::AddrFamily; // non local hostname if (protocol() || protocolName()) return KResolver::BadFlags; // cannot have Unix sockets with protocols QString pathname = serviceName(); if (pathname.isEmpty()) return KResolver::NoName;; // no path? if (pathname[0] != '/') // non absolute pathname // put it in /tmp pathname.prepend("/tmp/"); // qDebug("QNoResolveWorker::addUnix(): adding Unix socket for %s", pathname.local8Bit().data()); KUnixSocketAddress sa(pathname); int socktype = socketType(); if (socktype == 0) socktype = SOCK_STREAM; // default results.append(KResolverEntry(sa, socktype, 0)); setError(KResolver::NoError); return KResolver::NoError;}bool KStandardWorker::resolveNumerically(){ // if the NoResolve flag is active, our result from this point forward // will always be true, even if the resolution failed. // that indicates that our result is authoritative. bool wantV4 = familyMask() & KResolver::IPv4Family, wantV6 = familyMask() & KResolver::IPv6Family; if (!wantV6 && !wantV4) // no Internet address is wanted! return (flags() & KResolver::NoResolve); // now try to find results if (!resolveScopeId() || !resolveService()) return (flags() & KResolver::NoResolve); // we have scope IDs and port numbers // now try to resolve the hostname numerically KInetSocketAddress sa; setError(KResolver::NoError); sa.setHost(KIpAddress(QString::fromLatin1(m_encodedName))); // if it failed, the length was reset to 0 bool ok = sa.length() != 0; sa.setPort(port); if (sa.ipVersion() == 6) sa.setScopeId(scopeid); int proto = protocol(); int socktype = socketType(); if (socktype == 0) socktype = SOCK_STREAM; if (ok) { // the given hostname was successfully converted to an IP address // check if the user wanted this kind of address if ((sa.ipVersion() == 4 && wantV4) || (sa.ipVersion() == 6 && wantV6)) results.append(KResolverEntry(sa, socktype, proto)); else { // Note: the address *IS* a numeric IP // but it's not of the kind the user asked for // // that means that it cannot be a Unix socket (because it's an IP) // and that means that no resolution will tell us otherwise // // This is a failed resolution setError(KResolver::AddrFamily); return true; } } else if (m_encodedName.isEmpty()) { // user wanted localhost if (flags() & KResolver::Passive) { if (wantV6) { sa.setHost(KIpAddress::anyhostV6); results.append(KResolverEntry(sa, socktype, proto)); } if (wantV4) { sa.setHost(KIpAddress::anyhostV4); results.append(KResolverEntry(sa, socktype, proto)); } } else { if (wantV6) { sa.setHost(KIpAddress::localhostV6); results.append(KResolverEntry(sa, socktype, proto)); } if (wantV4) { sa.setHost(KIpAddress::localhostV4); results.append(KResolverEntry(sa, socktype, proto)); } } ok = true; } else { // probably bad flags, since the address is not convertible without // resolution setError(KResolver::BadFlags); ok = false; } return ok || (flags() & KResolver::NoResolve);}bool KStandardWorker::preprocess(){ // check sanity if (!sanityCheck()) return false; // this worker class can only handle known families if (familyMask() & KResolver::UnknownFamily) { setError(KResolver::UnsupportedFamily); return false; // we don't know about this } // check the socket types if (socketType() != SOCK_STREAM && socketType() != SOCK_DGRAM && socketType() != 0) { setError(KResolver::UnsupportedSocketType); return false; } // check if we can resolve all numerically // resolveNumerically always returns true if the NoResolve flag is set if (resolveNumerically() || m_encodedName.isEmpty()) { // indeed, we have resolved numerically setError(addUnix()); if (results.count()) setError(KResolver::NoError); finished(); return true; } // check if the user wants something we know about#ifdef AF_INET6# define mask (KResolver::IPv6Family | KResolver::IPv4Family | KResolver::UnixFamily)#else# define mask (KResolver::IPv4Family | KResolver::UnixFamily)#endif if ((familyMask() & mask) == 0) // errr... nothing we know about return false;#undef mask return true; // it's ok}bool KStandardWorker::run(){#ifndef HAVE_GETADDRINFO // check the scope id first // since most of the resolutions won't have a scope id, this should be fast // and we won't have wasted time on services if this fails if (!resolveScopeId()) return false; // resolve the service now, before entering the blocking operation if (!resolveService()) return false;#endif // good // now we need the hostname setError(KResolver::NoName); // these are the family types that we know of struct { KResolver::SocketFamilies mask; int af; } families[] = { { KResolver::IPv4Family, AF_INET }#ifdef AF_INET6 , { KResolver::IPv6Family, AF_INET6 }#endif }; int familyCount = sizeof(families)/sizeof(families[0]); bool skipIPv6 = !hasIPv6(); resultList.setAutoDelete(true); for (int i = 0; i < familyCount; i++) if (familyMask() & families[i].mask) {#ifdef AF_INET6 if (skipIPv6 && families[i].af == AF_INET6) continue;#endif KResolverWorkerBase *worker; KResolverResults *res = new KResolverResults; resultList.append(res);#ifdef HAVE_GETADDRINFO worker = new GetAddrInfoThread(m_encodedName, serviceName().latin1(), families[i].af, flags(), res);#else worker = new GetHostByNameThread(m_encodedName, port, scopeid, families[i].af, res);#endif enqueue(worker); } // not finished return true;}bool KStandardWorker::postprocess(){ if (results.count()) return true; // no need // now copy over what we need from the underlying results // start backwards because IPv6 was launched later (if at all) if (resultList.isEmpty()) { results.setError(KResolver::NoName); return true; } KResolverResults *rr = resultList.last(); while (rr) { if (!rr->isEmpty()) { results.setError(KResolver::NoError); KResolverResults::Iterator it = rr->begin(); for ( ; it != rr->end(); ++it) results.append(*it); } else if (results.isEmpty()) // this generated an error // copy the error code over setError(rr->error(), rr->systemError()); rr = resultList.prev(); } resultList.clear(); return true;}#ifdef HAVE_GETADDRINFOKGetAddrinfoWorker::~KGetAddrinfoWorker(){}bool KGetAddrinfoWorker::preprocess(){ // getaddrinfo(3) can always handle any kind of request that makes sense if (!sanityCheck()) return false; if (flags() & KResolver::NoResolve) // oops, numeric resolution? return run(); return true;}bool KGetAddrinfoWorker::run(){ // make an AF_UNSPEC getaddrinfo(3) call GetAddrInfoThread worker(m_encodedName, serviceName().latin1(), AF_UNSPEC, flags(), &results); if (!worker.run()) { if (wantThis(AF_UNIX)) { if (addUnix() == KResolver::NoError) setError(KResolver::NoError); } else setError(worker.results.error(), worker.results.systemError()); return false; } // The worker has finished working // now copy over only what we may want // keep track of any Unix-domain sockets bool seen_unix = false; KResolverResults::Iterator it = results.begin(); for ( ; it != results.end(); ) { if ((*it).family() == AF_UNIX) seen_unix = true; if (!wantThis((*it).family())) it = results.remove(it); else ++it; } if (!seen_unix) addUnix(); finished(); return true;}bool KGetAddrinfoWorker::wantThis(int family){ // tells us if the user wants a socket of this family#ifdef AF_INET6 if (family == AF_INET6 && familyMask() & KResolver::IPv6Family) return true;#endif if (family == AF_INET && familyMask() & KResolver::IPv4Family) return true; if (family == AF_UNIX && familyMask() & KResolver::UnixFamily) return true; // it's not a family we know about... if (familyMask() & KResolver::UnknownFamily) return true; return false;}#endifvoid KNetwork::Internal::initStandardWorkers(){ //KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KBlacklistWorker>); KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KStandardWorker>);#ifdef HAVE_GETADDRINFO KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KGetAddrinfoWorker>);#endif}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?