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

📄 dnsresult.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
   {      mDns.lookup<RR_A>(target, Protocol::Sip, this);   }   else   {      assert(0);   }}intDnsResult::getDefaultPort(TransportType transport, int port){   if (port == 0)   {      switch (transport)      {         case UDP:            return Symbols::DefaultSipPort;         case TCP:            return mSips ? Symbols::DefaultSipsPort : Symbols::DefaultSipPort;         case TLS:         case DTLS:            return Symbols::DefaultSipsPort;         default:            ErrLog( << "Should not get this - unknown transport" );            return Symbols::DefaultSipPort; // !cj! todo - remove             assert(0);      }   }   else   {      return port;   }	assert(0);	return 0;}voidDnsResult::primeResults(){   StackLog(<< "Priming " << Inserter(mSRVResults));   //assert(mType != Pending);   //assert(mType != Finished);   assert(mResults.empty());   if (!mSRVResults.empty())   {      SRV next = retrieveSRV();      StackLog (<< "Primed with SRV=" << next);      transition(Pending);      mPort = next.port;      mTransport = next.transport;      StackLog (<< "No A or AAAA record for " << next.target << " in additional records");      if (mInterface.isSupported(mTransport, V6) || mInterface.isSupported(mTransport, V4))      {         Item top;         while (!mCurrentPath.empty())         {            top = mCurrentPath.back();            if (top.rrType != T_NAPTR)            {               mCurrentPath.pop_back();            }            else            {               break;            }         }         top.domain = next.key;         top.rrType = T_SRV;         top.value = next.target + ":" + Data(next.port);         mCurrentPath.push_back(top);         lookupHost(next.target);      }      else      {         assert(0);         if (mHandler) mHandler->handle(this);      }      // don't call primeResults since we need to wait for the response to      // AAAA/A query first   }   else if(!mGreylistedTuples.empty())   {      for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i)      {         mResults.push_back(*i);      }      mGreylistedTuples.clear();      transition(Available);   }   else   {      bool changed = (mType == Pending);      transition(Finished);      if (changed && mHandler) mHandler->handle(this);   }   // Either we are finished or there are results primed}// implement the selection algorithm from rfc2782 (SRV records)DnsResult::SRV DnsResult::retrieveSRV(){    // !ah! if mTransport is known -- should we ignore those that don't match?!   assert(!mSRVResults.empty());   assert(mSRVCount==0);   const SRV& srv = *mSRVResults.begin();   int priority = srv.priority;   TransportType transport=UNKNOWN_TRANSPORT;      if(!mHaveChosenTransport)   {      // .bwc. We have not chosen a transport yet; this happens when we fail      // to find a NAPTR record, and the transport is not specified in the uri.      // In this contingency, we manufacture best-guess SRV queries for each      // transport we support, and try one transport at a time. This      // means we might try more than one transport for the uri in question.      transport = srv.transport;   }   else   {      // .bwc. We chose our transport before we started looking up SRVs.      // All SRVs must match.             transport=mTransport;      assert(mSRVResults.begin()->transport==transport);   }      if (mCumulativeWeight == 0)   {      for (std::vector<SRV>::iterator i=mSRVResults.begin();            i!=mSRVResults.end()               && i->priority == priority               && i->transport == transport; i++)      {         assert(i->weight>=0);         mCumulativeWeight += i->weight;      }   }      int selected =0;   if(mCumulativeWeight!=0)   {      selected = Random::getRandom() % (mCumulativeWeight);   }   else   {      // .bwc. All of the remaining SRVs (at this priority/type) have a weight      // of 0. The best we can do here is pick arbitrarily. In this case, we       // will end up picking the first.      // (selected will be less than the weight of the first SRV, causing the      // loop below to break on the first iteration)      selected=-1;   }      StackLog (<< "cumulative weight = " << mCumulativeWeight << " selected=" << selected);   std::vector<SRV>::iterator i;   int cumulativeWeight=0;   for (i=mSRVResults.begin(); i!=mSRVResults.end(); ++i)   {      cumulativeWeight+=i->weight;      if (cumulativeWeight > selected)      {         break;      }   }      if (i == mSRVResults.end())   {      InfoLog (<< "SRV Results problem selected=" << selected << " cum=" << mCumulativeWeight);   }   assert(i != mSRVResults.end());   SRV next = *i;   mCumulativeWeight -= next.weight;   mSRVResults.erase(i);      if(!mSRVResults.empty())   {      int nextPriority=mSRVResults.begin()->priority;      TransportType nextTransport=mSRVResults.begin()->transport;            // .bwc. If we have finished traversing a priority value/transport type,      // we reset the cumulative weight to 0, to prompt its recalculation.      if(priority!=nextPriority || transport!=nextTransport)      {         mCumulativeWeight=0;      }   }      StackLog (<< "SRV: " << Inserter(mSRVResults));   return next;}// adapted from the adig.c example in aresconst unsigned char* DnsResult::skipDNSQuestion(const unsigned char *aptr,                           const unsigned char *abuf,                           int alen){   char *name=0;   int status=0;   int len=0;      // Parse the question name.    status = ares_expand_name(aptr, abuf, alen, &name, &len);   if (status != ARES_SUCCESS)   {      StackLog (<< "Failed parse of RR");      return NULL;   }   aptr += len;   // Make sure there's enough data after the name for the fixed part   // of the question.   if (aptr + QFIXEDSZ > abuf + alen)   {      free(name);      StackLog (<< "Failed parse of RR");      return NULL;   }   // Parse the question type and class.    //int type = DNS_QUESTION_TYPE(aptr);   //int dnsclass = DNS_QUESTION_CLASS(aptr);   aptr += QFIXEDSZ;      free(name);   return aptr;}DnsResult::NAPTR::NAPTR() : order(0), pref(0){}bool DnsResult::NAPTR::operator<(const DnsResult::NAPTR& rhs) const{   if (key.empty()) // default value   {      return false;   }   else if (rhs.key.empty()) // default value   {      return true;   }   else if (order < rhs.order)   {      return true;   }   else if (order == rhs.order)   {      if (pref < rhs.pref)      {         return true;      }      else if (pref == rhs.pref)      {         return replacement < rhs.replacement;      }   }   return false;}DnsResult::SRV::SRV() : priority(0), weight(0), port(0){}bool DnsResult::SRV::operator<(const DnsResult::SRV& rhs) const{   if (transport < rhs.transport)   {      return true;   }   else if (transport == rhs.transport)   {      if (priority < rhs.priority)      {         return true;      }      else if (priority == rhs.priority)      {         if (weight < rhs.weight)         {            return true;         }         else if (weight == rhs.weight)         {            if (target < rhs.target)            {               return true;            }         }      }   }   return false;}void DnsResult::onDnsResult(const DNSResult<DnsHostRecord>& result){   if (!mInterface.isSupported(mTransport, V4) && !mInterface.isSupported(mTransport, V6))   {      return;   }   StackLog (<< "Received dns result for: " << mTarget);   StackLog (<< "DnsResult::onDnsResult() " << result.status);      // This function assumes that the A query that caused this callback   // is the _only_ outstanding DNS query that might result in a   // callback into this function   if ( mType == Destroyed )   {      destroy();      return;   }   if (result.status == 0)   {      for (vector<DnsHostRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it)      {         in_addr addr;         addr.s_addr = (*it).addr().s_addr;         Tuple tuple(addr, mPort, mTransport, mTarget);                  switch(mInterface.getMarkManager().getMarkType(tuple))         {            case TupleMarkManager::OK:               StackLog (<< "Adding " << tuple << " to result set");               mResults.push_back(tuple);               break;            case TupleMarkManager::GREY:               StackLog(<< "Adding greylisted tuple " << tuple);               mGreylistedTuples.push_back(tuple);               break;            case TupleMarkManager::BLACK:            default:               ;// .bwc. Do nothing.         }            }         }   else   {      StackLog (<< "Failed async A query: " << result.msg);   }   if (mSRVCount == 0)   {      bool changed = (mType == Pending);      if (mResults.empty())      {#ifdef WIN32_SYNCRONOUS_RESOLUTION_ON_ARES_FAILURE         // Try Windows Name Resolution (not asyncronous)         WSAQUERYSET QuerySet = { 0 };	     GUID guidServiceTypeUDP = SVCID_UDP(mPort);	     GUID guidServiceTypeTCP = SVCID_TCP(mPort);         HANDLE hQuery;         QuerySet.dwSize = sizeof(WSAQUERYSET);         QuerySet.lpServiceClassId = mTransport == UDP ? &guidServiceTypeUDP : &guidServiceTypeTCP;         QuerySet.dwNameSpace = NS_ALL;         QuerySet.lpszServiceInstanceName = (char *)mTarget.c_str();         if(WSALookupServiceBegin(&QuerySet, LUP_RETURN_ADDR, &hQuery) == 0)         {             DWORD dwQuerySize = 256;   // Starting size             int iRet = 0;             bool fDone = false;             LPWSAQUERYSET pQueryResult = (LPWSAQUERYSET) new char[dwQuerySize];             while(iRet == 0 && pQueryResult)             {                iRet = WSALookupServiceNext(hQuery, 0, &dwQuerySize, pQueryResult);                if(pQueryResult && iRet == -1 && GetLastError() == WSAEFAULT)                {                   delete [] pQueryResult;                   pQueryResult = (LPWSAQUERYSET) new char[dwQuerySize]; // Re-allocate new size                   iRet = WSALookupServiceNext(hQuery, 0, &dwQuerySize, pQueryResult);                }                if(pQueryResult && iRet == 0)                {                   for(DWORD i = 0; i < pQueryResult->dwNumberOfCsAddrs; i++)                   {     	              SOCKADDR_IN *pSockAddrIn = (SOCKADDR_IN *)pQueryResult->lpcsaBuffer[i].RemoteAddr.lpSockaddr;                      Tuple tuple(pSockAddrIn->sin_addr, mPort, mTransport, mTarget);                                            if(mInterface.getMarkManager().getMarkType(tuple)!=TupleMarkManager::BLACK)                      {                        // .bwc. This is the only result we have, so it doesn't                        // matter if it is greylisted.                        StackLog (<< "Adding (WIN) " << tuple << " to result set");                        mResults.push_back(tuple);                        transition(Available);                      }                                      }                }             }             delete [] pQueryResult;             WSALookupServiceEnd(hQuery);         }                  if(mResults.empty())         {            if(mSRVResults.empty())            {               if (mGreylistedTuples.empty())               {                  transition(Finished);                  clearCurrPath();               }               else               {                  for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i)                  {                     mResults.push_back(*i);                  }                  mGreylistedTuples.clear();                  transition(Available);               }            }            else            {               transition(Available);            }         }#else         // .bwc. If this A query failed, don't give up if there are more SRVs!         if(mSRVResults.empty())         {            if (mGreylistedTuples.empty())            {               transition(Finished);               clearCurrPath();            }            else            {               for(std::vector<Tuple>::iterator i = mGreylistedTuples.begin(); i != mGreylistedTuples.end(); ++i)               {                  mResults.push_back(*i);               }               mGreylistedTuples.clear();               transition(Available);            }         }         else         {            transition(Available);         }#endif      }      else       {         transition(Available);      }      if (changed && mHandler) mHandler->handle(this);   }}#ifdef USE_IPV6void DnsResult::onDnsResult(const DNSResult<DnsAAAARecord>& result){   StackLog (<< "Received AAAA result for: " << mTarget);   if (!mInterface.isSupported(mTransport, V6))   {      return;   }   StackLog (<< "DnsResult::onDnsResult() " << result.status);   assert(mInterface.isSupported(mTransport, V6));   // This function assumes that the AAAA query that caused this callback

⌨️ 快捷键说明

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