reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
SipStack.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#ifndef WIN32
6#include <unistd.h>
7#include <netdb.h>
8#include <netinet/in.h>
9#include <arpa/inet.h>
10#endif
11
12#include "rutil/compat.hxx"
13#include "rutil/Data.hxx"
14#include "rutil/DnsUtil.hxx"
15#include "rutil/Fifo.hxx"
16#include "rutil/Logger.hxx"
17#include "rutil/Random.hxx"
18#include "rutil/Socket.hxx"
19#include "rutil/Timer.hxx"
20#include "rutil/FdPoll.hxx"
21
28#include "rutil/Inserter.hxx"
39
40#ifdef USE_SSL
45#endif
46
47#include <utility>
48
49#if defined(WIN32) && !defined(__GNUC__)
50#pragma warning( disable : 4355 )
51#endif
52
53using namespace resip;
54
55#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
56
57// If PollGrp is not passed in, then EventStackThread isn't being used and the
58// application is most likely implementing a select/process loop to drive the
59// stack. The poll implementation (WSAPoll on Windows, poll() where there is
60// no epoll) does not support the select/process loop, so use fdset instead.
61static FdPollGrp*
63{
64 FdPollGrp* pollGrp = FdPollGrp::create();
65 if (pollGrp->getImplType() == FdPollGrp::PollImpl)
66 {
67 delete pollGrp;
68 pollGrp = FdPollGrp::create("fdset");
69 }
70 return pollGrp;
71}
72
74 mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
75 TransactionController::MaxTUFifoSize),
76 mTuSelector(mTUFifo),
77 mAppTimers(mTuSelector),
78 mStatsManager(*this),
79 mNextTransportKey(1)
80{
81 // WARNING - don't forget to add new member initialization to the init() method
82 init(options);
83 mTUFifo.setDescription("SipStack::mTUFifo");
84}
85
86
88 const DnsStub::NameserverList& additional,
89 AsyncProcessHandler* handler,
90 bool stateless,
92 Compression *compression,
93 FdPollGrp *pollGrp,
94 bool useDnsVip) :
95 mPollGrp(pollGrp?pollGrp:createDefaultPollGrp()),
96 mPollGrpIsMine(!pollGrp),
97#ifdef USE_SSL
98 mSecurity( pSecurity ? pSecurity : new Security()),
99#else
100 mSecurity(0),
101#endif
102 mDnsStub(new DnsStub(additional, socketFunc, handler, mPollGrp)),
103 mDnsThread(0),
104 mCompression(compression ? compression : new Compression(Compression::NONE)),
105 mAsyncProcessHandler(handler ? handler : new SelectInterruptor),
106 mInterruptorIsMine(!handler),
107 mTUFifo(TransactionController::MaxTUFifoTimeDepthSecs,
108 TransactionController::MaxTUFifoSize),
109 mCongestionManager(0),
110 mTuSelector(mTUFifo),
111 mAppTimers(mTuSelector),
112 mStatsManager(*this),
113 mTransactionController(new TransactionController(*this, mAsyncProcessHandler, useDnsVip)),
114 mTransactionControllerThread(0),
115 mTransportSelectorThread(0),
116 mInternalThreadsRunning(false),
117 mProcessingHasStarted(false),
118 mShuttingDown(false),
119 mStatisticsManagerEnabled(true),
120 mSocketFunc(socketFunc),
121 mNextTransportKey(1)
122{
123 Timer::getTimeMs(); // initalize time offsets
125 initNetwork();
126 if (pSecurity)
127 {
128#ifdef USE_SSL
129 pSecurity->preload();
130#else
131 resip_assert(0);
132#endif
133 }
134
135 mTUFifo.setDescription("SipStack::mTUFifo");
136 mTransactionController->transportSelector().setPollGrp(mPollGrp);
137
138#if 0
139 // .kw. originally tried to share common init() for the two
140 // constructors, but too much risk for changing sequencing,
141 // first prove out new constructor before merging (or obsoleting)
144 mTuSelector(mTUFifo),
145 mAppTimers(mTuSelector),
146 mStatsManager(*this)
147{
148 SipStackOptions options;
149 options.mSecurity = pSecurity;
150 options.mExtraNameserverList = &additional;
151 options.mStateless = stateless;
152 options.mSocketFunc = socketFunc;
153 options.mCompression = compression;
154 options.mPollGrp = pollGrp;
155 init(options);
156#endif
157}
158
159void
160SipStack::init(const SipStackOptions& options)
161{
162 mPollGrpIsMine=false;
163 if ( options.mPollGrp )
164 {
165 mPollGrp = options.mPollGrp;
166 }
167 else
168 {
169 mPollGrp = createDefaultPollGrp();
170 mPollGrpIsMine=true;
171 }
172
173#ifdef USE_SSL
174 mSecurity = options.mSecurity ? options.mSecurity : new Security();
175 mSecurity->preload();
176#else
177 mSecurity = 0;
178 resip_assert(options.mSecurity==0);
179#endif
180
181 if(options.mAsyncProcessHandler)
182 {
183 mAsyncProcessHandler = options.mAsyncProcessHandler;
184 mInterruptorIsMine = false;
185 }
186 else
187 {
188 mInterruptorIsMine = true;
189 mAsyncProcessHandler = new SelectInterruptor;
190 }
191
192 mDnsStub = new DnsStub(
195 options.mSocketFunc,
196 mAsyncProcessHandler,
197 mPollGrp);
198 mDnsThread = 0;
199
200 mCompression = options.mCompression
202
203 mCongestionManager = 0;
204
205 // WATCHOUT: the transaction controller constructor will
206 // grab the security, DnsStub, compression and statsManager
207 mTransactionController = new TransactionController(*this, mAsyncProcessHandler, options.mUseDnsVip);
208 mTransactionController->transportSelector().setPollGrp(mPollGrp);
209 mTransactionControllerThread = 0;
210 mTransportSelectorThread = 0;
211
212 mInternalThreadsRunning = false;
213 mProcessingHasStarted = false;
214 mShuttingDown = false;
215 mStatisticsManagerEnabled = true;
216 mSocketFunc = options.mSocketFunc;
217
218 // .kw. note that stats manager has already called getTimeMs()
219 Timer::getTimeMs(); // initalize time offsets
221 initNetwork();
222}
223
225{
226 DebugLog (<< "SipStack::~SipStack()");
228
229 delete mDnsThread;
230 mDnsThread=0;
231 delete mTransactionControllerThread;
232 mTransactionControllerThread=0;
233 delete mTransportSelectorThread;
234 mTransportSelectorThread=0;
235
236 delete mTransactionController;
237#ifdef USE_SSL
238 delete mSecurity;
239#endif
240 delete mCompression;
241
242 delete mDnsStub;
243 if (mPollGrpIsMine)
244 {
245 // delete pollGrp after deleting DNS
246 delete mPollGrp;
247 mPollGrp=0;
248 }
249
250 if(mInterruptorIsMine)
251 {
252 delete mAsyncProcessHandler;
253 mAsyncProcessHandler=0;
254 }
255}
256
257void
259{
260 if(mInternalThreadsRunning)
261 {
262 return;
263 }
264
265 mInternalThreadsRunning=true;
266 delete mDnsThread;
267 mDnsThread=new DnsThread(*mDnsStub);
268 mDnsThread->run();
269
270 delete mTransactionControllerThread;
271 mTransactionControllerThread=new TransactionControllerThread(*mTransactionController);
272 mTransactionControllerThread->run();
273
274 delete mTransportSelectorThread;
275 mTransportSelectorThread=new TransportSelectorThread(mTransactionController->transportSelector());
276 mTransportSelectorThread->run();
277}
278
279void
281{
282 InfoLog (<< "Shutting down sip stack " << this);
283
284 {
285 Lock lock(mShutdownMutex);
286 resip_assert(!mShuttingDown);
287 mShuttingDown = true;
288 }
289
290 mTransactionController->shutdown();
291}
292
293void
295{
296 if(mDnsThread)
297 {
298 mDnsThread->shutdown();
299 mDnsThread->join();
300 }
301
302 if(mTransactionControllerThread)
303 {
304 mTransactionControllerThread->shutdown();
305 mTransactionControllerThread->join();
306 }
307
308 if(mTransportSelectorThread)
309 {
310 mTransportSelectorThread->shutdown();
311 mTransportSelectorThread->join();
312 }
313 mInternalThreadsRunning=false;
314}
315
316void
321
322void
324{
325 for(SecureTransportMap::iterator itS = mSecureTransports.begin(); itS != mSecureTransports.end(); itS++)
326 {
327 itS->second->onReload();
328 }
329}
330
331void
332SipStack::setTransportSipMessageLoggingHandler(std::shared_ptr<Transport::SipMessageLoggingHandler> handler)
333{
334 mTransportSipMessageLoggingHandlers.clear();
335
336 if (handler)
337 {
338 mTransportSipMessageLoggingHandlers.push_back(handler);
339 }
340}
341
342void
343SipStack::addTransportSipMessageLoggingHandler(std::shared_ptr<Transport::SipMessageLoggingHandler> handler)
344{
345 if (!handler)
346 {
347 return;
348 }
349
350 mTransportSipMessageLoggingHandlers.push_back(handler);
351 for(auto& t : mNonSecureTransports)
352 {
353 t.second->addSipMessageLoggingHandler(handler);
354 }
355 for(auto& t : mSecureTransports)
356 {
357 t.second->addSipMessageLoggingHandler(handler);
358 }
359}
360
363 int port,
364 IpVersion version,
365 StunSetting stun,
366 const Data& ipInterface,
367 const Data& sipDomainname,
368 const Data& privateKeyPassPhrase,
370 unsigned transportFlags,
371 const Data& certificateFilename, const Data& privateKeyFilename,
373 bool useEmailAsSIP,
374 std::shared_ptr<WsConnectionValidator> wsConnectionValidator,
375 std::shared_ptr<WsCookieContextFactory> wsCookieContextFactory,
376 const Data& netNs)
377{
378 resip_assert(!mShuttingDown);
379
380 // If address is specified, ensure it is valid
381 if(!ipInterface.empty())
382 {
383 if(version == V6)
384 {
385 if(!DnsUtil::isIpV6Address(ipInterface))
386 {
387 ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V6 "
388 << Tuple::toData(protocol) << " " << port << " on "
389 << ipInterface.c_str());
390 throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__);
391 }
392 }
393 else // V4
394 {
395 if(!DnsUtil::isIpV4Address(ipInterface))
396 {
397 ErrLog(<< "Failed to create transport, invalid ipInterface specified (IP address required): V4 "
398 << Tuple::toData(protocol) << " " << port << " on "
399 << ipInterface.c_str());
400 throw Transport::Exception("Invalid ipInterface specified (IP address required)", __FILE__,__LINE__);
401 }
402 }
403 }
404
405#ifdef USE_NETNS
406 if(!netNs.empty() && protocol != TCP)
407 {
408 ErrLog(<< "Failed to create transport, netns is currently only supported for TCP. Cannot use netns: " << netNs);
409 throw Transport::Exception("netns only supported for TCP", __FILE__,__LINE__);
410 }
411#endif
412
413 InternalTransport* transport=0;
415 try
416 {
417 switch (protocol)
418 {
419 case UDP:
420 transport = new UdpTransport(stateMacFifo, port, version, stun, ipInterface, mSocketFunc, *mCompression, transportFlags);
421 break;
422 case TCP:
423 transport =
424 new TcpTransport(stateMacFifo, port, version, ipInterface, mSocketFunc, *mCompression, transportFlags, netNs);
425 break;
426 case TLS:
427#if defined( USE_SSL )
428 transport = new TlsTransport(stateMacFifo,
429 port,
430 version,
431 ipInterface,
432 *mSecurity,
433 sipDomainname,
434 sslType,
435 mSocketFunc,
436 *mCompression,
437 transportFlags,
438 cvm,
439 useEmailAsSIP,
440 certificateFilename,
441 privateKeyFilename,
442 privateKeyPassPhrase);
443#else
444 CritLog (<< "Can't add TLS transport: TLS not supported in this stack. You don't have openssl.");
445 throw Transport::Exception("Can't add TLS transport: TLS not supported in this stack. You don't have openssl.", __FILE__,__LINE__);
446#endif
447 break;
448 case DTLS:
449#if defined( USE_DTLS )
450 transport = new DtlsTransport(stateMacFifo,
451 port,
452 version, // !jf! stun
453 ipInterface,
454 *mSecurity,
455 sipDomainname,
456 mSocketFunc,
457 *mCompression,
458 certificateFilename,
459 privateKeyFilename,
460 privateKeyPassPhrase);
461#else
462 CritLog (<< "Can't add DTLS transport: DTLS not supported in this stack.");
463 throw Transport::Exception("Can't add DTLS transport: DTLS not supported in this stack.", __FILE__,__LINE__);
464#endif
465 break;
466
467 case WS:
468 transport = new WsTransport(stateMacFifo,
469 port,
470 version,
471 ipInterface,
472 mSocketFunc,
473 *mCompression,
474 transportFlags,
475 wsConnectionValidator,
476 wsCookieContextFactory);
477 break;
478
479 case WSS:
480#if defined( USE_SSL )
481 transport = new WssTransport(stateMacFifo,
482 port,
483 version,
484 ipInterface,
485 *mSecurity,
486 sipDomainname,
487 sslType,
488 mSocketFunc,
489 *mCompression,
490 transportFlags,
491 cvm,
492 useEmailAsSIP,
493 wsConnectionValidator,
494 wsCookieContextFactory,
495 certificateFilename,
496 privateKeyFilename,
497 privateKeyPassPhrase);
498#else
499 CritLog (<< "Can't add WSS transport: Secure Websockets not supported in this stack. You don't have openssl.");
500 throw Transport::Exception("Can't add WSS transport: Secure Websockets not supported in this stack. You don't have openssl.", __FILE__,__LINE__);
501#endif
502 break;
503 default:
504 CritLog (<< "Can't add unknown transport.");
505 throw Transport::Exception("Can't add unknown transport.", __FILE__,__LINE__);
506 break;
507 }
508 }
509 catch (BaseException& e)
510 {
511 ErrLog(<< "Failed to create transport: "
512 << (version == V4 ? "V4" : "V6") << " "
513 << Tuple::toData(protocol) << " " << port << " on "
514 << (ipInterface.empty() ? "ANY" : ipInterface.c_str())
515 << ": " << e);
516 throw;
517 }
518 addTransport(std::unique_ptr<Transport>(transport));
519 return transport;
520}
521
522void
523SipStack::addTransport(std::unique_ptr<Transport> transport)
524{
525 // Ensure we will be able to add the transport in the transport selector by ensure we
526 // don't have any transport collisions. Note: We store two set's here in order to
527 // avoid needing to ask the TransportSelector under some form of locking.
528 Tuple tuple(transport->interfaceName(), transport->port(),
529 transport->ipVersion(), transport->transport(),
530 Data::Empty, // target domain
531 transport->netNs());
532 if(!isSecure(transport->transport()))
533 {
534 if(mNonSecureTransports.find(tuple) == mNonSecureTransports.end())
535 {
536 // All is good - assign key to transport then add to mNonSecureTransports list
537 transport->setKey(mNextTransportKey++);
538 tuple.mTransportKey = transport->getKey();
539 mNonSecureTransports[tuple] = transport.get();
540 }
541 else
542 {
543 // Nonsecure transport collision with existing transport
544 ErrLog(<< "Failed to add non-secure transport, transport with similar properties already exists: " << tuple);
545 throw Transport::Exception("Failed to add non-secure transport, transport with similar properties already exists.", __FILE__,__LINE__);
546 return;
547 }
548 }
549 else
550 {
551 TransportSelector::TlsTransportKey tlsKey(transport->tlsDomain(), tuple);
552 if(mSecureTransports.find(tlsKey) == mSecureTransports.end())
553 {
554 // All is good - assign key to transport then add to mNonSecureTransports list
555 transport->setKey(mNextTransportKey++);
556 tlsKey.mTuple.mTransportKey = transport->getKey();
557 mSecureTransports[tlsKey] = transport.get();
558 }
559 else
560 {
561 // Secure transport collision with existing transport
562 ErrLog(<< "Failed to add secure transport, transport with similar properties already exists: "
563 << tuple << " (domain=" << transport->tlsDomain() << ")");
564 throw Transport::Exception("Failed to add secure transport, transport with similar properties already exists.", __FILE__,__LINE__);
565 return;
566 }
567 }
568
569 if (!transport->interfaceName().empty())
570 {
571 addAlias(transport->interfaceName(), transport->port());
572 }
573 else
574 {
575 // Using INADDR_ANY, get all IP interfaces
576 std::list<std::pair<Data, Data> > ipIfs(DnsUtil::getInterfaces());
577 if(transport->ipVersion()==V4)
578 {
579 ipIfs.push_back(std::make_pair<Data,Data>("lo0","127.0.0.1"));
580 }
581 while(!ipIfs.empty())
582 {
583 if(DnsUtil::isIpV4Address(ipIfs.back().second) == (transport->ipVersion()==V4))
584 {
585 addAlias(ipIfs.back().second, transport->port());
586 }
587 ipIfs.pop_back();
588 }
589 }
590 {
591 Lock lock(mPortsMutex);
592 mPorts[transport->port()]++; // add port / increment reference count
593 }
594
595 // Add to CongestionManager if required
596 if(mCongestionManager)
597 {
598 transport->setCongestionManager(mCongestionManager);
599 }
600
601 // Set Sip Message Logging Handler if one was provided
602 if (!mTransportSipMessageLoggingHandlers.empty())
603 {
604 transport->setSipMessageLoggingHandlers(mTransportSipMessageLoggingHandlers);
605 }
606
607 if(mProcessingHasStarted)
608 {
609 // Stack is running. Need to queue add request for TransactionController Thread
610 mTransactionController->addTransport(std::move(transport));
611 }
612 else
613 {
614 // Stack isn't running yet - just add transport directly on transport selector from this thread
615 mTransactionController->transportSelector().addTransport(std::move(transport), false /* isStackRunning */);
616 }
617}
618
619void
620SipStack::removeTransport(unsigned int transportKey)
621{
622 Tuple removeTuple;
623 Transport* transportToRemove = 0;
624
625 // Find transport using Key in SipStack lists(sets)
626 for(NonSecureTransportMap::iterator itNS = mNonSecureTransports.begin(); itNS != mNonSecureTransports.end(); itNS++)
627 {
628 if(itNS->first.mTransportKey == transportKey)
629 {
630 removeTuple = itNS->first;
631 transportToRemove = itNS->second;
632 mNonSecureTransports.erase(itNS);
633 break;
634 }
635 }
636 // If not found look in Secure list(set)
637 if(!transportToRemove)
638 {
639 for(SecureTransportMap::iterator itS = mSecureTransports.begin(); itS != mSecureTransports.end(); itS++)
640 {
641 if(itS->first.mTuple.mTransportKey == transportKey)
642 {
643 removeTuple = itS->first.mTuple;
644 transportToRemove = itS->second;
645 mSecureTransports.erase(itS);
646 break;
647 }
648 }
649 }
650 if(!transportToRemove)
651 {
652 WarningLog (<< "removeTransport: could not find transport specified by transportKey=" << transportKey);
653 return;
654 }
655
656 if(mSecureTransports.size() == 0 && mNonSecureTransports.size() == 0)
657 {
658 // If we have no more transports we can just clear out the mDomains map and mUri
659 Lock lock(mDomainsMutex);
660 mDomains.clear();
661 mUri.host().clear();
662 mUri.port() = 0;
663 }
664 else if(!transportToRemove->interfaceName().empty())
665 {
666 removeAlias(transportToRemove->interfaceName(), transportToRemove->port());
667 }
668 else
669 {
670 // Warning: This removal could produce unexpected results if the querying of the
671 // current interface addresses yields a different result then when we added the
672 // transport.
673 // Using INADDR_ANY, get all IP interfaces
674 std::list<std::pair<Data, Data> > ipIfs(DnsUtil::getInterfaces());
675 if(transportToRemove->ipVersion()==V4)
676 {
677 ipIfs.push_back(std::make_pair<Data,Data>("lo0","127.0.0.1"));
678 }
679 while(!ipIfs.empty())
680 {
681 if(DnsUtil::isIpV4Address(ipIfs.back().second) == (transportToRemove->ipVersion()==V4))
682 {
683 removeAlias(ipIfs.back().second, transportToRemove->port());
684 }
685 ipIfs.pop_back();
686 }
687 }
688
689 // Remove from port map if reference count is 0
690 {
691 Lock lock(mPortsMutex);
692 std::map<int, unsigned int>::iterator itP = mPorts.find(transportToRemove->port());
693 if(itP != mPorts.end())
694 {
695 // Decrement reference count and erase if 0
696 if(--itP->second == 0)
697 {
698 mPorts.erase(itP);
699 }
700 }
701 }
702
703 if(mProcessingHasStarted)
704 {
705 // Stack is running. Need to queue remove request for TransactionController Thread
706 mTransactionController->removeTransport(transportKey);
707 }
708 else
709 {
710 // Stack isn't running yet - just remove transport directly on transport selector from this thread
711 mTransactionController->transportSelector().removeTransport(transportKey);
712 }
713}
714
717{
718 return mTransactionController->transportSelector().stateMacFifo();
719}
720
721void
722SipStack::addAlias(const Data& domain, int port)
723{
724 int portToUse = (port == 0) ? Symbols::DefaultSipPort : port;
725
726 DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse);
727 resip_assert(!mShuttingDown);
728
729 Lock lock(mDomainsMutex);
730 mDomains[domain + ":" + Data(portToUse)]++;
731
732 if(mUri.host().empty())
733 {
734 mUri.host() = domain;
735 mUri.port() = portToUse;
736 }
737}
738
739void
740SipStack::removeAlias(const Data& domain, int port)
741{
742 int portToUse = (port == 0) ? Symbols::DefaultSipPort : port;
743
744 DebugLog (<< "Removing domain alias: " << domain << ":" << portToUse);
745 resip_assert(!mShuttingDown);
746
747 Lock lock(mDomainsMutex);
748 DomainsMap::iterator it = mDomains.find(domain + ":" + Data(portToUse));
749 if(it != mDomains.end())
750 {
751 if(--it->second == 0)
752 {
753 mDomains.erase(it);
754 }
755 }
756
757 // TODO - could reset mUri to be first item in Domain map - would need
758 // to seperate domain name and port though. Not sure who is using mUri
759 // anyway.
760}
761
762Data
764{
765 char hostName[1024];
766 int err = gethostname(hostName, sizeof(hostName));
767 if (err != 0)
768 {
769 ErrLog(<< "gethostname failed with return " << err << " Returning \"localhost\"");
770 resip_assert(0);
771 return "localhost";
772 }
773
774 struct addrinfo hints = {};
775 struct addrinfo* res = NULL;
776 hints.ai_family = AF_INET;
777 hints.ai_socktype = SOCK_STREAM;
778
779 err = getaddrinfo(hostName, NULL, &hints, &res);
780 if (err != 0 || res == NULL)
781 {
782 ErrLog(<< "getaddrinfo failed - name server is probably down: " << gai_strerror(err));
783 return "localhost";
784 }
785
786 // get the canonical hostname
787 Data retHost(res->ai_canonname ? res->ai_canonname : hostName);
788
789 freeaddrinfo(res);
790 return retHost;
791}
792
793Data
795{
796 char hostName[1024];
797 int err = gethostname(hostName, sizeof(hostName));
798 if (err != 0)
799 {
800 ErrLog(<< "gethostname failed with return " << err << " Returning "
801 "\"127.0.0.1\"");
802 resip_assert(0);
803 return "127.0.0.1";
804 }
805
806 struct addrinfo hints = {};
807 struct addrinfo* res = NULL;
808 hints.ai_family = AF_INET;
809 hints.ai_socktype = SOCK_STREAM;
810
811 err = getaddrinfo(hostName, NULL, &hints, &res);
812 if (err != 0 || res == NULL)
813 {
814 ErrLog(<< "getaddrinfo failed, returning \"127.0.0.1\": " << gai_strerror(err));
815 resip_assert(0);
816 return "127.0.0.1";
817 }
818
819 struct sockaddr_in* addr = (struct sockaddr_in*)res->ai_addr;
820 if (!addr)
821 {
822 ErrLog(<< "getaddrinfo returned no address, returning \"127.0.0.1\"");
823 freeaddrinfo(res);
824 resip_assert(0);
825 return "127.0.0.1";
826 }
827
828 // inet_ntop replaces deprecated inet_ntoa - thread-safe and IPv6 ready
829 char addrBuf[INET_ADDRSTRLEN];
830 inet_ntop(AF_INET, &addr->sin_addr, addrBuf, sizeof(addrBuf));
831
832 freeaddrinfo(res);
833 return Data(addrBuf);
834}
835
836bool
837SipStack::isMyDomain(const Data& domain, int port) const
838{
839 auto key = domain + ":" +
840 Data(port == 0 ? Symbols::DefaultSipPort : port);
841
842 Lock lock(mDomainsMutex);
843 return mDomains.find(key) != mDomains.end();
844}
845
846bool
847SipStack::isMyPort(int port) const
848{
849 Lock lock(mPortsMutex);
850 return mPorts.find(port) != mPorts.end();
851}
852
853const Uri&
855{
856 Lock lock(mDomainsMutex);
857 if(mUri.host().empty())
858 {
859 CritLog(<< "There are no associated transports");
860 throw Exception("No associated transports", __FILE__, __LINE__);
861 }
862
863 return mUri;
864}
865
866void
868{
869 DebugLog (<< "SEND: " << msg.brief());
870 //DebugLog (<< msg);
871 //assert(!mShuttingDown);
872
873 SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
874 if (tu)
875 {
876 toSend->setTransactionUser(tu);
877 }
878 toSend->setFromTU();
879
880 mTransactionController->send(toSend);
881}
882
883void
884SipStack::send(std::unique_ptr<SipMessage> msg, TransactionUser* tu)
885{
886 DebugLog (<< "SEND: " << msg->brief());
887
888 if (tu)
889 {
890 msg->setTransactionUser(tu);
891 }
892 msg->setFromTU();
893
894 mTransactionController->send(msg.release());
895}
896
897void
898SipStack::sendTo(std::unique_ptr<SipMessage> msg, const Uri& uri, TransactionUser* tu)
899{
900 if (tu) msg->setTransactionUser(tu);
901 msg->setForceTarget(uri);
902 msg->setFromTU();
903
904 mTransactionController->send(msg.release());
905}
906
907void
908SipStack::sendTo(std::unique_ptr<SipMessage> msg, const Tuple& destination, TransactionUser* tu)
909{
910 resip_assert(!mShuttingDown);
911
912 if (tu) msg->setTransactionUser(tu);
913 msg->setDestination(destination);
914 msg->setFromTU();
915
916 mTransactionController->send(msg.release());
917}
918
919// this is only if you want to send to a destination not in the route. You
920// probably don't want to use it.
921void
922SipStack::sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu)
923{
924 //assert(!mShuttingDown);
925
926 SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
927 if (tu) toSend->setTransactionUser(tu);
928 toSend->setForceTarget(uri);
929 toSend->setFromTU();
930
931 mTransactionController->send(toSend);
932}
933
934// this is only if you want to send to a destination not in the route. You
935// probably don't want to use it.
936void
937SipStack::sendTo(const SipMessage& msg, const Tuple& destination, TransactionUser* tu)
938{
939 resip_assert(!mShuttingDown);
940
941 SipMessage* toSend = static_cast<SipMessage*>(msg.clone());
942 if (tu) toSend->setTransactionUser(tu);
943 toSend->setDestination(destination);
944 toSend->setFromTU();
945
946 mTransactionController->send(toSend);
947}
948
949void
950SipStack::checkAsyncProcessHandler()
951{
952 if (mAsyncProcessHandler)
953 {
954 mAsyncProcessHandler->handleProcessNotification();
955 }
956}
957
958void
959SipStack::post(std::unique_ptr<ApplicationMessage> message)
960{
961 resip_assert(!mShuttingDown);
962 mTuSelector.add(message.release(), TimeLimitFifo<Message>::InternalElement);
963}
964
965void
967{
968 resip_assert(!mShuttingDown);
969 Message* toPost = message.clone();
970 mTuSelector.add(toPost, TimeLimitFifo<Message>::InternalElement);
971}
972
973void
974SipStack::post(const ApplicationMessage& message, unsigned int secondsLater,
975 TransactionUser* tu)
976{
977 resip_assert(!mShuttingDown);
978 post(message, std::chrono::seconds(secondsLater), tu);
979}
980
981void
982SipStack::postMS(const ApplicationMessage& message, unsigned int ms,
983 TransactionUser* tu)
984{
985 resip_assert(!mShuttingDown);
986 post(message, std::chrono::milliseconds(ms), tu);
987}
988
989void
991 std::chrono::duration<double> interval,
992 TransactionUser* tu)
993{
994 resip_assert(!mShuttingDown);
995 Message* toPost = message.clone();
996 if (tu) toPost->setTransactionUser(tu);
997
998 auto ms = (uint32_t)std::chrono::duration_cast<std::chrono::milliseconds>(interval).count();
999 Lock lock(mAppTimerMutex);
1000 mAppTimers.add(ms,toPost);
1001 //.dcm. timer update rather than process cycle...optimize by checking if sooner
1002 //than current timeTillNextProcess?
1003 checkAsyncProcessHandler();
1004}
1005
1006void
1007SipStack::post(std::unique_ptr<ApplicationMessage> message,
1008 unsigned int secondsLater,
1009 TransactionUser* tu)
1010{
1011 post(std::move(message), std::chrono::seconds(secondsLater), tu);
1012}
1013
1014
1015void
1016SipStack::postMS( std::unique_ptr<ApplicationMessage> message,
1017 unsigned int ms,
1018 TransactionUser* tu)
1019{
1020 post(std::move(message), std::chrono::milliseconds(ms), tu);
1021}
1022
1023void
1024SipStack::post( std::unique_ptr<ApplicationMessage> message,
1025 std::chrono::duration<double> interval,
1026 TransactionUser* tu)
1027{
1028 resip_assert(!mShuttingDown);
1029 if (tu) message->setTransactionUser(tu);
1030
1031 auto ms = (uint32_t)std::chrono::duration_cast<std::chrono::milliseconds>(interval).count();
1032 Lock lock(mAppTimerMutex);
1033 mAppTimers.add(ms, message.release());
1034 //.dcm. timer update rather than process cycle...optimize by checking if sooner
1035 //than current timeTillNextProcess?
1036 checkAsyncProcessHandler();
1037}
1038
1039void
1041{
1042 mTransactionController->abandonServerTransaction(tid);
1043}
1044
1045void
1047{
1048 mTransactionController->cancelClientInviteTransaction(tid, reasons);
1049}
1050
1051bool
1053{
1054 return mTUFifo.messageAvailable();
1055}
1056
1059{
1060 // Check to see if a message is available and if it is return the
1061 // waiting message. Otherwise, return 0
1062 if (mTUFifo.messageAvailable())
1063 {
1064 // we should only ever have SIP messages on the TU Fifo
1065 // unless we've registered for termination messages.
1066 Message* msg = mTUFifo.getNext();
1067 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1068 if (sip)
1069 {
1070 DebugLog (<< "RECV: " << sip->brief());
1071 return sip;
1072 }
1073 else
1074 {
1075 // assert(0); // !CJ! removed the assert - happens 1 minute after
1076 // stack starts up
1077 delete msg;
1078 return 0;
1079 }
1080 }
1081 else
1082 {
1083 return 0;
1084 }
1085}
1086
1087Message*
1089{
1090 // Check to see if a message is available and if it is return the
1091 // waiting message. Otherwise, return 0
1092 if (mTUFifo.messageAvailable())
1093 {
1094 // application messages can flow through
1095 Message* msg = mTUFifo.getNext();
1096 SipMessage* sip=dynamic_cast<SipMessage*>(msg);
1097 if (sip)
1098 {
1099 DebugLog (<< "RECV: " << sip->brief());
1100 }
1101 return msg;
1102 }
1103 else
1104 {
1105 return 0;
1106 }
1107}
1108
1109void
1111{
1112 mTuSelector.setFallbackPostNotify(handler);
1113}
1114
1115/* Called from external epoll (e.g., EventStackThread) */
1116void
1118{
1119 if(!mTransactionControllerThread)
1120 {
1121 mTransactionController->process();
1122 }
1123
1124 if(!mDnsThread)
1125 {
1126 mDnsStub->processTimers();
1127 }
1128
1129 if(!mTransportSelectorThread)
1130 {
1131 mTransactionController->transportSelector().process();
1132 }
1133
1134 mTuSelector.process();
1135 Lock lock(mAppTimerMutex);
1136 mAppTimers.process();
1137}
1138
1139/* Called for internal epoll and non-epoll (e.g., StackThread) */
1140void
1142{
1143 mPollGrp->processFdSet(fdset);
1144 processTimers();
1145}
1146
1147bool
1148SipStack::process(unsigned int timeoutMs)
1149{
1150 // Go ahead and do this first. Should cut down on how frequently we call
1151 // waitAndProcess() with a timeout of 0, which should improve efficiency
1152 // somewhat.
1153 processTimers();
1154 bool result=mPollGrp->waitAndProcess(resipMin(timeoutMs, getTimeTillNextProcessMS()));
1155 return result;
1156}
1157
1159unsigned int
1161{
1162 Lock lock(mAppTimerMutex);
1163 mProcessingHasStarted = true;
1164
1165 unsigned int dnsNextProcess = (mDnsThread ?
1166 INT_MAX : mDnsStub->getTimeTillNextProcessMS());
1167 unsigned int tcNextProcess = mTransactionControllerThread ? INT_MAX :
1168 mTransactionController->getTimeTillNextProcessMS();
1169 unsigned int tsNextProcess = mTransportSelectorThread ? INT_MAX : mTransactionController->transportSelector().getTimeTillNextProcessMS();
1170
1172 resipMin(dnsNextProcess,
1173 resipMin(tcNextProcess,
1174 resipMin(tsNextProcess,
1175 resipMin(mTuSelector.getTimeTillNextProcessMS(), mAppTimers.msTillNextTimer())))));
1176}
1177
1178void
1180{
1181 mPollGrp->buildFdSet(fdset);
1182}
1183
1184Security*
1186{
1187 return mSecurity;
1188}
1189
1190void
1192{
1193 mStatsManager.setInterval(seconds);
1194}
1195
1196void
1198{
1200 {
1201 mTransactionController->zeroOutStatistics();
1202 }
1203}
1204
1205bool
1207{
1209 {
1210 mTransactionController->pollStatistics();
1211 return true;
1212 }
1213 return false;
1214}
1215
1216void
1218{
1219 mTuSelector.registerTransactionUser(tu, front);
1220}
1221
1222void
1224{
1225 mTuSelector.requestTransactionUserShutdown(tu);
1226 checkAsyncProcessHandler();
1227}
1228
1229void
1231{
1232 mTuSelector.unregisterTransactionUser(tu);
1233 checkAsyncProcessHandler();
1234}
1235
1236void
1238{
1239 mTransactionController->registerMarkListener(listener);
1240}
1241
1242void
1244{
1245 mTransactionController->unregisterMarkListener(listener);
1246}
1247
1248DnsStub&
1250{
1251 return *mDnsStub;
1252}
1253
1254void
1255SipStack::setEnumSuffixes(const std::vector<Data>& suffixes)
1256{
1257 mDnsStub->setEnumSuffixes(suffixes);
1258}
1259
1260void
1261SipStack::setEnumDomains(const std::map<Data,Data>& domains)
1262{
1263 mDnsStub->setEnumDomains(domains);
1264}
1265
1266void
1268{
1269 mDnsStub->clearDnsCache();
1270}
1271
1272void
1274{
1275 mDnsStub->logDnsCache();
1276}
1277
1278void
1279SipStack::getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler)
1280{
1281 mDnsStub->getDnsCacheDump(key, handler);
1282}
1283
1284void
1286{
1287 mDnsStub->reloadDnsServers();
1288}
1289
1290volatile bool&
1292{
1293 return mStatisticsManagerEnabled;
1294}
1295
1296const bool
1298{
1299 return mStatisticsManagerEnabled;
1300}
1301
1304{
1305 strm << "SipStack: " << (this->mSecurity ? "with security " : "without security ") << std::endl;
1306 {
1307 Lock lock(mDomainsMutex);
1308 strm << "domains: " << Inserter(this->mDomains) << std::endl;
1309 }
1310 strm << " TUFifo size=" << this->mTUFifo.size() << std::endl
1311 << " Timers size=" << this->mTransactionController->mTimers.size() << std::endl;
1312 {
1313 Lock lock(mAppTimerMutex);
1314 strm << " AppTimers size=" << this->mAppTimers.size() << std::endl;
1315 }
1316 strm << " ServerTransactionMap size=" << this->mTransactionController->mServerTransactionMap.size() << std::endl
1317 << " ClientTransactionMap size=" << this->mTransactionController->mClientTransactionMap.size() << std::endl
1318 // !slg! TODO - There is technically a threading concern with the following three lines and the runtime addTransport or removeTransport call
1319 << " Exact interface / Specific port=" << Inserter(this->mTransactionController->mTransportSelector.mExactTransports) << std::endl
1320 << " Any interface / Specific port=" << Inserter(this->mTransactionController->mTransportSelector.mAnyInterfaceTransports) << std::endl
1321 << " Exact interface / Any port =" << Inserter(this->mTransactionController->mTransportSelector.mAnyPortTransports) << std::endl
1322 << " Any interface / Any port=" << Inserter(this->mTransactionController->mTransportSelector.mAnyPortAnyInterfaceTransports) << std::endl
1323 << " TLS Transports=" << Inserter(this->mTransactionController->mTransportSelector.mTlsTransports) << std::endl;
1324 return strm;
1325}
1326
1328resip::operator<<(EncodeStream& strm, const SipStack& stack)
1329{
1330 return stack.dump(strm);
1331}
1332
1333void
1335{
1336 mTransactionController->terminateFlow(flow);
1337}
1338
1339void
1341{
1342 mTransactionController->enableFlowTimer(flow);
1343}
1344
1345void
1347{
1348 // Stack is assummed to be running. Need to queue invoke request for TransactionController Thread
1349 mTransactionController->invokeAfterSocketCreationFunc(type);
1350}
1351
1352/* ====================================================================
1353 * The Vovida Software License, Version 1.0
1354 *
1355 * Copyright (c) 2026 SIP Spectrum, Inc. http://www.sipspectrum.com
1356 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1357 *
1358 * Redistribution and use in source and binary forms, with or without
1359 * modification, are permitted provided that the following conditions
1360 * are met:
1361 *
1362 * 1. Redistributions of source code must retain the above copyright
1363 * notice, this list of conditions and the following disclaimer.
1364 *
1365 * 2. Redistributions in binary form must reproduce the above copyright
1366 * notice, this list of conditions and the following disclaimer in
1367 * the documentation and/or other materials provided with the
1368 * distribution.
1369 *
1370 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1371 * and "Vovida Open Communication Application Library (VOCAL)" must
1372 * not be used to endorse or promote products derived from this
1373 * software without prior written permission. For written
1374 * permission, please contact vocal@vovida.org.
1375 *
1376 * 4. Products derived from this software may not be called "VOCAL", nor
1377 * may "VOCAL" appear in their name, without prior written
1378 * permission of Vovida Networks, Inc.
1379 *
1380 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1381 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1382 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1383 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1384 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1385 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1386 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1387 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1388 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1389 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1390 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1391 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1392 * DAMAGE.
1393 *
1394 * ====================================================================
1395 *
1396 * This software consists of voluntary contributions made by Vovida
1397 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1398 * Inc. For more information on Vovida Networks, Inc., please see
1399 * <http://www.vovida.org/>.
1400 *
1401 * vi: set shiftwidth=3 expandtab:
1402 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define CritLog(args_)
Definition Logger.hxx:140
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
static FdPollGrp * createDefaultPollGrp()
Definition SipStack.cxx:62
Handles cross-platform sockets compatibility.
A base-class for messages used by applications.
virtual void handleProcessNotification()=0
The abstract base-class for all exceptions thrown by resip code.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
Data & clear()
Clears the contents of this Data.
Definition Data.hxx:800
virtual unsigned int getTimeTillNextProcessMS()
Definition DnsStub.cxx:124
static NameserverList EmptyNameserverList
Definition DnsStub.hxx:119
void reloadDnsServers()
Definition DnsStub.cxx:898
std::vector< GenericIPAddress > NameserverList
Definition DnsStub.hxx:117
void logDnsCache()
Definition DnsStub.cxx:869
void setEnumDomains(const std::map< Data, Data > &domains)
Definition DnsStub.cxx:837
void clearDnsCache()
Definition DnsStub.cxx:856
void getDnsCacheDump(std::pair< unsigned long, unsigned long > key, GetDnsCacheDumpHandler *handler)
Definition DnsStub.cxx:882
void processTimers()
Definition DnsStub.cxx:157
void setEnumSuffixes(const std::vector< Data > &suffixes)
Definition DnsStub.cxx:818
static bool isIpV6Address(const Data &ipAddress)
Definition DnsUtil.cxx:386
static std::list< std::pair< Data, Data > > getInterfaces(const Data &matchingInterface=Data::Empty)
Definition DnsUtil.cxx:460
static bool isIpV4Address(const Data &ipAddress)
Definition DnsUtil.cxx:290
static FdPollGrp * create(const char *implName=NULL)
factory
Definition FdPoll.cxx:972
virtual ImplType getImplType() const =0
virtual void buildFdSet(FdSet &fdSet)=0
virtual bool processFdSet(FdSet &fdset)=0
virtual bool waitAndProcess(int ms=0)=0
Wait at most {ms} milliseconds.
Object-oriented wrapper for your platform's file-descriptor set.
Definition Socket.hxx:162
A templated, threadsafe message-queue class.
Definition Fifo.hxx:16
The base-class used for message-passing.
Definition Message.hxx:21
virtual Brief brief() const
return a facet for brief encoding of message
Definition Message.cxx:16
virtual Message * clone() const =0
void setTransactionUser(TransactionUser *t)
Definition Message.hxx:48
static void initialize()
Definition Random.cxx:125
virtual void preload()
Definition Security.cxx:277
Used to 'artificially' interrupt a select call.
Represents a SIP message.
void setDestination(const Tuple &tuple)
Used by the stateless interface to specify where to send a request/response.
void setForceTarget(const Uri &uri)
deal with a notion of an "out-of-band" forced target for SIP routing
virtual Message * clone() const
void setFromTU()
Mark message as internally generated.
This class holds constructor-time initialization arguments for SipStack.
Definition SipStack.hxx:112
Compression * mCompression
Definition SipStack.hxx:127
AfterSocketCreationFuncPtr mSocketFunc
Definition SipStack.hxx:126
const DnsStub::NameserverList * mExtraNameserverList
Definition SipStack.hxx:123
AsyncProcessHandler * mAsyncProcessHandler
Definition SipStack.hxx:124
thrown when the stack is unable to function.
Definition SipStack.hxx:286
This is the primary point of interaction between the app-layer and the stack.
Definition SipStack.hxx:160
Fifo< TransactionMessage > & stateMacFifo()
Returns the fifo that subclasses of Transport should use for the rxFifo cons.
Definition SipStack.cxx:716
friend class TransactionController
void shutdownAndJoinThreads()
Shutdown and join any threads that the SipStack is running.
Definition SipStack.cxx:294
static Data getHostname()
Get one of the names for this host (calls through to gethostbyname) and is not threadsafe.
Definition SipStack.cxx:763
Security * getSecurity() const
Returns a pointer to the embedded Security object, 0 if not set.
DnsStub & getDnsStub() const
EncodeStream & dump(EncodeStream &strm) const
output current state of the stack - for debug
virtual ~SipStack()
Definition SipStack.cxx:224
void clearDnsCache()
Clear the DNS Cache.
void invokeAfterSocketCreationFunc(TransportType type=UNKNOWN_TRANSPORT)
void getDnsCacheDump(std::pair< unsigned long, unsigned long > key, GetDnsCacheDumpHandler *handler)
Get a string representation of the DNS Cache.
bool isMyPort(int port) const
Returns true if port is handled by this stack.
Definition SipStack.cxx:847
void send(const SipMessage &msg, TransactionUser *tu=0)
allows a TU to send a message
Definition SipStack.cxx:867
Transport * addTransport(TransportType protocol, int port, IpVersion version=V4, StunSetting stun=StunDisabled, const Data &ipInterface=Data::Empty, const Data &sipDomainname=Data::Empty, const Data &privateKeyPassPhrase=Data::Empty, SecurityTypes::SSLType sslType=SecurityTypes::DynamicTLS, unsigned transportFlags=0, const Data &certificateFilename="", const Data &privateKeyFilename="", SecurityTypes::TlsClientVerificationMode cvm=SecurityTypes::None, bool useEmailAsSIP=false, std::shared_ptr< WsConnectionValidator >=nullptr, std::shared_ptr< WsCookieContextFactory >=nullptr, const Data &netNs=Data::Empty)
Used by the application to add in a new built-in transport.
Definition SipStack.cxx:362
void cancelClientInviteTransaction(const Data &tid, const Tokens *reasons)
Tells the stack that the TU wishes to CANCEL an INVITE request.
void reloadCertificates()
reload the TLS X.509 certificates
Definition SipStack.cxx:323
void setFallbackPostNotify(AsyncProcessHandler *handler)
virtual void process(FdSet &fdset)
This allows the executive to give processing time to stack components.
bool isMyDomain(const Data &domain, int port) const
Returns true if domain is handled by this stack.
Definition SipStack.cxx:837
SipMessage * receive()
retrieve a SipMessage off the old TuFifo
void addTransportSipMessageLoggingHandler(std::shared_ptr< Transport::SipMessageLoggingHandler > handler)
Used by the application to provide a handler that will get called for all inbound and outbound SIP me...
Definition SipStack.cxx:343
void registerTransactionUser(TransactionUser &, const bool front=false)
add a TU to the TU selection chain
void removeTransport(unsigned int transportKey)
Used to remove a previously added transport.
Definition SipStack.cxx:620
static Data getHostAddress()
Get one of the IP address for this host (calls through to gethostbyname) and is not threadsafe.
Definition SipStack.cxx:794
void shutdown()
perform orderly shutdown
Definition SipStack.cxx:280
void abandonServerTransaction(const Data &tid)
Tells the stack that the TU has abandoned a server transaction.
void onReload()
reload configuration
Definition SipStack.cxx:317
virtual unsigned int getTimeTillNextProcessMS()
Returns time in milliseconds when process next needs to be called.
void terminateFlow(const resip::Tuple &flow)
void logDnsCache()
Log the DNS Cache to WarningLog for Debugging.
void post(std::unique_ptr< ApplicationMessage > message, unsigned int secondsLater, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in seconds.
void sendTo(std::unique_ptr< SipMessage > msg, const Uri &uri, TransactionUser *tu=0)
this is only if you want to send to a destination not in the route.
Definition SipStack.cxx:898
void unregisterTransactionUser(TransactionUser &)
Removes a TU from the TU selection chain.
virtual void buildFdSet(FdSet &fdset)
Build the FD set to use in a select to find out when process(FdSet&) must be called again.
void requestTransactionUserShutdown(TransactionUser &)
Queue a shutdown request to the specified TU.
void setTransportSipMessageLoggingHandler(std::shared_ptr< Transport::SipMessageLoggingHandler > handler)
Used by the application to provide a handler that will get called for all inbound and outbound SIP me...
Definition SipStack.cxx:332
SipStack(const SipStackOptions &options)
Constructor.
Definition SipStack.cxx:73
void zeroOutStatistics()
Resets all of the cumulative statistics counters.
const Uri & getUri() const
Get one of the domains/ports that are handled by this stack in Uri form.
Definition SipStack.cxx:854
void enableFlowTimer(const resip::Tuple &flow)
void run()
Causes this SipStack object to create and run threads for carrying out processing.
Definition SipStack.cxx:258
bool pollStatistics()
Immediately polls for statistics to be logged and sent to external handlers, instead of waiting for n...
bool hasMessage() const
does the stack have new messages for the TU?
void reloadDnsServers()
Check if DnsServers list has changed, and if so reinitializes the DNS resolver (ares).
void postMS(std::unique_ptr< ApplicationMessage > message, unsigned int ms, TransactionUser *tu=0)
Makes the message available to the TU at some later time, specified in milli-seconds.
virtual void processTimers()
Check all timers.
Message * receiveAny()
retrieve a message off the old TuFifo
void setInterval(unsigned long intvSecs)
static const int DefaultSipPort
Definition Symbols.hxx:81
virtual void shutdown()
Definition ThreadIf.cxx:190
virtual void run()
Definition ThreadIf.cxx:75
unsigned int msTillNextTimer()
provides the time in milliseconds before the next timer will fire
virtual uint64_t process()
gets the set of timers that have fired, and inserts TimerMsg into the state machine fifo and applicat...
static unsigned getMaxSystemTimeWaitMs(void)
On windows, change getSystemTime() to not use the actual clock time returned by ::GetSystemTime().
Definition Timer.hxx:104
static uint64_t getTimeMs()
Returns the current clock time in milliseconds.
Definition Timer.hxx:72
void invokeAfterSocketCreationFunc(TransportType type)
void addTransport(std::unique_ptr< Transport > transport)
void cancelClientInviteTransaction(const Data &tid, const resip::Tokens *reasons)
TransportSelector & transportSelector()
void abandonServerTransaction(const Data &tid)
void enableFlowTimer(const resip::Tuple &flow)
void removeTransport(unsigned int transportKey)
void registerMarkListener(MarkListener *listener)
void unregisterMarkListener(MarkListener *listener)
void terminateFlow(const resip::Tuple &flow)
The base-class for an RFC 3261 Transaction User.
void removeTransport(unsigned int transportKey)
void addTransport(std::unique_ptr< Transport > transport, bool isStackRunning)
Add/Remove a transport.
void setPollGrp(FdPollGrp *pollGrp)
Configure a PollGrp to use (instead of buildFdSet/process) Must be called before adding any transport...
void process(FdSet &fdset)
Calls process on all suitable transports NOTE that TransportSelector no longer handles DNSInterface N...
Fifo< TransactionMessage > & stateMacFifo()
General exception class for Transport.
The base class for Transport classes.
Definition Transport.hxx:83
IpVersion ipVersion() const
int port() const
const Data & interfaceName() const
uint64_t add(unsigned int timeMs, Message *payload)
void requestTransactionUserShutdown(TransactionUser &)
void add(Message *msg, TimeLimitFifo< Message >::DepthUsage usage)
void setFallbackPostNotify(AsyncProcessHandler *handler)
unsigned int getTimeTillNextProcessMS()
void unregisterTransactionUser(TransactionUser &)
void registerTransactionUser(TransactionUser &, const bool front=false)
Represents a network address.
Definition Tuple.hxx:59
static const Data & toData(TransportType)
Converts the TransportType to a string representation of the transport type, e.g.
Definition Tuple.cxx:927
TransportKey mTransportKey
Definition Tuple.hxx:190
A Transport based on UDP.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
int & port()
Definition Uri.hxx:145
Data & host()
Definition Uri.hxx:40
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
void unregisterMarkListener(MarkListener *listener)
Removed a registered BlacklistListener handler from the DNS Interface for a particualr Resource Recor...
volatile bool & statisticsManagerEnabled()
Enable Statistics Manager.
void addAlias(const Data &domain, int port)
add an alias for this sip element
Definition SipStack.cxx:722
void registerMarkListener(MarkListener *listener)
Register a handler with the DNS Interface for notifications of when a Dns Resource Record has been bl...
void setEnumSuffixes(const std::vector< Data > &suffixes)
Specify which enum domains will be searched when sending.
void setEnumDomains(const std::map< Data, Data > &domains)
Specify which domains in the To: Uri will be subject to ENUM.
void removeAlias(const Data &domain, int port)
removes an alias from this sip element
Definition SipStack.cxx:740
void setStatisticsInterval(unsigned long seconds)
Sets the interval that determines the time between Statistics messages.
SSLType
Note: Before adding to the SSLType enum, please see the comments about mTlsCtx in resip/stack/ssl/Sec...
dcm! – add UnusedChecking(_enum) below;
const _Tp & resipMin(const _Tp &__a, const _Tp &__b)
Definition compat.hxx:182
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
Definition Inserter.hxx:312
void(* AfterSocketCreationFuncPtr)(Socket s, int transportType, const char *file, int line)
Definition Socket.hxx:107
void initNetwork()
set up network - does nothing in unix but needed for windows
Definition Socket.cxx:83
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
Definition Lock.hxx:28
bool isSecure(TransportType type)
Returns true if passed in transport type is a secure transport protocol.
unsigned int uint32_t
Definition Stun.hxx:34
TransportType
An enumeration of transport protocols.
IpVersion
An enumeration of IP versions.
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
#define EncodeStream