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

📄 dnsresolver.cxx

📁 RTP协议
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF ,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const DnsResolver_cxx_Version =    "$Id: DnsResolver.cxx,v 1.4 2001/05/17 22:09:20 wbreu Exp $";#include "vtypes.h"#include "NetworkAddress.h"#include "DnsResolver.hxx"  const int MY_PACKETSZ = 64*1024;     // space to hold tcp answersconst int DEFAULT_PRIO= 10;          const int DEFAULT_WT  = 10;// constructor for testing: default myQType to SRV lookupDnsResolver::DnsResolver(const char * target) :                         myReady(0), myNumDns(0), myCurIdx(0),                         myQType(ns_t_srv){     assert( target != 0 );    myTarget.assign(target);    myQName.assign(target);	    (void) res_init();   // init resolve package}DnsResolver::DnsResolver(const char * target, int qType,                          const char * serviceType, const char* protocol):                         myReady(false), myNumDns(0), myCurIdx(0),                         myQType(qType){    assert( target != 0);    myTarget.assign(target);    if (qType == ns_t_a)      // A record type    {        myQName.assign(target);    }    else                     // assume SRV record type    {        string s = "";        string p = "";        if (serviceType)        {            cpLog(LOG_DEBUG, "serviceType = %s", serviceType);            s = serviceType;            s+= ".";        }        if (protocol)        {            cpLog(LOG_DEBUG, "protocol = %s", protocol);            p = protocol;            p+= ".";        }        s += p;        cpLog(LOG_DEBUG, "s+p = %s", s.c_str());        s += target;        cpLog(LOG_DEBUG, "s+p+target = %s", s.c_str());        myQName.assign( s );    }    cpLog(LOG_DEBUG, "myQName = %s", myQName.c_str());    (void) res_init();   // init resolve package	dnsLookUp(); }  // DnsResolver///DnsResolver::~DnsResolver(){    //  deallocate memory    cpLog( LOG_DEBUG, "entered DnsResolver destructor");    clear();}// This method is called on object instantiation and whenever the// user wants to refresh the local dns cache.void DnsResolver::dnsLookUp(){    if (myReady)    {        clear();    // clean up local cache    }	findRecords();         // do the dns lookup    int num = myVDns.size();    if ((num == 0) && (myQType == ns_t_srv))    {        cpLog( LOG_DEBUG, "no srv records, try finding A records:");        // reset type to A record, and use domain name instead        myQType = ns_t_a;        myQName.assign(myTarget);        findRecords();            }    int numRec = myVDns.size();	if ((isReady()) && (numRec > 1))    {        loadBalance();       }    else if (numRec == 1)    {        cpLog( LOG_DEBUG,                "dnsLookUp() - no loadbalancing done");    }    else    {        cpLog(LOG_ERR,              "dnsLookUp() not complete: DnsResolver obj malformed!");    }  	}  // dnsLookUp// shuffle the ordering of the list of Dns records based on priorities// and weights.  Note that if this object contains a list of A records,// then all entries have the same default priority (10) and weight (10).void DnsResolver::reOrder(){    myCurIdx = 0;   // reset the index pointer	if (myReady)    {        loadBalance();    }	else    {        cpLog( LOG_DEBUG,                "DnsResolver object is not well formed, reOrder not done!");    }}  // reOrder// Sptr<DnsRecord> *  /* VECTOR_DNS::iterator */ DnsResolver::getRecord( int idx ){    if ((idx < 0) || (idx >= myNumDns))    {       cpLog(LOG_DEBUG, "getRecord() fails: bad index %d", idx);       return myVDns.end();    }    return(&(myVDns[idx]));}// get the record (SRV or A) indexed by myCurIdx:bool DnsResolver::getNextRecord( DnsRecord& rec ){    if (myReady == false)    {        cpLog( LOG_DEBUG,                "cannot get next Dns record: DnsResolver obj not well formed!");        return false;    }    if (myCurIdx >= myNumDns)	{        cpLog( LOG_DEBUG,               "list of Dns records exhausts");		// user may want to call reOrder() to generate a different		// ordered list and call getNextRecord() again        return false;		}	// return a reference of myVDns[myCurIdx], and advance myCurIdx	rec = *(myVDns[myCurIdx++]);	return true;}  // getNextRecord()// bool DnsResolver::selectRecord( const string& callId, DnsRecord& rec ){    return false;}int DnsResolver::getHostByRecord( const DnsRecord& rec,                  struct hostent* hEnt, char* buf, int buflen ){    int rtn = 0;	int nsErr = 0;	const char * host = rec.getTarget();    // pre-conditions checks:	assert( hEnt ); 	assert( buf );	assert( buflen );    rtn = NetworkAddress::getHostByName( host,					hEnt, buf, buflen, &nsErr );	if (rtn != 0)    {        nsError( nsErr, host );        return rtn;    }	return rtn;}  // getHostByRecord///voidDnsResolver::clear(){    if (myReady == true)	{        // leave myQName and myQType as is        myVDns.clear();        myNumDns = 0;		myCurIdx = 0;        myReady  = false;	}    }   // clear()/** *  */voidDnsResolver::nsError( int error, const char* domain ){    switch(error){        case HOST_NOT_FOUND:            cpLog(LOG_DEBUG, "Unknown domain: %s\n", domain);        break;           case NO_DATA:    // same as NO_ADDRESS            cpLog(LOG_DEBUG, "No DNS records for %s\n", domain);        break;		case NO_RECOVERY:		    cpLog(LOG_DEBUG, 			"non-recoverable error occurs during nameserver lookup for %s\n", 			domain);		break;        case TRY_AGAIN:            cpLog(LOG_DEBUG, "No response for DNS query\n");        break;        default:            cpLog(LOG_DEBUG, "Unexpected error=%d, domain=%s\n",                           error, domain);        break;    }}   // end of nsError()/** * locate the DNS records */boolDnsResolver::findRecords(){    union {       HEADER hdr;              /* defined in resolv.h */                                /* next line changed NS_PACKETSZ to PACKETSZ */       u_char buf[PACKETSZ];    /* defined in arpa/nameser.h */    } response;                 /* response buffers */    int responseLen;            /* buffer length */    ns_msg handle;              /* handle for response packet */    char* domain = (char*)myQName.c_str();    // seed the random number generator    // **************** TBD: don't use srand    struct timeval t;    gettimeofday(&t, 0);    srand( (unsigned int)(t.tv_usec ^ t.tv_sec) );    // Ref: "DNS and BIND" book    // Look up the SRV records for the given domain name.        cpLog(LOG_DEBUG, "Domain is %s\n",domain);    if((responseLen =        res_search(domain,  /* the domain we care about */        ns_c_in,                   /* Internet class records   */        myQType,                   /* ns_t_srv or ns_t_a       */        (u_char *)&response,       /* response buffer          */        sizeof(response)))         /* buffer size              */                           < 0)    /* If negative              */    {        nsError(h_errno, domain);      /* report the error         */        return false;                  /* and quit                 */    }     /* Initialize a handle to this response.  The handle will     * be used to extract information from the response.  */    if (ns_initparse(response.buf, responseLen, &handle) < 0)    {        cpLog(LOG_INFO, "ns_initparse: %s\n",strerror(errno));        return false;    };    // place records found in a vector, myVSrv: 	// search result from the answer section    buildRecords(handle, ns_s_an, responseLen);    // sort records based on the priority of the srv records    // records having the same priority:	if (myVDns.size() > 1)    {       sortByPreference();    }     return myReady;    }   // findRecords()/** * Load balancing algorithm based on the weight.  assume a list of SRV records in myVDns having the same  priority, find that range:  1) add up all weights within the range = s  2) pick a random number between 0..1 = r  3) calculate the random weight, rw = r*s  4) the weight of records partitions sumOfWeights: what part     does the random weight fall into? (find that record, rrd)     Let current sum of weight so far, cs = 0     Loop all records w/i the priority range:        given weight of current record, cw: cs +=cw;        if rw <= cw           swap out current record with rrd;           break from loop        else           continue to loop */void DnsResolver::loadBalance( ){     cpLog( LOG_DEBUG, "\nloadBalance(): \n" );	if (myVDns.size() <= 1)   // don't bother for single record	{       return;	}    VECTOR_DNS::iterator i = myVDns.begin();    int prio;    int startIdx, endIdx;    endIdx = -1;    // end of previous range    while (i != myVDns.end())    {        prio = (*i)->getPriority();        startIdx = endIdx+1;     // start of current range        endIdx = findPriorityRange( startIdx);         // let's find all srv records of same priority        if (startIdx == endIdx)         {            cpLog(LOG_DEBUG, "range of 1 found for priority=",  prio);            i++;        }        else        {            // sort same priority range by weight:            sortByWeight( startIdx, endIdx );            // advance iterator to first element after endIdx:            int n  = endIdx - startIdx + 1;            advance(i,n);        }    }    print( LOG_DEBUG ); 

⌨️ 快捷键说明

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