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

📄 dnsresolver.cxx

📁 RTP协议
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#if 0    // **************  debug only   **************    // applicable for testLoadBalance testcase #4 only:    myVDns[0]->incrTimesSelected(1);    myVDns[1]->incrTimesSelected(2);    myVDns[2]->incrTimesSelected(3);#endif}   // loadBalance()/** *  print elements in the myVDns vector */voidDnsResolver::print( int logLevel ){   VECTOR_DNS::iterator i;    if ((logLevel < 0) || (logLevel >= LAST_PRIORITY))    {        logLevel = LOG_DEBUG;    }    cpLog(logLevel,      "\nprio   weight   target:port address\n");    for (i=myVDns.begin(); i != myVDns.end(); i++)    {         cpLog(logLevel, "\n%d   %5d  %s:%d  %s\n",                (*i)->getPriority(), (*i)->getWeight(),                (*i)->getTarget(), (*i)->getPort(),				(*i)->getAddress());    } }   // print()/** *  print myVDns vector including times selected to be 1st, 2nd & 3rd: *  ************** use for DEBUG ONLY *************** */voidDnsResolver::printTally(  ){   VECTOR_DNS::iterator i;    cpLog(LOG_DEBUG, "\n****** Final tally ******\n");    for (i=myVDns.begin(); i != myVDns.end(); i++)    {         (*i)->printTally();    }         findRecords();}   // printTally()/// Build a list and print the DNS response records found //void DnsResolver::buildRecords(ns_msg handle, ns_sect section, int responseLen){    int numRecords = ns_msg_count(handle, section);    cpLog(LOG_DEBUG, "Response Length is: %d\n"                     "Number of records found: %d\n",                     responseLen, numRecords);    // for efficiency, reserve capacity of myVDns vector to    // avoid dynamic reallocation of vector, actual size    // will be <= capacity (because not all records found    // will match the Record Class we are looking for: e.g.    // code will ignore CNAME record    myVDns.reserve( numRecords );      if (myQType == ns_t_srv)	{        cpLog( LOG_DEBUG, "building SRV records" );        buildSRVRecords( handle, section, responseLen, numRecords );    }	else if (myQType == ns_t_a)    {        cpLog( LOG_DEBUG, "building A records");        buildARecords( handle, section, responseLen, numRecords );    }	else	{        cpLog( LOG_DEBUG, "don't know how to build record type=%d", myQType );	}}  // buildRecordsvoid DnsResolver::buildSRVRecords(ns_msg handle, ns_sect section,                                  int responseLen, int numRecords){    int rrnum;              /* resource record number */	int rrt;                /* resource record type */    ns_rr rr;               /* expanded resource record */    u_char *cp;             /* character point to results (rdata in ns_rr) */    char name[NS_MAXDNAME]; /* expanded response hostname */    /* Loop through each record found  */    for(rrnum = 0; rrnum < numRecords; rrnum++)    {        /* Expand the resource record number rrnum into rr.  */        if (ns_parserr(&handle, section, rrnum, &rr))        {            cpLog(LOG_DEBUG, "ns_parserr: %s, skip rr #%d\n", 							strerror(errno), rrnum);            continue;        }        rrt = ns_rr_type(rr);		if (rrt != ns_t_srv)        {            cpLog(LOG_DEBUG, "skipping record number: %d, type: %d", 							rrnum, rrt);            continue;        }        DnsRecord *rec = new DnsRecord;        /* Check to see if answer is authoritive */        if(!ns_msg_getflag(handle,ns_f_aa))        {            cpLog(LOG_DEBUG,"Warning: Nameserver is not authoritative.\n");        }        /* Set cp to point the SRV record.  */        cp = (u_char *)ns_rr_rdata(rr);        rec->setPriority( ns_get16(cp) );        cp += sizeof(u_short);        rec->setWeight( ns_get16(cp) );        cp += sizeof(u_short);        rec->setPort( ns_get16(cp) );        cp += sizeof(u_short);        cp = (u_char *)expandName(cp, ns_msg_base(handle), name, sizeof(name));        rec->setTarget( name );        struct hostent hEnt;        char buf[2048];        if (getHostByRecord( *rec, &hEnt, buf, sizeof(buf))==0)        {            unsigned char* addr = (unsigned char*)(hEnt.h_addr_list[0]);            char addrBuf[1000];            sprintf(addrBuf, "%d.%d.%d.%d",                    int(*(addr + 0)),                    int(*(addr + 1)),                    int(*(addr + 2)),                    int(*(addr + 3)) );            rec->setAddress(addrBuf);        }        else        {            rec->setAddress("0.0.0.0");        }        cpLog(LOG_DEBUG, "Target/address = %s/%s", name,              rec->getAddress());        // put record in a multimap        // mmSrv.insert( make_pair( rec->getPriority, rec ) );          // insert record at end of vector        myVDns.push_back( rec );        // curious: what is the vector's capacity?        // cpLog(LOG_DEBUG, "Capacity of myVDns = %d", myVDns.capacity());        cpLog(LOG_DEBUG, "\nSRV Priority field: %d\n"                         "SRV Weight field: %d\n"                         "SRV Port field: %d\n"                         "SRV hostname field: %s\n"                         "Resource Record Type: %d\n"                         "Record Class: %d\n"                         "Resource Record Time To Live (ttl): %d\n",		             rec->getPriority(), rec->getWeight(), rec->getPort(),					 name, rrt, ns_rr_class(rr), ns_rr_ttl(rr));    }    myNumDns = myVDns.size();    myReady = true;    cpLog(LOG_DEBUG, "Number of DNS SRV records = %d\n", myNumDns);}  // buildSRVRecords()// parse the result of A Record lookup and build a DnsRecordvoid DnsResolver::buildARecords(ns_msg handle, ns_sect section,                               int responseLen, int numRecords){    int rrnum;              /* resource record number */	int rrt;                /* resource record type */    ns_rr rr;               /* expanded resource record */    u_char *cp;             /* character point to results (rdata in ns_rr) */    // char name[NS_MAXDNAME]; /* expanded response hostname */    /* Loop through each record found  */    for(rrnum = 0; rrnum < numRecords; rrnum++)    {        /* Expand the resource record number rrnum into rr.  */        if (ns_parserr(&handle, section, rrnum, &rr))        {            cpLog(LOG_DEBUG, "ns_parserr: %s, skip rr #%d\n", 							strerror(errno), rrnum);            continue;        }        rrt = ns_rr_type(rr);		if (rrt != ns_t_a)        {            cpLog(LOG_DEBUG, "skipping record num: %d, type: %d", 							rrnum, rrt);            continue;        }        DnsRecord *rec = new DnsRecord;        /* Expand the resource record number rrnum into rr.  */        if (ns_parserr(&handle, section, rrnum, &rr))        {            cpLog(LOG_INFO, "ns_parserr: %s\n", strerror(errno));        }        /* Check to see if answer is authoritive */        if(!ns_msg_getflag(handle,ns_f_aa))            cpLog(LOG_INFO,"Warning: Nameserver is not authoritative.\n");        /* Set cp to point the A record.  */        cp = (u_char *)ns_rr_rdata(rr);		u_int32_t ip4Addr = ns_get32(cp);        struct in_addr  addr;		// convert ip4 @ to network byte ordering		addr.s_addr = htonl(ip4Addr);		string strAddr = inet_ntoa( addr );		rec->setAddress( strAddr ); 		rec->setPriority( DEFAULT_PRIO );        rec->setWeight( DEFAULT_WT );		rec->setTarget( myQName );        cpLog(LOG_DEBUG, "\nA Record host: %s, IP4 @: %d(%s), prio: %d, wt: %d\n" 						"Resource Record Type: %d\n"						"Record Class: %d\n"						"Resource Record Time To Live (ttl): %d\n",              myQName.c_str(), ip4Addr, strAddr.c_str(), rec->getPriority(),			  rec->getWeight(), ns_rr_type(rr), ns_rr_class(rr), 			  ns_rr_ttl(rr));        // insert record at end of vector        myVDns.push_back( rec );        // curious: what is the vector's capacity?        // cpLog(LOG_DEBUG, "Capacity of myVDns = %d", myVDns.capacity());    }    myNumDns = myVDns.size();	myReady = true;    cpLog(LOG_DEBUG, "Number of A records found = %d\n", myNumDns);}  // buildARecords()/// compare function used to sort the DNS SRV records://struct comp_srv : public binary_function< Sptr <DnsRecord>,                                          Sptr <DnsRecord>, bool >{    bool operator() (Sptr <DnsRecord> iRec1, Sptr <DnsRecord> iRec2)    {               return iRec1->getPriority() < iRec2->getPriority();    }};   // comp_srv()/** */void DnsResolver::sortByPreference( ){    cpLog( LOG_DEBUG, "\nsortByPreference():\n(orig order)");	if (myVDns.size() <= 1)    {       // no need to sort       return;	}    print(LOG_DEBUG_STACK);       sort(myVDns.begin(), myVDns.end(), comp_srv());	cpLog( LOG_DEBUG_STACK, "\n(new order):" );    print(LOG_DEBUG_STACK);}/**/// given the start and end indices of the svr vector, sort// the elements with that range by their weights in a // random process */void DnsResolver::sortByWeight( int startIdx, int endIdx ){    Sptr <DnsRecord> tRec;   // temporary    cpLog( LOG_DEBUG, "sortByWeight(): startIdx=%d, endIdx=%d",            startIdx,endIdx );	if (myVDns.size() <= 1)    {       // no need to sort       return;	}   int sumOfWeights = addWeights( startIdx,  endIdx );   if (sumOfWeights == 0)   {       cpLog( LOG_DEBUG,  "sum of weights is 0" );                return;    // nothing to sort   }   int j;   // calculate the sum of weights   for (int i = startIdx; i < endIdx; i++)   {       sumOfWeights = addWeights( i, endIdx );       // generate a random weight:       double randWeight = (double (rand() )/RAND_MAX) * sumOfWeights;       int curWeight  = 0;    // sum of weights so far       // traverse each element till the one before the last (endIdx),       // (if j == endIdx, no need to swap)       for (j = i; j <= endIdx; j++)       {           curWeight += myVDns[j]->getWeight();           if ( randWeight < curWeight )           {               // found element matching the random weight                        // if randWeight falls on the current start range, skip	           cpLog(LOG_DEBUG_STACK, "randWeight=%d, curWeight=%d, i=%d, j=%d",                     randWeight, curWeight, i, j );               break;           }       }       if (j > endIdx)       {           j = endIdx;   // make sure j is w/i range       }       // swap the selected element w/ the i-th element, this       // sorts the range       if (i != j)       {           tRec = myVDns[i];           myVDns[i] = myVDns[j];           myVDns[j] = tRec;       }       // compute sumOfWeights for i+1 through endIdx:       sumOfWeights -= myVDns[i]->getWeight();  // i th element will not be con-                                              // sidered in the next iteration   }}   // sortByWeight/** * */const u_char*DnsResolver::expandName(const u_char *cp, const u_char *msg,            char *name, int namelen){    cpLog( LOG_DEBUG, "expandName()" );    int n=dn_expand(msg, msg + MY_PACKETSZ, cp, name, namelen - 2);    if (n < 0)    {        return (0);    }    if (name[0] == '\0')    {        name[0] = '.';        name[1] = '\0';    }    return (cp + n);}   // expandName()/** *  find the range of srv records that shares the same priority: *  for A records, we fake the priority, default to 10 */intDnsResolver::findPriorityRange( int startIdx){    cpLog( LOG_INFO, "findPriorityRange()" );    int length = myVDns.size();    assert( startIdx < length );    int endIdx = startIdx+1;    int prio = myVDns[startIdx]->getPriority();    cpLog( LOG_DEBUG, "findPriorityRange(): prio=%d, startIdx=%d",           prio, startIdx );    while ((endIdx < length) &&(prio == myVDns[endIdx]->getPriority()))    {        endIdx++;    }    return endIdx-1;}   // findPriorityRange()/** calculate the total sum of the weights */int DnsResolver::addWeights( int startIdx, int endIdx ){        int sumOfWeights = 0;    for (int x = startIdx; x <= endIdx; x++)    {        sumOfWeights += myVDns[x]->getWeight();    }    return sumOfWeights;}   // addWeights()

⌨️ 快捷键说明

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