Skip to content

Commit ad83330

Browse files
authored
Feat/update within invite transaction (#434)
* logging * handle UPDATE during an INVITE transaction that is not completed * avoid regex if not needed * route update during invite in uac transaction * add scenarios
1 parent f79f87f commit ad83330

17 files changed

+846
-89
lines changed

src/client-controller.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,14 @@ namespace drachtio {
337337
client_ptr client = this->findClientForDialog( dialogId );
338338
if( !client ) {
339339
client = this->findClientForNetTransaction( transactionId );
340+
if (!client) client = this->findClientForAppTransaction( transactionId );
340341
if( !client ) {
341-
DR_LOG(log_warning) << "ClientController::route_response_inside_invite - client managing transaction has disconnected: " << transactionId ;
342+
DR_LOG(log_warning) << "ClientController::route_request_inside_invite - client managing transaction has disconnected: " << transactionId ;
342343
return false ;
343344
}
344345
}
345346

346-
DR_LOG(log_debug) << "ClientController::route_response_inside_invite - sending response to client" ;
347+
DR_LOG(log_debug) << "ClientController::route_request_inside_invite - sending cancel prack or update to client" ;
347348
void (BaseClient::*fn)(const string&, const string&, const string&, const SipMsgData_t&) = &BaseClient::sendSipMessageToClient;
348349
m_ioservice.post( std::bind(fn, client, transactionId, dialogId, rawSipMsg, meta) ) ;
349350

@@ -355,13 +356,18 @@ namespace drachtio {
355356
client_ptr client = this->findClientForDialog( dialogId );
356357
string method_name = sip->sip_request->rq_method_name ;
357358
bool isBye = 0 == method_name.compare("BYE");
359+
bool isUpdate = 0 == method_name.compare("UPDATE");
358360
bool isFinalNotifyForSubscribe = sip_method_notify == sip->sip_request->rq_method &&
359361
NULL != sip->sip_subscription_state &&
360362
NULL != sip->sip_subscription_state->ss_substate &&
361363
NULL != strstr(sip->sip_subscription_state->ss_substate, "terminated") &&
362364
(NULL == sip->sip_event ||
363365
(sip->sip_event->o_type && !std::strstr(sip->sip_event->o_type, "refer") && !std::strstr(sip->sip_event->o_type, "REFER"))
364366
);
367+
368+
if (isUpdate && !client) {
369+
client = this->findClientForNetTransaction( transactionId );
370+
}
365371

366372
if( !client ) {
367373
DR_LOG(log_warning) << "ClientController::route_request_inside_dialog - client managing dialog has disconnected: " << dialogId ;

src/invite-in-progress.cpp

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@ namespace drachtio {
1818

1919
IIP::IIP(nta_leg_t* leg, nta_incoming_t* irq, const std::string& transactionId, std::shared_ptr<SipDialog> dlg) :
2020
m_leg(leg), m_irq(irq), m_orq(nullptr), m_strTransactionId(transactionId), m_dlg(dlg),
21-
m_role(uas_role),m_rel(nullptr), m_bCanceled(false), m_tmCreated(sip_now()), m_ppSelf(nullptr), m_timerCancel(nullptr) {
21+
m_role(uas_role), m_bCanceled(false), m_tmCreated(sip_now()), m_ppSelf(nullptr), m_timerCancel(nullptr) {
2222
DR_LOG(log_debug) << "adding IIP " << *this;
2323
}
2424

2525
IIP::IIP(nta_leg_t* leg, nta_outgoing_t* orq, const string& transactionId, std::shared_ptr<SipDialog> dlg) :
2626
m_leg(leg), m_irq(nullptr), m_orq(orq), m_strTransactionId(transactionId), m_dlg(dlg),
27-
m_role(uac_role),m_rel(nullptr), m_bCanceled(false), m_tmCreated(sip_now()), m_ppSelf(nullptr), m_timerCancel(nullptr) {
27+
m_role(uac_role), m_bCanceled(false), m_tmCreated(sip_now()), m_ppSelf(nullptr), m_timerCancel(nullptr) {
2828
DR_LOG(log_debug) << "adding IIP " << *this;
2929
}
3030

3131
IIP::~IIP() {
32-
stopCancelTimer() ;
33-
if( m_ppSelf) delete m_ppSelf ;
32+
stopCancelTimer();
33+
destroyAllReliables();
34+
if( m_ppSelf) delete m_ppSelf;
3435
}
3536

3637
void IIP::doCancelTimerHandling(void) {
@@ -66,7 +67,11 @@ namespace drachtio {
6667
" leg:" << iip.leg() <<
6768
" irq:" << iip.irq() <<
6869
" orq:" << iip.orq() <<
69-
" rel:" << iip.rel() ;
70+
" reliables:[";
71+
for(auto rel : iip.reliables()) {
72+
os << rel << " ";
73+
}
74+
os << "]";
7075
return os;
7176
}
7277

@@ -119,12 +124,16 @@ namespace drachtio {
119124
}
120125

121126
bool IIP_FindByReliable(const InvitesInProgress_t& iips, nta_reliable_t* rel, std::shared_ptr<IIP>& iip) {
122-
std::lock_guard<std::mutex> lock(iip_mutex) ;
123-
auto &idx = iips.get<RelTag>();
124-
auto it = idx.find(rel);
125-
if (it == idx.end()) return false;
126-
iip = *it;
127-
return true;
127+
std::lock_guard<std::mutex> lock(iip_mutex);
128+
auto &idx = iips.get<TransactionIdTag>();
129+
for (auto it = idx.begin(); it != idx.end(); ++it) {
130+
const auto& reliables = (*it)->reliables();
131+
if (std::find(reliables.begin(), reliables.end(), rel) != reliables.end()) {
132+
iip = *it;
133+
return true;
134+
}
135+
}
136+
return false;
128137
}
129138

130139
bool IIP_FindByTransactionId(const InvitesInProgress_t& iips, const std::string& transactionId, std::shared_ptr<IIP>& iip) {
@@ -144,21 +153,20 @@ namespace drachtio {
144153
}
145154

146155
void IIP_Clear(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip) {
147-
std::lock_guard<std::mutex> lock(iip_mutex) ;
156+
std::lock_guard<std::mutex> lock(iip_mutex);
148157

149158
nta_incoming_t* irq = const_cast<nta_incoming_t*>(iip->irq());
150159
nta_outgoing_t* orq = const_cast<nta_outgoing_t*>(iip->orq());
151-
nta_reliable_t* rel = const_cast<nta_reliable_t*>(iip->rel());
152-
if (irq) nta_incoming_destroy(irq) ;
160+
if (irq) nta_incoming_destroy(irq);
153161

154-
// DH: tmp commented this out as it appears to cause a crash
155-
// https://github.com/davehorton/drachtio-server/issues/76#event-2662761148
156-
// this needs investigation, because it also causes a memory leak
157-
//if( orq ) nta_outgoing_destroy( orq ) ;
158-
//
159-
// later note: the orq of the uac INVITE (as well as orq of uac ACK) is destroyed in SipDialog destructor
162+
// DH: tmp commented this out as it appears to cause a crash
163+
// https://github.com/davehorton/drachtio-server/issues/76#event-2662761148
164+
// this needs investigation, because it also causes a memory leak
165+
//if( orq ) nta_outgoing_destroy( orq ) ;
166+
//
167+
// later note: the orq of the uac INVITE (as well as orq of uac ACK) is destroyed in SipDialog destructor
160168

161-
if (rel) nta_reliable_destroy(rel) ;
169+
iip->destroyAllReliables();
162170

163171
auto &idx = iips.get<LegTag>();
164172
idx.erase(iip->leg());
@@ -170,14 +178,23 @@ namespace drachtio {
170178
return idx.size();
171179
}
172180

173-
/* since we are changing a key of the multiindex we need to use modify on the index */
174-
void IIP_SetReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel) {
175-
std::lock_guard<std::mutex> lock(iip_mutex) ;
181+
void IIP_AddReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel) {
182+
std::lock_guard<std::mutex> lock(iip_mutex);
183+
const std::string& transactionId = iip->getTransactionId();
184+
auto &idx = iips.get<TransactionIdTag>();
185+
auto it = idx.find(transactionId);
186+
idx.modify(it, [rel](std::shared_ptr<IIP>& iip) {
187+
iip->addReliable(rel);
188+
});
189+
}
190+
191+
void IIP_DestroyReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel) {
192+
std::lock_guard<std::mutex> lock(iip_mutex);
176193
const std::string& transactionId = iip->getTransactionId();
177194
auto &idx = iips.get<TransactionIdTag>();
178195
auto it = idx.find(transactionId);
179196
idx.modify(it, [rel](std::shared_ptr<IIP>& iip) {
180-
iip->setReliable(rel);
197+
iip->destroyReliable(rel);
181198
});
182199
}
183200

src/invite-in-progress.hpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ THE SOFTWARE.
2323
#define __SIP_IIP_HPP__
2424

2525
#include <iostream>
26+
#include <vector>
27+
#include <algorithm>
2628

2729
#include <boost/multi_index_container.hpp>
2830
#include <boost/multi_index/hashed_index.hpp>
@@ -62,18 +64,31 @@ namespace drachtio {
6264
const nta_leg_t* leg(void) const { return m_leg; }
6365
const nta_incoming_t* irq(void) const { return m_irq; }
6466
const nta_outgoing_t* orq(void) const { return m_orq; }
65-
const nta_reliable_t* rel(void) const { return m_rel; }
67+
const std::vector<nta_reliable_t*>& reliables(void) const { return m_reliables; }
68+
const nta_reliable_t* rel(void) const { return m_reliables.empty() ? nullptr : m_reliables.back(); }
6669
const string& getTransactionId(void) const { return m_strTransactionId; }
6770

6871
const agent_role role() const { return m_role; }
6972

70-
void setReliable(nta_reliable_t* rel) { m_rel = rel; }
71-
void destroyReliable(void) {
72-
if( m_rel ) {
73-
nta_reliable_destroy( m_rel ) ;
74-
m_rel = NULL ;
73+
void addReliable(nta_reliable_t* rel) {
74+
if(rel) m_reliables.push_back(rel);
75+
}
76+
77+
void destroyReliable(nta_reliable_t* rel) {
78+
auto it = std::find(m_reliables.begin(), m_reliables.end(), rel);
79+
if (it != m_reliables.end()) {
80+
if(*it) nta_reliable_destroy(*it);
81+
m_reliables.erase(it);
82+
}
83+
}
84+
85+
void destroyAllReliables(void) {
86+
for(auto rel : m_reliables) {
87+
if(rel) nta_reliable_destroy(rel);
7588
}
89+
m_reliables.clear();
7690
}
91+
7792
std::shared_ptr<SipDialog> dlg(void) { return m_dlg; }
7893

7994
void setCanceled(void);
@@ -91,7 +106,7 @@ namespace drachtio {
91106
nta_outgoing_t* m_orq ;
92107
nta_leg_t* m_leg ;
93108
string m_strTransactionId ;
94-
nta_reliable_t* m_rel ;
109+
std::vector<nta_reliable_t*> m_reliables;
95110
std::shared_ptr<SipDialog> m_dlg ;
96111
agent_role m_role ;
97112
bool m_bCanceled;
@@ -124,10 +139,6 @@ namespace drachtio {
124139
boost::multi_index::tag<LegTag>,
125140
boost::multi_index::const_mem_fun<IIP, const nta_leg_t*, &IIP::leg>
126141
>,
127-
hashed_non_unique<
128-
boost::multi_index::tag<RelTag>,
129-
boost::multi_index::const_mem_fun<IIP, const nta_reliable_t*, &IIP::rel>
130-
>,
131142
hashed_unique<
132143
boost::multi_index::tag<TransactionIdTag>,
133144
boost::multi_index::const_mem_fun<IIP, const std::string&, &IIP::getTransactionId>
@@ -146,8 +157,10 @@ namespace drachtio {
146157
void IIP_Clear(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip);
147158
void IIP_Clear(InvitesInProgress_t& iips, nta_leg_t* leg);
148159
size_t IIP_Size(const InvitesInProgress_t& iips);
149-
void IIP_SetReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel);
160+
void IIP_AddReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel);
161+
void IIP_DestroyReliable(InvitesInProgress_t& iips, std::shared_ptr<IIP>& iip, nta_reliable_t* rel);
150162
void IIP_Log(const InvitesInProgress_t& iips, bool full = false);
151163
}
152164

153165
#endif
166+

0 commit comments

Comments
 (0)