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

📄 q3dns.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"#include "qbytearray.h"#ifdef Q_OS_WIN32# include "qt_windows.h"#else# include <sys/types.h># include <netinet/in.h># include <arpa/nameser.h># include <resolv.h>extern "C" int res_init();#endif// POSIX Large File Support redefines open -> open64#if defined(open)# undef open#endif// POSIX Large File Support redefines truncate -> truncate64#if defined(truncate)# undef truncate#endif// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.#if defined(connect)# undef connect#endif// UnixWare 7 redefines socket -> _socket#if defined(socket)# undef socket#endif#include "q3dns.h"#ifndef QT_NO_DNS#include "qdatetime.h"#include "q3dict.h"#include "q3ptrlist.h"#include "qstring.h"#include "qtimer.h"#include "qapplication.h"#include "q3ptrvector.h"#include "q3strlist.h"#include "q3ptrdict.h"#include "qfile.h"#include "qtextstream.h"#include "q3socketdevice.h"#include "q3cleanuphandler.h"#include <limits.h>//#define Q3DNS_DEBUGstatic Q_UINT16 id; // ### seeded started by now()static QDateTime * originOfTime = 0;static Q3CleanupHandler<QDateTime> q3dns_cleanup_time;static Q_UINT32 now(){    if ( originOfTime )	return originOfTime->secsTo( QDateTime::currentDateTime() );    originOfTime = new QDateTime( QDateTime::currentDateTime() );    ::id = originOfTime->time().msec() * 60 + originOfTime->time().second();    q3dns_cleanup_time.add( &originOfTime );    return 0;}static Q3PtrList<QHostAddress> * ns = 0;static Q3StrList * domains = 0;static bool ipv6support = false;class Q3DnsPrivate {public:    Q3DnsPrivate() : queryTimer( 0 ), noNames(false)    {#if defined(Q_DNS_SYNCHRONOUS)#if defined(Q_OS_UNIX)	noEventLoop = qApp==0 || qApp->loopLevel()==0;#else	noEventLoop = false;#endif#endif    }    ~Q3DnsPrivate()    {	delete queryTimer;    }private:    QTimer * queryTimer;    bool noNames;#if defined(Q_DNS_SYNCHRONOUS)    bool noEventLoop;#endif    friend class Q3Dns;    friend class Q3DnsAnswer;};class Q3DnsRR;class Q3DnsDomain;// Q3DnsRR is the class used to store a single RR.  Q3DnsRR can store// all of the supported RR types.  a Q3DnsRR is always cached.// Q3DnsRR is mostly constructed from the outside.  a but hacky, but// permissible since the entire class is internal.class Q3DnsRR {public:    Q3DnsRR( const QString & label );    ~Q3DnsRR();public:    Q3DnsDomain * domain;    Q3Dns::RecordType t;    bool nxdomain;    bool current;    Q_UINT32 expireTime;    Q_UINT32 deleteTime;    // somewhat space-wasting per-type data    // a / aaaa    QHostAddress address;    // cname / mx / srv / ptr    QString target;    // mx / srv    Q_UINT16 priority;    // srv    Q_UINT16 weight;    Q_UINT16 port;    // txt    QString text; // could be overloaded into target...private:};class Q3DnsDomain {public:    Q3DnsDomain( const QString & label );    ~Q3DnsDomain();    static void add( const QString & label, Q3DnsRR * );    static Q3PtrList<Q3DnsRR> * cached( const Q3Dns * );    void take( Q3DnsRR * );    void sweep( Q_UINT32 thisSweep );    bool isEmpty() const { return rrs == 0 || rrs->isEmpty(); }    QString name() const { return l; }public:    QString l;    Q3PtrList<Q3DnsRR> * rrs;};class Q3DnsQuery: public QTimer { // this inheritance is a very evil hackpublic:    Q3DnsQuery():	id( 0 ), t( Q3Dns::None ), step(0), started(0),	dns( new Q3PtrDict<void>(17) ) {}    ~Q3DnsQuery() { delete dns; }    Q_UINT16 id;    Q3Dns::RecordType t;    QString l;    uint step;    Q_UINT32 started;    Q3PtrDict<void> * dns;};class Q3DnsAnswer {public:    Q3DnsAnswer( Q3DnsQuery * );    Q3DnsAnswer( const QByteArray &, Q3DnsQuery * );    ~Q3DnsAnswer();    void parse();    void notify();    bool ok;private:    Q3DnsQuery * query;    Q_UINT8 * answer;    int size;    int pp;    Q3PtrList<Q3DnsRR> * rrs;    // convenience    int next;    int ttl;    QString label;    Q3DnsRR * rr;    QString readString(bool multipleLabels = true);    void parseA();    void parseAaaa();    void parseMx();    void parseSrv();    void parseCname();    void parsePtr();    void parseTxt();    void parseNs();};Q3DnsRR::Q3DnsRR( const QString & label )    : domain( 0 ), t( Q3Dns::None ),      nxdomain( false ), current( false ),      expireTime( 0 ), deleteTime( 0 ),      priority( 0 ), weight( 0 ), port( 0 ){    Q3DnsDomain::add( label, this );}// not supposed to be deleted except by Q3DnsDomainQ3DnsRR::~Q3DnsRR(){    // nothing is necessary}// this one just sticks in a NXDomainQ3DnsAnswer::Q3DnsAnswer( Q3DnsQuery * query_ ){    ok = true;    answer = 0;    size = 0;    query = query_;    pp = 0;    rrs = new Q3PtrList<Q3DnsRR>;    rrs->setAutoDelete( false );    next = size;    ttl = 0;    label.clear();    rr = 0;    Q3DnsRR * newrr = new Q3DnsRR( query->l );    newrr->t = query->t;    newrr->deleteTime = query->started + 10;    newrr->expireTime = query->started + 10;    newrr->nxdomain = true;    newrr->current = true;    rrs->append( newrr );}Q3DnsAnswer::Q3DnsAnswer( const QByteArray& answer_,			Q3DnsQuery * query_ ){    ok = true;    answer = (Q_UINT8 *)(answer_.data());    size = (int)answer_.size();    query = query_;    pp = 0;    rrs = new Q3PtrList<Q3DnsRR>;    rrs->setAutoDelete( false );    next = size;    ttl = 0;    label.clear();    rr = 0;}Q3DnsAnswer::~Q3DnsAnswer(){    if ( !ok && rrs ) {	Q3PtrListIterator<Q3DnsRR> it( *rrs );	Q3DnsRR * tmprr;	while( (tmprr=it.current()) != 0 ) {	    ++it;	    tmprr->t = Q3Dns::None; // will be deleted soonish	}    }    delete rrs;}QString Q3DnsAnswer::readString(bool multipleLabels){    int p = pp;    QString r;    Q_UINT8 b;    for( ;; ) {	b = 128;        // Read one character        if ( p >= 0 && p < size )	    b = answer[p];	switch( b >> 6 ) {	case 0:            // b is less than 64	    p++;            // Detect end of data	    if ( b == 0 ) {		if ( p > pp )		    pp = p;                return r.isNull() ? QLatin1String( "." ) : r;	    }            // Read a label of size 'b' characters            if ( !r.isNull() )		r += QLatin1Char('.');	    while( b-- > 0 )                r += QLatin1Char( answer[p++] );            // Return immediately if we were only supposed to read one            // label.            if (!multipleLabels)                return r;	    break;	default:            // Ignore unrecognized control character, or p was out of            // range.	    goto not_ok;	case 3:            // Use the next character to determine the relative offset            // to jump to before continuing the packet parsing.	    int q = ( (answer[p] & 0x3f) << 8 ) + answer[p+1];	    if ( q >= pp || q >= p )		goto not_ok;	    if ( p >= pp )		pp = p + 2;	    p = q;        }    }not_ok:    ok = false;    return QString();}void Q3DnsAnswer::parseA(){    if ( next != pp + 4 ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw %d bytes long IN A for %s",		next - pp, label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->t = Q3Dns::A;    rr->address = QHostAddress( ( answer[pp+0] << 24 ) +				( answer[pp+1] << 16 ) +				( answer[pp+2] <<  8 ) +				( answer[pp+3] ) );#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN A %s (ttl %d)", label.ascii(),	    rr->address.toString().ascii(), ttl );#endif}void Q3DnsAnswer::parseAaaa(){    if ( next != pp + 16 ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw %d bytes long IN Aaaa for %s",		next - pp, label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->t = Q3Dns::Aaaa;    rr->address = QHostAddress( answer+pp );#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN Aaaa %s (ttl %d)", label.ascii(),	    rr->address.toString().ascii(), ttl );#endif}void Q3DnsAnswer::parseMx(){    if ( next < pp + 2 ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw %d bytes long IN MX for %s",		next - pp, label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->priority = (answer[pp] << 8) + answer[pp+1];    pp += 2;    rr->target = readString().lower();    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad string in MX for %s", label.ascii() );#endif	return;    }    rr->t = Q3Dns::Mx;#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN MX %d %s (ttl %d)", label.ascii(),	    rr->priority, rr->target.ascii(), ttl );#endif}void Q3DnsAnswer::parseSrv(){    if ( next < pp + 6 ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw %d bytes long IN SRV for %s",		next - pp, label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->priority = (answer[pp] << 8) + answer[pp+1];    rr->weight = (answer[pp+2] << 8) + answer[pp+3];    rr->port = (answer[pp+4] << 8) + answer[pp+5];    pp += 6;    rr->target = readString().lower();    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad string in SRV for %s", label.ascii() );#endif	return;    }    rr->t = Q3Dns::Srv;#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN SRV %d %d %d %s (ttl %d)", label.ascii(),	    rr->priority, rr->weight, rr->port, rr->target.ascii(), ttl );#endif}void Q3DnsAnswer::parseCname(){    QString target = readString().lower();    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad cname for for %s", label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->t = Q3Dns::Cname;    rr->target = target;#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN CNAME %s (ttl %d)", label.ascii(),	    rr->target.ascii(), ttl );#endif}void Q3DnsAnswer::parseNs(){    QString target = readString().lower();    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad cname for for %s", label.ascii() );#endif	return;    }    // parse, but ignore

⌨️ 快捷键说明

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