reSIProcate/stack  9694
SipStack.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #ifndef WIN32
00006 #include <unistd.h>
00007 #include <netdb.h>
00008 #include <netinet/in.h>
00009 #include <arpa/inet.h>
00010 #endif
00011 
00012 #include "rutil/compat.hxx"
00013 #include "rutil/Data.hxx"
00014 #include "rutil/DnsUtil.hxx"
00015 #include "rutil/Fifo.hxx"
00016 #include "rutil/Logger.hxx"
00017 #include "rutil/Random.hxx"
00018 #include "rutil/Socket.hxx"
00019 #include "rutil/Timer.hxx"
00020 #include "rutil/FdPoll.hxx"
00021 
00022 #include "rutil/dns/DnsThread.hxx"
00023 #include "resip/stack/Message.hxx"
00024 #include "resip/stack/ShutdownMessage.hxx"
00025 #include "resip/stack/SipMessage.hxx"
00026 #include "resip/stack/ApplicationMessage.hxx"
00027 #include "resip/stack/SipStack.hxx"
00028 #include "rutil/Inserter.hxx"
00029 #include "resip/stack/StatisticsManager.hxx"
00030 #include "rutil/AsyncProcessHandler.hxx"
00031 #include "resip/stack/TcpTransport.hxx"
00032 #include "resip/stack/UdpTransport.hxx"
00033 #include "resip/stack/TransactionUser.hxx"
00034 #include "resip/stack/TransactionUserMessage.hxx"
00035 #include "resip/stack/TransactionControllerThread.hxx"
00036 #include "resip/stack/TransportSelectorThread.hxx"
00037 #include "rutil/WinLeakCheck.hxx"
00038 
00039 #ifdef USE_SSL
00040 #include "resip/stack/ssl/Security.hxx"
00041 #include "resip/stack/ssl/DtlsTransport.hxx"
00042 #include "resip/stack/ssl/TlsTransport.hxx"
00043 #endif
00044 
00045 #if defined(WIN32) && !defined(__GNUC__)
00046 #pragma warning( disable : 4355 )
00047 #endif
00048 
00049 using namespace resip;
00050 
00051 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00052 
00053 SipStack::SipStack(const SipStackOptions& options) :
00054         mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
00055                 TransactionController::MaxTUFifoSize),
00056         mTuSelector(mTUFifo),
00057         mAppTimers(mTuSelector),
00058         mStatsManager(*this)
00059 {
00060    // WARNING - don't forget to add new member initialization to the init() method
00061    init(options);
00062    mTUFifo.setDescription("SipStack::mTUFifo");
00063 }
00064 
00065 
00066 SipStack::SipStack(Security* pSecurity,
00067                    const DnsStub::NameserverList& additional,
00068                    AsyncProcessHandler* handler,
00069                    bool stateless,
00070                    AfterSocketCreationFuncPtr socketFunc,
00071                    Compression *compression,
00072                    FdPollGrp *pollGrp) :
00073    mPollGrp(pollGrp?pollGrp:FdPollGrp::create()),
00074    mPollGrpIsMine(!pollGrp),
00075 #ifdef USE_SSL
00076    mSecurity( pSecurity ? pSecurity : new Security()),
00077 #else
00078    mSecurity(0),
00079 #endif
00080    mDnsStub(new DnsStub(additional, socketFunc, handler, mPollGrp)),
00081    mDnsThread(0),
00082    mCompression(compression ? compression : new Compression(Compression::NONE)),
00083    mAsyncProcessHandler(handler ? handler : new SelectInterruptor),
00084    mInterruptorIsMine(!handler),
00085    mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
00086            TransactionController::MaxTUFifoSize),
00087    mCongestionManager(0),
00088    mTuSelector(mTUFifo),
00089    mAppTimers(mTuSelector),
00090    mStatsManager(*this),
00091    mTransactionController(new TransactionController(*this, mAsyncProcessHandler)),
00092    mTransactionControllerThread(0),
00093    mTransportSelectorThread(0),
00094    mRunning(false),
00095    mShuttingDown(false),
00096    mStatisticsManagerEnabled(true),
00097    mSocketFunc(socketFunc)
00098 {
00099    Timer::getTimeMs(); // initalize time offsets
00100    Random::initialize();
00101    initNetwork();
00102    if (pSecurity)
00103    {
00104 #ifdef USE_SSL
00105       pSecurity->preload();
00106 #else
00107       assert(0);
00108 #endif
00109    }
00110    
00111    mTUFifo.setDescription("SipStack::mTUFifo");
00112    mTransactionController->transportSelector().setPollGrp(mPollGrp);
00113 
00114 #if 0
00115   // .kw. originally tried to share common init() for the two
00116   // constructors, but too much risk for changing sequencing,
00117   // first prove out new constructor before merging (or obsoleting)
00118         mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
00119            TransactionController::MaxTUFifoSize),
00120         mTuSelector(mTUFifo),
00121         mAppTimers(mTuSelector),
00122         mStatsManager(*this)
00123 {
00124    SipStackOptions options;
00125    options.mSecurity = pSecurity;
00126    options.mExtraNameserverList = &additional;
00127    options.mStateless = stateless;
00128    options.mSocketFunc = socketFunc;
00129    options.mCompression = compression;
00130    options.mPollGrp = pollGrp;
00131    init(options);
00132 #endif
00133 }
00134 
00135 void
00136 SipStack::init(const SipStackOptions& options)
00137 {
00138    mPollGrpIsMine=false;
00139    if ( options.mPollGrp )
00140    {
00141       mPollGrp = options.mPollGrp;
00142    }
00143    else
00144    {
00145       mPollGrp = FdPollGrp::create();
00146       mPollGrpIsMine=true;
00147    }
00148 
00149 #ifdef USE_SSL
00150    mSecurity = options.mSecurity ? options.mSecurity : new Security();
00151    mSecurity->preload();
00152 #else
00153    mSecurity = 0;
00154    assert(options.mSecurity==0);
00155 #endif
00156 
00157    if(options.mAsyncProcessHandler)
00158    {
00159       mAsyncProcessHandler = options.mAsyncProcessHandler;
00160       mInterruptorIsMine = false;
00161    }
00162    else
00163    {
00164       mInterruptorIsMine = true;
00165       mAsyncProcessHandler = new SelectInterruptor;
00166    }
00167 
00168    mDnsStub = new DnsStub(
00169          options.mExtraNameserverList
00170                 ? *options.mExtraNameserverList : DnsStub::EmptyNameserverList,
00171          options.mSocketFunc,
00172          mAsyncProcessHandler,
00173          mPollGrp);
00174    mDnsThread = 0;
00175 
00176    mCompression = options.mCompression
00177          ? options.mCompression : new Compression(Compression::NONE);
00178 
00179    mCongestionManager = 0;
00180 
00181    // WATCHOUT: the transaction controller constructor will
00182    // grab the security, DnsStub, compression and statsManager
00183    mTransactionController = new TransactionController(*this, mAsyncProcessHandler);
00184    mTransactionController->transportSelector().setPollGrp(mPollGrp);
00185    mTransactionControllerThread = 0;
00186    mTransportSelectorThread = 0;
00187 
00188    mRunning = false;
00189    mShuttingDown = false;
00190    mStatisticsManagerEnabled = true;
00191    mSocketFunc = options.mSocketFunc;
00192 
00193    // .kw. note that stats manager has already called getTimeMs()
00194    Timer::getTimeMs(); // initalize time offsets
00195    Random::initialize();
00196    initNetwork();
00197 }
00198 
00199 SipStack::~SipStack()
00200 {
00201    DebugLog (<< "SipStack::~SipStack()");
00202    shutdownAndJoinThreads();
00203 
00204    delete mDnsThread;
00205    mDnsThread=0;
00206    delete mTransactionControllerThread;
00207    mTransactionControllerThread=0;
00208    delete mTransportSelectorThread;
00209    mTransportSelectorThread=0;
00210 
00211    delete mTransactionController;
00212 #ifdef USE_SSL
00213    delete mSecurity;
00214 #endif
00215    delete mCompression;
00216 
00217    delete mDnsStub;
00218    if (mPollGrpIsMine)
00219    {
00220       // delete pollGrp after deleting DNS
00221       delete mPollGrp;
00222       mPollGrp=0;
00223    }
00224 
00225    if(mInterruptorIsMine)
00226    {
00227       delete mAsyncProcessHandler;
00228       mAsyncProcessHandler=0;
00229    }
00230 
00231 }
00232 
00233 void 
00234 SipStack::run()
00235 {
00236    if(mRunning)
00237    {
00238       return;
00239    }
00240 
00241    mRunning=true;
00242    delete mDnsThread;
00243    mDnsThread=new DnsThread(*mDnsStub);
00244    mDnsThread->run();
00245 
00246    delete mTransactionControllerThread;
00247    mTransactionControllerThread=new TransactionControllerThread(*mTransactionController);
00248    mTransactionControllerThread->run();
00249 
00250    delete mTransportSelectorThread;
00251    mTransportSelectorThread=new TransportSelectorThread(mTransactionController->transportSelector());
00252    mTransportSelectorThread->run();
00253 }
00254 
00255 void
00256 SipStack::shutdown()
00257 {
00258    InfoLog (<< "Shutting down sip stack " << this);
00259 
00260    {
00261       Lock lock(mShutdownMutex);
00262       assert(!mShuttingDown);
00263       mShuttingDown = true;
00264    }
00265 
00266    mTransactionController->shutdown();
00267 }
00268 
00269 void 
00270 SipStack::shutdownAndJoinThreads()
00271 {
00272    if(mDnsThread)
00273    {
00274       mDnsThread->shutdown();
00275       mDnsThread->join();
00276    }
00277 
00278    if(mTransactionControllerThread)
00279    {
00280       mTransactionControllerThread->shutdown();
00281       mTransactionControllerThread->join();
00282    }
00283 
00284    if(mTransportSelectorThread)
00285    {
00286       mTransportSelectorThread->shutdown();
00287       mTransportSelectorThread->join();
00288    }
00289    mRunning=false;
00290 }
00291 
00292 Transport*
00293 SipStack::addTransport( TransportType protocol,
00294                         int port,
00295                         IpVersion version,
00296                         StunSetting stun,
00297                         const Data& ipInterface,
00298                         const Data& sipDomainname,
00299                         const Data& privateKeyPassPhrase,
00300                         SecurityTypes::SSLType sslType,
00301                         unsigned transportFlags,
00302                         SecurityTypes::TlsClientVerificationMode cvm,
00303                         bool useEmailAsSIP)
00304 {
00305    assert(!mShuttingDown);
00306 
00307    // If address is specified, ensure it is valid
00308    if(!ipInterface.empty())
00309    {
00310       if(version == V6)
00311       {
00312          if(!DnsUtil::isIpV6Address(ipInterface))
00313          {
00314             ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V6 "
00315                    << Tuple::toData(protocol) << " " << port << " on "
00316                    << ipInterface.c_str());
00317             throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__);
00318          }
00319       }
00320       else // V4
00321       {
00322          if(!DnsUtil::isIpV4Address(ipInterface))
00323          {
00324             ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V4 "
00325                    << Tuple::toData(protocol) << " " << port << " on "
00326                    << ipInterface.c_str());
00327             throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__);
00328          }
00329       }
00330    }
00331 
00332    InternalTransport* transport=0;
00333    Fifo<TransactionMessage>& stateMacFifo = mTransactionController->transportSelector().stateMacFifo();
00334    try
00335    {
00336       switch (protocol)
00337       {
00338          case UDP:
00339             transport = new UdpTransport(stateMacFifo, port, version, stun, ipInterface, mSocketFunc, *mCompression, transportFlags);
00340             break;
00341          case TCP:
00342             transport = new TcpTransport(stateMacFifo, port, version, ipInterface, mSocketFunc, *mCompression, transportFlags);
00343             break;
00344          case TLS:
00345 #if defined( USE_SSL )
00346             transport = new TlsTransport(stateMacFifo,
00347                                          port,
00348                                          version,
00349                                          ipInterface,
00350                                          *mSecurity,
00351                                          sipDomainname,
00352                                          sslType,
00353                                          mSocketFunc,
00354                                          *mCompression,
00355                                          transportFlags,
00356                                          cvm,
00357                                          useEmailAsSIP);
00358 #else
00359             CritLog (<< "TLS not supported in this stack. You don't have openssl");
00360             assert(0);
00361 #endif
00362             break;
00363          case DTLS:
00364 #if defined( USE_DTLS )
00365             transport = new DtlsTransport(stateMacFifo,
00366                                           port,
00367                                           version, // !jf! stun
00368                                           ipInterface,
00369                                           *mSecurity,
00370                                           sipDomainname,
00371                                           mSocketFunc,
00372                                           *mCompression);
00373 #else
00374             CritLog (<< "DTLS not supported in this stack.");
00375             assert(0);
00376 #endif
00377             break;
00378          default:
00379             assert(0);
00380             break;
00381       }
00382    }
00383    catch (BaseException& e)
00384    {
00385       ErrLog(<< "Failed to create transport: "
00386              << (version == V4 ? "V4" : "V6") << " "
00387              << Tuple::toData(protocol) << " " << port << " on "
00388              << (ipInterface.empty() ? "ANY" : ipInterface.c_str()) 
00389              << ": " << e);
00390       throw;
00391    }
00392    addTransport(std::auto_ptr<Transport>(transport));
00393    return transport;
00394 }
00395 
00396 void
00397 SipStack::addTransport(std::auto_ptr<Transport> transport)
00398 {
00399    //.dcm. once addTransport starts throwing, need to back out alias
00400    if (!transport->interfaceName().empty())
00401    {
00402       addAlias(transport->interfaceName(), transport->port());
00403    }
00404    else
00405    {
00406       // Using INADDR_ANY, get all IP interfaces
00407       std::list<std::pair<Data, Data> > ipIfs(DnsUtil::getInterfaces());
00408       if(transport->ipVersion()==V4)
00409       {
00410          ipIfs.push_back(std::make_pair<Data,Data>("lo0","127.0.0.1"));
00411       }
00412       while(!ipIfs.empty())
00413       {
00414          if(DnsUtil::isIpV4Address(ipIfs.back().second)==
00415                                              (transport->ipVersion()==V4))
00416          {
00417             addAlias(ipIfs.back().second, transport->port());
00418          }
00419          ipIfs.pop_back();
00420       }
00421    }
00422    mPorts.insert(transport->port());
00423    mTransactionController->transportSelector().addTransport(transport,true);
00424 }
00425 
00426 Fifo<TransactionMessage>&
00427 SipStack::stateMacFifo()
00428 {
00429    return mTransactionController->transportSelector().stateMacFifo();
00430 }
00431 
00432 void
00433 SipStack::addAlias(const Data& domain, int port)
00434 {
00435    int portToUse = (port == 0) ? Symbols::DefaultSipPort : port;
00436 
00437    DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse);
00438    assert(!mShuttingDown);
00439    mDomains.insert(domain + ":" + Data(portToUse));
00440 
00441 
00442    if(mUri.host().empty())
00443    {
00444       mUri.host()=*mDomains.begin();
00445    }
00446 
00447 }
00448 
00449 Data
00450 SipStack::getHostname()
00451 {
00452    // if you change this, please #def old version for windows
00453    char hostName[1024];
00454    int err =  gethostname( hostName, sizeof(hostName) );
00455    if(err != 0)
00456    {
00457       ErrLog(<< "gethostname failed with return " << err << " Returning "
00458             "\"localhost\"");
00459       assert(0);
00460       return "localhost";
00461    }
00462    
00463    struct hostent* hostEnt = gethostbyname( hostName );
00464    if ( !hostEnt )
00465    {
00466       // this can fail when there is no name server
00467       // !cj! - need to decided what error to return
00468       ErrLog( << "gethostbyname failed - name server is probably down" );
00469       return "localhost";
00470    }
00471    assert( hostEnt );
00472 
00473    struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0];
00474    assert( addr );
00475 
00476    // if you change this, please #def old version for windows
00477    char* addrA = inet_ntoa( *addr );
00478    Data ret(addrA);
00479 
00480    Data retHost( hostEnt->h_name );
00481 
00482    return retHost;
00483 }
00484 
00485 
00486 Data
00487 SipStack::getHostAddress()
00488 {
00489    // if you change this, please #def old version for windows
00490    char hostName[1024];
00491    int err =  gethostname( hostName, sizeof(hostName) );
00492    if(err != 0)
00493    {
00494       ErrLog(<< "gethostname failed with return " << err << " Returning "
00495             "\"127.0.0.1\"");
00496       assert(0);
00497       return "127.0.0.1";
00498    }
00499    
00500    struct hostent* hostEnt = gethostbyname( hostName );
00501    if(!hostEnt)
00502    {
00503       ErrLog(<< "gethostbyname failed, returning \"127.0.0.1\"");
00504       assert(0);
00505       return "127.0.0.1";
00506    }
00507    
00508    struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0];
00509    if( !addr )
00510    {
00511       ErrLog(<< "gethostbyname returned a hostent* with an empty h_addr_list,"
00512                " returning \"127.0.0.1\"");
00513       assert(0);
00514       return "127.0.0.1";
00515    }
00516    
00517    // if you change this, please #def old version for windows 
00518    char* addrA = inet_ntoa( *addr );
00519    Data ret(addrA);
00520 
00521    //Data retHost( hostEnt->h_name );
00522 
00523    return ret;
00524 }
00525 
00526 bool
00527 SipStack::isMyDomain(const Data& domain, int port) const
00528 {
00529    return (mDomains.count(domain + ":" +
00530                           Data(port == 0 ? Symbols::DefaultSipPort : port)) != 0);
00531 }
00532 
00533 bool
00534 SipStack::isMyPort(int port) const
00535 {
00536    return mPorts.count(port) != 0;
00537 }
00538 
00539 const Uri&
00540 SipStack::getUri() const
00541 {
00542    if(mUri.host().empty())
00543    {
00544       CritLog(<< "There are no associated transports");
00545       throw Exception("No associated transports", __FILE__, __LINE__);
00546    }
00547 
00548    return mUri;
00549 }
00550 
00551 void
00552 SipStack::send(const SipMessage& msg, TransactionUser* tu)
00553 {
00554    DebugLog (<< "SEND: " << msg.brief());
00555    //DebugLog (<< msg);
00556    //assert(!mShuttingDown);
00557 
00558    SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
00559    if (tu)
00560    {
00561       toSend->setTransactionUser(tu);
00562    }
00563    toSend->setFromTU();
00564 
00565    mTransactionController->send(toSend);
00566 }
00567 
00568 void
00569 SipStack::send(std::auto_ptr<SipMessage> msg, TransactionUser* tu)
00570 {
00571    DebugLog (<< "SEND: " << msg->brief());
00572 
00573    if (tu)
00574    {
00575       msg->setTransactionUser(tu);
00576    }
00577    msg->setFromTU();
00578 
00579    mTransactionController->send(msg.release());
00580 }
00581 
00582 void
00583 SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Uri& uri, TransactionUser* tu)
00584 {
00585    if (tu) msg->setTransactionUser(tu);
00586    msg->setForceTarget(uri);
00587    msg->setFromTU();
00588 
00589    mTransactionController->send(msg.release());
00590 }
00591 
00592 void
00593 SipStack::sendTo(std::auto_ptr<SipMessage> msg, const Tuple& destination, TransactionUser* tu)
00594 {
00595    assert(!mShuttingDown);
00596 
00597    if (tu) msg->setTransactionUser(tu);
00598    msg->setDestination(destination);
00599    msg->setFromTU();
00600 
00601    mTransactionController->send(msg.release());
00602 }
00603 
00604 // this is only if you want to send to a destination not in the route. You
00605 // probably don't want to use it.
00606 void
00607 SipStack::sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu)
00608 {
00609    //assert(!mShuttingDown);
00610 
00611    SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
00612    if (tu) toSend->setTransactionUser(tu);
00613    toSend->setForceTarget(uri);
00614    toSend->setFromTU();
00615 
00616    mTransactionController->send(toSend);
00617 }
00618 
00619 // this is only if you want to send to a destination not in the route. You
00620 // probably don't want to use it.
00621 void
00622 SipStack::sendTo(const SipMessage& msg, const Tuple& destination, TransactionUser* tu)
00623 {
00624    assert(!mShuttingDown);
00625 
00626    SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
00627    if (tu) toSend->setTransactionUser(tu);
00628    toSend->setDestination(destination);
00629    toSend->setFromTU();
00630 
00631    mTransactionController->send(toSend);
00632 }
00633 
00634 void
00635 SipStack::checkAsyncProcessHandler()
00636 {
00637    if (mAsyncProcessHandler)
00638    {
00639       mAsyncProcessHandler->handleProcessNotification();
00640    }
00641 }
00642 
00643 void
00644 SipStack::post(std::auto_ptr<ApplicationMessage> message)
00645 {
00646    assert(!mShuttingDown);
00647    mTuSelector.add(message.release(), TimeLimitFifo<Message>::InternalElement);
00648 }
00649 
00650 void
00651 SipStack::post(const ApplicationMessage& message)
00652 {
00653    assert(!mShuttingDown);
00654    Message* toPost = message.clone();
00655    mTuSelector.add(toPost, TimeLimitFifo<Message>::InternalElement);
00656 }
00657 
00658 void
00659 SipStack::post(const ApplicationMessage& message,  unsigned int secondsLater,
00660                TransactionUser* tu)
00661 {
00662    assert(!mShuttingDown);
00663    postMS(message, secondsLater*1000, tu);
00664 }
00665 
00666 void
00667 SipStack::postMS(const ApplicationMessage& message, unsigned int ms,
00668                  TransactionUser* tu)
00669 {
00670    assert(!mShuttingDown);
00671    Message* toPost = message.clone();
00672    if (tu) toPost->setTransactionUser(tu);
00673    Lock lock(mAppTimerMutex);
00674    mAppTimers.add(ms,toPost);
00675    //.dcm. timer update rather than process cycle...optimize by checking if sooner
00676    //than current timeTillNextProcess?
00677    checkAsyncProcessHandler();
00678 }
00679 
00680 void
00681 SipStack::post(std::auto_ptr<ApplicationMessage> message,
00682                unsigned int secondsLater,
00683                TransactionUser* tu)
00684 {
00685    postMS(message, secondsLater*1000, tu);
00686 }
00687 
00688 
00689 void
00690 SipStack::postMS( std::auto_ptr<ApplicationMessage> message,
00691                   unsigned int ms,
00692                   TransactionUser* tu)
00693 {
00694    assert(!mShuttingDown);
00695    if (tu) message->setTransactionUser(tu);
00696    Lock lock(mAppTimerMutex);
00697    mAppTimers.add(ms, message.release());
00698    //.dcm. timer update rather than process cycle...optimize by checking if sooner
00699    //than current timeTillNextProcess?
00700    checkAsyncProcessHandler();
00701 }
00702 
00703 void
00704 SipStack::abandonServerTransaction(const Data& tid)
00705 {
00706    mTransactionController->abandonServerTransaction(tid);
00707 }
00708 
00709 void
00710 SipStack::cancelClientInviteTransaction(const Data& tid)
00711 {
00712    mTransactionController->cancelClientInviteTransaction(tid);
00713 }
00714 
00715 bool
00716 SipStack::hasMessage() const
00717 {
00718    return mTUFifo.messageAvailable();
00719 }
00720 
00721 SipMessage*
00722 SipStack::receive()
00723 {
00724    // Check to see if a message is available and if it is return the
00725    // waiting message. Otherwise, return 0
00726    if (mTUFifo.messageAvailable())
00727    {
00728       // we should only ever have SIP messages on the TU Fifo
00729       // unless we've registered for termination messages.
00730       Message* msg = mTUFifo.getNext();
00731       SipMessage* sip = dynamic_cast<SipMessage*>(msg);
00732       if (sip)
00733       {
00734          DebugLog (<< "RECV: " << sip->brief());
00735          return sip;
00736       }
00737       else
00738       {
00739          // assert(0); // !CJ! removed the assert - happens 1 minute after
00740          // stack starts up
00741          delete msg;
00742          return 0;
00743       }
00744    }
00745    else
00746    {
00747       return 0;
00748    }
00749 }
00750 
00751 Message*
00752 SipStack::receiveAny()
00753 {
00754    // Check to see if a message is available and if it is return the
00755    // waiting message. Otherwise, return 0
00756    if (mTUFifo.messageAvailable())
00757    {
00758       // application messages can flow through
00759       Message* msg = mTUFifo.getNext();
00760       SipMessage* sip=dynamic_cast<SipMessage*>(msg);
00761       if (sip)
00762       {
00763          DebugLog (<< "RECV: " << sip->brief());
00764       }
00765       return msg;
00766    }
00767    else
00768    {
00769       return 0;
00770    }
00771 }
00772 
00773 void
00774 SipStack::setFallbackPostNotify(AsyncProcessHandler *handler) 
00775 {
00776    mTuSelector.setFallbackPostNotify(handler);
00777 }
00778 
00779 /* Called from external epoll (e.g., EventStackThread) */
00780 void
00781 SipStack::processTimers()
00782 {
00783    if(!mShuttingDown && mStatisticsManagerEnabled)
00784    {
00785       mStatsManager.process();
00786    }
00787 
00788    if(!mTransactionControllerThread)
00789    {
00790       mTransactionController->process();
00791    }
00792 
00793    if(!mDnsThread)
00794    {
00795       mDnsStub->processTimers();
00796    }
00797 
00798    if(!mTransportSelectorThread)
00799    {
00800       mTransactionController->transportSelector().process();
00801    }
00802 
00803    mTuSelector.process();
00804    Lock lock(mAppTimerMutex);
00805    mAppTimers.process();
00806 }
00807 
00808 /* Called for internal epoll and non-epoll (e.g., StackThread) */
00809 void
00810 SipStack::process(FdSet& fdset)
00811 {
00812    mPollGrp->processFdSet(fdset);
00813    processTimers();
00814 }
00815 
00816 bool 
00817 SipStack::process(unsigned int timeoutMs)
00818 {
00819    // Go ahead and do this first. Should cut down on how frequently we call 
00820    // waitAndProcess() with a timeout of 0, which should improve efficiency 
00821    // somewhat.
00822    processTimers();
00823    bool result=mPollGrp->waitAndProcess(resipMin(timeoutMs, getTimeTillNextProcessMS()));
00824    return result;
00825 }
00826 
00828 unsigned int
00829 SipStack::getTimeTillNextProcessMS()
00830 {
00831    Lock lock(mAppTimerMutex);
00832 
00833    unsigned int dnsNextProcess = (mDnsThread ? 
00834                            INT_MAX : mDnsStub->getTimeTillNextProcessMS());
00835    unsigned int tcNextProcess = mTransactionControllerThread ? INT_MAX : 
00836                            mTransactionController->getTimeTillNextProcessMS();
00837    unsigned int tsNextProcess = mTransportSelectorThread ? INT_MAX : mTransactionController->transportSelector().getTimeTillNextProcessMS();
00838 
00839    return resipMin(Timer::getMaxSystemTimeWaitMs(),
00840             resipMin(dnsNextProcess,
00841                resipMin(tcNextProcess,
00842                   resipMin(tsNextProcess,
00843                      resipMin(mTuSelector.getTimeTillNextProcessMS(), mAppTimers.msTillNextTimer())))));
00844 }
00845 
00846 void
00847 SipStack::buildFdSet(FdSet& fdset)
00848 {
00849    mPollGrp->buildFdSet(fdset);
00850 }
00851 
00852 Security*
00853 SipStack::getSecurity() const
00854 {
00855     return mSecurity;
00856 }
00857 
00858 void
00859 SipStack::setStatisticsInterval(unsigned long seconds)
00860 {
00861    mStatsManager.setInterval(seconds);
00862 }
00863 
00864 void
00865 SipStack::zeroOutStatistics()
00866 {
00867    if(statisticsManagerEnabled())
00868    {
00869       mTransactionController->zeroOutStatistics();
00870    }
00871 }
00872 
00873 bool
00874 SipStack::pollStatistics()
00875 {
00876    if(statisticsManagerEnabled())
00877    {
00878       mTransactionController->pollStatistics();
00879       return true;
00880    }
00881    return false;
00882 }
00883 
00884 void
00885 SipStack::registerTransactionUser(TransactionUser& tu)
00886 {
00887    mTuSelector.registerTransactionUser(tu);
00888 }
00889 
00890 void
00891 SipStack::requestTransactionUserShutdown(TransactionUser& tu)
00892 {
00893    mTuSelector.requestTransactionUserShutdown(tu);
00894    checkAsyncProcessHandler();
00895 }
00896 
00897 void
00898 SipStack::unregisterTransactionUser(TransactionUser& tu)
00899 {
00900    mTuSelector.unregisterTransactionUser(tu);
00901    checkAsyncProcessHandler();
00902 }
00903 
00904 void
00905 SipStack::registerMarkListener(MarkListener* listener)
00906 {
00907    mTransactionController->registerMarkListener(listener);
00908 }
00909 
00910 void
00911 SipStack::unregisterMarkListener(MarkListener* listener)
00912 {
00913    mTransactionController->unregisterMarkListener(listener);
00914 }
00915 
00916 DnsStub&
00917 SipStack::getDnsStub() const
00918 {
00919    return *mDnsStub;
00920 }
00921 
00922 void
00923 SipStack::setEnumSuffixes(const std::vector<Data>& suffixes)
00924 {
00925    mDnsStub->setEnumSuffixes(suffixes);
00926 }
00927 
00928 void
00929 SipStack::clearDnsCache()
00930 {
00931    mDnsStub->clearDnsCache();
00932 }
00933 
00934 void
00935 SipStack::logDnsCache()
00936 {
00937    mDnsStub->logDnsCache();
00938 }
00939 
00940 void 
00941 SipStack::getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler)
00942 {
00943    mDnsStub->getDnsCacheDump(key, handler);
00944 }
00945 
00946 volatile bool&
00947 SipStack::statisticsManagerEnabled()
00948 {
00949    return mStatisticsManagerEnabled;
00950 }
00951 
00952 const bool
00953 SipStack::statisticsManagerEnabled() const
00954 {
00955    return mStatisticsManagerEnabled;
00956 }
00957 
00958 EncodeStream&
00959 SipStack::dump(EncodeStream& strm)  const
00960 {
00961    Lock lock(mAppTimerMutex);
00962    strm << "SipStack: " << (this->mSecurity ? "with security " : "without security ")
00963         << std::endl
00964         << "domains: " << Inserter(this->mDomains)
00965         << std::endl
00966         << " TUFifo size=" << this->mTUFifo.size() << std::endl
00967         << " Timers size=" << this->mTransactionController->mTimers.size() << std::endl
00968         << " AppTimers size=" << this->mAppTimers.size() << std::endl
00969         << " ServerTransactionMap size=" << this->mTransactionController->mServerTransactionMap.size() << std::endl
00970         << " ClientTransactionMap size=" << this->mTransactionController->mClientTransactionMap.size() << std::endl
00971         << " Exact Transports=" << Inserter(this->mTransactionController->mTransportSelector.mExactTransports) << std::endl
00972         << " Any Transports=" << Inserter(this->mTransactionController->mTransportSelector.mAnyInterfaceTransports) << std::endl;
00973    return strm;
00974 }
00975 
00976 EncodeStream&
00977 resip::operator<<(EncodeStream& strm,
00978 const SipStack& stack)
00979 {
00980    return stack.dump(strm);
00981 }
00982 
00983 void 
00984 SipStack::terminateFlow(const resip::Tuple& flow)
00985 {
00986    mTransactionController->terminateFlow(flow);
00987 }
00988 
00989 void 
00990 SipStack::enableFlowTimer(const resip::Tuple& flow)
00991 {
00992    mTransactionController->enableFlowTimer(flow);
00993 }
00994 
00995 /* ====================================================================
00996  * The Vovida Software License, Version 1.0
00997  *
00998  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00999  *
01000  * Redistribution and use in source and binary forms, with or without
01001  * modification, are permitted provided that the following conditions
01002  * are met:
01003  *
01004  * 1. Redistributions of source code must retain the above copyright
01005  *    notice, this list of conditions and the following disclaimer.
01006  *
01007  * 2. Redistributions in binary form must reproduce the above copyright
01008  *    notice, this list of conditions and the following disclaimer in
01009  *    the documentation and/or other materials provided with the
01010  *    distribution.
01011  *
01012  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01013  *    and "Vovida Open Communication Application Library (VOCAL)" must
01014  *    not be used to endorse or promote products derived from this
01015  *    software without prior written permission. For written
01016  *    permission, please contact vocal@vovida.org.
01017  *
01018  * 4. Products derived from this software may not be called "VOCAL", nor
01019  *    may "VOCAL" appear in their name, without prior written
01020  *    permission of Vovida Networks, Inc.
01021  *
01022  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01023  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01024  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01025  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01026  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01027  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01029  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01030  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01031  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01033  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01034  * DAMAGE.
01035  *
01036  * ====================================================================
01037  *
01038  * This software consists of voluntary contributions made by Vovida
01039  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01040  * Inc.  For more information on Vovida Networks, Inc., please see
01041  * <http://www.vovida.org/>.
01042  *
01043  * vi: set shiftwidth=3 expandtab:
01044  */