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

📄 dnsresult.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
         }
         else if (srv.key.find("_dtls") != Data::npos)
         {
            srv.transport = DTLS;
         }
         else if (srv.key.find("_tls") != Data::npos)
         {
            srv.transport = TLS;
         }
         else if (srv.key.find("_tcp") != Data::npos)
         {
            srv.transport = TCP;
         }
         else
         {
            StackLog (<< "Skipping SRV " << srv.key);
            continue;
         }
         mSRVResults.push_back(srv);
      }
   }
   else
   {
      StackLog (<< "SRV lookup failed: " << result.domain << " " << result.status);
   }

   // no outstanding queries 
   if (mSRVCount == 0) 
   {
      if (mSRVResults.empty())
      {
         if (mTransport == UNKNOWN_TRANSPORT)
         {
            if (mSips)
            {
               mTransport = TLS;
               mPort = Symbols::DefaultSipsPort;
            }
            else
            {
               mTransport = UDP;
               mPort = Symbols::DefaultSipPort;
            }
         }
         else
         {
            mPort = getDefaultPort(mTransport, 0);
         }
         
         StackLog (<< "No SRV records for " << mTarget << ". Trying A records");
         if (mInterface.isSupported(mTransport, V6) || mInterface.isSupported(mTransport, V4))
         {
            lookupHost(mTarget);
         }
         else
         {
            primeResults();
         }
      }
      else
      {
         std::sort(mSRVResults.begin(),mSRVResults.end()); // !jf! uggh
         primeResults();
      }
   }
}

void
DnsResult::onEnumResult(const DNSResult<DnsNaptrRecord>& result)
{
   mDoingEnum = false;
   
   if (result.status == 0)
   {
      static Data enumService1("e2u+sip");
      static Data enumService2("sip+e2u");

      DnsNaptrRecord best;
      best.order() = -1;

      for (vector<DnsNaptrRecord>::const_iterator i = result.records.begin(); i != result.records.end(); ++i)
      {
         InfoLog (<< "service=" << i->service()
                  << " order=" << i->order()
                  << " flags="  << i->flags() 
                  << " regexp substitution=" << i->regexp().replacement()
                  << " replacement=" << i->replacement());

         if ( (isEqualNoCase(i->service(), enumService1) ||
               isEqualNoCase(i->service(), enumService2) )  && // only E2U records
              //i->flags().find("u") != Data::npos && // must be terminal record
              i->replacement().empty() )
               
         {
            if (best.order() == -1)
            {
               best = *i;
            }
            else if (i->order() < best.order())
            {
               best = *i;
            }
            else if (i->order() == best.order() && 
                     i->preference() < best.preference())
            {
               best = *i;
            }
         }
      }
      
      if (best.order() != -1)
      {
         InfoLog (<< "Found an enum result: " << best.regexp().replacement());
         try
         {
            Uri rewrite(best.regexp().apply(Data::from(mInputUri)));
            InfoLog (<< "Rewrote uri " << mInputUri << " -> " << rewrite);
            mHandler->rewriteRequest(rewrite);
            lookupInternal(rewrite);
         }
         catch (ParseBuffer::Exception& /* e */)
         {
            lookupInternal(mInputUri);
         }
      }
      else
      {
         lookupInternal(mInputUri);
      }
   }
   else
   {
      lookupInternal(mInputUri);
   }
}

void
DnsResult::onNaptrResult(const DNSResult<DnsNaptrRecord>& result)
{
   bool bFail = false;
   if (result.status == 0)
   {
      for (vector<DnsNaptrRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it)
      {
         NAPTR naptr;
         naptr.key = (*it).name();
         naptr.flags = (*it).flags();
         naptr.order = (*it).order();
         naptr.pref = (*it).preference();
         naptr.regex = (*it).regexp();
         naptr.replacement = (*it).replacement();
         naptr.service = (*it).service();
         
         StackLog (<< "Adding NAPTR record: " << naptr);
         
         if ( mSips && naptr.service.find("SIPS") == 0)
         {
            if (mInterface.isSupported(naptr.service) && naptr < mPreferredNAPTR)
            {
               mPreferredNAPTR = naptr;
               StackLog (<< "Picked preferred: " << mPreferredNAPTR);
            }
         }
         else if (mInterface.isSupported(naptr.service) && naptr < mPreferredNAPTR)
         {
            mPreferredNAPTR = naptr;
            StackLog (<< "Picked preferred: " << mPreferredNAPTR);
         }
      }

      // This means that dns / NAPTR is misconfigured for this client 
      if (mPreferredNAPTR.key.empty())
      {
         StackLog (<< "There are no NAPTR records supported by this client so do an SRV lookup instead");
         bFail = true;
      }
      else
      {
         transition(Pending);
         Item item;
         item.domain = mPreferredNAPTR.key;
         item.rrType = T_NAPTR;
         item.value = mPreferredNAPTR.replacement;
         clearCurrPath();
         mCurrResultPath.push(item);
         mCurrSuccessPath.push(item);
         mSRVCount++;
         InfoLog (<< "Doing SRV lookup of " << mPreferredNAPTR.replacement);
         mDns.lookup<RR_SRV>(mPreferredNAPTR.replacement, Protocol::Sip, this);
      }
   }
   else
   {
      if (result.status > 6)
      {
         DebugLog (<< "NAPTR lookup failed: " << result.domain << " " << result.msg);
      }
      else
      {
         StackLog (<< "NAPTR lookup failed: " << result.domain << " " << result.msg);
      }
      bFail = true;
   }

   if (bFail)
   {

      if (mSips)
      {
         if (!mInterface.isSupportedProtocol(TLS))
         {
            transition(Finished);
            if (mHandler) mHandler->handle(this);
            return;
         }

         mSRVCount++;
         mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this);
         StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget);
      }
      else
      {
         if (mInterface.isSupportedProtocol(TLS))
         {
            mDns.lookup<RR_SRV>("_sips._tcp." + mTarget, Protocol::Sip, this);
            ++mSRVCount;
            StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget);
         }
         if (mInterface.isSupportedProtocol(DTLS))
         {
            mDns.lookup<RR_SRV>("_sips._udp." + mTarget, Protocol::Sip, this);
            ++mSRVCount;
            StackLog (<< "Doing SRV lookup of _sips._udp." << mTarget);
         }
         if (mInterface.isSupportedProtocol(TCP))
         {
            mDns.lookup<RR_SRV>("_sip._tcp." + mTarget, Protocol::Sip, this);
            ++mSRVCount;
            StackLog (<< "Doing SRV lookup of _sip._tcp." << mTarget);
         }
         if (mInterface.isSupportedProtocol(UDP))
         {
            mDns.lookup<RR_SRV>("_sip._udp." + mTarget, Protocol::Sip, this);
            ++mSRVCount;
            StackLog (<< "Doing SRV lookup of _sip._udp." << mTarget);
         }
      }
   }
}

void 
DnsResult::onDnsResult(const DNSResult<DnsNaptrRecord>& result)
{
   StackLog (<< "Received NAPTR result for: " << mInputUri << " target=" << mTarget);
   StackLog (<< "DnsResult::onDnsResult() " << result.status);

   // This function assumes that the NAPTR query that caused this
   // callback is the ONLY outstanding query that might cause
   // a callback into this object
   if (mType == Destroyed)
   {
      destroy();
      return;
   }

   if (mDoingEnum)
   {
      onEnumResult(result);
   }
   else
   {
      onNaptrResult(result);
   }
  
}

void DnsResult::onDnsResult(const DNSResult<DnsCnameRecord>& result)
{
}

void DnsResult::clearCurrPath()
{
   while (!mCurrResultPath.empty())
   {
      mCurrResultPath.pop();
   }

   while (!mCurrSuccessPath.empty())
   {
      mCurrSuccessPath.pop();
   }
}

void DnsResult::blacklistLastReturnedResult()
{
   assert(!mCurrResultPath.empty());
   Item top = mCurrResultPath.top();
   assert(top.rrType==T_A || top.rrType==T_AAAA);
   assert(top.domain==mLastReturnedResult.getTargetDomain());
   assert(top.value==Tuple::inet_ntop(mLastReturnedResult));
   vector<Data> records;
   records.push_back(top.value);
   DebugLog( << "Blacklisting " << top.domain << "(" << top.rrType << "): " << top.value);
   mDns.blacklist(top.domain, top.rrType, Protocol::Sip, records);
   DebugLog( << "Remove vip " << top.domain << "(" << top.rrType << ")");
   mVip.removeVip(top.domain, top.rrType);
   mCurrResultPath.pop();
}

void DnsResult::addToPath(const std::deque<Tuple>& results)
{
   assert(mCurrResultPath.size()<=2);
   for (std::deque<Tuple>::const_reverse_iterator it = results.rbegin(); it != results.rend(); ++it)
   {
      Item item;
      item.domain = (*it).getTargetDomain();
      item.rrType = (*it).isV4()? T_A : T_AAAA;
      item.value = Tuple::inet_ntop((*it));
      mCurrResultPath.push(item);
   }
}

std::ostream& 
resip::operator<<(std::ostream& strm, const resip::DnsResult& result)
{
   strm << result.mTarget << " --> " << Inserter(result.mResults);
   return strm;
}


std::ostream& 
resip::operator<<(std::ostream& strm, const resip::DnsResult::NAPTR& naptr)
{
   strm << "key=" << naptr.key
        << " order=" << naptr.order
        << " pref=" << naptr.pref
        << " flags=" << naptr.flags
        << " service=" << naptr.service
        << " regex=" << naptr.regex.regexp() << " -> " << naptr.regex.replacement()
        << " replacement=" << naptr.replacement;
   return strm;
}

std::ostream& 
resip::operator<<(std::ostream& strm, const resip::DnsResult::SRV& srv)
{
   strm << "key=" << srv.key
        << " t=" << Tuple::toData(srv.transport) 
        << " p=" << srv.priority
        << " w=" << srv.weight
        << " c=" << srv.cumulativeWeight
        << " port=" << srv.port
        << " target=" << srv.target;
   return strm;
}


//  Copyright (c) 2003, Jason Fischl 
/* ====================================================================
 * 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 $1,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/>.
 *
 */

⌨️ 快捷键说明

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