reSIProcate/stack  9694
testDns.cxx
Go to the documentation of this file.
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  */