|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #if defined (HAVE_POPT_H) 00006 #include <popt.h> 00007 #else 00008 #ifndef WIN32 00009 #warning "will not work very well without libpopt" 00010 #endif 00011 #endif 00012 00013 #include <sys/types.h> 00014 #include <iostream> 00015 #include <memory> 00016 00017 #include <fstream> 00018 00019 #include "rutil/socket.hxx" 00020 #include "rutil/Data.hxx" 00021 #include "rutil/DnsUtil.hxx" 00022 #include "resip/stack/DnsInterface.hxx" 00023 #include "rutil/dns/QueryTypes.hxx" 00024 #include "rutil/dns/RROverlay.hxx" 00025 #include "rutil/dns/RRList.hxx" 00026 #include "rutil/dns/RRCache.hxx" 00027 #include "rutil/dns/DnsStub.hxx" 00028 00029 using namespace resip; 00030 using namespace std; 00031 00032 class MyDnsSink : public DnsResultSink 00033 { 00034 void onDnsResult(const DNSResult<DnsHostRecord>&); 00035 #ifdef USE_IPV6 00036 void onDnsResult(const DNSResult<DnsAAAARecord>&); 00037 #endif 00038 void onDnsResult(const DNSResult<DnsSrvRecord>&); 00039 void onDnsResult(const DNSResult<DnsNaptrRecord>&) {} 00040 void onDnsResult(const DNSResult<DnsCnameRecord>&); 00041 }; 00042 00043 void MyDnsSink::onDnsResult(const DNSResult<DnsHostRecord>& result) 00044 { 00045 cout << "A records" << endl; 00046 cout << "Status: " << result.status << endl; 00047 cout << "Domain: " << result.domain << endl; 00048 if (result.status == 0) 00049 { 00050 for (vector<DnsHostRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) 00051 { 00052 cout << (*it).host() << endl; 00053 } 00054 } 00055 cout << endl; 00056 } 00057 00058 void MyDnsSink::onDnsResult(const DNSResult<DnsCnameRecord>& result) 00059 { 00060 cout << "CNAME records" << endl; 00061 cout << "Status: " << result.status << endl; 00062 cout << "Domain: " << result.domain << endl; 00063 if (result.status == 0) 00064 { 00065 for (vector<DnsCnameRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) 00066 { 00067 cout << (*it).cname() << endl; 00068 } 00069 } 00070 cout << endl; 00071 } 00072 00073 void MyDnsSink::onDnsResult(const DNSResult<DnsSrvRecord>& result) 00074 { 00075 cout << "SRV records" << endl; 00076 cout << "Status: " << result.status << endl; 00077 cout << "Domain: " << result.domain << endl; 00078 if (result.status == 0) 00079 { 00080 for (vector<DnsSrvRecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) 00081 { 00082 cout << "Name: " << (*it).name() << endl; 00083 cout << "Priority: " << (*it).priority() << endl; 00084 cout << "Weight: " << (*it).weight() << endl; 00085 cout << "Port: " << (*it).port() << endl; 00086 cout << "Target: " << (*it).target() << endl; 00087 } 00088 } 00089 cout << endl; 00090 } 00091 00092 00093 // adopted from DnsUtil. 00094 const int NS_INT16SZ = 2; 00095 const int NS_INADDRSZ = 4; 00096 const int NS_IN6ADDRSZ = 16; 00097 00098 static const char* 00099 MyInet_ntop4(const u_char *src, char *dst, size_t size) 00100 { 00101 static const char fmt[] = "%u.%u.%u.%u"; 00102 #ifdef WIN32 00103 if ( _snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) < 0) 00104 #else 00105 if ( snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) < 0) 00106 #endif 00107 { 00108 errno = ENOSPC; 00109 dst[size-1] = 0; 00110 return NULL; 00111 } 00112 return (dst); 00113 } 00114 00115 static const char * 00116 MyInet_ntop6(const u_char *src, char *dst, size_t size) 00117 { 00118 /* 00119 * Note that int32_t and int16_t need only be "at least" large enough 00120 * to contain a value of the specified size. On some systems, like 00121 * Crays, there is no such thing as an integer variable with 16 bits. 00122 * Keep this in mind if you think this function should have been coded 00123 * to use pointer overlays. All the world's not a VAX. 00124 */ 00125 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 00126 struct { int base, len; } best, cur; 00127 u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; 00128 int i; 00129 00130 /* 00131 * Preprocess: 00132 * Copy the input (bytewise) array into a wordwise array. 00133 * Find the longest run of 0x00's in src[] for :: shorthanding. 00134 */ 00135 memset(words, '\0', sizeof words); 00136 for (i = 0; i < NS_IN6ADDRSZ; i++) 00137 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); 00138 best.base = -1; 00139 cur.base = -1; 00140 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 00141 if (words[i] == 0) { 00142 if (cur.base == -1) 00143 cur.base = i, cur.len = 1; 00144 else 00145 cur.len++; 00146 } else { 00147 if (cur.base != -1) { 00148 if (best.base == -1 || cur.len > best.len) 00149 best = cur; 00150 cur.base = -1; 00151 } 00152 } 00153 } 00154 if (cur.base != -1) { 00155 if (best.base == -1 || cur.len > best.len) 00156 best = cur; 00157 } 00158 if (best.base != -1 && best.len < 2) 00159 best.base = -1; 00160 00161 /* 00162 * Format the result. 00163 */ 00164 tp = tmp; 00165 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 00166 /* Are we inside the best run of 0x00's? */ 00167 if (best.base != -1 && i >= best.base && 00168 i < (best.base + best.len)) { 00169 if (i == best.base) 00170 *tp++ = ':'; 00171 continue; 00172 } 00173 /* Are we following an initial run of 0x00s or any real hex? */ 00174 if (i != 0) 00175 *tp++ = ':'; 00176 /* Is this address an encapsulated IPv4? */ 00177 if (i == 6 && best.base == 0 && 00178 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 00179 if (!MyInet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) 00180 return (NULL); 00181 tp += strlen(tp); 00182 break; 00183 } 00184 tp += sprintf(tp, "%x", words[i]); 00185 } 00186 /* Was it a trailing run of 0x00's? */ 00187 if (best.base != -1 && (best.base + best.len) == 00188 (NS_IN6ADDRSZ / NS_INT16SZ)) 00189 *tp++ = ':'; 00190 *tp++ = '\0'; 00191 00192 /* 00193 * Check for overflow, copy, and we're done. 00194 */ 00195 if ((size_t)(tp - tmp) > size) { 00196 errno = ENOSPC; 00197 return (NULL); 00198 } 00199 strcpy(dst, tmp); 00200 return (dst); 00201 } 00202 00203 #ifdef USE_IPV6 00204 void MyDnsSink::onDnsResult(const DNSResult<DnsAAAARecord>& result) 00205 { 00206 cout << "AAAA records" << endl; 00207 cout << "Status: " << result.status << endl; 00208 cout << "Domain: " << result.domain << endl; 00209 if (result.status == 0) 00210 { 00211 for (vector<DnsAAAARecord>::const_iterator it = result.records.begin(); it != result.records.end(); ++it) 00212 { 00213 char str[256]; 00214 cout << MyInet_ntop6((const u_char*)&(*it).v6Address(), str, sizeof(str)) << endl; 00215 } 00216 } 00217 cout << endl; 00218 } 00219 #endif 00220 00221 00222 // NOTE: In order to run this test, you need to uncomment out the USE_LOCAL_DNS define in 00223 // ExternalDnsFactory.cxx. 00224 main(int argc, char* argv[]) 00225 { 00226 { 00227 const char* const key = "yahoo.com"; 00228 MyDnsSink sink; 00229 DnsStub stub; 00230 DnsInterface dns(stub); 00231 stub.lookup<RR_A>(key, Protocol::Sip, &sink); 00232 } 00233 00234 { 00235 const char* const key = "_ldap._tcp.openldap.org"; 00236 MyDnsSink sink; 00237 DnsStub stub; 00238 DnsInterface dns(stub); 00239 stub.lookup<RR_SRV>(key, Protocol::Sip, &sink); 00240 } 00241 00242 { 00243 #ifdef USE_IPV6 00244 const char* const key = "quartz"; 00245 MyDnsSink sink; 00246 DnsStub stub; 00247 DnsInterface dns(stub); 00248 stub.lookup<RR_AAAA>(key, Protocol::Sip, &sink); 00249 #endif 00250 } 00251 00252 { 00253 const char* const key = "www.google.com"; 00254 MyDnsSink sink; 00255 DnsStub stub; 00256 DnsInterface dns(stub); 00257 stub.lookup<RR_CNAME>(key, Protocol::Sip, &sink); 00258 } 00259 00260 return 0; 00261 } 00262 /* ==================================================================== 00263 * The Vovida Software License, Version 1.0 00264 * 00265 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00266 * 00267 * Redistribution and use in source and binary forms, with or without 00268 * modification, are permitted provided that the following conditions 00269 * are met: 00270 * 00271 * 1. Redistributions of source code must retain the above copyright 00272 * notice, this list of conditions and the following disclaimer. 00273 * 00274 * 2. Redistributions in binary form must reproduce the above copyright 00275 * notice, this list of conditions and the following disclaimer in 00276 * the documentation and/or other materials provided with the 00277 * distribution. 00278 * 00279 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00280 * and "Vovida Open Communication Application Library (VOCAL)" must 00281 * not be used to endorse or promote products derived from this 00282 * software without prior written permission. For written 00283 * permission, please contact vocal@vovida.org. 00284 * 00285 * 4. Products derived from this software may not be called "VOCAL", nor 00286 * may "VOCAL" appear in their name, without prior written 00287 * permission of Vovida Networks, Inc. 00288 * 00289 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00290 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00291 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00292 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00293 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00294 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00295 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00296 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00297 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00298 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00299 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00300 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00301 * DAMAGE. 00302 * 00303 * ==================================================================== 00304 * 00305 * This software consists of voluntary contributions made by Vovida 00306 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00307 * Inc. For more information on Vovida Networks, Inc., please see 00308 * <http://www.vovida.org/>. 00309 * 00310 */ 00311
1.7.5.1