/[resiprocate]/main/resip/stack/test/testDns.cxx
ViewVC logotype

Contents of /main/resip/stack/test/testDns.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9485 - (show annotations) (download)
Sat Apr 7 00:34:03 2012 UTC (7 years, 7 months ago) by dpocock
File MIME type: text/plain
File size: 36432 byte(s)
Switch over to autotools build system from dpocock-autotools branch
1 #if defined(HAVE_CONFIG_H)
2 #include "config.h"
3 #endif
4
5 #if defined (HAVE_POPT_H)
6 #include <popt.h>
7 #else
8 #ifndef WIN32
9 #warning "will not work very well without libpopt"
10 #endif
11 #endif
12
13 #include <iostream>
14 #include <iomanip>
15 #include <list>
16
17 #include "rutil/Lock.hxx"
18 #include "rutil/Mutex.hxx"
19 #include "rutil/Socket.hxx"
20 #include "rutil/Logger.hxx"
21 #include "rutil/ThreadIf.hxx"
22 #include "rutil/ParseBuffer.hxx"
23 #include "rutil/DnsUtil.hxx"
24 #include "resip/stack/DnsInterface.hxx"
25 #include "resip/stack/DnsResult.hxx"
26 #include "resip/stack/SipStack.hxx"
27 #include "resip/stack/TupleMarkManager.hxx"
28 #include "resip/stack/MarkListener.hxx"
29 #include "rutil/dns/RRVip.hxx"
30 #include "rutil/dns/DnsStub.hxx"
31 #include "rutil/dns/DnsHandler.hxx"
32
33 #include "resip/stack/test/tassert.h"
34 using namespace std;
35
36
37 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST
38
39 const char bf[] = "\033[01;34m";
40 const char gf[] = "\033[01;32m";
41 const char rf[] = "\033[01;31m";
42 const char ub[] = "\033[01;00m";
43
44 #ifdef WIN32
45 #define usleep(x) Sleep(x/1000)
46 #define sleep(x) Sleep(x*1000)
47 #endif
48
49 namespace resip
50 {
51
52 // called on the DNS processing thread, therefore state must be locked
53 class TestDnsHandler : public DnsHandler
54 {
55 public:
56 TestDnsHandler()
57 : mComplete(false),
58 mCheckExpectedResults(false),
59 mPermutationNumber(0)
60 {}
61
62 TestDnsHandler(const std::vector<Tuple>& expectedResults,
63 const resip::Uri& uri)
64 : mComplete(false),
65 mExpectedResults(expectedResults),
66 mCheckExpectedResults(true),
67 mUri(uri),
68 mPermutationNumber(0)
69 {}
70
71 TestDnsHandler(const std::vector<Tuple>& expectedResults,
72 const std::set<Tuple>& resultsToBlacklist,
73 const std::set<Tuple>& resultsToGreylist,
74 const resip::Uri& uri)
75 : mComplete(false),
76 mExpectedResults(expectedResults),
77 mCheckExpectedResults(true),
78 mUri(uri),
79 mPermutationNumber(0),
80 mResultsToBlacklist(resultsToBlacklist),
81 mResultsToGreylist(resultsToGreylist)
82 {}
83
84 void handle(DnsResult* result)
85 {
86
87 std::cout << gf << "DnsHandler received " << result->target() << ub << std::endl;
88 Lock lock(mutex);
89 DnsResult::Type type;
90 while ((type=result->available()) == DnsResult::Available)
91 {
92 Tuple tuple = result->next();
93 results.push_back(tuple);
94 resipCout << gf << result->target() << " -> " << tuple << ub << std::endl;
95 if(mResultsToGreylist.count(tuple)!=0)
96 {
97 result->greylistLast(Timer::getTimeMs()+15000);
98 }
99
100 if(mResultsToBlacklist.count(tuple)!=0)
101 {
102 result->blacklistLast(Timer::getTimeMs()+15000);
103 }
104 }
105 if (type != DnsResult::Pending)
106 {
107 mComplete = true;
108 if(mCheckExpectedResults)
109 {
110 checkExpectedResults();
111 }
112 }
113 }
114
115 void rewriteRequest(const Uri& rewrite)
116 {
117 std::cout << "Rewriting uri (enum) to " << rewrite << std::endl;
118 }
119
120
121 bool complete()
122 {
123 Lock lock(mutex);
124 return mComplete;
125 }
126
127 void checkExpectedResults()
128 {
129 std::cout << "Input Uri was " << mUri << endl;
130 tassert(mExpectedResults.size() == results.size());
131 tassert_reset();
132 std::cout << "Expected " << mExpectedResults.size() << ", got " << results.size() << endl;
133 std::vector<Tuple>::const_iterator e;
134 std::vector<Tuple>::const_iterator o;
135
136 for(e=mExpectedResults.begin();e!=mExpectedResults.end();++e)
137 {
138 int p=0;
139 resipCout << "Looking for " << *e << endl;
140 bool found=false;
141 for(o=results.begin();(o!=results.end() && !found);++o)
142 {
143 ++p;
144 if(*e==*o)
145 {
146 found=true;
147 resipCout << *o << " matched!" << endl;
148 mPermutation.push_back(p);
149 }
150 else
151 {
152 resipCout << *o << " didn't match." << endl;
153 }
154 }
155
156 tassert(found);
157 tassert_reset();
158 }
159 }
160
161 int getPermutationNumber()
162 {
163 if(mPermutationNumber!=0)
164 {
165 return mPermutationNumber;
166 }
167
168 int result=1;
169
170 // .bwc. Please forgive me for my use of permutation-group-foo.
171 for(int i=mPermutation.size();i>0;--i)
172 {
173 int foundAt=0;
174 for(std::list<int>::iterator j=mPermutation.begin();j!=mPermutation.end();++j)
175 {
176 ++foundAt;
177 if(*j==i)
178 {
179 result*=((foundAt-i)%i+1);
180 mPermutation.erase(j);
181 j=mPermutation.end();
182 }
183 }
184 }
185
186 mPermutationNumber=result;
187 return result;
188 }
189
190 std::vector<Tuple> results;
191
192 private:
193 bool mComplete;
194 std::vector<Tuple> mExpectedResults;
195 bool mCheckExpectedResults;
196 Mutex mutex;
197 Uri mUri;
198 std::list<int> mPermutation;
199 int mPermutationNumber;
200 std::set<resip::Tuple> mResultsToBlacklist;
201 std::set<resip::Tuple> mResultsToGreylist;
202 };
203
204 /*
205 class VipListener : public RRVip::Listener
206 {
207 void onVipInvalidated(int rrType, const Data& vip) const
208 {
209 cout << rf << "VIP " << " -> " << vip << " type" << " -> " << rrType << " has been invalidated." << ub << endl;
210 }
211 };
212 */
213
214 class TestMarkListener : public MarkListener
215 {
216 public:
217 TestMarkListener(const resip::Tuple& listenFor)
218 : mTuple(listenFor),
219 mGotOkCallback(false),
220 mGotGreylistCallback(false),
221 mGotBlacklistCallback(false)
222 {}
223 virtual ~TestMarkListener(){}
224
225 virtual void onMark(const Tuple& tuple, UInt64& expiry, TupleMarkManager::MarkType& mark)
226 {
227 if(mTuple == tuple)
228 {
229 switch(mark)
230 {
231 case TupleMarkManager::OK:
232 mGotOkCallback=true;
233 break;
234 case TupleMarkManager::GREY:
235 mGotGreylistCallback=true;
236 break;
237 case TupleMarkManager::BLACK:
238 mGotBlacklistCallback=true;
239 break;
240 default:
241 ;
242 }
243 }
244 }
245
246 bool gotOkCallback() const {return mGotOkCallback;}
247 bool gotGreylistCallback() const {return mGotGreylistCallback;}
248 bool gotBlacklistCallback() const {return mGotBlacklistCallback;}
249
250 void resetAll()
251 {
252 mGotOkCallback=false;
253 mGotGreylistCallback=false;
254 mGotBlacklistCallback=false;
255 }
256 private:
257 Tuple mTuple;
258 bool mGotOkCallback;
259 bool mGotGreylistCallback;
260 bool mGotBlacklistCallback;
261
262 };
263
264 class TestDns : public DnsInterface, public ThreadIf
265 {
266 public:
267 TestDns(DnsStub& stub) : DnsInterface(stub), mStub(stub)
268 {
269 addTransportType(TCP, V4);
270 addTransportType(UDP, V4);
271 addTransportType(TLS, V4);
272 #ifdef USE_IPV6
273 addTransportType(TCP, V6);
274 addTransportType(UDP, V6);
275 addTransportType(TLS, V6);
276 #endif
277 }
278
279 void thread()
280 {
281 while (!waitForShutdown(100))
282 {
283 FdSet fdset;
284 mStub.buildFdSet(fdset);
285 fdset.selectMilliSeconds(mStub.getTimeTillNextProcessMS());
286 mStub.process(fdset);
287 }
288 }
289
290 DnsStub& mStub;
291 };
292
293 }
294
295 using namespace resip;
296
297 typedef struct
298 {
299 DnsResult* result;
300 Uri uri;
301 TestDnsHandler* handler;
302 //VipListener* listener;
303 } Query;
304
305 int
306 main(int argc, const char** argv)
307 {
308 const char* logType = "cout";
309 const char* logLevel = "STACK";
310 const char* enumSuffix = "e164.arpa";
311
312 #if defined(HAVE_POPT_H)
313 struct poptOption table[] = {
314 {"log-type", 'l', POPT_ARG_STRING, &logType, 0, "where to send logging messages", "syslog|cerr|cout"},
315 {"log-level", 'v', POPT_ARG_STRING, &logLevel, 0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"},
316 {"enum-suffix", 'e', POPT_ARG_STRING, &enumSuffix, 0, "specify what enum domain to search in", "e164.arpa"},
317 POPT_AUTOHELP
318 { NULL, 0, 0, NULL, 0 }
319 };
320
321 poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0);
322 poptGetNextOpt(context);
323 #endif
324
325 Log::initialize(logType, logLevel, argv[0]);
326 initNetwork();
327 DnsStub* stub = new DnsStub;
328 TestDns dns(*stub);
329 dns.run();
330 cerr << "Starting" << endl;
331 std::list<Query> queries;
332 #if defined(HAVE_POPT_H)
333 const char** args = poptGetArgs(context);
334 #else
335 const char** args = argv;
336 #endif
337
338 std::vector<Data> enumSuffixes;
339 enumSuffixes.push_back(enumSuffix);
340 stub->setEnumSuffixes(enumSuffixes);
341
342 resip::Data uris[16]={
343 "sip:127.0.0.1:5070;transport=udp",
344 "sips:127.0.0.1:5071;transport=tls",
345 "sip:127.0.0.1;transport=udp",
346 "sips:127.0.0.1;transport=tls",
347 "sip:user.test.resiprocate.org:5070;transport=udp",
348 "sips:user.test.resiprocate.org:5071;transport=tls",
349 "sip:user.test.resiprocate.org;transport=udp",
350 "sips:user.test.resiprocate.org;transport=tls",
351 "sip:127.0.0.1:5070",
352 "sips:127.0.0.1:5071",
353 "sip:127.0.0.1",
354 "sips:127.0.0.1",
355 "sip:user.test.resiprocate.org:5070",
356 "sips:user.test.resiprocate.org:5071",
357 "sip:user-tcp.test.resiprocate.org",
358 "sips:user-tcp.test.resiprocate.org"
359 };
360
361
362 int expectedPorts[16][3]={
363 {5070,0,0},
364 {5071,0,0},
365 {5060,0,0},
366 {5061,0,0},
367 {5070,0,0},
368 {5071,0,0},
369 {5060,5070,5080},
370 {5061,5071,5081},
371 {5070,0,0},
372 {5071,0,0},
373 {5060,0,0},
374 {5061,0,0},
375 {5070,0,0},
376 {5071,0,0},
377 {5060,5070,5080},
378 {5061,5071,5081}
379 };
380
381 TransportType expectedTransports[16][3]={
382 {UDP,UDP,UDP},
383 {TLS,TLS,TLS},
384 {UDP, UDP, UDP},
385 {TLS,TLS,TLS},
386 {UDP, UDP, UDP},
387 {TLS,TLS,TLS},
388 {UDP, UDP, UDP},
389 {TLS,TLS,TLS},
390 {UDP, UDP, UDP},
391 {TLS,TLS,TLS},
392 {UDP, UDP, UDP},
393 {TLS,TLS,TLS},
394 {UDP, UDP, UDP},
395 {TLS,TLS,TLS},
396 {TCP, TCP, TCP},
397 {TLS,TLS,TLS}
398 };
399
400 resip::Data subUris[8]={
401 "sip:<hostname>:5080;transport=TCP",
402 "sips:<hostname>:5081;transport=TLS",
403 "sip:<hostname>;transport=TCP",
404 "sips:<hostname>;transport=TLS",
405 "sip:<hostname>:5080",
406 "sips:<hostname>:5081",
407 "sip:<hostname>",
408 "sips:<hostname>"
409 };
410
411 resip::Data ipAddr("127.0.0.1");
412
413 Uri uri;
414
415 for(int i=0; i< 16;++i)
416 {
417 Query query;
418 std::vector<Tuple> expected;
419
420 for(int j=0;j<3;++j)
421 {
422 if(expectedPorts[i][j]==0)
423 {
424 break;
425 }
426
427 expected.push_back(Tuple(ipAddr,expectedPorts[i][j],V4,expectedTransports[i][j]));
428 }
429
430
431 //query.listener = new VipListener;
432 cerr << "Creating Uri " << uris[i] << endl;
433 uri = Uri(uris[i]);
434
435 query.handler = new TestDnsHandler(expected,uri);
436
437 query.uri = uri;
438 cerr << "Creating DnsResult" << endl;
439 DnsResult* res = dns.createDnsResult(query.handler);
440 query.result = res;
441 queries.push_back(query);
442 cerr << rf << "Looking up" << ub << endl;
443
444 dns.lookup(res, uri);
445 }
446
447 resip::Data NAPTRstrings[3]={
448 "",
449 "-brokenNAPTR",
450 "-noNAPTR"
451 };
452
453 resip::Data SRVstrings[3]={
454 "",
455 "-brokenSRV",
456 "-noSRV"
457 };
458
459
460 for(int i=0;i<8;++i)
461 {
462
463
464 for(int n=0;n<3;++n)
465 {
466 for(int s=0;s<3;++s)
467 {
468 if(n==0 && s==0)
469 {
470 // .bwc. This is just user.test.resiprocate.org, which we have already done.
471 continue;
472 }
473
474 if(n==1 && s==2)
475 {
476 // .bwc. broken NAPTR and missing SRV is equivalent to OK NAPTR
477 // and missing SRV (n==0 and s==2). The former is not provisioned
478 // in the DNS zone, but the latter is, so we have already taken
479 // care of this case.
480 continue;
481 }
482
483
484 resip::Data hostname(resip::Data("user")+NAPTRstrings[n]+SRVstrings[s]+resip::Data(".test.resiprocate.org"));
485 resip::Data target=subUris[i];
486 target.replace("<hostname>",hostname);
487
488 //query.listener = new VipListener;
489 cerr << "Creating Uri " << target << endl;
490 uri = Uri(target);
491 unsigned int port=0;
492 TransportType type=UNKNOWN_TRANSPORT;
493
494 // .bwc. Choose expected destination.
495 if(uri.exists(p_transport))
496 {
497 // .bwc. Transport is explicitly specified; no NAPTR query
498 // will be made. State of NAPTR is irrelevant.
499
500 if(uri.port()!=0)
501 {
502 // .bwc. Port is explicitly specified. No SRV query will
503 // be made. This will be a bare A record lookup.
504 port=uri.port();
505 type=toTransportType(uri.param(p_transport));
506 if(uri.scheme()=="sips" && type!=TLS)
507 {
508 // What is the resolver supposed to do in this case?
509 assert(0);
510 }
511 }
512 else
513 {
514 // .bwc. Port is not explicitly specified. SRV query will
515 // be attempted.
516
517 if(s==0)
518 {
519 // SRV ok. Will land on 127.0.0.1:507[01] on specified
520 // transport.
521 type=toTransportType(uri.param(p_transport));
522 if(type==TLS)
523 {
524 port=5071;
525 }
526 else
527 {
528 port=5070;
529 }
530 }
531 else if(s==1)
532 {
533 // SRV broken. (Exists, so will be followed into space)
534 // Leave port as 0, since no results will come of this.
535 }
536 else
537 {
538 // SRV missing. DNS fill fail over to A record lookup.
539 type=toTransportType(uri.param(p_transport));
540 if(type==TLS)
541 {
542 port=5061;
543 }
544 else
545 {
546 port=5060;
547 }
548 }
549 }
550 }
551 else
552 {
553 // transport is not specified
554
555 if(uri.port()!=0)
556 {
557 // Port is specified, so we need to make an A query. We choose
558 // UDP if scheme is sip, and TLS if scheme is sips.
559 port=uri.port();
560
561 if(uri.scheme()=="sip")
562 {
563 type=UDP;
564 }
565 else if(uri.scheme()=="sips")
566 {
567 type=TLS;
568 }
569 else
570 {
571 assert(0);
572 }
573 }
574 else
575 {
576 // Port is not specified, and neither is transport. Full
577 // NAPTR lookup.
578
579 if(n==0)
580 {
581 // NAPTR ok.
582 if(s==0)
583 {
584 // SRV ok. We know what we're getting at this point.
585
586 if(uri.scheme()=="sips")
587 {
588 type=TLS;
589 }
590 else if(uri.scheme()=="sip")
591 {
592 type=TCP;
593 }
594 else
595 {
596 assert(0);
597 }
598
599 if(type==TLS)
600 {
601 port=5071;
602 }
603 else
604 {
605 port=5070;
606 }
607 }
608 else if(s==1)
609 {
610 // SRV broken. We fail.
611 }
612 else
613 {
614 // SRV missing. Do A lookup, default the port.
615 // (We have already chosen transport)
616
617 if(uri.scheme()=="sips")
618 {
619 type=TLS;
620 }
621 else if(uri.scheme()=="sip")
622 {
623 type=UDP;
624 }
625 else
626 {
627 assert(0);
628 }
629
630 if(type==TLS)
631 {
632 port=5061;
633 }
634 else
635 {
636 port=5060;
637 }
638 }
639 }
640 else if(n==1)
641 {
642 // NAPTR is broken. This is the same situation as
643 // missing SRVs.
644 if(uri.scheme()=="sips")
645 {
646 type=TLS;
647 }
648 else if(uri.scheme()=="sip")
649 {
650 type=UDP;
651 }
652 else
653 {
654 assert(0);
655 }
656
657 if(type==TLS)
658 {
659 port=5061;
660 }
661 else
662 {
663 port=5060;
664 }
665 }
666 else
667 {
668 // NAPTR is missing. Next we try SRV.
669
670 if(uri.scheme()=="sips")
671 {
672 type=TLS;
673 }
674
675 if(s==0)
676 {
677 // SRV ok.
678 if(type==TLS)
679 {
680 port=5071;
681 }
682 else
683 {
684 port=5070;
685 }
686 }
687 else if(s==1)
688 {
689 // SRV broken. We are hosed.
690 }
691 else
692 {
693 // SRVs missing. Fail over to A records.
694 if(uri.scheme()=="sips")
695 {
696 type=TLS;
697 }
698 else if(uri.scheme()=="sip")
699 {
700 type=UDP;
701 }
702 else
703 {
704 assert(0);
705 }
706
707 if(type==TLS)
708 {
709 port=5061;
710 }
711 else
712 {
713 port=5060;
714 }
715
716 }
717 }
718 }
719 }
720
721
722 Query query;
723 std::vector<Tuple> expected;
724
725 if(port)
726 {
727 if(type!=UNKNOWN_TRANSPORT)
728 {
729 expected.push_back(Tuple(ipAddr,port,V4,type));
730 }
731 else
732 {
733 // .bwc. If we get UNKNOWN_TRANSPORT from the block of
734 // code above, it means we will try all three. (Yes, this
735 // is hackish. At least I documented it.)
736 assert(port%2==0);
737 expected.push_back(Tuple(ipAddr,port,V4,UDP));
738 expected.push_back(Tuple(ipAddr,port,V4,TCP));
739 expected.push_back(Tuple(ipAddr,port+1,V4,TLS));
740 }
741 }
742
743 query.handler = new TestDnsHandler(expected,uri);
744 query.uri = uri;
745 cerr << "Creating DnsResult" << endl;
746 DnsResult* res = dns.createDnsResult(query.handler);
747 query.result = res;
748 queries.push_back(query);
749 cerr << rf << "Looking up" << ub << endl;
750
751 dns.lookup(res, uri);
752
753 }
754 }
755 }
756
757 // .bwc. Resolves uris from command line, if they are present.
758 while (argc > 1 && args && *args != 0)
759 {
760 Uri uri;
761 Query query;
762 query.handler = new TestDnsHandler;
763 //query.listener = new VipListener;
764 cerr << "Creating Uri: " << *args << endl;
765 try
766 {
767 Data input(*args++);
768 uri = Uri(input);
769 query.uri = uri;
770 cerr << "Creating DnsResult" << endl;
771 DnsResult* res = dns.createDnsResult(query.handler);
772 query.result = res;
773 queries.push_back(query);
774 cerr << rf << "Looking up" << ub << endl;
775 dns.lookup(res, uri);
776 }
777 catch (ParseException& e)
778 {
779 cerr << "Couldn't parse arg " << *(args-1) << ": " << e.getMessage() << endl;
780 }
781
782 argc--;
783 }
784
785 // .bwc. Wait for outstanding queries to finish.
786 int count = queries.size();
787 while (count>0)
788 {
789 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); )
790 {
791 if ((*it).handler->complete())
792 {
793 cerr << rf << "DNS results for " << (*it).uri << ub << endl;
794 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i)
795 {
796 resipCerr << rf << (*i) << ub << endl;
797 }
798
799 --count;
800 (*it).result->destroy();
801 delete (*it).handler;
802
803 std::list<Query>::iterator temp = it;
804 ++it;
805 queries.erase(temp);
806 }
807 else
808 {
809 ++it;
810 }
811 }
812 sleep(1);
813 }
814
815 assert(queries.empty());
816
817 std::map<resip::Tuple,unsigned int> ipAddrToNum;
818 ipAddrToNum[Tuple("127.0.0.1",5060,V4,TCP)]=0;
819 ipAddrToNum[Tuple("127.0.0.2",5060,V4,TCP)]=1;
820 ipAddrToNum[Tuple("127.0.0.3",5060,V4,TCP)]=2;
821 ipAddrToNum[Tuple("127.0.0.4",5060,V4,TCP)]=3;
822
823 // .bwc. Test load-leveling.
824 for(unsigned int numSRV=2;numSRV<5;++numSRV)
825 {
826 resip::Data hostname("loadlevel");
827 hostname+=Data::from(numSRV)+".test.resiprocate.org";
828
829 Uri uri;
830 uri.host()=hostname;
831 uri.scheme()="sip";
832
833 for(int i=0; i<1000;++i)
834 {
835 Query query;
836 query.handler = new TestDnsHandler();
837 query.uri = uri;
838 cerr << "Creating DnsResult" << endl;
839 DnsResult* res = dns.createDnsResult(query.handler);
840 query.result = res;
841 queries.push_back(query);
842 cerr << rf << "Looking up" << ub << endl;
843 dns.lookup(res, uri);
844 if(i%20==0)
845 {
846 // .bwc. Let things have some time to cache, so we don't hammer the
847 // DNS to death. (Odds are good that we have hit every NAPTR at
848 // least once by now)
849 sleep(2);
850 stub->logDnsCache();
851 }
852 }
853
854 // .bwc. first index is the order (1st=0, 2nd=1, etc), and second index
855 // is the last tuple in the IP address (127.0.0.1 is 0, 127.0.0.2 is 1)
856 // The value stored is the number of times this combination was encountered.
857 #ifdef __GNUC__
858 int table[numSRV][numSRV];
859 #else
860 int table[5][5];
861 #endif
862
863 for(unsigned int i=0;i<numSRV;++i)
864 {
865 for(unsigned int j=0;j<numSRV;++j)
866 {
867 table[i][j]=0;
868 }
869 }
870
871 int count = queries.size();
872 while (count>0)
873 {
874 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); )
875 {
876 if ((*it).handler->complete())
877 {
878 cerr << rf << "DNS results for " << (*it).uri << ub << endl;
879 assert(it->handler->results.size()==numSRV);
880
881 for(unsigned int i=0;i<numSRV;++i)
882 {
883 assert(ipAddrToNum[it->handler->results[i]] >=0);
884 assert(ipAddrToNum[it->handler->results[i]] <numSRV);
885 ++table[i][ipAddrToNum[it->handler->results[i]]];
886 resipCerr << rf << it->handler->results[i] << ub << endl;
887 }
888
889 --count;
890 (*it).result->destroy();
891 delete (*it).handler;
892
893 std::list<Query>::iterator temp = it;
894 ++it;
895 queries.erase(temp);
896 }
897 else
898 {
899 ++it;
900 }
901 }
902 sleep(1);
903 }
904
905 assert(queries.empty());
906
907 std::cout << "Tabulated results:" << std::endl;
908 for(unsigned int i=0;i<numSRV;++i)
909 {
910 for(unsigned int j=0;j<numSRV;++j)
911 {
912 std::cout << table[i][j] << std::setw(6);
913 }
914 std::cout << std::endl;
915 }
916
917 }
918
919
920 // .bwc. Test blacklisting
921 std::cout << "Testing blacklisting." << std::endl;
922 {
923 Tuple toBlacklist("127.0.0.1",5060,V4,TCP);
924 Tuple ok2("127.0.0.2",5060,V4,TCP);
925 Tuple ok3("127.0.0.3",5060,V4,TCP);
926 Tuple ok4("127.0.0.4",5060,V4,TCP);
927
928 std::vector<Tuple> expected;
929 expected.push_back(ok2);
930 expected.push_back(ok3);
931 expected.push_back(ok4);
932 expected.push_back(toBlacklist);
933
934 std::set<Tuple> blacklist;
935 blacklist.insert(toBlacklist);
936 std::set<Tuple> greylist;
937
938 Uri uri;
939 uri.scheme()="sip";
940 uri.host()="loadlevel4.test.resiprocate.org";
941
942 TestMarkListener* listener = new TestMarkListener(toBlacklist);
943 dns.getMarkManager().registerMarkListener(listener);
944
945 Query query;
946 query.handler = new TestDnsHandler(expected,blacklist,greylist,uri);
947 query.uri = uri;
948 cerr << "Creating DnsResult" << endl;
949 DnsResult* res = dns.createDnsResult(query.handler);
950 query.result = res;
951 queries.push_back(query);
952 cerr << rf << "Looking up" << ub << endl;
953 dns.lookup(res, uri);
954
955 // .bwc. Give this query plenty of time.
956 sleep(2);
957
958 assert(listener->gotBlacklistCallback());
959 listener->resetAll();
960
961 // This removes the Tuple toBlacklist
962 expected.pop_back();
963
964 for(int i=0;i<20;++i)
965 {
966 Query query;
967 query.handler = new TestDnsHandler(expected,uri);
968 query.uri = uri;
969 cerr << "Creating DnsResult" << endl;
970 DnsResult* res = dns.createDnsResult(query.handler);
971 query.result = res;
972 queries.push_back(query);
973 cerr << rf << "Looking up" << ub << endl;
974 dns.lookup(res, uri);
975 }
976
977 // .bwc. Wait for blacklist to expire.
978 sleep(16);
979
980 // Put the blacklisted Tuple back.
981 expected.push_back(toBlacklist);
982
983 for(int i=0;i<20;++i)
984 {
985 Query query;
986 query.handler = new TestDnsHandler(expected,uri);
987 query.uri = uri;
988 cerr << "Creating DnsResult" << endl;
989 DnsResult* res = dns.createDnsResult(query.handler);
990 query.result = res;
991 queries.push_back(query);
992 cerr << rf << "Looking up" << ub << endl;
993 dns.lookup(res, uri);
994 }
995
996 int count = queries.size();
997 while (count>0)
998 {
999 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); )
1000 {
1001 if ((*it).handler->complete())
1002 {
1003 cerr << rf << "DNS results for " << (*it).uri << ub << endl;
1004 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i)
1005 {
1006 resipCerr << rf << (*i) << ub << endl;
1007 }
1008
1009 --count;
1010 (*it).result->destroy();
1011 delete (*it).handler;
1012
1013 std::list<Query>::iterator temp = it;
1014 ++it;
1015 queries.erase(temp);
1016 }
1017 else
1018 {
1019 ++it;
1020 }
1021 }
1022 sleep(1);
1023 }
1024
1025 assert(queries.empty());
1026 assert(listener->gotOkCallback());
1027 listener->resetAll();
1028 dns.getMarkManager().unregisterMarkListener(listener);
1029 delete listener;
1030 }
1031
1032 // .bwc. Test greylisting
1033 std::cout << "Testing greylisting." << std::endl;
1034 {
1035 Tuple toGreylist("127.0.0.1",5060,V4,TCP);
1036 Tuple ok2("127.0.0.2",5060,V4,TCP);
1037 Tuple ok3("127.0.0.3",5060,V4,TCP);
1038 Tuple ok4("127.0.0.4",5060,V4,TCP);
1039
1040 std::vector<Tuple> expected;
1041 expected.push_back(ok2);
1042 expected.push_back(ok3);
1043 expected.push_back(ok4);
1044 expected.push_back(toGreylist);
1045
1046 std::set<Tuple> blacklist;
1047 std::set<Tuple> greylist;
1048 greylist.insert(toGreylist);
1049
1050 Uri uri;
1051 uri.scheme()="sip";
1052 uri.host()="loadlevel4.test.resiprocate.org";
1053
1054 TestMarkListener* listener = new TestMarkListener(toGreylist);
1055 dns.getMarkManager().registerMarkListener(listener);
1056
1057 {
1058 Query query;
1059 query.handler = new TestDnsHandler(expected,blacklist,greylist,uri);
1060 query.uri = uri;
1061 cerr << "Creating DnsResult" << endl;
1062 DnsResult* res = dns.createDnsResult(query.handler);
1063 query.result = res;
1064 queries.push_back(query);
1065 cerr << rf << "Looking up" << ub << endl;
1066 dns.lookup(res, uri);
1067 }
1068
1069 // .bwc. Give this query plenty of time.
1070 sleep(2);
1071
1072 assert(listener->gotGreylistCallback());
1073 listener->resetAll();
1074
1075 resipCout << toGreylist << " was greylisted." << std::endl;
1076
1077 for(int i=0;i<20;++i)
1078 {
1079 Query query;
1080 query.handler = new TestDnsHandler(expected,uri);
1081 query.uri = uri;
1082 cerr << "Creating DnsResult" << endl;
1083 DnsResult* res = dns.createDnsResult(query.handler);
1084 query.result = res;
1085 queries.push_back(query);
1086 cerr << rf << "Looking up" << ub << endl;
1087 dns.lookup(res, uri);
1088 }
1089
1090 // .bwc. Wait for greylist to expire.
1091 sleep(16);
1092
1093 {
1094 Query query;
1095 query.handler = new TestDnsHandler(expected,uri);
1096 query.uri = uri;
1097 cerr << "Creating DnsResult" << endl;
1098 DnsResult* res = dns.createDnsResult(query.handler);
1099 query.result = res;
1100 queries.push_back(query);
1101 cerr << rf << "Looking up" << ub << endl;
1102 dns.lookup(res, uri);
1103 }
1104
1105 // .bwc. Give this query plenty of time.
1106 sleep(2);
1107
1108 assert(listener->gotOkCallback());
1109 listener->resetAll();
1110 resipCout << "greylist on " << toGreylist << " has expired." << std::endl;
1111
1112 for(int i=0;i<20;++i)
1113 {
1114 Query query;
1115 query.handler = new TestDnsHandler(expected,uri);
1116 query.uri = uri;
1117 cerr << "Creating DnsResult" << endl;
1118 DnsResult* res = dns.createDnsResult(query.handler);
1119 query.result = res;
1120 queries.push_back(query);
1121 cerr << rf << "Looking up" << ub << endl;
1122 dns.lookup(res, uri);
1123 }
1124
1125 int count = queries.size();
1126 while (count>0)
1127 {
1128 for (std::list<Query>::iterator it = queries.begin(); it != queries.end(); )
1129 {
1130 if ((*it).handler->complete())
1131 {
1132 cerr << rf << "DNS results for " << (*it).uri << ub << endl;
1133 for (std::vector<Tuple>::iterator i = (*it).handler->results.begin(); i != (*it).handler->results.end(); ++i)
1134 {
1135 resipCerr << rf << (*i) << ub << endl;
1136 }
1137
1138 --count;
1139 (*it).result->destroy();
1140 delete (*it).handler;
1141
1142 std::list<Query>::iterator temp = it;
1143 ++it;
1144 queries.erase(temp);
1145 }
1146 else
1147 {
1148 ++it;
1149 }
1150 }
1151 sleep(1);
1152 }
1153
1154 assert(queries.empty());
1155 dns.getMarkManager().unregisterMarkListener(listener);
1156 delete listener;
1157 }
1158
1159 dns.shutdown();
1160 dns.join();
1161
1162 delete stub;
1163
1164 return 0;
1165 }
1166
1167
1168 /* ====================================================================
1169 * The Vovida Software License, Version 1.0
1170 *
1171 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1172 *
1173 * Redistribution and use in source and binary forms, with or without
1174 * modification, are permitted provided that the following conditions
1175 * are met:
1176 *
1177 * 1. Redistributions of source code must retain the above copyright
1178 * notice, this list of conditions and the following disclaimer.
1179 *
1180 * 2. Redistributions in binary form must reproduce the above copyright
1181 * notice, this list of conditions and the following disclaimer in
1182 * the documentation and/or other materials provided with the
1183 * distribution.
1184 *
1185 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1186 * and "Vovida Open Communication Application Library (VOCAL)" must
1187 * not be used to endorse or promote products derived from this
1188 * software without prior written permission. For written
1189 * permission, please contact vocal@vovida.org.
1190 *
1191 * 4. Products derived from this software may not be called "VOCAL", nor
1192 * may "VOCAL" appear in their name, without prior written
1193 * permission of Vovida Networks, Inc.
1194 *
1195 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1196 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1197 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1198 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1199 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1200 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1201 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1202 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1203 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1204 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1205 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1206 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1207 * DAMAGE.
1208 *
1209 * ====================================================================
1210 *
1211 * This software consists of voluntary contributions made by Vovida
1212 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1213 * Inc. For more information on Vovida Networks, Inc., please see
1214 * <http://www.vovida.org/>.
1215 *
1216 */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27