Commit e409d579 authored by Guillaume Beraudo's avatar Guillaume Beraudo

Incoming transport stored in RequestSipEvent

- stored on initial event creation;
- propagated on event copy.

Note that an event created on incoming transaction callback
will not have the tport.
parent 02910e1d
......@@ -677,6 +677,19 @@ void Agent::sendTransactionEvent(shared_ptr<TransactionEvent> ev) {
}
}
/**
* This is a dangerous function when called at the wrong time.
* So we prefer an early abort with a stack trace.
* Indeed, incoming tport is global in sofia and will be overwritten
*/
static std::shared_ptr<tport_t> getIncomingTport(const msg_t *orig, Agent *ag) {
tport_t *primaries=nta_agent_tports(ag->getSofiaAgent());
tport_t *tport=tport_delivered_by(primaries,orig);
if (!tport) SLOGA << "tport not found";
return shared_ptr<tport_t>(tport_ref(tport), tport_unref);
}
int Agent::onIncomingMessage(msg_t *msg, sip_t *sip) {
if (mTerminating) {
// Avoid throwing a bad weak pointer on GatewayAdapter destruction
......@@ -686,10 +699,11 @@ int Agent::onIncomingMessage(msg_t *msg, sip_t *sip) {
// Assuming sip is derived from msg
shared_ptr<MsgSip> ms(new MsgSip(msg));
if (sip->sip_request) {
shared_ptr<RequestSipEvent> ev(new RequestSipEvent(dynamic_pointer_cast<IncomingAgent>(shared_from_this()), ms));
auto inTport=getIncomingTport(msg, this);
auto ev = make_shared<RequestSipEvent>(shared_from_this(), ms, inTport);
sendRequestEvent(ev);
} else {
shared_ptr<ResponseSipEvent> ev(new ResponseSipEvent(dynamic_pointer_cast<OutgoingAgent>(shared_from_this()), ms));
auto ev = make_shared<ResponseSipEvent>(shared_from_this(), ms);
sendResponseEvent(ev);
}
msg_destroy(msg);
......
......@@ -131,14 +131,19 @@ void SipEvent::restartProcessing() {
}
}
RequestSipEvent::RequestSipEvent(const shared_ptr<IncomingAgent> &incomingAgent, const shared_ptr<MsgSip> &msgSip) :
RequestSipEvent::RequestSipEvent(shared_ptr<IncomingAgent> incomingAgent,
const shared_ptr<MsgSip> &msgSip,
shared_ptr<tport_t> inTport
) :
SipEvent(msgSip), mRecordRouteAdded(false) {
mIncomingTport=inTport;
mIncomingAgent = incomingAgent;
mOutgoingAgent = incomingAgent->getAgent()->shared_from_this();
}
RequestSipEvent::RequestSipEvent(const shared_ptr<RequestSipEvent> &sipEvent) :
SipEvent(*sipEvent), mRecordRouteAdded(sipEvent->mRecordRouteAdded) {
SipEvent(*sipEvent), mIncomingTport(sipEvent->mIncomingTport),
mRecordRouteAdded(sipEvent->mRecordRouteAdded) {
}
void RequestSipEvent::send(const shared_ptr<MsgSip> &msg, url_string_t const *u, tag_type_t tag, tag_value_t value, ...) {
......@@ -214,7 +219,7 @@ void RequestSipEvent::suspendProcessing() {
RequestSipEvent::~RequestSipEvent() {
}
ResponseSipEvent::ResponseSipEvent(const shared_ptr<OutgoingAgent> &outgoingAgent, const shared_ptr<MsgSip> &msgSip) :
ResponseSipEvent::ResponseSipEvent(shared_ptr<OutgoingAgent> outgoingAgent, const shared_ptr<MsgSip> &msgSip) :
SipEvent(msgSip) {
mOutgoingAgent = outgoingAgent;
mIncomingAgent = outgoingAgent->getAgent()->shared_from_this();
......
......@@ -23,6 +23,7 @@
#include <string>
#include <ostream>
#include <functional>
#include <sofia-sip/tport.h>
#include <sofia-sip/msg.h>
#include <sofia-sip/sip.h>
#include <sofia-sip/nta.h>
......@@ -67,6 +68,9 @@ public:
const char *print();
private:
MsgSip(msg_t *msg);
static inline std::shared_ptr<MsgSip> createFromOriginalMsg(msg_t *msg) {
return std::shared_ptr<MsgSip>(new MsgSip(msg));
}
void defineMsg(msg_t *msg);
mutable su_home_t *mHome;
msg_t *mOriginalMsg;
......@@ -76,6 +80,7 @@ private:
std::shared_ptr<SipAttributes> mSipAttr;
};
class SipEvent : public std::enable_shared_from_this<SipEvent>{
friend class Agent;
public:
......@@ -158,13 +163,15 @@ protected:
return "unknown";
}
}
private:
};
class RequestSipEvent: public SipEvent {
std::shared_ptr<tport_t> mIncomingTport;
public:
RequestSipEvent(const std::shared_ptr<IncomingAgent> &incomingAgent, const std::shared_ptr<MsgSip> &msgSip);
RequestSipEvent(std::shared_ptr<IncomingAgent> incomingAgent,
const std::shared_ptr<MsgSip> &msgSip,
std::shared_ptr<tport_t> inTport
);
RequestSipEvent(const std::shared_ptr<RequestSipEvent> &sipEvent);
virtual void suspendProcessing();
......@@ -177,6 +184,9 @@ public:
virtual void reply(int status, char const *phrase, tag_type_t tag, tag_value_t value, ...);
virtual void setIncomingAgent(const std::shared_ptr<IncomingAgent> &agent);
std::shared_ptr<tport_t> getIncomingTport() {
return mIncomingTport;
}
~RequestSipEvent();
bool mRecordRouteAdded;
......@@ -184,7 +194,7 @@ public:
class ResponseSipEvent: public SipEvent {
public:
ResponseSipEvent(const std::shared_ptr<OutgoingAgent> &outgoingAgent, const std::shared_ptr<MsgSip> &msgSip);
ResponseSipEvent(std::shared_ptr<OutgoingAgent> outgoingAgent, const std::shared_ptr<MsgSip> &msgSip);
ResponseSipEvent(const std::shared_ptr<SipEvent> &sipEvent);
virtual void send(const std::shared_ptr<MsgSip> &msg, url_string_t const *u, tag_type_t tag, tag_value_t value, ...);
......
......@@ -443,7 +443,7 @@ void ModuleRegistrar::onRequest(shared_ptr<RequestSipEvent> &ev) {
}
// Use path as a contact route in all cases
addPathHeader(ev, getIncomingTport(ev, getAgent()));
addPathHeader(ev, ev->getIncomingTport().get());
// Handle modifications
if (!mUpdateOnResponse) {
......
......@@ -20,6 +20,7 @@
#include "agent.hh"
#include "entryfilter.hh"
#include "sofia-sip/auth_digest.h"
#include "sofia-sip/nta.h"
#include "log/logmanager.hh"
#include "expressionparser.hh"
......@@ -310,24 +311,16 @@ void ModuleToolbox::addRecordRoute(su_home_t *home, Agent *ag, const shared_ptr<
ev->mRecordRouteAdded=true;
}
const tport_t *ModuleToolbox::getIncomingTport(const shared_ptr<RequestSipEvent> &ev, Agent *ag) {
msg_t *orig_msg=ev->getMsgSip()->createOrigMsgRef();
tport_t *primaries=nta_agent_tports(ag->getSofiaAgent());
const tport_t *tport=tport_delivered_by(primaries,orig_msg);
msg_destroy(orig_msg);
return tport;
}
void ModuleToolbox::addRecordRouteIncoming(su_home_t *home, Agent *ag, const shared_ptr<RequestSipEvent> &ev ) {
if (ev->mRecordRouteAdded) return;
const tport_t *tport=getIncomingTport(ev, ag);
if (tport==NULL){
auto tport=ev->getIncomingTport();
if (!tport){
LOGE("Cannot find incoming tport, cannot add a Record-Route.");
return;
}
addRecordRoute(home,ag,ev,tport);
addRecordRoute(home,ag,ev,tport.get());
}
bool ModuleToolbox::fromMatch(const sip_from_t *from1, const sip_from_t *from2) {
......
......@@ -196,9 +196,12 @@ int IncomingTransaction::_callback(nta_incoming_magic_t *magic, nta_incoming_t *
LOGD("IncomingTransaction callback %p", it);
if (sip != NULL) {
msg_t *msg = nta_incoming_getrequest_ackcancel(it->mIncoming);
shared_ptr<RequestSipEvent> sipevent(new RequestSipEvent(dynamic_pointer_cast<IncomingAgent>(it->shared_from_this()), shared_ptr<MsgSip>(new MsgSip(msg))));
auto ev = make_shared<RequestSipEvent>(it->shared_from_this(),
MsgSip::createFromOriginalMsg(msg),
shared_ptr<tport_t>() /* no access to nta_agent: may put tport in transaction if needed */
);
msg_destroy(msg);
it->mAgent->sendRequestEvent(sipevent);
it->mAgent->sendRequestEvent(ev);
if (sip->sip_request && sip->sip_request->rq_method == sip_method_cancel) {
it->destroy();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment