⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3dns.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*!    \class Q3Dns q3dns.h    \brief The Q3Dns class provides asynchronous DNS lookups.    \compat    Both Windows and Unix provide synchronous DNS lookups; Windows    provides some asynchronous support too. At the time of writing    neither operating system provides asynchronous support for    anything other than hostname-to-address mapping.    Q3Dns rectifies this shortcoming, by providing asynchronous caching    lookups for the record types that we expect modern GUI    applications to need in the near future.    The class is \e not straightforward to use (although it is much    simpler than the native APIs); Q3Socket provides much easier to use    TCP connection facilities. The aim of Q3Dns is to provide a correct    and small API to the DNS and nothing more. (We use "correctness"    to mean that the DNS information is correctly cached, and    correctly timed out.)    The API comprises a constructor, functions to set the DNS node    (the domain in DNS terminology) and record type (setLabel() and    setRecordType()), the corresponding get functions, an isWorking()    function to determine whether Q3Dns is working or reading, a    resultsReady() signal and query functions for the result.    There is one query function for each RecordType, namely    addresses(), mailServers(), servers(), hostNames() and texts().    There are also two generic query functions: canonicalName()    returns the name you'll presumably end up using (the exact meaning    of this depends on the record type) and qualifiedNames() returns a    list of the fully qualified names label() maps to.    \sa Q3Socket*//*!    Constructs a DNS query object with invalid settings for both the    label and the search type.*/Q3Dns::Q3Dns(){    d = new Q3DnsPrivate;    t = None;}/*!    Constructs a DNS query object that will return record type \a rr    information about \a label.    The DNS lookup is started the next time the application enters the    event loop. When the result is found the signal resultsReady() is    emitted.    \a rr defaults to \c A, IPv4 addresses.*/Q3Dns::Q3Dns( const QString & label, RecordType rr ){    d = new Q3DnsPrivate;    t = rr;    setLabel( label );    setStartQueryTimer(); // start query the next time we enter event loop}/*!    Constructs a DNS query object that will return record type \a rr    information about host address \a address. The label is set to the    IN-ADDR.ARPA domain name. This is useful in combination with the    \c Ptr record type (e.g. if you want to look up a hostname for a    given address).    The DNS lookup is started the next time the application enters the    event loop. When the result is found the signal resultsReady() is    emitted.    \a rr defaults to \c Ptr, that maps addresses to hostnames.*/Q3Dns::Q3Dns( const QHostAddress & address, RecordType rr ){    d = new Q3DnsPrivate;    t = rr;    setLabel( address );    setStartQueryTimer(); // start query the next time we enter event loop}/*!    Destroys the DNS query object and frees its allocated resources.*/Q3Dns::~Q3Dns(){    if ( globalManager ) {	uint q = 0;	Q3DnsManager * m = globalManager;	while( q < m->queries.size() ) {	    Q3DnsQuery * query=m->queries[q];	    if ( query && query->dns )		    (void)query->dns->take( (void*) this );		q++;	}    }    delete d;    d = 0;}/*!    Sets this DNS query object to query for information about \a    label.    This does not change the recordType(), but its isWorking() status    will probably change as a result.    The DNS lookup is started the next time the application enters the    event loop. When the result is found the signal resultsReady() is    emitted.*/void Q3Dns::setLabel( const QString & label ){    l = label;    d->noNames = false;    // construct a list of qualified names    n.clear();    if ( l.length() > 1 && l[(int)l.length()-1] == QLatin1Char('.') ) {	n.append( l.left( l.length()-1 ).lower() );    } else {	int i = l.length();	int dots = 0;	const int maxDots = 2;	while( i && dots < maxDots ) {	    if ( l[--i] == QLatin1Char('.') )		dots++;	}	if ( dots < maxDots ) {	    (void)Q3DnsManager::manager(); // create a Q3DnsManager, if it is not already there	    Q3StrListIterator it( *domains );	    const char * dom;	    while( (dom=it.current()) != 0 ) {		++it;		n.append( l.lower() + QLatin1String(".") + QLatin1String(dom) );	    }	}	n.append( l.lower() );    }#if defined(Q_DNS_SYNCHRONOUS)    if ( d->noEventLoop ) {	doSynchronousLookup();    } else {	setStartQueryTimer(); // start query the next time we enter event loop    }#else    setStartQueryTimer(); // start query the next time we enter event loop#endif#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns::setLabel: %d address(es) for %s", n.count(), l.ascii() );    int i = 0;    for( i = 0; i < (int)n.count(); i++ )	qDebug( "Q3Dns::setLabel: %d: %s", i, n[i].ascii() );#endif}/*!    \overload    Sets this DNS query object to query for information about the host    address \a address. The label is set to the IN-ADDR.ARPA domain    name. This is useful in combination with the \c Ptr record type    (e.g. if you want to look up a hostname for a given address).*/void Q3Dns::setLabel( const QHostAddress & address ){    setLabel( toInAddrArpaDomain( address ) );}/*!    \fn QStringList Q3Dns::qualifiedNames() const    Returns a list of the fully qualified names label() maps to.    Note that if you want to iterate over the list, you should iterate    over a copy, e.g.    \code    QStringList list = myDns.qualifiedNames();    QStringList::Iterator it = list.begin();    while( it != list.end() ) {        myProcessing( *it );        ++it;    }    \endcode*//*!    \fn QString Q3Dns::label() const    Returns the domain name for which this object returns information.    \sa setLabel()*//*!    \enum Q3Dns::RecordType    This enum type defines the record types Q3Dns can handle. The DNS    provides many more; these are the ones we've judged to be in    current use, useful for GUI programs and important enough to    support right away:    \value None  No information. This exists only so that Q3Dns can    have a default.    \value A  IPv4 addresses. By far the most common type.    \value Aaaa  IPv6 addresses. So far mostly unused.    \value Mx  Mail eXchanger names. Used for mail delivery.    \value Srv  SeRVer names. Generic record type for finding    servers. So far mostly unused.    \value Cname  Canonical names. Maps from nicknames to the true    name (the canonical name) for a host.    \value Ptr  name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.    \value Txt  arbitrary TeXT for domains.    We expect that some support for the    \l{http://www.rfc-editor.org/rfc/rfc2535.txt}{RFC 2535}    extensions will be added in future versions.*//*!    Sets this object to query for record type \a rr records.    The DNS lookup is started the next time the application enters the    event loop. When the result is found the signal resultsReady() is    emitted.    \sa RecordType*/void Q3Dns::setRecordType( RecordType rr ){    t = rr;    d->noNames = false;    setStartQueryTimer(); // start query the next time we enter event loop}/*!  \internal  Private slot for starting the query.*/void Q3Dns::startQuery(){    // isWorking() starts the query (if necessary)    if ( !isWorking() )	emit resultsReady();}/*!    The three functions Q3Dns::Q3Dns(QString, RecordType),    Q3Dns::setLabel() and Q3Dns::setRecordType() may start a DNS lookup.    This function handles setting up the single shot timer.*/void Q3Dns::setStartQueryTimer(){#if defined(Q_DNS_SYNCHRONOUS)    if ( !d->queryTimer && !d->noEventLoop )#else    if ( !d->queryTimer )#endif    {	// start the query the next time we enter event loop	d->queryTimer = new QTimer( this );	connect( d->queryTimer, SIGNAL(timeout()),		 this, SLOT(startQuery()) );	d->queryTimer->start( 0, true );    }}/*    Transforms the host address \a address to the IN-ADDR.ARPA domain    name. Returns something indeterminate if you're sloppy or    naughty. This function has an IPv4-specific name, but works for    IPv6 too.*/QString Q3Dns::toInAddrArpaDomain( const QHostAddress &address ){    QString s;    if ( address.isNull() ) {	// if the address isn't valid, neither of the other two make	// cases make sense. better to just return.    } else if ( address.isIp4Addr() ) {	Q_UINT32 i = address.ip4Addr();	s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA",		   i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff );    } else {	// RFC 3152. (1886 is deprecated, and clients no longer need to	// support it, in practice).	Q_IPV6ADDR i = address.toIPv6Address();	s = QLatin1String("ip6.arpa");	uint b = 0;	while( b < 16 ) {	    s = QString::number( i.c[b]%16, 16 ) + QLatin1String(".") +		QString::number( i.c[b]/16, 16 ) + QLatin1String(".") + s;	    b++;	}    }    return s;}/*!    \fn Q3Dns::RecordType Q3Dns::recordType() const    Returns the record type of this DNS query object.    \sa setRecordType() RecordType*//*!    \fn void Q3Dns::resultsReady()    This signal is emitted when results are available for one of the    qualifiedNames().*//*!    Returns true if Q3Dns is doing a lookup for this object (i.e. if it    does not already have the necessary information); otherwise    returns false.    Q3Dns emits the resultsReady() signal when the status changes to false.*/bool Q3Dns::isWorking() const{#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns::isWorking (%s, %d)", l.ascii(), t );#endif    if ( t == None )	return false;#if defined(Q_DNS_SYNCHRONOUS)    if ( d->noEventLoop )	return true;#endif    Q3PtrList<Q3DnsRR> * ll = Q3DnsDomain::cached( this );    Q_LONG queries = n.count();    while( ll->current() != 0 ) {	if ( ll->current()->nxdomain ) {	    queries--;	} else {	    delete ll;	    return false;	}	ll->next();    }    delete ll;    if ( queries <= 0 )	return false;    if ( d->noNames )	return false;    return true;}/*!    Returns a list of the addresses for this name if this Q3Dns object    has a recordType() of Q3Dns::A or Q3Dns::Aaaa and the answer    is available; otherwise returns an empty list.    As a special case, if label() is a valid numeric IP address, this    function returns that address.    Note that if you want to iterate over the list, you should iterate    over a copy, e.g.    \code    Q3ValueList<QHostAddress> list = myDns.addresses();    Q3ValueList<QHostAddress>::Iterator it = list.begin();    while( it != list.end() ) {        myProcessing( *it );        ++it;    }    \endcode*/Q3ValueList<QHostAddress> Q3Dns::addresses() const{#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns::addresses (%s)", l.ascii() );#endif    Q3ValueList<QHostAddress> result;    if ( t != A && t != Aaaa )	return result;    Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this );    Q3DnsRR * rr;    while( (rr=cached->current()) != 0 ) {	if ( rr->current && !rr->nxdomain )	    result.append( rr->address );	cached->next();    }    delete cached;    return result;}/*!    \class Q3Dns::MailServer    \brief The Q3Dns::MailServer class is  described in Q3Dns::mailServers().    \internal*//*!    Returns a list of mail servers if the record type is \c Mx. The    class Q3Dns::MailServer contains the following public variables:    \list    \i QString Q3Dns::MailServer::name    \i Q_UINT16 Q3Dns::MailServer::priority    \endlist    Note that if you want to iterate over the list, you should iterate    over a copy, e.g.    \code    Q3ValueList<Q3Dns::MailServer> list = myDns.mailServers();    Q3ValueList<Q3Dns::MailServer>::Iterator it = list.begin();    while( it != list.end() ) {        myProcessing( *it );        ++it;    }    \endcode*/Q3ValueList<Q3Dns::MailServer> Q3Dns::mailServers() const{#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns::mailServers (%s)", l.ascii() );#endif    Q3ValueList<Q3Dns::MailServer> result;    if ( t != Mx )	return result;    Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this );    Q3DnsRR * rr;    while( (rr=cached->current()) != 0 ) {	if ( rr->current && !rr->nxdomain ) {	    MailServer ms( rr->target, rr->priority );	    result.append( ms );	}	cached->next();    }    delete cached;    return result;}/*!    \class Q3Dns::Server    \brief The Q3Dns::Server class is described in Q3Dns::servers().    \internal*//*!    Returns a list of servers if the record type is \c Srv. The class    Q3Dns::Server contains the following public variables:    \list    \i QString Q3Dns::Server::name    \i Q_UINT16 Q3Dns::Server::priority    \i Q_UINT16 Q3Dns::Server::weight    \i Q_UINT16 Q3Dns::Server::port    \endlist    Note that if you want to iterate over the list, you should iterate    over a copy, e.g.    \code    Q3ValueList<Q3Dns::Server> list = myDns.servers();    Q3ValueList<Q3Dns::Server>::Iterator it = list.begin();    while( it != list.end() ) {        myProcessing( *it );        ++it;    }    \endcode*/Q3ValueList<Q3Dns::Server> Q3Dns::servers() const{#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns::servers (%s)", l.ascii() );#endif    Q3ValueList<Q3Dns::Server> result;    if ( t != Srv )	return result;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -