|
reSIProcate/rutil
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include <vector> 00006 #include <list> 00007 00008 #include "ares.h" 00009 #ifdef WIN32 00010 #undef write // Note: ares.h defines write to be _write for WIN32 - we don't want that here, since we use fdset.write and stream write 00011 #endif 00012 00013 #ifndef WIN32 00014 #ifndef __CYGWIN__ 00015 #include <arpa/nameser.h> 00016 #endif 00017 #endif 00018 00019 #include "rutil/Logger.hxx" 00020 #include "rutil/compat.hxx" 00021 #include "rutil/BaseException.hxx" 00022 #include "rutil/Timer.hxx" 00023 #include "rutil/DnsUtil.hxx" 00024 #include "rutil/dns/DnsResourceRecord.hxx" 00025 #include "rutil/dns/DnsHostRecord.hxx" 00026 #include "rutil/dns/RRFactory.hxx" 00027 #include "rutil/dns/RRList.hxx" 00028 #include "rutil/dns/DnsAAAARecord.hxx" 00029 #include "rutil/dns/DnsHostRecord.hxx" 00030 #include "rutil/dns/DnsNaptrRecord.hxx" 00031 #include "rutil/dns/DnsSrvRecord.hxx" 00032 #include "rutil/dns/DnsCnameRecord.hxx" 00033 00034 using namespace resip; 00035 using namespace std; 00036 00037 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS 00038 00039 RRList::RRList() : mRRType(0), mStatus(0), mAbsoluteExpiry(ULONG_MAX) {} 00040 00041 RRList::RRList(const Data& key, 00042 const int rrtype, 00043 int ttl, 00044 int status) 00045 : mKey(key), mRRType(rrtype), mStatus(status) 00046 { 00047 mAbsoluteExpiry = ttl + Timer::getTimeSecs(); 00048 } 00049 00050 RRList::RRList(const DnsHostRecord &record, int ttl) 00051 : mKey(record.name()), mRRType(T_A), mStatus(0), mAbsoluteExpiry(ULONG_MAX) 00052 { 00053 update(record, ttl); 00054 } 00055 00056 void RRList::update(const DnsHostRecord &record, int ttl) 00057 { 00058 this->clear(); 00059 00060 RecordItem item; 00061 item.record = new DnsHostRecord(record); 00062 mRecords.push_back(item); 00063 mAbsoluteExpiry = Timer::getTimeSecs() + ttl; 00064 } 00065 00066 RRList::RRList(const Data& key, int rrtype) 00067 : mKey(key), mRRType(rrtype), mStatus(0), mAbsoluteExpiry(ULONG_MAX) 00068 {} 00069 00070 RRList::~RRList() 00071 { 00072 this->clear(); 00073 } 00074 00075 RRList::RRList(const RRFactoryBase* factory, 00076 const Data& key, 00077 const int rrType, 00078 Itr begin, 00079 Itr end, 00080 int ttl) 00081 : mKey(key), mRRType(rrType), mStatus(0) 00082 { 00083 update(factory, begin, end, ttl); 00084 } 00085 00086 void RRList::update(const RRFactoryBase* factory, Itr begin, Itr end, int ttl) 00087 { 00088 this->clear(); 00089 mAbsoluteExpiry = ULONG_MAX; 00090 00091 for (Itr it = begin; it != end; it++) 00092 { 00093 try 00094 { 00095 RecordItem item; 00096 item.record = factory->create(*it); 00097 mRecords.push_back(item); 00098 if ((UInt64)it->ttl() < mAbsoluteExpiry) 00099 { 00100 mAbsoluteExpiry = it->ttl(); 00101 } 00102 } 00103 catch (BaseException& e) 00104 { 00105 ErrLog(<< e.getMessage() << endl); 00106 } 00107 } 00108 00109 if (mAbsoluteExpiry < (UInt64)ttl) 00110 { 00111 mAbsoluteExpiry = ttl; 00112 } 00113 00114 mAbsoluteExpiry += Timer::getTimeSecs(); 00115 } 00116 00117 RRList::Records RRList::records(const int protocol) 00118 { 00119 Records records; 00120 if (mRecords.empty()) return records; 00121 00122 for (std::vector<RecordItem>::iterator it = mRecords.begin(); it != mRecords.end(); ++it) 00123 { 00124 records.push_back((*it).record); 00125 } 00126 return records; 00127 } 00128 00129 RRList::RecordItr RRList::find(const Data& value) 00130 { 00131 for (RecordItr it = mRecords.begin(); it != mRecords.end(); ++it) 00132 { 00133 if ((*it).record->isSameValue(value)) 00134 { 00135 return it; 00136 } 00137 } 00138 return mRecords.end(); 00139 } 00140 00141 void RRList::clear() 00142 { 00143 for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) 00144 { 00145 delete (*it).record; 00146 } 00147 mRecords.clear(); 00148 } 00149 00150 EncodeStream& 00151 RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) 00152 { 00153 strm << "DNSCACHE: Type="; 00154 00155 switch(mRRType) 00156 { 00157 case T_CNAME: 00158 { 00159 DnsCnameRecord* record = dynamic_cast<DnsCnameRecord*>(item.record); 00160 assert(record); 00161 strm << "CNAME: " << record->name() << " -> " << record->cname(); 00162 break; 00163 } 00164 00165 case T_NAPTR: 00166 { 00167 DnsNaptrRecord* record = dynamic_cast<DnsNaptrRecord*>(item.record); 00168 assert(record); 00169 strm << "NAPTR: " << record->name() << " -> repl=" << record->replacement() << " service=" << record->service() 00170 << " order=" << record->order() << " pref=" << record->preference() << " flags=" << record->flags() 00171 << " regexp=" << record->regexp().regexp(); 00172 break; 00173 } 00174 00175 case T_SRV: 00176 { 00177 DnsSrvRecord* record = dynamic_cast<DnsSrvRecord*>(item.record); 00178 assert(record); 00179 strm << "SRV: " << record->name() << " -> " << record->target() << ":" << record->port() 00180 << " priority=" << record->priority() << " weight=" << record->weight(); 00181 break; 00182 } 00183 00184 #ifdef USE_IPV6 00185 case T_AAAA: 00186 { 00187 DnsAAAARecord* record = dynamic_cast<DnsAAAARecord*>(item.record); 00188 assert(record); 00189 strm << "AAAA(Host): " << record->name() << " -> " << DnsUtil::inet_ntop(record->v6Address()); 00190 break; 00191 } 00192 #endif 00193 00194 case T_A: 00195 { 00196 DnsHostRecord* record = dynamic_cast<DnsHostRecord*>(item.record); 00197 assert(record); 00198 strm << "A(Host): " << record->name() << " -> " << record->host(); 00199 break; 00200 } 00201 default: 00202 strm << "UNKNOWN(" << mRRType << ")" << " key=" << mKey << " name=" << item.record->name(); 00203 break; 00204 } 00205 00206 strm << " secsToExpirey=" << (mAbsoluteExpiry - Timer::getTimeSecs()) << " status=" << mStatus; 00207 strm.flush(); 00208 return strm; 00209 } 00210 00211 void RRList::log() 00212 { 00213 for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) 00214 { 00215 Data buffer; 00216 DataStream strm(buffer); 00217 00218 encodeRecordItem(*it, strm); 00219 WarningLog( << buffer); 00220 } 00221 } 00222 00223 EncodeStream& 00224 RRList:: encodeRRList(EncodeStream& strm) 00225 { 00226 for (RecordArr::iterator it = mRecords.begin(); it != mRecords.end(); ++it) 00227 { 00228 encodeRecordItem(*it, strm); 00229 strm << endl; 00230 } 00231 return strm; 00232 } 00233 00234 00235 /* ==================================================================== 00236 * The Vovida Software License, Version 1.0 00237 * 00238 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00239 * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. 00240 * 00241 * Redistribution and use in source and binary forms, with or without 00242 * modification, are permitted provided that the following conditions 00243 * are met: 00244 * 00245 * 1. Redistributions of source code must retain the above copyright 00246 * notice, this list of conditions and the following disclaimer. 00247 * 00248 * 2. Redistributions in binary form must reproduce the above copyright 00249 * notice, this list of conditions and the following disclaimer in 00250 * the documentation and/or other materials provided with the 00251 * distribution. 00252 * 00253 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00254 * and "Vovida Open Communication Application Library (VOCAL)" must 00255 * not be used to endorse or promote products derived from this 00256 * software without prior written permission. For written 00257 * permission, please contact vocal@vovida.org. 00258 * 00259 * 4. Products derived from this software may not be called "VOCAL", nor 00260 * may "VOCAL" appear in their name, without prior written 00261 * permission of Vovida Networks, Inc. 00262 * 00263 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00264 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00265 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00266 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00267 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00268 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00269 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00270 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00271 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00272 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00273 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00274 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00275 * DAMAGE. 00276 * 00277 * ==================================================================== 00278 * 00279 * This software consists of voluntary contributions made by Vovida 00280 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00281 * Inc. For more information on Vovida Networks, Inc., please see 00282 * <http://www.vovida.org/>. 00283 * 00284 */
1.7.5.1