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

📄 q3dns.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN NS %s (ttl %d)", label.ascii(),	    target.ascii(), ttl );#endif}void Q3DnsAnswer::parsePtr(){    QString target = readString().lower();    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad PTR for for %s", label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->t = Q3Dns::Ptr;    rr->target = target;#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN PTR %s (ttl %d)", label.ascii(),	    rr->target.ascii(), ttl );#endif}void Q3DnsAnswer::parseTxt(){    QString text = readString(false);    if ( !ok ) {#if defined(Q3DNS_DEBUG)	qDebug( "Q3Dns: saw bad TXT for for %s", label.ascii() );#endif	return;    }    rr = new Q3DnsRR( label );    rr->t = Q3Dns::Txt;    rr->text = text;#if defined(Q3DNS_DEBUG)    qDebug( "Q3Dns: saw %s IN TXT \"%s\" (ttl %d)", label.ascii(),	    rr->text.ascii(), ttl );#endif}void Q3DnsAnswer::parse(){    // okay, do the work...    if ( (answer[2] & 0x78) != 0 ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: answer to wrong query type (%d)", answer[1] );#endif	ok = false;	return;    }    // AA    bool aa = (answer[2] & 4) != 0;    // TC    if ( (answer[2] & 2) != 0 ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: truncated answer; pressing on" );#endif    }    // RD    bool rd = (answer[2] & 1) != 0;    // we don't test RA    // we don't test the MBZ fields    if ( (answer[3] & 0x0f) == 3 ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: saw NXDomain for %s", query->l.ascii() );#endif	// NXDomain.  cache that for one minute.	rr = new Q3DnsRR( query->l );	rr->t = query->t;	rr->deleteTime = query->started + 60;	rr->expireTime = query->started + 60;	rr->nxdomain = true;	rr->current = true;	rrs->append( rr );	return;    }    if ( (answer[3] & 0x0f) != 0 ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: error code %d", answer[3] & 0x0f );#endif	ok = false;	return;    }    int qdcount = ( answer[4] << 8 ) + answer[5];    int ancount = ( answer[6] << 8 ) + answer[7];    int nscount = ( answer[8] << 8 ) + answer[9];    int adcount = (answer[10] << 8 ) +answer[11];    pp = 12;    // read query    while( qdcount > 0 && pp < size ) {	// should I compare the string against query->l?	(void)readString();	if ( !ok )	    return;	pp += 4;	qdcount--;    }    // answers and stuff    int rrno = 0;    // if we parse the answer completely, but there are no answers,    // ignore the entire thing.    int answers = 0;    while( ( rrno < ancount ||	     ( ok && answers >0 && rrno < ancount + nscount + adcount ) ) &&	   pp < size ) {	label = readString().lower();	if ( !ok )	    return;	int rdlength = 0;	if ( pp + 10 <= size )	    rdlength = ( answer[pp+8] << 8 ) + answer[pp+9];	if ( pp + 10 + rdlength > size ) {#if defined(Q3DNS_DEBUG)	    qDebug( "DNS Manager: ran out of stuff to parse (%d+%d>%d (%d)",		    pp, rdlength, size, rrno < ancount );#endif	    // if we're still in the AN section, we should go back and	    // at least down the TTLs.  probably best to invalidate	    // the results.	    // the rrs list is good for this	    ok = ( rrno < ancount );	    return;	}	uint type, clas;	type = ( answer[pp+0] << 8 ) + answer[pp+1];	clas = ( answer[pp+2] << 8 ) + answer[pp+3];	ttl = ( answer[pp+4] << 24 ) + ( answer[pp+5] << 16 ) +	      ( answer[pp+6] <<  8 ) + answer[pp+7];	pp = pp + 10;	if ( clas != 1 ) {#if defined(Q3DNS_DEBUG)	    qDebug( "DNS Manager: class %d (not internet) for %s",		    clas, label.isNull() ? "." : label.ascii() );#endif	} else {            next = pp + rdlength;	    rr = 0;	    switch( type ) {	    case 1:		parseA();		break;	    case 28:		parseAaaa();		break;	    case 15:		parseMx();		break;	    case 33:		parseSrv();		break;	    case 5:		parseCname();		break;	    case 12:		parsePtr();		break;	    case 16:		parseTxt();		break;	    case 2:		parseNs();		break;	    default:		// something we don't know#if defined(Q3DNS_DEBUG)		qDebug( "DNS Manager: type %d for %s", type,			label.isNull() ? "." : label.ascii() );#endif		break;	    }	    if ( rr ) {		rr->deleteTime = 0;		if ( ttl > 0 )		    rr->expireTime = query->started + ttl;		else		    rr->expireTime = query->started + 20;		if ( rrno < ancount ) {		    answers++;		    rr->deleteTime = rr->expireTime;		}		rr->current = true;		rrs->append( rr );	    }        }	if ( !ok )	    return;	pp = next;	next = size;	rrno++;    }    if ( answers == 0 ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: answer contained no answers" );#endif	ok = ( aa && rd );    }    // now go through the list and mark all the As that are referenced    // by something we care about.  we want to cache such As.    rrs->first();    Q3Dict<void> used( 17 );    used.setAutoDelete( false );    while( (rr=rrs->current()) != 0 ) {	rrs->next();	if ( rr->target.length() && rr->deleteTime > 0 && rr->current )	    used.insert( rr->target, (void*)42 );	if ( ( rr->t == Q3Dns::A || rr->t == Q3Dns::Aaaa ) &&	     used.find( rr->domain->name() ) != 0 )	    rr->deleteTime = rr->expireTime;    }    // next, for each RR, delete any older RRs that are equal to it    rrs->first();    while( (rr=rrs->current()) != 0 ) {	rrs->next();	if ( rr && rr->domain && rr->domain->rrs ) {	    Q3PtrList<Q3DnsRR> * drrs = rr->domain->rrs;	    drrs->first();	    Q3DnsRR * older;	    while( (older=drrs->current()) != 0 ) {		if ( older != rr &&		     older->t == rr->t &&		     older->nxdomain == rr->nxdomain &&		     older->address == rr->address &&		     older->target == rr->target &&		     older->priority == rr->priority &&		     older->weight == rr->weight &&		     older->port == rr->port &&		     older->text == rr->text ) {		    // well, it's equal, but it's not the same. so we kill it,		    // but use its expiry time.#if defined(Q3DNS_DEBUG)		    qDebug( "killing off old %d for %s, expire was %d",                            older->t, older->domain->name().latin1(),                            rr->expireTime );#endif		    older->t = Q3Dns::None;		    rr->expireTime = QMAX( older->expireTime, rr->expireTime );		    rr->deleteTime = QMAX( older->deleteTime, rr->deleteTime );		    older->deleteTime = 0;#if defined(Q3DNS_DEBUG)		    qDebug( "    adjusted expire is %d", rr->expireTime );#endif		}		drrs->next();	    }	}    }#if defined(Q3DNS_DEBUG)    //qDebug( "DNS Manager: ()" );#endif}class Q3DnsUgleHack: public Q3Dns {public:    void ugle( bool emitAnyway=false );};void Q3DnsAnswer::notify(){    if ( !rrs || !ok || !query || !query->dns )	return;    Q3PtrDict<void> notified;    notified.setAutoDelete( false );    Q3PtrDictIterator<void> it( *query->dns );    Q3Dns * dns;    it.toFirst();    while( (dns=(Q3Dns*)(it.current())) != 0 ) {	++it;	if ( notified.find( (void*)dns ) == 0 ) {	    notified.insert( (void*)dns, (void*)42 );	    if ( rrs->count() == 0 ) {#if defined(Q3DNS_DEBUG)		qDebug( "DNS Manager: found no answers!" );#endif		dns->d->noNames = true;		((Q3DnsUgleHack*)dns)->ugle( true );	    } else {		QStringList n = dns->qualifiedNames();		if ( query && n.contains(query->l) )		    ((Q3DnsUgleHack*)dns)->ugle();#if defined(Q3DNS_DEBUG)		else		    qDebug( "DNS Manager: DNS thing %s not notified for %s",			    dns->label().ascii(), query->l.ascii() );#endif	    }	}    }}////// Q3DnsManager////class Q3DnsManager: public Q3DnsSocket {private:public: // just to silence the moronic g++.    Q3DnsManager();    ~Q3DnsManager();public:    static Q3DnsManager * manager();    Q3DnsDomain * domain( const QString & );    void transmitQuery( Q3DnsQuery * );    void transmitQuery( int );    // reimplementation of the slots    void cleanCache();    void retransmit();    void answer();public:    Q3PtrVector<Q3DnsQuery> queries;    Q3Dict<Q3DnsDomain> cache;    Q3SocketDevice * ipv4Socket;#if !defined (QT_NO_IPV6)    Q3SocketDevice * ipv6Socket;#endif};static Q3DnsManager * globalManager = 0;static void cleanupDns(){    delete globalManager;    globalManager = 0;}Q3DnsManager * Q3DnsManager::manager(){    if ( !globalManager ) {        qAddPostRoutine(cleanupDns);	new Q3DnsManager();    }    return globalManager;}void Q3DnsUgleHack::ugle( bool emitAnyway){    if ( emitAnyway || !isWorking() ) {#if defined(Q3DNS_DEBUG)	qDebug( "DNS Manager: status change for %s (type %d)",		label().ascii(), recordType() );#endif	emit resultsReady();    }}Q3DnsManager::Q3DnsManager()    : Q3DnsSocket( qApp, "Internal DNS manager" ),      queries( Q3PtrVector<Q3DnsQuery>( 0 ) ),      cache( Q3Dict<Q3DnsDomain>( 83, false ) ),      ipv4Socket( new Q3SocketDevice( Q3SocketDevice::Datagram, Q3SocketDevice::IPv4, 0 ) )#if !defined (QT_NO_IPV6)      , ipv6Socket( new Q3SocketDevice( Q3SocketDevice::Datagram, Q3SocketDevice::IPv6, 0 ) )#endif{    cache.setAutoDelete( true );    globalManager = this;    QTimer * sweepTimer = new QTimer( this );    sweepTimer->start( 1000 * 60 * 3 );    connect( sweepTimer, SIGNAL(timeout()),	     this, SLOT(cleanCache()) );    QSocketNotifier * rn4 = new QSocketNotifier( ipv4Socket->socket(),						 QSocketNotifier::Read,						 this, "dns IPv4 socket watcher" );    ipv4Socket->setAddressReusable( false );    ipv4Socket->setBlocking( false );    connect( rn4, SIGNAL(activated(int)), SLOT(answer()) );#if !defined (QT_NO_IPV6)    // Don't connect the IPv6 socket notifier if the host does not    // support IPv6.    if ( ipv6Socket->socket() != -1 ) {	QSocketNotifier * rn6 = new QSocketNotifier( ipv6Socket->socket(),						     QSocketNotifier::Read,						     this, "dns IPv6 socket watcher" );	ipv6support = true;	ipv6Socket->setAddressReusable( false );	ipv6Socket->setBlocking( false );	connect( rn6, SIGNAL(activated(int)), SLOT(answer()) );    }#endif    if ( !ns )	Q3Dns::doResInit();    // O(n*n) stuff here.  but for 3 and 6, O(n*n) with a low k should    // be perfect.  the point is to eliminate any duplicates that    // might be hidden in the lists.    Q3PtrList<QHostAddress> * ns = new Q3PtrList<QHostAddress>;    ::ns->first();    QHostAddress * h;    while( (h=::ns->current()) != 0 ) {	ns->first();	while( ns->current() != 0 && !(*ns->current() == *h) )	    ns->next();	if ( !ns->current() ) {	    ns->append( new QHostAddress(*h) );#if defined(Q3DNS_DEBUG)	    qDebug( "using name server %s", h->toString().latin1() );	} else {	    qDebug( "skipping address %s", h->toString().latin1() );#endif	}	::ns->next();    }    delete ::ns;    ::ns = ns;    ::ns->setAutoDelete( true );    Q3StrList * domains = new Q3StrList( true );    ::domains->first();    const char * s;    while( (s=::domains->current()) != 0 ) {	domains->first();	while( domains->current() != 0 && qstrcmp( domains->current(), s ) )	    domains->next();	if ( !domains->current() ) {	    domains->append( s );#if defined(Q3DNS_DEBUG)	    qDebug( "searching domain %s", s );	} else {	    qDebug( "skipping domain %s", s );#endif	}	::domains->next();    }    delete ::domains;    ::domains = domains;    ::domains->setAutoDelete( true );}Q3DnsManager::~Q3DnsManager(){    if ( globalManager )	globalManager = 0;    queries.setAutoDelete( true );    cache.setAutoDelete( true );    delete ipv4Socket;#if !defined (QT_NO_IPV6)    delete ipv6Socket;#endif}static Q_UINT32 lastSweep = 0;void Q3DnsManager::cleanCache(){    bool again = false;    Q3DictIterator<Q3DnsDomain> it( cache );    Q3DnsDomain * d;    Q_UINT32 thisSweep = now();#if defined(Q3DNS_DEBUG)    qDebug( "Q3DnsManager::cleanCache(: Called, time is %u, last was %u",	   thisSweep, lastSweep );#endif    while( (d=it.current()) != 0 ) {	++it;	d->sweep( thisSweep ); // after this, d may be empty	if ( !again )	    again = !d->isEmpty();    }    if ( !again )	delete this;    lastSweep = thisSweep;}void Q3DnsManager::retransmit(){    const QObject * o = sender();    if ( o == 0 || globalManager == 0 || this != globalManager )	return;    uint q = 0;    while( q < queries.size() && queries[q] != o )	q++;    if ( q < queries.size() )	transmitQuery( q );}void Q3DnsManager::answer(){

⌨️ 快捷键说明

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