|
reSIProcate/stack
9694
|
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 */
1.7.5.1