reSIProcate/repro  9694
Public Member Functions | Private Member Functions | Private Attributes
repro::RRDecorator Class Reference

#include <RRDecorator.hxx>

Inheritance diagram for repro::RRDecorator:
Inheritance graph
[legend]
Collaboration diagram for repro::RRDecorator:
Collaboration graph
[legend]

List of all members.

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 ProxymProxy
int mAddedRecordRoute
bool mAlreadySingleRecordRouted
bool mHasInboundFlowToken
bool mForceRecordRouteEnabled
bool mDoPath
const bool mIsOriginalSenderBehindNAT
const resip::TransportmReceivedTransport

Detailed Description

Definition at line 17 of file RRDecorator.hxx.


Constructor & Destructor Documentation

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]

Member Function Documentation

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;
}

Member Data Documentation

Definition at line 53 of file RRDecorator.hxx.

Definition at line 54 of file RRDecorator.hxx.

Definition at line 57 of file RRDecorator.hxx.

Definition at line 56 of file RRDecorator.hxx.

Definition at line 55 of file RRDecorator.hxx.

Definition at line 58 of file RRDecorator.hxx.

Definition at line 52 of file RRDecorator.hxx.

Definition at line 59 of file RRDecorator.hxx.


The documentation for this class was generated from the following files: