|
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 <iostream> 00014 #include <iomanip> 00015 #include <list> 00016 00017 #include "rutil/Lock.hxx" 00018 #include "rutil/Mutex.hxx" 00019 #include "rutil/Socket.hxx" 00020 #include "rutil/Logger.hxx" 00021 #include "rutil/ThreadIf.hxx" 00022 #include "rutil/ParseBuffer.hxx" 00023 #include "rutil/DnsUtil.hxx" 00024 #include "resip/stack/DnsInterface.hxx" 00025 #include "resip/stack/DnsResult.hxx" 00026 #include "resip/stack/SipStack.hxx" 00027 #include "resip/stack/TupleMarkManager.hxx" 00028 #include "resip/stack/MarkListener.hxx" 00029 #include "rutil/dns/RRVip.hxx" 00030 #include "rutil/dns/DnsStub.hxx" 00031 #include "rutil/dns/DnsHandler.hxx" 00032 00033 #include "resip/stack/test/tassert.h" 00034 using namespace std; 00035 00036 00037 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST 00038 00039 const char bf[] = "\033[01;34m"; 00040 const char gf[] = "\033[01;32m"; 00041 const char rf[] = "\033[01;31m"; 00042 const char ub[] = "\033[01;00m"; 00043 00044 #ifdef WIN32 00045 #define usleep(x) Sleep(x/1000) 00046 #define sleep(x) Sleep(x*1000) 00047 #endif 00048 00049 namespace resip 00050 { 00051 00052 // called on the DNS processing thread, therefore state must be locked 00053 class TestDnsHandler : public DnsHandler 00054 { 00055 public: 00056 TestDnsHandler() 00057 : mComplete(false), 00058 mCheckExpectedResults(false), 00059 mPermutationNumber(0) 00060 {} 00061 00062 TestDnsHandler(const std::vector<Tuple>& expectedResults, 00063 const resip::Uri& uri) 00064 : mComplete(false), 00065 mExpectedResults(expectedResults), 00066 mCheckExpectedResults(true), 00067 mUri(uri), 00068 mPermutationNumber(0) 00069 {} 00070 00071 TestDnsHandler(const std::vector<Tuple>& expectedResults, 00072 const std::set<Tuple>& resultsToBlacklist, 00073 const std::set<Tuple>& resultsToGreylist, 00074 const resip::Uri& uri) 00075 : mComplete(false), 00076 mExpectedResults(expectedResults), 00077 mCheckExpectedResults(true), 00078 mUri(uri), 00079 mPermutationNumber(0), 00080 mResultsToBlacklist(resultsToBlacklist), 00081 mResultsToGreylist(resultsToGreylist) 00082 {} 00083 00084 void handle(DnsResult* result) 00085 { 00086 00087 std::cout << gf << "DnsHandler received " << result->target() << ub << std::endl; 00088 Lock lock(mutex); 00089 DnsResult::Type type; 00090 while ((type=result->available()) == DnsResult::Available) 00091 { 00092 Tuple tuple = result->next(); 00093 results.push_back(tuple); 00094 resipCout << gf << result->target() << " -> " << tuple << ub << std::endl; 00095 if(mResultsToGreylist.count(tuple)!=0) 00096 { 00097 result->greylistLast(Timer::getTimeMs()+15000); 00098 } 00099 00100 if(mResultsToBlacklist.count(tuple)!=0) 00101 { 00102 result->blacklistLast(Timer::getTimeMs()+15000); 00103 } 00104 } 00105 if (type != DnsResult::Pending) 00106 { 00107 mComplete = true; 00108 if(mCheckExpectedResults) 00109 { 00110 checkExpectedResults(); 00111 } 00112 } 00113 } 00114 00115 void rewriteRequest(const Uri& rewrite) 00116 { 00117 std::cout << "Rewriting uri (enum) to " << rewrite << std::endl; 00118 } 00119 00120 00121 bool complete() 00122 { 00123 Lock lock(mutex); 00124 return mComplete; 00125 } 00126 00127 void checkExpectedResults() 00128 { 00129 std::cout << "Input Uri was " << mUri << endl; 00130 tassert(mExpectedResults.size() == results.size()); 00131 tassert_reset(); 00132 std::cout << "Expected " << mExpectedResults.size() << ", got " << results.size() << endl; 00133 std::vector<Tuple>::const_iterator e; 00134 std::vector<Tuple>::const_iterator o; 00135 00136 for(e=mExpectedResults.begin();e!=mExpectedResults.end();++e) 00137 { 00138 int p=0; 00139 resipCout << "Looking for " << *e << endl; 00140 bool found=false; 00141 for(o=results.begin();(o!=results.end() && !found);++o) 00142 { 00143 ++p; 00144 if(*e==*o) 00145 { 00146 found=true; 00147 resipCout << *o << " matched!" << endl; 00148 mPermutation.push_back(p); 00149 } 00150 else 00151 { 00152 resipCout << *o << " didn't match." << endl; 00153 } 00154 } 00155 00156 tassert(found); 00157 tassert_reset(); 00158 } 00159 } 00160 00161 int getPermutationNumber() 00162 { 00163 if(mPermutationNumber!=0) 00164 { 00165 return mPermutationNumber; 00166 } 00167 00168 int result=1; 00169 00170 // .bwc. Please forgive me for my use of permutation-group-foo. 00171 for(int i=mPermutation.size();i>0;--i) 00172 { 00173 int foundAt=0; 00174 for(std::list<int>::iterator j=mPermutation.begin();j!=mPermutation.end();++j) 00175 { 00176 ++foundAt; 00177 if(*j==i) 00178 { 00179 result*=((foundAt-i)%i+1); 00180 mPermutation.erase(j); 00181 j=mPermutation.end(); 00182 } 00183 } 00184 } 00185 00186 mPermutationNumber=result; 00187 return result; 00188 } 00189 00190 std::vector<Tuple> results; 00191 00192 private: 00193 bool mComplete; 00194 std::vector<Tuple> mExpectedResults; 00195 bool mCheckExpectedResults; 00196 Mutex mutex; 00197 Uri mUri; 00198 std::list<int> mPermutation; 00199 int mPermutationNumber; 00200 std::set<resip::Tuple> mResultsToBlacklist; 00201 std::set<resip::Tuple> mResultsToGreylist; 00202 }; 00203 00204 /* 00205 class VipListener : public RRVip::Listener 00206 { 00207 void onVipInvalidated(int rrType, const Data& vip) const 00208 { 00209 cout << rf << "VIP " << " -> " << vip << " type" << " -> " << rrType << " has been invalidated." << ub << endl; 00210 } 00211 }; 00212 */ 00213 00214 class TestMarkListener : public MarkListener 00215 { 00216 public: 00217 TestMarkListener(const resip::Tuple& listenFor) 00218 : mTuple(listenFor), 00219 mGotOkCallback(false), 00220 mGotGreylistCallback(false), 00221 mGotBlacklistCallback(false) 00222 {} 00223 virtual ~TestMarkListener(){} 00224 00225 virtual void onMark(const Tuple& tuple, UInt64& expiry, TupleMarkManager::MarkType& mark) 00226 { 00227 if(mTuple == tuple) 00228 { 00229 switch(mark) 00230 { 00231 case TupleMarkManager::OK: 00232 mGotOkCallback=true; 00233 break; 00234 case TupleMarkManager::GREY: 00235 mGotGreylistCallback=true; 00236 break; 00237 case TupleMarkManager::BLACK: 00238 mGotBlacklistCallback=true; 00239 break; 00240 default: 00241 ; 00242 } 00243 } 00244 } 00245 00246 bool gotOkCallback() const {return mGotOkCallback;} 00247 bool gotGreylistCallback() const {return mGotGreylistCallback;} 00248 bool gotBlacklistCallback() const {return mGotBlacklistCallback;} 00249 00250 void resetAll() 00251 { 00252 mGotOkCallback=false; 00253 mGotGreylistCallback=false; 00254 mGotBlacklistCallback=false; 00255 } 00256 private: 00257 Tuple mTuple; 00258 bool mGotOkCallback; 00259 bool mGotGreylistCallback; 00260 bool mGotBlacklistCallback; 00261 00262 }; 00263 00264 class TestDns : public DnsInterface, public ThreadIf 00265 { 00266 public: 00267 TestDns(DnsStub& stub) : DnsInterface(stub), mStub(stub) 00268 { 00269 addTransportType(TCP, V4); 00270 addTransportType(UDP, V4); 00271 addTransportType(TLS, V4); 00272 #ifdef USE_IPV6 00273 addTransportType(TCP, V6); 00274 addTransportType(UDP, V6); 00275 addTransportType(TLS, V6); 00276 #endif 00277 } 00278 00279 void thread() 00280 { 00281 while (!waitForShutdown(100)) 00282 { 00283 FdSet fdset; 00284 mStub.buildFdSet(fdset); 00285 fdset.selectMilliSeconds(mStub.getTimeTillNextProcessMS()); 00286 mStub.process(fdset); 00287 } 00288 } 00289 00290 DnsStub& mStub; 00291 }; 00292 00293 } 00294 00295 using namespace resip; 00296 00297 typedef struct 00298 { 00299 DnsResult* result; 00300 Uri uri; 00301 TestDnsHandler* handler; 00302 //VipListener* listener; 00303 } Query; 00304 00305 int 00306 main(int argc, const char** argv) 00307 { 00308 const char* logType = "cout"; 00309 const char* logLevel = "STACK"; 00310 const char* enumSuffix = "e164.arpa"; 00311 00312 #if defined(HAVE_POPT_H) 00313 struct poptOption table[] = { 00314 {"log-type", 'l', POPT_ARG_STRING, &logType, 0, "where to send logging messages", "syslog|cerr|cout"}, 00315 {"log-level", 'v', POPT_ARG_STRING, &logLevel, 0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"}, 00316 {"enum-suffix", 'e', POPT_ARG_STRING, &enumSuffix, 0, "specify what enum domain to search in", "e164.arpa"}, 00317 POPT_AUTOHELP 00318 { NULL, 0, 0, NULL, 0 } 00319 }; 00320 00321 poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0); 00322 poptGetNextOpt(context); 00323 #endif 00324 00325 Log::initialize(logType, logLevel, argv[0]); 00326 initNetwork(); 00327 DnsStub* stub = new DnsStub; 00328 TestDns dns(*stub); 00329 dns.run(); 00330 cerr << "Starting" << endl; 00331 std::list<Query> queries; 00332 #if defined(HAVE_POPT_H) 00333 const char** args = poptGetArgs(context); 00334 #else 00335 const char** args = argv; 00336 #endif 00337 00338 std::vector<Data> enumSuffixes; 00339 enumSuffixes.push_back(enumSuffix); 00340 stub->setEnumSuffixes(enumSuffixes); 00341 00342 resip::Data uris[16]={ 00343 "sip:127.0.0.1:5070;transport=udp", 00344 "sips:127.0.0.1:5071;transport=tls", 00345 "sip:127.0.0.1;transport=udp", 00346 "sips:127.0.0.1;transport=tls", 00347 "sip:user.test.resiprocate.org:5070;transport=udp", 00348 "sips:user.test.resiprocate.org:5071;transport=tls", 00349 "sip:user.test.resiprocate.org;transport=udp", 00350 "sips:user.test.resiprocate.org;transport=tls", 00351 "sip:127.0.0.1:5070", 00352 "sips:127.0.0.1:5071", 00353 "sip:127.0.0.1", 00354 "sips:127.0.0.1", 00355 "sip:user.test.resiprocate.org:5070", 00356 "sips:user.test.resiprocate.org:5071", 00357 "sip:user-tcp.test.resiprocate.org", 00358 "sips:user-tcp.test.resiprocate.org" 00359 }; 00360 00361 00362 int expectedPorts[16][3]={ 00363 {5070,0,0}, 00364 {5071,0,0}, 00365 {5060,0,0}, 00366 {5061,0,0}, 00367 {5070,0,0}, 00368 {5071,0,0}, 00369 {5060,5070,5080}, 00370 {5061,5071,5081}, 00371 {5070,0,0}, 00372 {5071,0,0}, 00373 {5060,0,0}, 00374 {5061,0,0}, 00375 {5070,0,0}, 00376 {5071,0,0}, 00377 {5060,5070,5080}, 00378 {5061,5071,5081} 00379 }; 00380 00381 TransportType expectedTransports[16][3]={ 00382 {UDP,UDP,UDP}, 00383 {TLS,TLS,TLS}, 00384 {UDP, UDP, UDP}, 00385 {TLS,TLS,TLS}, 00386 {UDP, UDP, UDP}, 00387 {TLS,TLS,TLS}, 00388 {UDP, UDP, UDP}, 00389 {TLS,TLS,TLS}, 00390 {UDP, UDP, UDP}, 00391 {TLS,TLS,TLS}, 00392 {UDP, UDP, UDP}, 00393 {TLS,TLS,TLS}, 00394 {UDP, UDP, UDP}, 00395 {TLS,TLS,TLS}, 00396 {TCP, TCP, TCP}, 00397 {TLS,TLS,TLS} 00398 }; 00399 00400 resip::Data subUris[8]={ 00401 "sip:<hostname>:5080;transport=TCP", 00402 "sips:<hostname>:5081;transport=TLS", 00403 "sip:<hostname>;transport=TCP", 00404 "sips:<hostname>;transport=TLS", 00405 "sip:<hostname>:5080", 00406 "sips:<hostname>:5081", 00407 "sip:<hostname>", 00408 "sips:<hostname>" 00409 }; 00410 00411 resip::Data ipAddr("127.0.0.1"); 00412 00413 Uri uri; 00414 00415 for(int i=0; i< 16;++i) 00416 { 00417 Query query; 00418 std::vector<Tuple> expected; 00419 00420 for(int j=0;j<3;++j) 00421 { 00422 if(expectedPorts[i][j]==0) 00423 { 00424 break; 00425 } 00426 00427 expected.push_back(Tuple(ipAddr,expectedPorts[i][j],V4,expectedTransports[i][j])); 00428 } 00429 00430 00431 //query.listener = new VipListener; 00432 cerr << "Creating Uri " << uris[i] << endl; 00433 uri = Uri(uris[i]); 00434 00435 query.handler = new TestDnsHandler(expected,uri); 00436 00437 query.uri = uri; 00438 cerr << "Creating DnsResult" << endl; 00439 DnsResult* res = dns.createDnsResult(query.handler); 00440 query.result = res; 00441 queries.push_back(query); 00442 cerr << rf << "Looking up" << ub << endl; 00443 00444 dns.lookup(res, uri); 00445 } 00446 00447 resip::Data NAPTRstrings[3]={ 00448 "", 00449 "-brokenNAPTR", 00450 "-noNAPTR" 00451 }; 00452 00453 resip::Data SRVstrings[3]={ 00454 "", 00455 "-brokenSRV", 00456 "-noSRV" 00457 }; 00458 00459 00460 for(int i=0;i<8;++i) 00461 { 00462 00463 00464 for(int n=0;n<3;++n) 00465 { 00466 for(int s=0;s<3;++s) 00467 { 00468 if(n==0 && s==0) 00469 { 00470 // .bwc. This is just user.test.resiprocate.org, which we have already done. 00471 continue; 00472 } 00473 00474 if(n==1 && s==2) 00475 { 00476 // .bwc. broken NAPTR and missing SRV is equivalent to OK NAPTR 00477 // and missing SRV (n==0 and s==2). The former is not provisioned 00478 // in the DNS zone, but the latter is, so we have already taken 00479 // care of this case. 00480 continue; 00481 } 00482 00483 00484 resip::Data hostname(resip::Data("user")+NAPTRstrings[n]+SRVstrings[s]+resip::Data(".test.resiprocate.org")); 00485 resip::Data target=subUris[i]; 00486 target.replace("<hostname>",hostname); 00487 00488 //query.listener = new VipListener; 00489 cerr << "Creating Uri " << target << endl; 00490 uri = Uri(target); 00491 unsigned int port=0; 00492 TransportType type=UNKNOWN_TRANSPORT; 00493 00494 // .bwc. Choose expected destination. 00495 if(uri.exists(p_transport)) 00496 { 00497 // .bwc. Transport is explicitly specified; no NAPTR query 00498 // will be made. State of NAPTR is irrelevant. 00499 00500 if(uri.port()!=0) 00501 { 00502 // .bwc. Port is explicitly specified. No SRV query will 00503 // be made. This will be a bare A record lookup. 00504 port=uri.port(); 00505 type=toTransportType(uri.param(p_transport)); 00506 if(uri.scheme()=="sips" && type!=TLS) 00507 { 00508 // What is the resolver supposed to do in this case? 00509 assert(0); 00510 } 00511 } 00512 else 00513 { 00514 // .bwc. Port is not explicitly specified. SRV query will 00515 // be attempted. 00516 00517 if(s==0) 00518 { 00519 // SRV ok. Will land on 127.0.0.1:507[01] on specified 00520 // transport. 00521 type=toTransportType(uri.param(p_transport)); 00522 if(type==TLS) 00523 { 00524 port=5071; 00525 } 00526 else 00527 { 00528 port=5070; 00529 } 00530 } 00531 else if(s==1) 00532 { 00533 // SRV broken. (Exists, so will be followed into space) 00534 // Leave port as 0, since no results will come of this. 00535 } 00536 else 00537 { 00538 // SRV missing. DNS fill fail over to A record lookup. 00539 type=toTransportType(uri.param(p_transport)); 00540 if(type==TLS) 00541 { 00542 port=5061; 00543 } 00544 else 00545 { 00546 port=5060; 00547 } 00548 } 00549 } 00550 } 00551 else 00552 { 00553 // transport is not specified 00554 00555 if(uri.port()!=0) 00556 { 00557 // Port is specified, so we need to make an A query. We choose 00558 // UDP if scheme is sip, and TLS if scheme is sips. 00559 port=uri.port(); 00560 00561 if(uri.scheme()=="sip") 00562 { 00563 type=UDP; 00564 } 00565 else if(uri.scheme()=="sips") 00566 { 00567 type=TLS; 00568 } 00569 else 00570 { 00571 assert(0); 00572 } 00573 } 00574 else 00575 { 00576 // Port is not specified, and neither is transport. Full 00577 // NAPTR lookup. 00578 00579 if(n==0) 00580 { 00581 // NAPTR ok. 00582 if(s==0) 00583 { 00584 // SRV ok. We know what we're getting at this point. 00585 00586 if(uri.scheme()=="sips") 00587 { 00588 type=TLS; 00589 } 00590 else if(uri.scheme()=="sip") 00591 { 00592 type=TCP; 00593 } 00594 else 00595 { 00596 assert(0); 00597 } 00598 00599 if(type==TLS) 00600 { 00601 port=5071; 00602 } 00603 else 00604 { 00605 port=5070; 00606 } 00607 } 00608 else if(s==1) 00609 { 00610 // SRV broken. We fail. 00611 } 00612 else 00613 { 00614 // SRV missing. Do A lookup, default the port. 00615 // (We have already chosen transport) 00616 00617 if(uri.scheme()=="sips") 00618 { 00619 type=TLS; 00620 } 00621 else if(uri.scheme()=="sip") 00622 { 00623 type=UDP; 00624 } 00625 else 00626 { 00627 assert(0); 00628 } 00629 00630 if(type==TLS) 00631 { 00632 port=5061; 00633 } 00634 else 00635 { 00636 port=5060; 00637 } 00638 } 00639 } 00640 else if(n==1) 00641 { 00642 // NAPTR is broken. This is the same situation as 00643 // missing SRVs. 00644 if(uri.scheme()=="sips") 00645 { 00646 type=TLS; 00647 } 00648 else if(uri.scheme()=="sip") 00649 { 00650 type=UDP; 00651 } 00652 else 00653 { 00654 assert(0); 00655 } 00656 00657 if(type==TLS) 00658 { 00659 port=5061; 00660 } 00661 else 00662 { 00663 port=5060; 00664 } 00665 } 00666 else 00667 { 00668 // NAPTR is missing. Next we try SRV. 00669 00670 if(uri.scheme()=="sips") 00671 { 00672 type=TLS; 00673 } 00674 00675 if(s==0) 00676 { 00677 // SRV ok. 00678 if(type==TLS) 00679 { 00680 port=5071; 00681 } 00682 else 00683 { 00684 port=5070; 00685 } 00686 } 00687 else if(s==1) 00688 { 00689 // SRV broken. We are hosed. 00690 } 00691 else 00692 { 00693 // SRVs missing. Fail over to A records. 00694 if(uri.scheme()=="sips") 00695 { 00696 type=TLS; 00697 } 00698 else if(uri.scheme()=="sip") 00699 { 00700 type=UDP; 00701 } 00702 else 00703 { 00704 assert(0); 00705 } 00706 00707 if(type==TLS) 00708 { 00709 port=5061; 00710 } 00711 else 00712 { 00713 port=5060; 00714 } 00715 00716 } 00717 } 00718 } 00719 } 00720 00721 00722 Query query; 00723 std::vector<Tuple> expected; 00724 00725 if(port) 00726 { 00727 if(type!=UNKNOWN_TRANSPORT) 00728 { 00729 expected.push_back(Tuple(ipAddr,port,V4,type)); 00730 } 00731 else 00732 { 00733 // .bwc. If we get UNKNOWN_TRANSPORT from the block of 00734 // code above, it means we will try all three. (Yes, this 00735 // is hackish. At least I documented it.) 00736 assert(port%2==0); 00737 expected.push_back(Tuple(ipAddr,port,V4,UDP)); 00738 expected.push_back(Tuple(ipAddr,port,V4,TCP)); 00739 expected.push_back(Tuple(ipAddr,port+1,V4,TLS)); 00740 } 00741 } 00742 00743 query.handler = new TestDnsHandler(expected,uri); 00744 query.uri = uri; 00745 cerr << "Creating DnsResult" << endl; 00746 DnsResult* res = dns.createDnsResult(query.handler); 00747 query.result = res; 00748 queries.push_back(query); 00749 cerr << rf << "Looking up" << ub << endl; 00750 00751 dns.lookup(res, uri); 00752 00753 } 00754 } 00755 } 00756 00757 // .bwc. Resolves uris from command line, if they are present. 00758 while (argc > 1 && args && *args != 0) 00759 { 00760 Uri uri; 00761 Query query; 00762 query.handler = new TestDnsHandler; 00763 //query.listener = new VipListener; 00764 cerr << "Creating Uri: " << *args << endl; 00765 try 00766 { 00767 Data input(*args++); 00768 uri = Uri(input); 00769 query.uri = uri; 00770 cerr << "Creating DnsResult" << endl; 00771 DnsResult* res = dns.createDnsResult(query.handler); 00772 query.result = res; 00773 queries.push_back(query); 00774 cerr << rf << "Looking up" << ub << endl; 00775 dns.lookup(res, uri); 00776 } 00777 catch (ParseException& e) 00778 { 00779 cerr << "Couldn't parse arg " << *(args-1) << ": " << e.getMessage() << endl; 00780 } 00781 00782 argc--; 00783 } 00784 00785 // .bwc. Wait for outstanding queries to finish. 00786 int count = queries.size(); 00787 while (count>0) 00788 { 00789 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); ) 00790 { 00791 if ((*it).handler->complete()) 00792 { 00793 cerr << rf << "DNS results for " << (*it).uri << ub << endl; 00794 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i) 00795 { 00796 resipCerr << rf << (*i) << ub << endl; 00797 } 00798 00799 --count; 00800 (*it).result->destroy(); 00801 delete (*it).handler; 00802 00803 std::list<Query>::iterator temp = it; 00804 ++it; 00805 queries.erase(temp); 00806 } 00807 else 00808 { 00809 ++it; 00810 } 00811 } 00812 sleep(1); 00813 } 00814 00815 assert(queries.empty()); 00816 00817 std::map<resip::Tuple,unsigned int> ipAddrToNum; 00818 ipAddrToNum[Tuple("127.0.0.1",5060,V4,TCP)]=0; 00819 ipAddrToNum[Tuple("127.0.0.2",5060,V4,TCP)]=1; 00820 ipAddrToNum[Tuple("127.0.0.3",5060,V4,TCP)]=2; 00821 ipAddrToNum[Tuple("127.0.0.4",5060,V4,TCP)]=3; 00822 00823 // .bwc. Test load-leveling. 00824 for(unsigned int numSRV=2;numSRV<5;++numSRV) 00825 { 00826 resip::Data hostname("loadlevel"); 00827 hostname+=Data::from(numSRV)+".test.resiprocate.org"; 00828 00829 Uri uri; 00830 uri.host()=hostname; 00831 uri.scheme()="sip"; 00832 00833 for(int i=0; i<1000;++i) 00834 { 00835 Query query; 00836 query.handler = new TestDnsHandler(); 00837 query.uri = uri; 00838 cerr << "Creating DnsResult" << endl; 00839 DnsResult* res = dns.createDnsResult(query.handler); 00840 query.result = res; 00841 queries.push_back(query); 00842 cerr << rf << "Looking up" << ub << endl; 00843 dns.lookup(res, uri); 00844 if(i%20==0) 00845 { 00846 // .bwc. Let things have some time to cache, so we don't hammer the 00847 // DNS to death. (Odds are good that we have hit every NAPTR at 00848 // least once by now) 00849 sleep(2); 00850 stub->logDnsCache(); 00851 } 00852 } 00853 00854 // .bwc. first index is the order (1st=0, 2nd=1, etc), and second index 00855 // is the last tuple in the IP address (127.0.0.1 is 0, 127.0.0.2 is 1) 00856 // The value stored is the number of times this combination was encountered. 00857 #ifdef __GNUC__ 00858 int table[numSRV][numSRV]; 00859 #else 00860 int table[5][5]; 00861 #endif 00862 00863 for(unsigned int i=0;i<numSRV;++i) 00864 { 00865 for(unsigned int j=0;j<numSRV;++j) 00866 { 00867 table[i][j]=0; 00868 } 00869 } 00870 00871 int count = queries.size(); 00872 while (count>0) 00873 { 00874 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); ) 00875 { 00876 if ((*it).handler->complete()) 00877 { 00878 cerr << rf << "DNS results for " << (*it).uri << ub << endl; 00879 assert(it->handler->results.size()==numSRV); 00880 00881 for(unsigned int i=0;i<numSRV;++i) 00882 { 00883 assert(ipAddrToNum[it->handler->results[i]] >=0); 00884 assert(ipAddrToNum[it->handler->results[i]] <numSRV); 00885 ++table[i][ipAddrToNum[it->handler->results[i]]]; 00886 resipCerr << rf << it->handler->results[i] << ub << endl; 00887 } 00888 00889 --count; 00890 (*it).result->destroy(); 00891 delete (*it).handler; 00892 00893 std::list<Query>::iterator temp = it; 00894 ++it; 00895 queries.erase(temp); 00896 } 00897 else 00898 { 00899 ++it; 00900 } 00901 } 00902 sleep(1); 00903 } 00904 00905 assert(queries.empty()); 00906 00907 std::cout << "Tabulated results:" << std::endl; 00908 for(unsigned int i=0;i<numSRV;++i) 00909 { 00910 for(unsigned int j=0;j<numSRV;++j) 00911 { 00912 std::cout << table[i][j] << std::setw(6); 00913 } 00914 std::cout << std::endl; 00915 } 00916 00917 } 00918 00919 00920 // .bwc. Test blacklisting 00921 std::cout << "Testing blacklisting." << std::endl; 00922 { 00923 Tuple toBlacklist("127.0.0.1",5060,V4,TCP); 00924 Tuple ok2("127.0.0.2",5060,V4,TCP); 00925 Tuple ok3("127.0.0.3",5060,V4,TCP); 00926 Tuple ok4("127.0.0.4",5060,V4,TCP); 00927 00928 std::vector<Tuple> expected; 00929 expected.push_back(ok2); 00930 expected.push_back(ok3); 00931 expected.push_back(ok4); 00932 expected.push_back(toBlacklist); 00933 00934 std::set<Tuple> blacklist; 00935 blacklist.insert(toBlacklist); 00936 std::set<Tuple> greylist; 00937 00938 Uri uri; 00939 uri.scheme()="sip"; 00940 uri.host()="loadlevel4.test.resiprocate.org"; 00941 00942 TestMarkListener* listener = new TestMarkListener(toBlacklist); 00943 dns.getMarkManager().registerMarkListener(listener); 00944 00945 Query query; 00946 query.handler = new TestDnsHandler(expected,blacklist,greylist,uri); 00947 query.uri = uri; 00948 cerr << "Creating DnsResult" << endl; 00949 DnsResult* res = dns.createDnsResult(query.handler); 00950 query.result = res; 00951 queries.push_back(query); 00952 cerr << rf << "Looking up" << ub << endl; 00953 dns.lookup(res, uri); 00954 00955 // .bwc. Give this query plenty of time. 00956 sleep(2); 00957 00958 assert(listener->gotBlacklistCallback()); 00959 listener->resetAll(); 00960 00961 // This removes the Tuple toBlacklist 00962 expected.pop_back(); 00963 00964 for(int i=0;i<20;++i) 00965 { 00966 Query query; 00967 query.handler = new TestDnsHandler(expected,uri); 00968 query.uri = uri; 00969 cerr << "Creating DnsResult" << endl; 00970 DnsResult* res = dns.createDnsResult(query.handler); 00971 query.result = res; 00972 queries.push_back(query); 00973 cerr << rf << "Looking up" << ub << endl; 00974 dns.lookup(res, uri); 00975 } 00976 00977 // .bwc. Wait for blacklist to expire. 00978 sleep(16); 00979 00980 // Put the blacklisted Tuple back. 00981 expected.push_back(toBlacklist); 00982 00983 for(int i=0;i<20;++i) 00984 { 00985 Query query; 00986 query.handler = new TestDnsHandler(expected,uri); 00987 query.uri = uri; 00988 cerr << "Creating DnsResult" << endl; 00989 DnsResult* res = dns.createDnsResult(query.handler); 00990 query.result = res; 00991 queries.push_back(query); 00992 cerr << rf << "Looking up" << ub << endl; 00993 dns.lookup(res, uri); 00994 } 00995 00996 int count = queries.size(); 00997 while (count>0) 00998 { 00999 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); ) 01000 { 01001 if ((*it).handler->complete()) 01002 { 01003 cerr << rf << "DNS results for " << (*it).uri << ub << endl; 01004 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i) 01005 { 01006 resipCerr << rf << (*i) << ub << endl; 01007 } 01008 01009 --count; 01010 (*it).result->destroy(); 01011 delete (*it).handler; 01012 01013 std::list<Query>::iterator temp = it; 01014 ++it; 01015 queries.erase(temp); 01016 } 01017 else 01018 { 01019 ++it; 01020 } 01021 } 01022 sleep(1); 01023 } 01024 01025 assert(queries.empty()); 01026 assert(listener->gotOkCallback()); 01027 listener->resetAll(); 01028 dns.getMarkManager().unregisterMarkListener(listener); 01029 delete listener; 01030 } 01031 01032 // .bwc. Test greylisting 01033 std::cout << "Testing greylisting." << std::endl; 01034 { 01035 Tuple toGreylist("127.0.0.1",5060,V4,TCP); 01036 Tuple ok2("127.0.0.2",5060,V4,TCP); 01037 Tuple ok3("127.0.0.3",5060,V4,TCP); 01038 Tuple ok4("127.0.0.4",5060,V4,TCP); 01039 01040 std::vector<Tuple> expected; 01041 expected.push_back(ok2); 01042 expected.push_back(ok3); 01043 expected.push_back(ok4); 01044 expected.push_back(toGreylist); 01045 01046 std::set<Tuple> blacklist; 01047 std::set<Tuple> greylist; 01048 greylist.insert(toGreylist); 01049 01050 Uri uri; 01051 uri.scheme()="sip"; 01052 uri.host()="loadlevel4.test.resiprocate.org"; 01053 01054 TestMarkListener* listener = new TestMarkListener(toGreylist); 01055 dns.getMarkManager().registerMarkListener(listener); 01056 01057 { 01058 Query query; 01059 query.handler = new TestDnsHandler(expected,blacklist,greylist,uri); 01060 query.uri = uri; 01061 cerr << "Creating DnsResult" << endl; 01062 DnsResult* res = dns.createDnsResult(query.handler); 01063 query.result = res; 01064 queries.push_back(query); 01065 cerr << rf << "Looking up" << ub << endl; 01066 dns.lookup(res, uri); 01067 } 01068 01069 // .bwc. Give this query plenty of time. 01070 sleep(2); 01071 01072 assert(listener->gotGreylistCallback()); 01073 listener->resetAll(); 01074 01075 resipCout << toGreylist << " was greylisted." << std::endl; 01076 01077 for(int i=0;i<20;++i) 01078 { 01079 Query query; 01080 query.handler = new TestDnsHandler(expected,uri); 01081 query.uri = uri; 01082 cerr << "Creating DnsResult" << endl; 01083 DnsResult* res = dns.createDnsResult(query.handler); 01084 query.result = res; 01085 queries.push_back(query); 01086 cerr << rf << "Looking up" << ub << endl; 01087 dns.lookup(res, uri); 01088 } 01089 01090 // .bwc. Wait for greylist to expire. 01091 sleep(16); 01092 01093 { 01094 Query query; 01095 query.handler = new TestDnsHandler(expected,uri); 01096 query.uri = uri; 01097 cerr << "Creating DnsResult" << endl; 01098 DnsResult* res = dns.createDnsResult(query.handler); 01099 query.result = res; 01100 queries.push_back(query); 01101 cerr << rf << "Looking up" << ub << endl; 01102 dns.lookup(res, uri); 01103 } 01104 01105 // .bwc. Give this query plenty of time. 01106 sleep(2); 01107 01108 assert(listener->gotOkCallback()); 01109 listener->resetAll(); 01110 resipCout << "greylist on " << toGreylist << " has expired." << std::endl; 01111 01112 for(int i=0;i<20;++i) 01113 { 01114 Query query; 01115 query.handler = new TestDnsHandler(expected,uri); 01116 query.uri = uri; 01117 cerr << "Creating DnsResult" << endl; 01118 DnsResult* res = dns.createDnsResult(query.handler); 01119 query.result = res; 01120 queries.push_back(query); 01121 cerr << rf << "Looking up" << ub << endl; 01122 dns.lookup(res, uri); 01123 } 01124 01125 int count = queries.size(); 01126 while (count>0) 01127 { 01128 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); ) 01129 { 01130 if ((*it).handler->complete()) 01131 { 01132 cerr << rf << "DNS results for " << (*it).uri << ub << endl; 01133 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i) 01134 { 01135 resipCerr << rf << (*i) << ub << endl; 01136 } 01137 01138 --count; 01139 (*it).result->destroy(); 01140 delete (*it).handler; 01141 01142 std::list<Query>::iterator temp = it; 01143 ++it; 01144 queries.erase(temp); 01145 } 01146 else 01147 { 01148 ++it; 01149 } 01150 } 01151 sleep(1); 01152 } 01153 01154 assert(queries.empty()); 01155 dns.getMarkManager().unregisterMarkListener(listener); 01156 delete listener; 01157 } 01158 01159 dns.shutdown(); 01160 dns.join(); 01161 01162 delete stub; 01163 01164 return 0; 01165 } 01166 01167 01168 /* ==================================================================== 01169 * The Vovida Software License, Version 1.0 01170 * 01171 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 01172 * 01173 * Redistribution and use in source and binary forms, with or without 01174 * modification, are permitted provided that the following conditions 01175 * are met: 01176 * 01177 * 1. Redistributions of source code must retain the above copyright 01178 * notice, this list of conditions and the following disclaimer. 01179 * 01180 * 2. Redistributions in binary form must reproduce the above copyright 01181 * notice, this list of conditions and the following disclaimer in 01182 * the documentation and/or other materials provided with the 01183 * distribution. 01184 * 01185 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 01186 * and "Vovida Open Communication Application Library (VOCAL)" must 01187 * not be used to endorse or promote products derived from this 01188 * software without prior written permission. For written 01189 * permission, please contact vocal@vovida.org. 01190 * 01191 * 4. Products derived from this software may not be called "VOCAL", nor 01192 * may "VOCAL" appear in their name, without prior written 01193 * permission of Vovida Networks, Inc. 01194 * 01195 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 01196 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 01197 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 01198 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 01199 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 01200 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 01201 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 01202 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 01203 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 01204 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 01205 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 01206 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 01207 * DAMAGE. 01208 * 01209 * ==================================================================== 01210 * 01211 * This software consists of voluntary contributions made by Vovida 01212 * Networks, Inc. and many individuals on behalf of Vovida Networks, 01213 * Inc. For more information on Vovida Networks, Inc., please see 01214 * <http://www.vovida.org/>. 01215 * 01216 */
1.7.5.1