2#if defined(HAVE_CONFIG_H)
79#define RESIPROCATE_SUBSYSTEM Subsystem::DUM
84#ifdef RESIP_DUM_THREAD_DEBUG
85#define threadCheck() \
90 resip_assert(ThreadIf::tlsGetValue(mThreadDebugKey)); \
94#define threadCheck() void()
103 mInviteSessionHandler(0),
104 mClientRegistrationHandler(0),
105 mServerRegistrationHandler(0),
107 mDialogSetHandler(0),
108 mRequestValidationHandler(0),
109 mRegistrationPersistenceManager(0),
110 mPublicationPersistenceManager(0),
111 mIsDefaultServerReferHandler(true),
112 mClientPagerMessageHandler(0),
113 mServerPagerMessageHandler(0),
114 mDialogEventStateManager(0),
117 mDumShutdownHandler(0),
118 mShutdownState(Running),
120 mHiddenThreadDebugKey(0)
126 mFifo.setDescription(
"DialogUsageManager::mFifo");
128 mIncomingTarget =
new IncomingTarget(*
this);
129 mOutgoingTarget =
new OutgoingTarget(*
this);
131 if (createDefaultFeatures)
133 auto identity = std::make_shared<IdentityHandler>(*
this, *mIncomingTarget);
136 auto encryptionIncoming = std::make_shared<EncryptionManager>(*
this, *mIncomingTarget);
137 auto encryptionOutgoing = std::make_shared<EncryptionManager>(*
this, *mOutgoingTarget);
155 mShutdownState = Destroying;
158 if(!mDialogSetMap.empty())
160 DebugLog(<<
"DialogUsageManager::mDialogSetMap has " << mDialogSetMap.size() <<
" DialogSets");
161 DialogSetMap::const_iterator ds = mDialogSetMap.begin();
162 for(; ds != mDialogSetMap.end(); ++ds)
164 DebugLog(<<
"DialgSetId:" << ds->first);
165 DialogSet::DialogMap::const_iterator d = ds->second->mDialogs.begin();
166 for(; d != ds->second->mDialogs.end(); ++d)
169 DebugLog(<<
"DialogId:" << d->first <<
", " << *d->second);
174 while(!mDialogSetMap.empty())
176 DialogSet* ds = mDialogSetMap.begin()->second;
180 if(mIsDefaultServerReferHandler)
182 delete mServerSubscriptionHandlers[
"refer"];
185 delete mIncomingTarget;
186 delete mOutgoingTarget;
189 while (!mServerPublications.empty())
191 delete mServerPublications.begin()->second;
206 static Data n(
"DialogUsageManager");
214 const Data& ipInterface,
215 const Data& sipDomainname,
216 const Data& privateKeyPassPhrase,
218 unsigned transportFlags)
221 sipDomainname, privateKeyPassPhrase, sslType,
252 if (mDumShutdownHandler)
254 switch (mShutdownState)
256 case ShutdownRequested:
257 InfoLog (<<
"DialogUsageManager::onAllHandlesDestroyed: removing TU");
259 mShutdownState = RemovingTransactionUser;
272 InfoLog (<<
"shutdown: dialogSets=" << mDialogSetMap.size());
274 mDumShutdownHandler = h;
275 mShutdownState = ShutdownRequested;
296 mDumShutdownHandler = h;
298 mShutdownState = ShutdownRequested;
304 mAppDialogSetFactory = std::move(factory);
307std::shared_ptr<MasterProfile>&
311 return mMasterProfile;
314std::shared_ptr<UserProfile>&
318 return mMasterUserProfile;
324 mMasterProfile = masterProfile;
325 mMasterUserProfile = masterProfile;
330 mKeepAliveManager = std::move(manager);
331 mKeepAliveManager->setDialogUsageManager(
this);
336 mRedirectManager = std::move(manager);
341 mRedirectHandler = handler;
346 return mRedirectHandler;
352 mClientAuthManager = std::move(manager);
365 mClientRegistrationHandler = handler;
372 mServerRegistrationHandler = handler;
378 mDialogSetHandler = handler;
385 mInviteSessionHandler = handler;
392 mRequestValidationHandler = handler;
399 mRegistrationPersistenceManager = manager;
406 mPublicationPersistenceManager = manager;
413 DumTimeout t(type, duration, target, cseq, rseq);
414 mStack.
post(t, duration,
this);
418DialogUsageManager::addTimerMs(
DumTimeout::Type type,
unsigned long duration,
420 const Data &transactionId )
422 DumTimeout t(type, duration, target, cseq, rseq, transactionId);
423 mStack.
postMS(t, duration,
this);
430 resip_assert(mClientSubscriptionHandlers.find(eventType) == mClientSubscriptionHandlers.end());
431 mClientSubscriptionHandlers[eventType] = handler;
439 if (eventType ==
"refer")
441 auto it = mServerSubscriptionHandlers.find(eventType);
442 if (it != mServerSubscriptionHandlers.end())
445 mIsDefaultServerReferHandler =
false;
450 mServerSubscriptionHandlers[eventType] = handler;
457 resip_assert(mClientPublicationHandlers.find(eventType) == mClientPublicationHandlers.end());
458 mClientPublicationHandlers[eventType] = handler;
465 resip_assert(mServerPublicationHandlers.find(eventType) == mServerPublicationHandlers.end());
466 mServerPublicationHandlers[eventType] = handler;
473 resip_assert(mOutOfDialogHandlers.find(type) == mOutOfDialogHandlers.end());
474 mOutOfDialogHandlers[type] = handler;
480 mClientPagerMessageHandler = handler;
486 mServerPagerMessageHandler = handler;
492 std::vector<ExternalMessageHandler*>::iterator found = std::find(mExternalMessageHandlers.begin(), mExternalMessageHandlers.end(), handler);
493 if (found == mExternalMessageHandlers.end())
495 mExternalMessageHandlers.push_back(handler);
502 std::vector<ExternalMessageHandler*>::iterator found = std::find(mExternalMessageHandlers.begin(), mExternalMessageHandlers.end(), handler);
503 if (found != mExternalMessageHandlers.end())
505 mExternalMessageHandlers.erase(found);
512 std::vector<ExternalMessageHandler*>
empty;
513 empty.swap(mExternalMessageHandlers);
521 if (mDumShutdownHandler)
523 throw DumException(
"Cannot create new sessions when DUM is shutting down.", __FILE__, __LINE__);
532 appDs->mDialogSet = ds;
533 ds->mAppDialogSet = appDs;
535 StackLog ( <<
"************* Adding DialogSet ***************: " << ds->
getId());
537 mDialogSetMap[ds->
getId()] = ds;
542std::shared_ptr<SipMessage>
545 makeUacDialogSet(creator, appDs);
550DialogUsageManager::makeResponse(
SipMessage& response,
553 const Data& reason)
const
560DialogUsageManager::sendResponse(
const SipMessage& response)
563 mStack.
send(response,
this);
566std::shared_ptr<SipMessage>
572std::shared_ptr<SipMessage>
578std::shared_ptr<SipMessage>
580 const std::shared_ptr<UserProfile>& userProfile,
586 auto inv = makeNewSession(
new InviteSessionCreator(*
this, target, userProfile, initialOffer, level, alternative), appDs);
591std::shared_ptr<SipMessage>
601std::shared_ptr<SipMessage>
604 const std::shared_ptr<UserProfile>& userProfile,
610 resip_assert(mDialogSetMap.find(dialogSetId) == mDialogSetMap.end());
614 auto inv = makeNewSession(baseCreator, appDs);
619std::shared_ptr<SipMessage>
622 const std::shared_ptr<UserProfile>& userProfile,
633 replaces.
value() =
id.getCallId();
634 replaces.
param(p_toTag) =
id.getRemoteTag();
635 replaces.
param(p_fromTag) =
id.getLocalTag();
636 inv->header(h_Replaces) = replaces;
641std::shared_ptr<SipMessage>
644 const std::shared_ptr<UserProfile>& userProfile,
650 auto inv =
makeInviteSession(target, userProfile, initialOffer, level, alternative, ads);
657 replaces.
value() =
id.getCallId();
658 replaces.
param(p_toTag) =
id.getRemoteTag();
659 replaces.
param(p_fromTag) =
id.getLocalTag();
660 inv->header(h_Replaces) = replaces;
665std::shared_ptr<SipMessage>
680 replaces.
value() =
id.getCallId();
681 replaces.
param(p_toTag) =
id.getRemoteTag();
682 replaces.
param(p_fromTag) =
id.getLocalTag();
683 inv->header(h_Replaces) = replaces;
688std::shared_ptr<SipMessage>
697std::shared_ptr<SipMessage>
699 const std::shared_ptr<UserProfile>& userProfile,
707std::shared_ptr<SipMessage>
718std::shared_ptr<SipMessage>
720 const std::shared_ptr<UserProfile>& userProfile,
729 DebugLog(<<
"implicit subscription");
736 auto notify = serverSub->
update(&contents);
738 serverSub->
send(notify);
750 initialOffer, level, alternative, serverSub), appDs);
755 if (refer.
exists(h_ReferredBy))
757 inv->header(h_ReferredBy) = refer.
header(h_ReferredBy);
770std::shared_ptr<SipMessage>
773 return makeNewSession(
new SubscriptionCreator(*
this, target, userProfile, referTo), appDs);
776std::shared_ptr<SipMessage>
782std::shared_ptr<SipMessage>
786 return makeNewSession(
new SubscriptionCreator(*
this, target, userProfile, eventType, userProfile->getDefaultSubscriptionTime()), appDs);
789std::shared_ptr<SipMessage>
793 return makeNewSession(
new SubscriptionCreator(*
this, target, userProfile, eventType, subscriptionTime), appDs);
796std::shared_ptr<SipMessage>
800 return makeNewSession(
new SubscriptionCreator(*
this, target, userProfile, eventType, subscriptionTime, refreshInterval), appDs);
803std::shared_ptr<SipMessage>
809std::shared_ptr<SipMessage>
816std::shared_ptr<SipMessage>
823std::shared_ptr<SipMessage>
827 return makeNewSession(
new RegistrationCreator(*
this, target, userProfile, userProfile->getDefaultRegistrationTime()), appDs);
830std::shared_ptr<SipMessage>
833 return makeNewSession(
new RegistrationCreator(*
this, target, userProfile, registrationTime), appDs);
836std::shared_ptr<SipMessage>
842std::shared_ptr<SipMessage>
848std::shared_ptr<SipMessage>
850 const std::shared_ptr<UserProfile>& userProfile,
852 const Data& eventType,
856 return makeNewSession(
new PublicationCreator(*
this, targetDocument, userProfile, body, eventType, expiresSeconds), appDs);
859std::shared_ptr<SipMessage>
862 const Data& eventType,
869std::shared_ptr<SipMessage>
875std::shared_ptr<SipMessage>
884 if (!mClientPagerMessageHandler)
886 throw DumException(
"Cannot send MESSAGE messages without a ClientPagerMessageHandler", __FILE__, __LINE__);
890 ds->mClientPagerMessage = cpm;
918 msg->header(h_UserAgent).value() = userProfile->
getUserAgent();
922 msg->remove(h_ReplyTo);
923 msg->remove(h_UserAgent);
924 msg->remove(h_Organization);
925 msg->remove(h_Server);
926 msg->remove(h_Subject);
927 msg->remove(h_InReplyTo);
929 msg->remove(h_CallInfos);
930 msg->remove(h_Warnings);
949 msg->clearOutboundDecorators();
956 if (outboundDecorator)
958 msg->addOutboundDecorator(std::unique_ptr<MessageDecorator>(outboundDecorator->clone()));
961 if (msg->isRequest())
968 msg->header(h_Vias).front().param(p_branch).reset();
971 if (msg->exists(h_Vias))
975 msg->header(h_Vias).front().param(p_rport);
979 msg->header(h_Vias).front().remove(p_rport);
982 if(fixedTransportPort != 0)
984 msg->header(h_Vias).front().sentPort() = fixedTransportPort;
987 if(!fixedTransportInterface.
empty())
989 msg->header(h_Vias).front().sentHost() = fixedTransportInterface;
993 if (mClientAuthManager.get() && msg->header(
h_RequestLine).method() != ACK)
995 mClientAuthManager->addAuthentication(*msg);
1002 if (mDialogEventStateManager)
1004 Dialog* d = ds->findDialog(*msg);
1008 mDialogEventStateManager->onTryingUac(*ds, *msg);
1015 DebugLog (<<
"SEND: " << std::endl << std::endl << *msg);
1018 outgoingProcess(std::unique_ptr<Message>(event));
1029void DialogUsageManager::outgoingProcess(std::unique_ptr<Message> message)
1042 InfoLog(<<
"Got a DumFeatureMessage" << featureMsg);
1054 FeatureChainMap::iterator it;
1089 if (event->message()->isRequest())
1107 std::unique_ptr<SipMessage> toSend(
static_cast<SipMessage*
>(event->message()->clone()));
1112 if (event->message()->exists(h_Routes) &&
1113 !event->message()->header(h_Routes).empty() &&
1114 event->message()->header(h_Routes).front().isWellFormed() &&
1115 !event->message()->header(h_Routes).front().uri().exists(p_lr))
1118 sendUsingOutboundIfAppropriate(*userProfile, std::move(toSend));
1122 sendUsingOutboundIfAppropriate(*userProfile, std::move(toSend));
1127 sendResponse(*event->message());
1133DialogUsageManager::sendUsingOutboundIfAppropriate(
UserProfile& userProfile, std::unique_ptr<SipMessage> msg)
1146 DebugLog(<<
"Sending with OutboundProxy=" << userProfile.
getOutboundProxy().
uri() <<
" in route set, to FlowTuple=" << userProfile.mClientOutboundFlowTuple <<
", FlowKey=" << userProfile.mClientOutboundFlowTuple.
mFlowKey <<
": " << msg->brief());
1147 mStack.
sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple,
this);
1152 mStack.
send(std::move(msg),
this);
1159 DebugLog(<<
"Sending to FlowTuple=" << userProfile.mClientOutboundFlowTuple <<
", FlowKey=" << userProfile.mClientOutboundFlowTuple.
mFlowKey <<
": " << msg->brief());
1160 mStack.
sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple,
this);
1173 DebugLog(<<
"Sending to FlowTuple=" << userProfile.mClientOutboundFlowTuple <<
", FlowKey=" << userProfile.mClientOutboundFlowTuple.
mFlowKey <<
": " << msg->brief());
1174 mStack.
sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple,
this);
1178 DebugLog(<<
"Send: " << msg->brief());
1179 mStack.
send(std::move(msg),
this);
1191 throw Exception(
"Request no longer exists", __FILE__, __LINE__);
1202 if (mShutdownState != Destroying)
1208 InfoLog(<<
"DialogUsageManager::destroy() not posting to stack");
1213DialogUsageManager::destroy(
DialogSet* dset)
1215 if (mShutdownState != Destroying)
1221 InfoLog(<<
"DialogUsageManager::destroy() not posting to stack");
1226DialogUsageManager::destroy(
Dialog* d)
1228 if (mShutdownState != Destroying)
1234 InfoLog(<<
"DialogUsageManager::destroy() not posting to stack");
1240DialogUsageManager::findDialog(
const DialogId&
id)
1242 DialogSet* ds = findDialogSet(
id.getDialogSetId());
1245 return ds->findDialog(
id);
1257 Dialog* dialog = findDialog(
id);
1258 if (dialog && dialog->mInviteSession)
1266pair<InviteSessionHandle, int>
1273 replaces.
param(p_toTag),
1274 replaces.
param(p_fromTag)));
1275 int ErrorStatusCode = 481;
1286 ErrorStatusCode = 603;
1292 if(replaces.
exists(p_earlyOnly))
1294 ErrorStatusCode = 486;
1301 ErrorStatusCode = 481;
1305 return make_pair(is, ErrorStatusCode);
1310 Dialog* pDialog = findDialog(
id);
1312 if(pDialog && pDialog->mAppDialog)
1314 return pDialog->mAppDialog->
getHandle();
1323 DialogSet* pDialogSet = findDialogSet(
id);
1325 if(pDialogSet && pDialogSet->mAppDialogSet)
1327 return pDialogSet->mAppDialogSet->
getHandle();
1337#ifdef RESIP_DUM_THREAD_DEBUG
1338 if(!mThreadDebugKey)
1353 ErrLog(<<
"ThreadIf::tlsKeyCreate() failed!");
1361 if (mShutdownState == Shutdown)
1370 InfoLog (<<
"TU unregistered ");
1371 resip_assert(mShutdownState == RemovingTransactionUser);
1373 mShutdownState = Shutdown;
1374 if (mDumShutdownHandler)
1377 mDumShutdownHandler = 0;
1388 if (mKeepAliveManager.get())
1390 mKeepAliveManager->receivedPong(pong->
getFlow());
1425 if (mKeepAliveManager.get())
1427 mKeepAliveManager->process(*keepAliveMsg);
1435 if (keepAlivePongMsg)
1438 if (mKeepAliveManager.get())
1440 mKeepAliveManager->process(*keepAlivePongMsg);
1453 std::list<DialogSet*> dialogSetsToNotify;
1454 DialogSetMap::iterator it = mDialogSetMap.begin();
1455 for(; it != mDialogSetMap.end(); it++)
1457 if(it->second->mUserProfile->clientOutboundEnabled() &&
1458 it->second->mUserProfile->getClientOutboundFlowTuple().mFlowKey == terminated->
getFlow().
mFlowKey &&
1459 it->second->mUserProfile->getClientOutboundFlowTuple() == terminated->
getFlow())
1461 if(it->second->getClientRegistration().isValid())
1464 dialogSetsToNotify.push_front(it->second);
1468 dialogSetsToNotify.push_back(it->second);
1473 std::list<DialogSet*>::iterator it2 = dialogSetsToNotify.begin();
1474 for(; it2 != dialogSetsToNotify.end();it2++)
1476 (*it2)->flowTerminated(terminated->
getFlow());
1480 if (mConnectionTerminatedEventDispatcher.dispatch(msg.get()))
1501 if (externalMessage)
1503 processExternalMessage(externalMessage);
1508 incomingProcess(std::move(msg));
1514 bool handled =
false;
1515 for(std::vector<ExternalMessageHandler*>::iterator i = mExternalMessageHandlers.begin();
1516 i != mExternalMessageHandlers.end(); ++i)
1518 (*i)->onMessage(externalMessage, handled);
1527DialogUsageManager::incomingProcess(std::unique_ptr<Message> msg)
1542 reason.
append(
"Malformed From, ",16);
1548 reason.
append(
"Malformed To, ",14);
1554 reason.
append(
"Malformed Call-Id, ",19);
1563 reason.
append(
"fix your code!",14);
1565 makeResponse(failure, *sipMsg, 400, reason);
1566 sendResponse(failure);
1569 InfoLog (<<
"Malformed header in message (" << reason <<
") - rejecting/discarding: " << *sipMsg);
1586 FeatureChainMap::iterator it;
1628 DebugLog (<<
"Got: " << msg->brief());
1637 sipMsg =
dynamic_cast<SipMessage*
>(msg.get());
1642 DebugLog ( <<
"DialogUsageManager::process: found SipMessage" );
1646 if( !validateRequestURI(*sipMsg) )
1648 DebugLog (<<
"Failed RequestURI validation " << *sipMsg);
1656 if( !validateRequiredOptions(*sipMsg) )
1658 DebugLog (<<
"Failed required options validation " << *sipMsg);
1661 if( !validate100RelSupport(*sipMsg) )
1663 DebugLog (<<
"Remote party does not support 100rel " << *sipMsg);
1666 if(
getMasterProfile()->validateContentEnabled() && !validateContent(*sipMsg) )
1668 DebugLog (<<
"Failed content validation " << *sipMsg);
1671 if(
getMasterProfile()->validateAcceptEnabled() && !validateAccept(*sipMsg) )
1673 DebugLog (<<
"Failed accept validation " << *sipMsg);
1677 if (sipMsg->
header(h_From).exists(p_tag))
1679 if (mergeRequest(*sipMsg) )
1681 InfoLog (<<
"Merged request: " << *sipMsg);
1685 processRequest(*sipMsg);
1689 processResponse(*sipMsg);
1703 return mFifo.messageAvailable();
1710 if (
mFifo.messageAvailable())
1713#ifdef RESIP_DUM_THREAD_DEBUG
1714 mThreadDebugKey=mHiddenThreadDebugKey;
1717#ifdef RESIP_DUM_THREAD_DEBUG
1724 mHiddenThreadDebugKey=mThreadDebugKey;
1728 return mFifo.messageAvailable();
1734 std::unique_ptr<Message> message;
1738 message.reset(
mFifo.getNext());
1742 message.reset(
mFifo.getNext(timeoutMs));
1747#ifdef RESIP_DUM_THREAD_DEBUG
1748 mThreadDebugKey=mHiddenThreadDebugKey;
1751#ifdef RESIP_DUM_THREAD_DEBUG
1758 mHiddenThreadDebugKey=mThreadDebugKey;
1762 return mFifo.messageAvailable();
1769 if (
mFifo.messageAvailable())
1772#ifdef RESIP_DUM_THREAD_DEBUG
1773 mThreadDebugKey = mHiddenThreadDebugKey;
1776#ifdef RESIP_DUM_THREAD_DEBUG
1783 mHiddenThreadDebugKey = mThreadDebugKey;
1784 mThreadDebugKey = 0;
1787 return mFifo.messageAvailable();
1793 std::unique_ptr<Message> message;
1795 if (timeoutMs == -1)
1797 message.reset(
mFifo.getNext());
1801 message.reset(
mFifo.getNext(timeoutMs));
1806#ifdef RESIP_DUM_THREAD_DEBUG
1807 mThreadDebugKey = mHiddenThreadDebugKey;
1810#ifdef RESIP_DUM_THREAD_DEBUG
1817 mHiddenThreadDebugKey = mThreadDebugKey;
1818 mThreadDebugKey = 0;
1821 return mFifo.messageAvailable();
1825DialogUsageManager::validateRequestURI(
const SipMessage& request)
1830 InfoLog (<<
"Received an unsupported method: " << request.
brief());
1833 makeResponse(failure, request, 405);
1835 sendResponse(failure);
1837 if(mRequestValidationHandler)
1846 InfoLog (<<
"Received an unsupported scheme: " << request.
brief());
1848 makeResponse(failure, request, 416);
1849 sendResponse(failure);
1851 if(mRequestValidationHandler)
1862DialogUsageManager::validateRequiredOptions(
const SipMessage& request)
1865 if(request.
exists(h_Requires) &&
1870 if (!unsupported.
empty())
1872 InfoLog (<<
"Received an unsupported option tag(s): " << request.
brief());
1875 makeResponse(failure, request, 420);
1876 failure.
header(h_Unsupporteds) = unsupported;
1877 sendResponse(failure);
1879 if(mRequestValidationHandler)
1891DialogUsageManager::validate100RelSupport(
const SipMessage& request)
1901 makeResponse(failure, request, 421);
1903 sendResponse(failure);
1905 if(mRequestValidationHandler)
1918DialogUsageManager::validateContent(
const SipMessage& request)
1922 if (!(request.
exists(h_ContentDisposition) &&
1924 request.
header(h_ContentDisposition).exists(p_handling) &&
1929 InfoLog (<<
"Received an unsupported mime type: " << request.
header(h_ContentType) <<
" for " << request.
brief());
1932 makeResponse(failure, request, 415);
1934 sendResponse(failure);
1936 if(mRequestValidationHandler)
1944 InfoLog (<<
"Received an unsupported content encoding: " << request.
header(h_ContentEncoding) <<
" for " << request.
brief());
1946 makeResponse(failure, request, 415);
1948 sendResponse(failure);
1950 if(mRequestValidationHandler)
1959 InfoLog (<<
"Received an unsupported language: " << request.
header(h_ContentLanguages).front() <<
" for " << request.
brief());
1962 makeResponse(failure, request, 415);
1964 sendResponse(failure);
1966 if(mRequestValidationHandler)
1977DialogUsageManager::validateAccept(
const SipMessage& request)
1981 if(request.
exists(h_Accepts))
1983 for (Mimes::const_iterator i = request.
header(h_Accepts).begin();
1984 i != request.
header(h_Accepts).end(); i++)
1993 else if(method == INVITE ||
1994 method == OPTIONS ||
2009 InfoLog (<<
"Received unsupported mime types in accept header: " << request.
brief());
2011 makeResponse(failure, request, 406);
2013 sendResponse(failure);
2015 if(mRequestValidationHandler)
2022DialogUsageManager::mergeRequest(
const SipMessage& request)
2027 if (!request.
header(h_To).exists(p_tag))
2032 makeResponse(failure, request, 482,
"Merged Request");
2034 sendResponse(failure);
2043DialogUsageManager::processRequest(
const SipMessage& request)
2045 DebugLog ( <<
"DialogUsageManager::processRequest: " << request.
brief());
2047 if (mShutdownState != Running && mShutdownState != ShutdownRequested)
2049 WarningLog (<<
"Ignoring a request since we are shutting down " << request.
brief());
2052 makeResponse(failure, request, 480,
"UAS is shutting down");
2053 sendResponse(failure);
2059 processPublish(request);
2063 bool toTag = request.
header(h_To).exists(p_tag);
2079 makeResponse(failure, request, 400,
"Registration requests can't have To: tags.");
2081 sendResponse(failure);
2093 makeResponse(failure, request, 481);
2095 InfoLog (<<
"Rejected request (which was in a dialog) " << request.
brief());
2096 sendResponse(failure);
2100 InfoLog (<<
"ACK doesn't match any dialog" << request.
brief());
2105 InfoLog (<<
"Handling in-dialog request: " << request.
brief());
2125 makeResponse(failure, request, 481);
2127 sendResponse(failure);
2134 if (i != mCancelMap.end())
2136 i->second->dispatch(request);
2142 makeResponse(failure, request, 481);
2143 sendResponse(failure);
2151 if (!checkEventPackage(request))
2153 InfoLog (<<
"Rejecting request (unsupported package) "
2154 << request.
brief());
2169 if(mDialogSetMap.find(
id) != mDialogSetMap.end())
2175 makeResponse(badrequest, request, 400);
2177 sendResponse(badrequest);
2181 if (mDumShutdownHandler)
2184 makeResponse(forbidden, request, 480);
2186 sendResponse(forbidden);
2193 StackLog ( <<
"*********** Calling AppDialogSetFactory *************: " << dset->
getId());
2194 AppDialogSet* appDs = mAppDialogSetFactory->createAppDialogSet(*
this, request);
2195 appDs->mDialogSet = dset;
2197 dset->mAppDialogSet = appDs;
2199 StackLog ( <<
"************* Adding DialogSet ***************: " << dset->
getId());
2201 mDialogSetMap[dset->
getId()] = dset;
2209 makeResponse(failure, request, 400, e.
getMessage());
2211 sendResponse(failure);
2229DialogUsageManager::processResponse(
const SipMessage& response)
2237 DebugLog ( <<
"DialogUsageManager::processResponse: " << std::endl << std::endl << response.
brief());
2242 InfoLog (<<
"Throwing away stray response: " << std::endl << std::endl << response.
brief());
2248DialogUsageManager::processPublish(
const SipMessage& request)
2250 if (!checkEventPackage(request))
2252 InfoLog(<<
"Rejecting request (unsupported package) " << request.
brief());
2256 if (request.
exists(h_SIPIfMatch))
2258 ServerPublications::iterator i = mServerPublications.find(request.
header(h_SIPIfMatch).value());
2259 if (i != mServerPublications.end())
2261 i->second->dispatch(request);
2268 if (mPublicationPersistenceManager &&
2272 mServerPublications[request.
header(h_SIPIfMatch).value()] = sp;
2277 auto response = std::make_shared<SipMessage>();
2278 makeResponse(*response, request, 412);
2286 while (mServerPublications.find(etag) != mServerPublications.end())
2294 mServerPublications[etag] = sp;
2300 auto response = std::make_shared<SipMessage>();
2301 makeResponse(*response, request, 400);
2308DialogUsageManager::checkEventPackage(
const SipMessage& request)
2310 int failureCode = 0;
2315 if (!request.
exists(h_Event))
2327 InfoLog (<<
"No handler for event package for SUBSCRIBE: "
2328 << request.
header(h_Event).value());
2335 InfoLog (<<
"No handler for event package for NOTIFY: "
2336 << request.
header(h_Event).value());
2343 InfoLog (<<
"No handler for event package for PUBLISH: "
2344 << request.
header(h_Event).value());
2353 if (failureCode > 0)
2355 auto response = std::make_shared<SipMessage>();
2356 makeResponse(*response, request, failureCode);
2357 if(failureCode == 489)
2368DialogUsageManager::findDialogSet(
const DialogSetId&
id)
2371 StackLog ( <<
"Looking for dialogSet: " <<
id <<
" in map:");
2373 DialogSetMap::const_iterator it = mDialogSetMap.find(
id);
2375 if (it == mDialogSetMap.end())
2382 if(it->second->isDestroying())
2384 StackLog ( <<
"isDestroying() == true" );
2396DialogUsageManager::findCreator(
const DialogId&
id)
2398 DialogSet* ds = findDialogSet(
id.getDialogSetId());
2410DialogUsageManager::removeDialogSet(
const DialogSetId& dsId)
2412 StackLog ( <<
"************* Removing DialogSet ***************: " << dsId);
2414 mDialogSetMap.erase(dsId);
2416 if (mRedirectManager)
2418 mRedirectManager->removeDialogSet(dsId);
2425 map<Data, ClientSubscriptionHandler*>::iterator res = mClientSubscriptionHandlers.find(eventType);
2426 if (res != mClientSubscriptionHandlers.end())
2439 map<Data, ServerSubscriptionHandler*>::iterator res = mServerSubscriptionHandlers.find(eventType);
2440 if (res != mServerSubscriptionHandlers.end())
2453 map<Data, ClientPublicationHandler*>::iterator res = mClientPublicationHandlers.find(eventType);
2454 if (res != mClientPublicationHandlers.end())
2467 map<Data, ServerPublicationHandler*>::iterator res = mServerPublicationHandlers.find(eventType);
2468 if (res != mServerPublicationHandlers.end())
2479DialogUsageManager::getOutOfDialogHandler(
const MethodTypes type)
2481 map<MethodTypes, OutOfDialogHandler*>::iterator res = mOutOfDialogHandlers.find(type);
2482 if (res != mOutOfDialogHandlers.end())
2508 mOutgoingMessageInterceptor = feat;
2515 for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it)
2517 for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i)
2519 std::vector<ServerSubscriptionHandle> serverSubs = i->second->getServerSubscriptions();
2520 for (std::vector<ServerSubscriptionHandle>::iterator iss = serverSubs.begin(); iss != serverSubs.end(); ++iss)
2522 functor->
apply(*iss);
2532 for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it)
2534 for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i)
2536 std::vector<ClientSubscriptionHandle> clientSubs = i->second->getClientSubscriptions();
2537 for (std::vector<ClientSubscriptionHandle>::iterator ics = clientSubs.begin(); ics != clientSubs.end(); ++ics)
2539 functor->
apply(*ics);
2550 ServerSubscriptions tempSubscriptions = mServerSubscriptions;
2551 ServerSubscriptions::iterator it = tempSubscriptions.begin();
2552 for (; it != tempSubscriptions.end(); it++)
2554 it->second->end(reason);
2563 ServerPublications tempPublications = mServerPublications;
2564 ServerPublications::iterator it = tempPublications.begin();
2565 for (; it != tempPublications.end(); it++)
2574 mConnectionTerminatedEventDispatcher.addListener(listener);
2580 mConnectionTerminatedEventDispatcher.removeListener(listener);
2584DialogUsageManager::requestMergedRequestRemoval(
const MergedRequestKey& key)
2587 if (mShutdownState == Running)
2589 DebugLog(<<
"Got merged request removal request");
2598 DebugLog(<<
"Merged request removed");
2599 mMergedRequests.erase(key);
2605 return *mIncomingTarget;
2611 return *mOutgoingTarget;
2620 mDialogEventStateManager->mDialogEventHandler = handler;
2624 delete mDialogEventStateManager;
2625 mDialogEventStateManager=0;
2627 return mDialogEventStateManager;
2633 if(userProfile->isAdvertisedCapability(Headers::Allow))
2637 if(userProfile->isAdvertisedCapability(Headers::AcceptEncoding))
2641 if(userProfile->isAdvertisedCapability(Headers::AcceptLanguage))
2645 if(userProfile->isAdvertisedCapability(Headers::AllowEvents))
2649 if(userProfile->isAdvertisedCapability(Headers::Supported))
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
AppDialogSetHandle getHandle()
virtual std::shared_ptr< UserProfile > selectUASUserProfile(const SipMessage &)
AppDialogHandle getHandle()
std::shared_ptr< SipMessage > getLastRequest() const noexcept
The abstract base-class for all exceptions thrown by resip code.
const Data & getMessage() const noexcept
virtual void dispatch(const SipMessage &msg)=0
Represents the "callid" element in the SIP grammar.
bool exists(const Param< CallID > ¶mType) const
const Data & param(const ExtensionParameter ¶m) const
Const accessor for non-natively-supported parameter types.
virtual void apply(ClientSubscriptionHandle)=0
const Tuple & getFlow() const
Base class for all SIP body types.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
Data & append(const char *str, size_type len)
Appends the specified number of bytes to the end of this Data.
bool empty() const noexcept
Checks whether the Data is empty.
Implements the FSM for dialog state as spec'd in RFC 4235.
const Data & getCallId() const
const Data & getLocalTag() const
BaseCreator * getCreator() const noexcept
void end(const Data &endReason)
void dispatch(const SipMessage &msg)
void setUserProfile(std::shared_ptr< UserProfile > userProfile)
std::shared_ptr< UserProfile > getUserProfile() const
DialogSetId getId() const
FeatureChainMap mIncomingFeatureChainMap
void addTransport(TransportType protocol, int port=0, IpVersion version=V4, const Data &ipInterface=Data::Empty, const Data &sipDomainname=Data::Empty, const Data &privateKeyPassPhrase=Data::Empty, SecurityTypes::SSLType sslType=SecurityTypes::DynamicTLS, unsigned transportFlags=0)
void setClientRegistrationHandler(ClientRegistrationHandler *)
If there is no such handler, calling makeRegistration will throw.
void addServerPublicationHandler(const Data &eventType, ServerPublicationHandler *)
void addOutOfDialogHandler(MethodTypes, OutOfDialogHandler *)
DialogEventStateManager * createDialogEventStateManager(DialogEventHandler *handler)
void send(std::shared_ptr< SipMessage > request)
void addExternalMessageHandler(ExternalMessageHandler *handler)
Add/Remove External Message Handler do following op when processing thread in not running.
void shutdown(DumShutdownHandler *)
virtual const Data & name() const
Return the name of this TransactionUser.
void applyToAllServerSubscriptions(ServerSubscriptionFunctor *)
friend class ServerPublication
void setInviteSessionHandler(InviteSessionHandler *)
If there is no such handler, calling makeInviteSession will throw and receiving an INVITE as a UAS wi...
void setClientAuthManager(std::unique_ptr< ClientAuthManager > client) noexcept
If there is no ClientAuthManager, when the client receives a 401/407, pass it up through the normal B...
std::shared_ptr< DumFeature > mOutgoingMessageInterceptor
void setServerPagerMessageHandler(ServerPagerMessageHandler *) noexcept
void addClientPublicationHandler(const Data &eventType, ClientPublicationHandler *)
If there is no such handler, calling makePublication will throw.
void setServerRegistrationHandler(ServerRegistrationHandler *)
If no such handler, UAS will respond to REGISTER with 405 Method Not Allowed.
friend class ClientPagerMessage
void setRedirectManager(std::unique_ptr< RedirectManager > redirect) noexcept
std::shared_ptr< UserProfile > & getMasterUserProfile()
void removeExternalMessageHandler(ExternalMessageHandler *handler)
std::shared_ptr< SipMessage > makePublication(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, const Contents &body, const Data &eventType, uint32_t expiresSeconds, AppDialogSet *=nullptr)
bool process(Mutex *mutex=NULL)
void end(DialogSetId invSessionId)
std::shared_ptr< SipMessage > makeRefer(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, const H_ReferTo::Type &referTo, AppDialogSet *=nullptr)
void setServerAuthManager(std::shared_ptr< ServerAuthManager > server)
If there is no ServerAuthManager, the server does not authenticate requests.
void setDialogSetHandler(DialogSetHandler *handler) noexcept
void setRegistrationPersistenceManager(RegistrationPersistenceManager *)
Sets a manager to handle storage of registration or publication state.
DialogUsageManager(SipStack &stack, bool createDefaultFeatures=false)
std::shared_ptr< SipMessage > makeInviteSession(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, const Contents *initialOffer, AppDialogSet *ads=nullptr)
RedirectHandler * getRedirectHandler() const noexcept
void clearExternalMessageHandler()
ClientPublicationHandler * getClientPublicationHandler(const Data &eventType)
DumFeatureChain::FeatureList mOutgoingFeatureList
InviteSessionHandle findInviteSession(const DialogId &id)
std::shared_ptr< SipMessage > makeOutOfDialogRequest(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, MethodTypes meth, AppDialogSet *=nullptr)
ClientSubscriptionHandler * getClientSubscriptionHandler(const Data &eventType)
void registerForConnectionTermination(Postable *)
Note: Implementations of Postable must delete the message passed via post.
ServerPublicationHandler * getServerPublicationHandler(const Data &eventType)
virtual ~DialogUsageManager()
FeatureChainMap mOutgoingFeatureChainMap
void endAllServerPublications()
AppDialogSetHandle findAppDialogSet(const DialogSetId &id)
TargetCommand::Target & dumOutgoingTarget()
void setMasterProfile(const std::shared_ptr< MasterProfile > &masterProfile)
void addIncomingFeature(std::shared_ptr< DumFeature > feat)
void sendCommand(std::shared_ptr< SipMessage > request)
TargetCommand::Target & dumIncomingTarget()
void endAllServerSubscriptions(TerminateReason reason=Deactivated)
void addOutgoingFeature(std::shared_ptr< DumFeature > feat)
void setClientPagerMessageHandler(ClientPagerMessageHandler *) noexcept
ClientPagerMessageHandle makePagerMessage(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, AppDialogSet *=nullptr)
void applyToAllClientSubscriptions(ClientSubscriptionFunctor *)
ServerSubscriptionHandler * getServerSubscriptionHandler(const Data &eventType)
void setAppDialogSetFactory(std::unique_ptr< AppDialogSetFactory >) noexcept
void setRequestValidationHandler(RequestValidationHandler *)
void setOutgoingMessageInterceptor(std::shared_ptr< DumFeature > feat) noexcept
void addServerSubscriptionHandler(const Data &eventType, ServerSubscriptionHandler *)
AppDialogHandle findAppDialog(const DialogId &id)
DumFeatureChain::FeatureList mIncomingFeatureList
void internalProcess(std::unique_ptr< Message > msg)
void setKeepAliveManager(std::unique_ptr< KeepAliveManager > keepAlive) noexcept
std::shared_ptr< SipMessage > makeInviteSessionFromRefer(const SipMessage &refer, ServerSubscriptionHandle, const Contents *initialOffer, AppDialogSet *=nullptr)
virtual void onAllHandlesDestroyed()
void setPublicationPersistenceManager(PublicationPersistenceManager *)
std::shared_ptr< MasterProfile > & getMasterProfile()
void unRegisterForConnectionTermination(Postable *)
void setAdvertisedCapabilities(SipMessage &msg, const std::shared_ptr< UserProfile > &userProfile)
void setRedirectHandler(RedirectHandler *handler) noexcept
std::shared_ptr< SipMessage > makeRegistration(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, AppDialogSet *=nullptr)
void forceShutdown(DumShutdownHandler *)
void addClientSubscriptionHandler(const Data &eventType, ClientSubscriptionHandler *)
If there is no such handler, calling makeSubscription will throw.
std::shared_ptr< SipMessage > makeSubscription(const NameAddr &target, const std::shared_ptr< UserProfile > &userProfile, const Data &eventType, AppDialogSet *=nullptr)
const DialogId & getDialogId() const
dcm! – kill typedef std::list<DialogId> DialogIdSet;
virtual void executeCommand()=0
dcm! – what is the intent of ApplicationMessage, especially as used in
virtual const Data & getTransactionId() const
static void setOutgoingEncryptionLevel(SipMessage &message, DialogUsageManager::EncryptionLevel level)
virtual void onDumCanBeDeleted()=0
BaseUsageHandle getBaseUsage() const
virtual void shutdownWhenEmpty()
virtual void dumpHandles() const
static Handle< InviteSession > NotValid()
static void processStrictRoute(SipMessage &request)
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
InviteSessionHandle getSessionHandle()
bool isTerminated() const
const Tuple & getFlow() const
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
virtual Brief brief() const
return a facet for brief encoding of message
Represents the "media-type" element in the RFC 3261 grammar.
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
const Data & getTransactionId() const
bool empty() const
return true or false indicating whether the mParsers vector is empty or not
virtual const NameAddr & getOutboundProxy() const
virtual bool getForceOutboundProxyOnAllRequestsEnabled() const noexcept
virtual const Data & getUserAgent() const
virtual std::shared_ptr< MessageDecorator > getOutboundDecorator() noexcept
virtual const Tokens & getProxyRequires() const
virtual bool hasUserAgent() const noexcept
virtual int getFixedTransportPort() const noexcept
virtual bool hasProxyRequires() const noexcept
virtual bool getExpressOutboundAsRouteSetEnabled() const noexcept
virtual const Data & getFixedTransportInterface() const
virtual bool hasOutboundProxy() const noexcept
virtual bool getRportEnabled() const noexcept
Much like class Lock above, but takes pointer argument to Lockable, which may be NULL.
Abstract interface of a datastore of all publication documents processed by DUM.
virtual bool documentExists(const Data &eventType, const Data &documentKey, const Data &eTag)=0
static Data getCryptoRandomHex(unsigned int numBytes)
This class creates registration requests on behalf of a client.
Abstract interface of a datastore of all registered endpoints processed by DUM.
Data & unknownMethodName()
MethodTypes getMethod() const
Handler used to know when an incoming request failed validation.
virtual void onInvalidContentType(const SipMessage &request)=0
virtual void onInvalidRequiredOptions(const SipMessage &request)=0
virtual void onInvalidMethod(const SipMessage &request)=0
virtual void onInvalidContentLanguage(const SipMessage &request)=0
virtual void on100RelNotSupportedByRemote(const SipMessage &request)=0
virtual void onInvalidScheme(const SipMessage &request)=0
virtual void onInvalidAccept(const SipMessage &request)=0
virtual void onInvalidContentEncoding(const SipMessage &request)=0
virtual void dispatch(const SipMessage &msg)
virtual void apply(ServerSubscriptionHandle)=0
void setSubscriptionState(SubscriptionState state)
std::shared_ptr< SipMessage > update(const Contents *document)
void send(std::shared_ptr< SipMessage > msg) override
SIP body type for holding SipFrag contents (MIME content-type message/sipfrag).
Represents a SIP message.
bool isRequest() const
Returns true if message is a request, false otherwise.
Contents * getContents() const
Retrieves the body of a SIP message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
virtual const Data & getTransactionId() const
Returns the transaction id from the branch or if 2543, the computed hash.
bool isResponse() const
Returns true if message is a response, false otherwise.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
bool isExternal() const
Check if SipMessage is to be treated as it came off the wire.
resip::MethodTypes method() const
returns the method type of the message
This is the primary point of interaction between the app-layer and the stack.
Security * getSecurity() const
Returns a pointer to the embedded Security object, 0 if not set.
void send(const SipMessage &msg, TransactionUser *tu=0)
allows a TU to send a message
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.
void registerTransactionUser(TransactionUser &, const bool front=false)
add a TU to the TU selection chain
static Data getHostAddress()
Get one of the IP address for this host (calls through to gethostbyname) and is not threadsafe.
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.
void unregisterTransactionUser(TransactionUser &)
Removes a TU from the TU selection chain.
void requestTransactionUserShutdown(TransactionUser &)
Queue a shutdown request to the specified TU.
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.
static const char * Optional
static const char * C100rel
static int tlsKeyCreate(TlsKey &key, TlsDestructor *destructor)
This function follows pthread_key_create() signature.
static int tlsSetValue(TlsKey key, const void *val)
This function follows pthread_setspecific() signature.
Represents the "token" element in the RFC 3261 grammar.
The base-class for an RFC 3261 Transaction User.
TimeLimitFifo< Message > mFifo
This TransactionUser's fifo.
void post(Message *msg)
Posts a Message to this TransactionUser's fifo.
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
void remove(const Param< Uri > ¶mType)
virtual bool & clientOutboundEnabled() noexcept
SSLType
Note: Before adding to the SSLType enum, please see the comments about mTlsCtx in resip/stack/ssl/Sec...
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
std::mutex Mutex
A semaphore that can be locked by only one thread at a time.
bool isEqualNoCase(const Data &left, const Data &right)
Handle< AppDialogSet > AppDialogSetHandle
Handle< AppDialog > AppDialogHandle
std::unique_lock< RecursiveMutex > RecursiveLock
InserterPClass< T > InserterP(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
TransportType
An enumeration of transport protocols.
RequestLineType h_RequestLine
std::recursive_mutex RecursiveMutex
IpVersion
An enumeration of IP versions.
H_AllowEventss h_AllowEvents