|
reSIProcate/repro
9694
|
#include <RRDecorator.hxx>


Public Member Functions | |
| RRDecorator (const Proxy &proxy, const resip::Transport *receivedTransport, bool alreadySingleRecordRouted, bool hasInboundFlowToken, bool forceRecordRouteEnabled, bool doPath=false, bool isOriginalSenderBehindNAT=false) | |
| virtual | ~RRDecorator () |
| virtual void | decorateMessage (resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data &sigcompId) |
| virtual void | rollbackMessage (resip::SipMessage &msg) |
| virtual MessageDecorator * | clone () const |
Private Member Functions | |
| void | singleRecordRoute (resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data &sigcompId) |
| void | doubleRecordRoute (resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data &sigcompId) |
| bool | isTransportSwitch (const resip::Tuple &sendingFrom) |
| bool | outboundFlowTokenNeeded (resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data &sigcompId) |
| RRDecorator () | |
Private Attributes | |
| const Proxy & | mProxy |
| int | mAddedRecordRoute |
| bool | mAlreadySingleRecordRouted |
| bool | mHasInboundFlowToken |
| bool | mForceRecordRouteEnabled |
| bool | mDoPath |
| const bool | mIsOriginalSenderBehindNAT |
| const resip::Transport * | mReceivedTransport |
Definition at line 17 of file RRDecorator.hxx.
| repro::RRDecorator::RRDecorator | ( | const Proxy & | proxy, |
| const resip::Transport * | receivedTransport, | ||
| bool | alreadySingleRecordRouted, | ||
| bool | hasInboundFlowToken, | ||
| bool | forceRecordRouteEnabled, | ||
| bool | doPath = false, |
||
| bool | isOriginalSenderBehindNAT = false |
||
| ) |
Definition at line 31 of file RRDecorator.cxx.
: mProxy(proxy), mAddedRecordRoute(0), mAlreadySingleRecordRouted(alreadySingleRecordRouted), mHasInboundFlowToken(hasInboundFlowToken), mForceRecordRouteEnabled(forceRecordRouteEnabled), mDoPath(doPath), mIsOriginalSenderBehindNAT(isOriginalSenderBehindNAT), mReceivedTransport(receivedTransport) {}
| repro::RRDecorator::~RRDecorator | ( | ) | [virtual] |
Definition at line 48 of file RRDecorator.cxx.
{}
| repro::RRDecorator::RRDecorator | ( | ) | [private] |
| resip::MessageDecorator * repro::RRDecorator::clone | ( | ) | const [virtual] |
Implements resip::MessageDecorator.
Definition at line 263 of file RRDecorator.cxx.
{
return new RRDecorator(*this);
}
| void repro::RRDecorator::decorateMessage | ( | resip::SipMessage & | msg, |
| const resip::Tuple & | source, | ||
| const resip::Tuple & | destination, | ||
| const resip::Data & | sigcompId | ||
| ) | [virtual] |
Implements resip::MessageDecorator.
Definition at line 52 of file RRDecorator.cxx.
{
DebugLog(<<"Proxy::decorateMessage called.");
resip::NameAddr rt;
if(isTransportSwitch(source))
{
if(mAlreadySingleRecordRouted)
{
singleRecordRoute(request, source, destination, sigcompId);
}
else
{
doubleRecordRoute(request, source, destination, sigcompId);
}
}
else
{
// We might still want to record-route in this case; if we need an
// outbound flow token or we've already added an inbound flow token
if(outboundFlowTokenNeeded(request, source, destination, sigcompId) ||
mHasInboundFlowToken) // or we have an inbound flow
{
assert(mAlreadySingleRecordRouted);
singleRecordRoute(request, source, destination, sigcompId);
}
}
static ExtensionParameter p_drr("drr");
resip::NameAddrs* routes=0;
if(mDoPath)
{
routes=&(request.header(resip::h_Paths));
}
else
{
routes=&(request.header(resip::h_RecordRoutes));
}
if(routes->size() > 1 &&
mAddedRecordRoute &&
routes->front().uri().exists(p_drr))
{
// .bwc. It is possible that we have duplicate Record-Routes at this
// point, if we have done a transport switch but both transports use the
// same FQDN.
resip::NameAddrs::iterator second = ++(routes->begin());
if(*second == routes->front())
{
// Duplicated record-routes; pare down to a single one.
routes->pop_front();
--mAddedRecordRoute;
routes->front().uri().remove(p_drr);
}
}
}
| void repro::RRDecorator::doubleRecordRoute | ( | resip::SipMessage & | msg, |
| const resip::Tuple & | source, | ||
| const resip::Tuple & | destination, | ||
| const resip::Data & | sigcompId | ||
| ) | [private] |
Definition at line 180 of file RRDecorator.cxx.
{
// We only use this on transport switch when we have not yet Record-Routed.
// If we needed a flow-token in the inbound Record-Route, it would have been
// added already.
resip::NameAddr rt(mProxy.getRecordRoute(mReceivedTransport));
resip::Helper::massageRoute(request,rt);
if(mDoPath)
{
request.header(h_Paths).push_front(rt);
}
else
{
request.header(h_RecordRoutes).push_front(rt);
}
++mAddedRecordRoute;
singleRecordRoute(request, source, destination, sigcompId);
}
| bool repro::RRDecorator::isTransportSwitch | ( | const resip::Tuple & | sendingFrom | ) | [private] |
Definition at line 203 of file RRDecorator.cxx.
{
if(mForceRecordRouteEnabled)
{
// If we are forcing record routes to be added, then DRR on any transport switch
return mReceivedTransport != sendingFrom.transport;
}
else
{
// If record routing is not forced then only DRR if we are switching transport types or
// protocol versions, since the interfaces themselves may all be equally reachable
// !slg! - could make this behavior more configurable
return sendingFrom.getType() != mReceivedTransport->getTuple().getType() ||
sendingFrom.ipVersion() != mReceivedTransport->getTuple().ipVersion();
}
}
| bool repro::RRDecorator::outboundFlowTokenNeeded | ( | resip::SipMessage & | msg, |
| const resip::Tuple & | source, | ||
| const resip::Tuple & | destination, | ||
| const resip::Data & | sigcompId | ||
| ) | [private] |
Definition at line 221 of file RRDecorator.cxx.
{
return (destination.onlyUseExistingConnection // destination is an outbound target
|| resip::InteropHelper::getRRTokenHackEnabled() // or the token is enabled
|| mIsOriginalSenderBehindNAT // or the nat detection hack is enabled
|| !sigcompId.empty()); // or we are routing to a SigComp transport
// ?slg? For Sigcomp are we guaranteed to always have
// single RR at this point? If not, then strangeness
// will happen when singleRecordRoute adds a ;drr param
}
| void repro::RRDecorator::rollbackMessage | ( | resip::SipMessage & | msg | ) | [virtual] |
Implements resip::MessageDecorator.
Definition at line 236 of file RRDecorator.cxx.
{
resip::NameAddrs* routes=0;
if(mDoPath)
{
routes=&(request.header(resip::h_Paths));
}
else
{
routes=&(request.header(resip::h_RecordRoutes));
}
while(mAddedRecordRoute--)
{
assert(!routes->empty());
routes->pop_front();
}
if(mAlreadySingleRecordRouted)
{
// Make sure we remove the drr param if it is there.
static ExtensionParameter p_drr("drr");
routes->front().uri().remove(p_drr);
}
}
| void repro::RRDecorator::singleRecordRoute | ( | resip::SipMessage & | msg, |
| const resip::Tuple & | source, | ||
| const resip::Tuple & | destination, | ||
| const resip::Data & | sigcompId | ||
| ) | [private] |
Definition at line 113 of file RRDecorator.cxx.
{
resip::NameAddr rt;
// .bwc. outboundFlowTokenNeeded means that we are assuming that whoever is
// just downstream will remain in the call-path throughout the dialog.
if(outboundFlowTokenNeeded(request, source, destination, sigcompId))
{
if(destination.getType()==resip::TLS ||
destination.getType()==resip::DTLS)
{
rt = mProxy.getRecordRoute(destination.transport);
rt.uri().scheme()="sips";
}
else
{
// .bwc. It is safe to put ip+port+proto here, since we have an
// existing flow to the next hop.
rt.uri().host()=resip::Tuple::inet_ntop(source);
rt.uri().port()=source.getPort();
rt.uri().param(resip::p_transport)=resip::Tuple::toDataLower(source.getType());
}
// .bwc. If our target has an outbound flow to us, we need to put a flow
// token in a Record-Route.
resip::Helper::massageRoute(request,rt);
resip::Data binaryFlowToken;
resip::Tuple::writeBinaryToken(destination,binaryFlowToken, Proxy::FlowTokenSalt);
rt.uri().user()=binaryFlowToken.base64encode();
}
else
{
// No need for a flow-token; just use an ordinary record-route.
rt = mProxy.getRecordRoute(destination.transport);
resip::Helper::massageRoute(request,rt);
}
#ifdef USE_SIGCOMP
if(mProxy.compressionEnabled() && !sigcompId.empty())
{
rt.uri().param(p_comp)="sigcomp";
}
#endif
static ExtensionParameter p_drr("drr");
rt.uri().param(p_drr);
resip::NameAddrs* routes=0;
if(mDoPath)
{
routes=&(request.header(resip::h_Paths));
InfoLog(<< "Adding outbound Path: " << rt);
}
else
{
routes=&(request.header(resip::h_RecordRoutes));
InfoLog(<< "Adding outbound Record-Route: " << rt);
}
routes->front().uri().param(p_drr);
routes->push_front(rt);
++mAddedRecordRoute;
}
int repro::RRDecorator::mAddedRecordRoute [private] |
Definition at line 53 of file RRDecorator.hxx.
bool repro::RRDecorator::mAlreadySingleRecordRouted [private] |
Definition at line 54 of file RRDecorator.hxx.
bool repro::RRDecorator::mDoPath [private] |
Definition at line 57 of file RRDecorator.hxx.
bool repro::RRDecorator::mForceRecordRouteEnabled [private] |
Definition at line 56 of file RRDecorator.hxx.
bool repro::RRDecorator::mHasInboundFlowToken [private] |
Definition at line 55 of file RRDecorator.hxx.
const bool repro::RRDecorator::mIsOriginalSenderBehindNAT [private] |
Definition at line 58 of file RRDecorator.hxx.
const Proxy& repro::RRDecorator::mProxy [private] |
Definition at line 52 of file RRDecorator.hxx.
const resip::Transport* repro::RRDecorator::mReceivedTransport [private] |
Definition at line 59 of file RRDecorator.hxx.
1.7.5.1