reSIProcate/repro  9694
RequestContext.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include <iostream>
00006 
00007 #include "repro/Proxy.hxx"
00008 #include "repro/RequestContext.hxx"
00009 #include "resip/stack/ExtensionParameter.hxx"
00010 #include "resip/stack/SipMessage.hxx"
00011 #include "resip/stack/TransactionTerminated.hxx"
00012 #include "resip/stack/SipStack.hxx"
00013 #include "resip/stack/Helper.hxx"
00014 #include "resip/stack/InteropHelper.hxx"
00015 #include "rutil/Inserter.hxx"
00016 #include "rutil/Logger.hxx"
00017 
00018 #include "repro/Ack200DoneMessage.hxx"
00019 #include "repro/ForkControlMessage.hxx"
00020 #include "repro/ProcessorMessage.hxx"
00021 #include "rutil/WinLeakCheck.hxx"
00022 
00023 // Remove warning about 'this' use in initiator list
00024 #if defined(WIN32) && !defined(__GNUC__)
00025 #pragma warning( disable : 4355 ) // using this in base member initializer list
00026 #endif
00027 
00028 #define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
00029 
00030 using namespace resip;
00031 using namespace repro;
00032 using namespace std;
00033 
00034 RequestContext::RequestContext(Proxy& proxy, 
00035                                ProcessorChain& requestP,
00036                                ProcessorChain& responseP,
00037                                ProcessorChain& targetP) :
00038    mHaveSentFinalResponse(false),
00039    mOriginalRequest(0),
00040    mCurrentEvent(0),
00041    mAck200ToRetransmit(0),
00042    mRequestProcessorChain(requestP),
00043    mResponseProcessorChain(responseP),
00044    mTargetProcessorChain(targetP),
00045    mTransactionCount(1),
00046    mProxy(proxy),
00047    mResponseContext(*this),
00048    mTCSerial(0),
00049    mKeyValueStore(*Proxy::getRequestKeyValueStoreKeyAllocator())
00050 {
00051    mInitialTimerCSet=false;
00052 }
00053 
00054 RequestContext::~RequestContext()
00055 {
00056    DebugLog (<< "RequestContext::~RequestContext() " << this);
00057    if (mOriginalRequest != mCurrentEvent)
00058    {
00059       delete mOriginalRequest;
00060       mOriginalRequest = 0;
00061    }
00062    delete mCurrentEvent;
00063    mCurrentEvent = 0;
00064    delete mAck200ToRetransmit;
00065    mAck200ToRetransmit=0;
00066 }
00067 
00068 
00069 void
00070 RequestContext::process(resip::TransactionTerminated& msg)
00071 {
00072    InfoLog (<< "RequestContext::process(TransactionTerminated) " 
00073             << msg.getTransactionId() << " : " << *this);
00074 
00075    if (msg.isClientTransaction())
00076    {
00077       mResponseContext.removeClientTransaction(msg.getTransactionId());
00078    }
00079    mTransactionCount--;
00080    if (mTransactionCount == 0)
00081    {
00082       delete this;
00083    }
00084 }
00085 
00086 void
00087 RequestContext::process(std::auto_ptr<resip::SipMessage> sipMessage)
00088 {
00089    bool original = false;
00090    InfoLog (<< "RequestContext::process(SipMessage) " << sipMessage->getTransactionId());
00091 
00092    if (mCurrentEvent != mOriginalRequest)
00093    {
00094       delete mCurrentEvent;
00095    }
00096    mCurrentEvent = sipMessage.release();
00097    
00098    SipMessage* sip = dynamic_cast<SipMessage*>(mCurrentEvent);
00099    if (!mOriginalRequest) 
00100    { 
00101       assert(sip);
00102       mOriginalRequest=sip;
00103       original = true;
00104       mResponseContext.mIsClientBehindNAT = InteropHelper::getClientNATDetectionMode() != InteropHelper::ClientNATDetectionDisabled && 
00105                                             Helper::isClientBehindNAT(*sip, 
00106                                                   InteropHelper::getClientNATDetectionMode() == InteropHelper::ClientNATDetectionPrivateToPublicOnly);
00107      
00108       // RFC 3261 Section 16.4
00109       try
00110       {
00111          fixStrictRouterDamage();
00112          removeTopRouteIfSelf();
00113       }
00114       catch(resip::ParseException& e)
00115       {
00116          InfoLog(<<"Parse failure Exception caught: " << e);
00117          if(mOriginalRequest->method()==ACK)
00118          {
00119             postAck200Done();
00120          }
00121          else
00122          {
00123             resip::SipMessage response;
00124             Helper::makeResponse(response, *mOriginalRequest,400); 
00125             response.header(h_StatusLine).reason()="Malformed header-field-value: " + e.getMessage();
00126             sendResponse(response);
00127          }
00128          return;
00129       }
00130       catch(resip::BaseException& e)
00131       {
00132          ErrLog(<<"Exception caught: " << e);
00133          if(mOriginalRequest->method()==ACK)
00134          {
00135             postAck200Done();
00136          }
00137          else
00138          {
00139             resip::SipMessage response;
00140             Helper::makeResponse(response, *mOriginalRequest,500); 
00141             response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00142             sendResponse(response);
00143          }
00144          return;
00145       }
00146    }
00147 
00148    if (sip->isRequest())
00149    {
00150       DebugLog(<<"Got a request.");
00151       bool postProcess=false;
00152       switch(mOriginalRequest->method())
00153       {
00154          case ACK:
00155             processRequestAckTransaction(sip,original);
00156             break;
00157          case INVITE:
00158             postProcess=processRequestInviteTransaction(sip,original);
00159             if(postProcess) doPostRequestProcessing(sip,original);
00160             break;
00161          default:
00162             postProcess=processRequestNonInviteTransaction(sip,original);
00163             if(postProcess) doPostRequestProcessing(sip,original);
00164       }
00165    }
00166    else if (sip->isResponse())
00167    {
00168       assert(!original);
00169       bool postProcess=false;
00170       switch(mOriginalRequest->method())
00171       {
00172          case ACK:
00173             // !bwc! Got a response to an ACK? 
00174             // Why did the stack let this through?
00175             assert(0);
00176             break;
00177          case INVITE:
00178             postProcess=processResponseInviteTransaction(sip);
00179             break;
00180          default:
00181             postProcess=processResponseNonInviteTransaction(sip);
00182       }
00183 
00184       if(postProcess) 
00185       {
00186          doPostResponseProcessing(sip);
00187       }
00188    }
00189 }
00190 
00191 bool
00192 RequestContext::processRequestInviteTransaction(SipMessage* msg, bool original)
00193 {
00194    bool doPostProcess=false;
00195    assert(msg->isRequest());
00196    
00197    if(original)
00198    {
00199       assert(msg->method()==INVITE);
00200 
00201       try
00202       {
00203          Processor::processor_action_t ret=Processor::Continue;
00204          ret = mRequestProcessorChain.process(*this);
00205          if(ret!=Processor::WaitingForEvent && !mHaveSentFinalResponse)
00206          {
00207             doPostProcess=true;
00208          }
00209       }
00210       catch(resip::BaseException& e)
00211       {
00212          SipMessage response;
00213          Helper::makeResponse(response,*mOriginalRequest,500);
00214          response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00215          ErrLog(<<"Exception caught: " << e);
00216          sendResponse(response);
00217       }
00218    }
00219    else
00220    {
00221       if(msg->method()==CANCEL)
00222       {
00223          mResponseContext.processCancel(*msg);
00224          doPostProcess=true;
00225       }
00226       else if(msg->method()==ACK)
00227       {
00228          // .bwc. The stack should not be forwarding ACK/failure to the TU,
00229          // nor should we be getting a bad ACK/200. (There is code further
00230          // up that makes bad ACK/200 look like a new transaction, like it
00231          // is supposed to be.)
00232          // TODO Remove this code block entirely.
00233          assert(0);
00234          
00235          DebugLog(<<"This ACK has the same tid as the original INVITE.");
00236          DebugLog(<<"The reponse we sent back was a " 
00237                << mResponseContext.mBestResponse.header(h_StatusLine).statusCode());
00238          // .bwc. Since this is not an ACK transaction, the stack will let
00239          // us know when we need to clean up.
00240          if(!mHaveSentFinalResponse)
00241          {
00242             // .bwc. Whoa, something went wrong here. We got an ACK, but we
00243             // haven't sent back a final response. The stack shouldn't have
00244             // allowed this through!
00245             ErrLog(<<"Got an ACK, but haven't sent a final response. "
00246                         "What happened here?");
00247          }
00248          else if(mResponseContext.mBestResponse.header(h_StatusLine).statusCode() / 100 == 2)
00249          {
00250             InfoLog(<<"Got an ACK within an INVITE transaction, but our "
00251                      "response was a 2xx. Someone didn't change their tid "
00252                      "like they were supposed to...");
00253             if(
00254                (
00255                   msg->exists(h_Routes) && 
00256                   !msg->header(h_Routes).empty()
00257                ) 
00258                ||
00259                (
00260                   !getProxy().isMyUri(msg->header(h_RequestLine).uri()) && 
00261                   (msg->header(h_From).isWellFormed() && getProxy().isMyUri(msg->header(h_From).uri())) 
00262                )
00263                )
00264             {
00265                forwardAck200(*msg);
00266             }
00267          }
00268       }
00269       else
00270       {
00271          // .bwc. The stack should not have done this. This indicates either a 
00272          // bug in the stack, processInvite was called in a non-invite 
00273          // RequestContext, or this RequestContext was leaked and hit with a 
00274          // subsequent transaction 
00275          ErrLog(<<"We got an unexpected request from "
00276                                     "the stack in an invite RequestContext. "
00277                                     "Why?"
00278                                     " Orig: " << mOriginalRequest->brief() <<
00279                                     " This: " << msg->brief());
00280          assert(0);
00281       }
00282    }
00283 
00284    return doPostProcess;
00285 
00286 }
00287 
00288 bool
00289 RequestContext::processRequestNonInviteTransaction(SipMessage* msg, bool original)
00290 {
00291    assert(msg->isRequest());
00292    bool doPostProcess=false;
00293    
00294    if(original)
00295    {
00296       assert(msg->method()==mOriginalRequest->method());
00297       try
00298       {
00299          Processor::processor_action_t ret=Processor::Continue;
00300          ret = mRequestProcessorChain.process(*this);
00301          if(ret!=Processor::WaitingForEvent && !mHaveSentFinalResponse)
00302          {
00303             doPostProcess=true;
00304          }
00305       }
00306       catch(resip::BaseException& e)
00307       {
00308          SipMessage response;
00309          Helper::makeResponse(response,*mOriginalRequest,500);
00310          response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00311          ErrLog(<<"Exception caught: " << e);
00312          sendResponse(response);
00313       }
00314    }
00315    else
00316    {
00317       if(msg->method()==CANCEL)
00318       {
00319          // .bwc. Got a CANCEL in a non-invite transaction. Just respond with
00320          // 200 and ignore.
00321          SipMessage response;
00322          Helper::makeResponse(response,*msg,200);
00323          send(response);
00324       }
00325       else
00326       {
00327          // ?bwc? We got a second request from the stack. Why?
00328          ErrLog(<<"We got a second non-invite request from the"
00329                                     " stack in an already-established non-"
00330                                     "invite RequestContext. "
00331                                     "Why?"
00332                                     " Orig: " << mOriginalRequest->brief() <<
00333                                     " This: " << msg->brief());
00334          if(msg->method()!=ACK)
00335          {
00336             SipMessage response;
00337             Helper::makeResponse(response,*msg,500);
00338             response.header(h_StatusLine).reason()="Server error: got an "
00339                            "unexpected request in a non-invite RequestContext";
00340             send(response);
00341          }
00342          assert(0);
00343       }
00344    }
00345 
00346    return doPostProcess;
00347 }
00348 
00349 void
00350 RequestContext::processRequestAckTransaction(SipMessage* msg, bool original)
00351 {
00352    assert(msg->isRequest());
00353    if(msg->method()!=ACK)
00354    {
00355       // !bwc! Somebody collided with an ACK/200. Send a failure response.
00356       SipMessage response;
00357       Helper::makeResponse(response,*msg,400);
00358       response.header(h_StatusLine).reason()="Transaction-id collision";
00359       send(response);
00360       return;
00361    }
00362    
00363    DebugLog(<<"This ACK has its own tid.");
00364 
00365    try
00366    {
00367       // .slg. look at mOriginalRequest for Routes since removeTopRouteIfSelf() is only called on mOriginalRequest
00368       if((!mOriginalRequest->exists(h_Routes) || mOriginalRequest->header(h_Routes).empty()) &&
00369           getProxy().isMyUri(msg->header(h_RequestLine).uri()))
00370       {
00371          // .bwc. Someone sent an ACK with us in the Request-Uri, and no
00372          // Route headers (after we have removed ourself). We will never perform 
00373          // location service or retargeting on an ACK, and we shouldn't send 
00374          // it to ourselves.  So, just drop the thing.
00375          handleSelfAimedStrayAck(msg);
00376       }
00377       // Note: mTopRoute is only populated if RemoveTopRouteIfSelf successfully removes the top route.
00378       else if(!mTopRoute.uri().host().empty() || getProxy().isMyUri(msg->header(h_From).uri()))
00379       {
00380          // Top most route is us, or From header uri is ours.  Note:  The From check is 
00381          // required to interoperate with endpoints that configure outbound proxy 
00382          // settings, and do not place the outbound proxy in a Route header.
00383          mResponseContext.cancelAllClientTransactions();
00384          forwardAck200(*mOriginalRequest);
00385       }
00386       else
00387       {
00388          // .slg. Someone is using us to relay an ACK, but we are not the 
00389          // top-most route and the host in From isn't ours. Refusing to do so.
00390          InfoLog(<<"Top most route or From header are not ours.  We do not allow relaying ACKs.  Dropping it...");            
00391       }
00392    }
00393    catch(resip::ParseException&)
00394    {
00395       InfoLog(<<"Parse error processing ACK. Dropping it...");            
00396    }
00397 
00398    if(original)  // Only queue Ack200Done if this is the original request
00399    {
00400       postAck200Done();
00401    }
00402 }
00403 
00404 void
00405 RequestContext::doPostRequestProcessing(SipMessage* msg, bool original)
00406 {
00407    assert(msg->isRequest());
00408    
00409    // .bwc. This is called after an incoming request is done processing. This
00410    // IS NOT called if the request-processor chain goes async, and IS NOT called
00411    // when async work finishes. The intent of this function is to prompt either:
00412    // 1) The initiation of new client transactions.
00413    // 2) Failing 1, the sending of a failure response to the original request.
00414    
00415    
00416    // if target list is empty return a 480
00417    if (!mResponseContext.hasTargets())
00418    {
00419       // make 480, send, dispose of memory
00420       resip::SipMessage response;
00421       InfoLog (<< *this << ": no targets for " 
00422                << mOriginalRequest->header(h_RequestLine).uri() 
00423                << " send 480");
00424       Helper::makeResponse(response, *mOriginalRequest, 480); 
00425       sendResponse(response);
00426    }
00427    else
00428    {
00429       Processor::processor_action_t ret=Processor::Continue;
00430       InfoLog (<< *this << " there are " 
00431       << mResponseContext.mCandidateTransactionMap.size() 
00432       << " candidates -> continue");
00433       
00434       try
00435       {
00436          ret = mTargetProcessorChain.process(*this);
00437       }
00438       catch(resip::BaseException& e)
00439       {
00440          if(mResponseContext.hasActiveTransactions())
00441          {
00442             // .bwc. Whoops. We may have just forwarded garbage upstream.
00443             // TODO is it appropriate to try to CANCEL here?
00444             ErrLog(<<"Server error caught after"
00445                            " request was forwarded. Exception was: "<<e);
00446          }
00447          else
00448          {
00449             mResponseContext.clearCandidateTransactions();
00450             SipMessage response;
00451             Helper::makeResponse(response,*mOriginalRequest,500);
00452             response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00453             ErrLog(<<"Exception caught: " << e);
00454             sendResponse(response);
00455          }
00456       }
00457 
00458       if(ret != Processor::WaitingForEvent &&
00459          !mHaveSentFinalResponse && 
00460          !mResponseContext.hasActiveTransactions())
00461       {
00462          if(mResponseContext.hasCandidateTransactions())
00463          {
00464             // Someone forgot to start any of the targets they just added.
00465             // Send a 500 response
00466             resip::SipMessage response;
00467             ErrLog(  << "In RequestContext, target processor chain appears "
00468                      << "to have failed to process any targets. (Bad baboon?)"
00469                      << "Sending a 500 response for this request:" 
00470                      << mOriginalRequest->header(h_RequestLine).uri() );
00471             Helper::makeResponse(response, *mOriginalRequest, 500); 
00472             sendResponse(response);
00473          }
00474          else
00475          {
00476             ErrLog(<< "In RequestContext, request processor chain "
00477             << " appears to have added Targets, but all of these Targets"
00478             << " are already Terminated. Further, there are no candidate"
00479             << " Targets. (Bad monkey?)");
00480             // Send best response
00481             mResponseContext.forwardBestResponse();
00482          }
00483       }
00484    }
00485 }
00486 
00487 bool
00488 RequestContext::processResponseInviteTransaction(SipMessage* msg)
00489 {
00490    assert(msg->isResponse());
00491    
00492    bool doPostProcessing=false;
00493    resip::Data tid(msg->getTransactionId());
00494    tid.lowercase();
00495    if(msg->method()==INVITE)
00496    {
00497       try
00498       {
00499          Processor::processor_action_t ret = Processor::Continue;
00500          ret = mResponseProcessorChain.process(*this);
00501          assert(ret != Processor::WaitingForEvent);
00502          
00503          if (ret == Processor::Continue)
00504          {
00505             doPostProcessing=true;
00506          }
00507          else
00508          {
00509             // This means the response has been eaten. Do not forward back.
00510             mResponseContext.terminateClientTransaction(tid);
00511          }
00512       }
00513       catch(resip::ParseException& e)
00514       {
00515          InfoLog(<<"Garbage in response; dropping message. " << e);
00516          mResponseContext.terminateClientTransaction(tid);
00517       }
00518       catch(resip::BaseException& e)
00519       {
00520          ErrLog(<<"Exception thrown in response processor chain: " << e);
00521          // ?bwc? TODO what do we do here? Continue processing? Give up?
00522          mResponseContext.terminateClientTransaction(tid);
00523       }
00524    }
00525    else if(msg->method()==CANCEL)
00526    {
00527       // .bwc. Do nothing.
00528    }
00529    else
00530    {
00531       // ?bwc? Is this possible?
00532       assert(0);
00533    }
00534    
00535    return doPostProcessing;
00536 }
00537 
00538 bool
00539 RequestContext::processResponseNonInviteTransaction(SipMessage* msg)
00540 {
00541    assert(msg->isResponse());
00542    
00543    resip::Data tid(msg->getTransactionId());
00544    tid.lowercase();
00545    bool doPostProcessing=false;
00546    if(msg->method()==mOriginalRequest->method())
00547    {
00548       try
00549       {
00550          Processor::processor_action_t ret = Processor::Continue;
00551          ret = mResponseProcessorChain.process(*this);
00552          assert(ret != Processor::WaitingForEvent);
00553          
00554          if (ret == Processor::Continue)
00555          {
00556             doPostProcessing=true;
00557          }
00558          else
00559          {
00560             // This means the response has been eaten. Do not forward back.
00561             mResponseContext.terminateClientTransaction(tid);
00562          }
00563       }
00564       catch(resip::ParseException& e)
00565       {
00566          InfoLog(<<"Garbage in response; dropping message. " << e);
00567          mResponseContext.terminateClientTransaction(tid);
00568       }
00569       catch(resip::BaseException& e)
00570       {
00571          ErrLog(<<"Exception thrown in response processor chain: " << e);
00572          // ?bwc? TODO what do we do here? Continue processing? Give up?
00573          mResponseContext.terminateClientTransaction(tid);
00574       }
00575    }
00576    else
00577    {
00578       // ?bwc? Is this possible?
00579       assert(0);
00580    }
00581    
00582    return doPostProcessing;
00583 
00584 }
00585 
00586 void
00587 RequestContext::doPostResponseProcessing(SipMessage* msg)
00588 {
00589    bool nit408 = msg->method() != INVITE && msg->header(resip::h_StatusLine).statusCode() == 408;
00590 
00591    mResponseContext.processResponse(*msg);
00592 
00593    //If everything we have tried so far has gone quiescent, we
00594    //need to fire up some more Targets (if there are any left)
00595    mTargetProcessorChain.process(*this);
00596 
00597    if(!mHaveSentFinalResponse && 
00598       !mResponseContext.hasActiveTransactions())
00599    {
00600       if(mResponseContext.hasCandidateTransactions())
00601       {
00602          resip::SipMessage response;
00603          Helper::makeResponse(response, *mOriginalRequest, 500); 
00604          // The last active transaction has ended, and the response processors
00605          // did not start any of the pending transactions.
00606          // Send a 500 response.
00607          ErrLog( << "In RequestContext, after processing a sip response:"
00608                  << " We have no active transactions, but there are candidates "
00609                  << " remaining. (Bad baboon?)"
00610                  << "Sending a 500 response for this request:" 
00611                  << mOriginalRequest->header(h_RequestLine).uri() );
00612          sendResponse(response);
00613       }
00614       else if(nit408)
00615       {
00616          InfoLog(<<"In RequestContext, after processing a NIT/408, all"
00617                << " transactions are terminated. In this case, we do not send a"
00618                << " final response.");
00619       }
00620       else
00621       {
00622          ErrLog(<<"In RequestContext, after processing "
00623          << "a sip response (_not_ a NIT/408): all transactions are terminated,"
00624          << " but we have not sent a final response. (What happened here?) ");
00625 
00626          // Send best response
00627          mResponseContext.forwardBestResponse();
00628       }
00629    }
00630 }
00631 
00632 void
00633 RequestContext::process(std::auto_ptr<ApplicationMessage> app)
00634 {
00635    InfoLog (<< "RequestContext::process(ApplicationMessage) " << *app);
00636 
00637    if (mCurrentEvent != mOriginalRequest)
00638    {
00639       delete mCurrentEvent;
00640    }
00641    mCurrentEvent = app.release();
00642 
00643    Ack200DoneMessage* ackDone = dynamic_cast<Ack200DoneMessage*>(mCurrentEvent);
00644    if (ackDone)
00645    {
00646       delete this;
00647       return;
00648    }
00649 
00650    TimerCMessage* tc = dynamic_cast<TimerCMessage*>(mCurrentEvent);
00651 
00652    if(tc)
00653    {
00654       if(tc->mSerial == mTCSerial)
00655       {
00656          mResponseContext.processTimerC();
00657       }
00658 
00659       return;
00660    }
00661 
00662    ProcessorMessage* proc=dynamic_cast<ProcessorMessage*>(mCurrentEvent);
00663    
00664    if(proc)
00665    {
00666       Processor::ChainType type = proc->chainType();
00667       Processor::processor_action_t ret=Processor::Continue;
00668 
00669       switch(type)
00670       {
00671          case Processor::REQUEST_CHAIN:
00672             try
00673             {
00674                ret = mRequestProcessorChain.process(*this);
00675             }
00676             catch(resip::BaseException& e)
00677             {
00678                resip::SipMessage response;
00679                Helper::makeResponse(response,*mOriginalRequest,500);
00680                response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00681                ErrLog(<<"Exception caught: " << e);
00682                sendResponse(response);            
00683             }
00684 
00685             if(ret != Processor::WaitingForEvent && !mHaveSentFinalResponse)
00686             {
00687                if (!mResponseContext.hasTargets())
00688                {
00689                   // make 480, send, dispose of memory
00690                   resip::SipMessage response;
00691                   Helper::makeResponse(response, *mOriginalRequest, 480); 
00692                   InfoLog (<< *this << ": no targets for " 
00693                            << mOriginalRequest->header(h_RequestLine).uri() 
00694                            << " send 480");
00695                   sendResponse(response);
00696                }
00697                else
00698                {
00699                   InfoLog (<< *this << " there are " 
00700                   << mResponseContext.mCandidateTransactionMap.size() 
00701                   << " candidates -> continue");
00702 
00703                   try
00704                   {
00705                      ret = mTargetProcessorChain.process(*this);
00706                   }
00707                   catch(resip::BaseException& e)
00708                   {
00709                      if(mResponseContext.hasActiveTransactions())
00710                      {
00711                         // .bwc. Whoops. We may have just forwarded garbage upstream.
00712                         // ?bwc? TODO is it appropriate to try to CANCEL here?
00713                         ErrLog(<<"Server error caught after"
00714                                        " request was forwarded. Exception was: "<<e);
00715                      }
00716                      else
00717                      {
00718                         mResponseContext.clearCandidateTransactions();
00719                         resip::SipMessage response;
00720                         Helper::makeResponse(response,*mOriginalRequest,500);
00721                         response.header(h_StatusLine).reason()="Server error: " + e.getMessage();
00722                         ErrLog(<<"Exception caught: " << e);
00723                         sendResponse(response);
00724                      }            
00725                   }
00726 
00727                   if(ret != Processor::WaitingForEvent &&
00728                      !mHaveSentFinalResponse && 
00729                      !mResponseContext.hasActiveTransactions())
00730                   {
00731                      if(mResponseContext.hasCandidateTransactions())
00732                      {
00733                         resip::SipMessage response;
00734                         Helper::makeResponse(response, *mOriginalRequest, 500); 
00735                         // Someone forgot to start any of the targets they just added.
00736                         // Send a 500 response
00737                         ErrLog( << "In RequestContext, request and target processor"
00738                                  << " chains have run, and we have some Candidate Targets,"
00739                                  << " but no active Targets. (Bad baboon?)"
00740                                  << "Sending a 500 response for this request:" 
00741                                  << mOriginalRequest->header(h_RequestLine).uri() );
00742                         sendResponse(response);
00743                      }
00744                      else if(mResponseContext.mBestResponse.header(h_StatusLine).statusCode() != 408)
00745                      {
00746                         ErrLog(<< "In RequestContext, request and target processor "
00747                         << "chains have run, and all Targets are now Terminated."
00748                         << " However, we have not sent a final response, and our "
00749                         << "best final response is not a 408.(What happened here?)");
00750 
00751                         // Send best response
00752                         mResponseContext.forwardBestResponse();
00753                      }
00754                   }
00755                }
00756             }
00757             break;
00758 
00759          case Processor::RESPONSE_CHAIN:
00760             ret = mResponseProcessorChain.process(*this);
00761 
00762             mTargetProcessorChain.process(*this);
00763             break;
00764 
00765          case Processor::TARGET_CHAIN:
00766             ret = mTargetProcessorChain.process(*this);
00767             break;
00768 
00769          default:
00770             ErrLog(<<"RequestContext " << getTransactionId() << " got a "
00771                      << "ProcessorMessage addressed to a non existent chain "
00772                      << type);
00773       }
00774    }
00775 }
00776 
00777 void
00778 RequestContext::handleSelfAimedStrayAck(SipMessage* sip)
00779 {
00780    InfoLog(<<"Stray ACK aimed at us that routes back to us. Dropping it...");  
00781 }
00782 
00783 void
00784 RequestContext::cancelClientTransaction(const resip::Data& tid)
00785 {
00786    getProxy().getStack().cancelClientInviteTransaction(tid);
00787 }
00788 
00789 void
00790 RequestContext::forwardAck200(const resip::SipMessage& ack)
00791 {
00792    if(!mAck200ToRetransmit)
00793    {
00794       mAck200ToRetransmit = new SipMessage(ack);
00795       mAck200ToRetransmit->header(h_MaxForwards).value()--;
00796       Helper::processStrictRoute(*mAck200ToRetransmit);
00797       
00798       mAck200ToRetransmit->header(h_Vias).push_front(Via());
00799 
00800       // .bwc. Check for flow-token
00801       if(!mTopRoute.uri().user().empty())
00802       {
00803          resip::Tuple dest(Tuple::makeTupleFromBinaryToken(mTopRoute.uri().user().base64decode(), Proxy::FlowTokenSalt));
00804          if(!(dest==resip::Tuple()))
00805          {
00806             // valid flow token
00807             mAck200ToRetransmit->setDestination(dest);
00808          }
00809       }
00810    }
00811 
00812    send(*mAck200ToRetransmit);
00813 }
00814 
00815 resip::SipMessage& 
00816 RequestContext::getOriginalRequest()
00817 {
00818    return *mOriginalRequest;
00819 }
00820 
00821 const resip::SipMessage& 
00822 RequestContext::getOriginalRequest() const
00823 {
00824    return *mOriginalRequest;
00825 }
00826 
00827 resip::Data
00828 RequestContext::getTransactionId() const
00829 {
00830    if(mOriginalRequest->mIsBadAck200)
00831    {
00832       static Data ack("ack");
00833       return mOriginalRequest->getTransactionId()+ack;
00834    }
00835    else
00836    {
00837       return mOriginalRequest->getTransactionId();
00838    }
00839 }
00840 
00841 resip::Message* 
00842 RequestContext::getCurrentEvent()
00843 {
00844    return mCurrentEvent;
00845 }
00846 
00847 const resip::Message* 
00848 RequestContext::getCurrentEvent() const
00849 {
00850    return mCurrentEvent;
00851 }
00852 
00853 void 
00854 RequestContext::setDigestIdentity (const resip::Data& data)
00855 {
00856    mDigestIdentity = data;
00857 }
00858 
00859 const resip::Data& 
00860 RequestContext::getDigestIdentity() const
00861 {
00862    return mDigestIdentity;
00863 }
00864 
00865 void
00866 RequestContext::updateTimerC()
00867 {
00868    InfoLog(<<"Updating timer C.");
00869    mTCSerial++;
00870    TimerCMessage* tc = new TimerCMessage(this->getTransactionId(),mTCSerial);
00871    mProxy.postTimerC(std::auto_ptr<TimerCMessage>(tc));
00872 }
00873 
00874 void
00875 RequestContext::postTimedMessage(std::auto_ptr<resip::ApplicationMessage> msg,int seconds)
00876 {
00877    mProxy.postMS(msg,seconds);
00878 }
00879 
00880 void
00881 RequestContext::postAck200Done()
00882 {
00883    assert(mOriginalRequest->method()==ACK);
00884    DebugLog(<<"Posting Ack200DoneMessage");
00885    // .bwc. This needs to have a timer attached to it. (We need to
00886    // wait until all potential retransmissions of the ACK/200 have
00887    // stopped. However, we must be mindful that we may receive a new,
00888    // non-ACK transaction with the same tid during this time, and make
00889    // sure we don't explode violently when this happens.)
00890    mProxy.postMS(
00891       std::auto_ptr<ApplicationMessage>(new Ack200DoneMessage(getTransactionId())),
00892       64*resip::Timer::T1);
00893 }
00894 
00895 void
00896 RequestContext::send(SipMessage& msg)
00897 {
00898    mProxy.send(msg);
00899 }
00900 
00901 void
00902 RequestContext::sendResponse(SipMessage& msg)
00903 {
00904    assert (msg.isResponse());
00905    
00906    // We can't respond to an ACK request - so just drop it and generate an Ack200DoneMessage so the request context
00907    // gets cleaned up properly
00908    if(mOriginalRequest->method() == ACK)
00909    {
00910       ErrLog(<<"Posting Ack200DoneMessage: due to sendResponse(). This is probably a bug.");
00911       postAck200Done();
00912    }
00913    else
00914    {
00915       DebugLog(<< "tid of orig req: " << mOriginalRequest->getTransactionId());
00916       resip::Data tid;
00917       try
00918       {
00919          tid=msg.getTransactionId();
00920       }
00921       catch(SipMessage::Exception&)
00922       {
00923          InfoLog(<< "Bad tid in response. Trying to replace with 2543 tid "
00924                   "from orig request.");
00925          tid=mOriginalRequest->getRFC2543TransactionId();
00926          // .bwc. If the original request didn't have a proper transaction-
00927          // id, the response will not either. We need to set the tid in the 
00928          // response in order to make sure that this response hits the 
00929          // correct transaction down in the stack.
00930          msg.setRFC2543TransactionId(tid);
00931       }
00932       
00933       if(tid!=mOriginalRequest->getTransactionId())
00934       {
00935          InfoLog(<<"Someone messed with the Via stack in a response. This "
00936                         "is not only bad behavior, but potentially malicious. "
00937                         "Response came from: " << msg.getSource() <<
00938                         " Request came from: " << 
00939                         mOriginalRequest->getSource() << 
00940                         " Via after modification (in response): " <<
00941                         msg.header(h_Vias).front() <<
00942                         " Via before modification (in orig request): " <<
00943                         mOriginalRequest->header(h_Vias).front());
00944          // .bwc. Compensate for malicous/broken UAS fiddling with Via stack.
00945          msg.header(h_Vias).front()=mOriginalRequest->header(h_Vias).front();
00946       }
00947 
00948       DebugLog(<<"Ensuring orig tid matches tid of response: " <<
00949                msg.getTransactionId() << " == " <<
00950                mOriginalRequest->getTransactionId());
00951       assert(msg.getTransactionId()==mOriginalRequest->getTransactionId());
00952       
00953       // .bwc. Provisionals are not final responses, and CANCEL/200 is not a final
00954       //response in this context.
00955       if (msg.header(h_StatusLine).statusCode()>199 && msg.method()!=CANCEL)
00956       {
00957          DebugLog(<<"Sending final response.");
00958          mHaveSentFinalResponse=true;
00959       }
00960       const resip::Data& serverText = mProxy.getServerText();
00961       if (!serverText.empty() && !msg.exists(h_Server) ) 
00962       {
00963          msg.header(h_Server).value() = serverText;
00964       }
00965       send(msg);
00966    }
00967 }
00968 
00969 // This function assumes that if ;lr shows up in the RURI, that it's a URI 
00970 // we put in a Record-Route header earlier. It will do the wrong thing if 
00971 // some other malbehaving implementation lobs something at us with
00972 // ;lr in the RURI and it wasn't us. (from Section 16.4 of RFC 3261)
00973 void
00974 RequestContext::fixStrictRouterDamage()
00975 {
00976    if(mOriginalRequest->header(h_RequestLine).uri().exists(p_lr))
00977    {
00978       if (mOriginalRequest->exists(h_Routes)
00979           && !mOriginalRequest->header(h_Routes).empty())
00980       {
00981          mOriginalRequest->header(h_RequestLine).uri() = mOriginalRequest->header(h_Routes).back().uri();
00982          mOriginalRequest->header(h_Routes).pop_back();
00983       }
00984       else
00985       {
00986          //!RjS! When we wire this class for logging, here's a
00987          //      place to log a warning
00988       }
00989    }
00990 }
00991 
00992 /** @brief Pops the topmost route if it's us */
00993 void
00994 RequestContext::removeTopRouteIfSelf()
00995 {
00996    if(mOriginalRequest->exists(h_Routes)
00997       && !mOriginalRequest->header(h_Routes).empty()
00998       &&  mProxy.isMyUri(mOriginalRequest->header(h_Routes).front().uri()))
00999    {
01000       // save the top-most Route header field so monkeys can check it later
01001       mTopRoute = mOriginalRequest->header(h_Routes).front();
01002 
01003       mOriginalRequest->header(h_Routes).pop_front();
01004 
01005       static ExtensionParameter p_drr("drr");
01006       if(mTopRoute.uri().exists(p_drr))
01007       {
01008          if(!mOriginalRequest->header(h_Routes).empty()
01009               &&  mProxy.isMyUri(mOriginalRequest->header(h_Routes).front().uri()))
01010          {
01011             // .bwc. Do double-record routing logic
01012             mTopRoute = mOriginalRequest->header(h_Routes).front();
01013       
01014             mOriginalRequest->header(h_Routes).pop_front();
01015          }
01016          else
01017          {
01018             // ?bwc? Somebody messed with our record-routes. Just ignore? Or 
01019             // should we reject?
01020          }
01021       }
01022    }
01023 }
01024 
01025 Proxy& 
01026 RequestContext::getProxy()
01027 {
01028    return mProxy;
01029 }
01030 
01031 ResponseContext&
01032 RequestContext::getResponseContext()
01033 {
01034    return mResponseContext;
01035 }
01036 
01037 NameAddr&
01038 RequestContext::getTopRoute()
01039 {
01040    return mTopRoute;
01041 }
01042 
01043 EncodeStream&
01044 repro::operator<<(EncodeStream& strm, const RequestContext& rc)
01045 {
01046    strm << "numtrans=" << rc.mTransactionCount
01047         << " final=" << rc.mHaveSentFinalResponse;
01048    if(!rc.mDigestIdentity.empty()) strm << " identity=" << rc.mDigestIdentity;
01049    if (rc.mOriginalRequest) strm << " req=" << rc.mOriginalRequest->brief();
01050    //if (rc.mCurrentEvent) strm << " current=" << rc.mCurrentEvent->brief();
01051    return strm;
01052 }
01053 
01054 
01055 
01056 /* ====================================================================
01057  * The Vovida Software License, Version 1.0 
01058  * 
01059  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
01060  * 
01061  * Redistribution and use in source and binary forms, with or without
01062  * modification, are permitted provided that the following conditions
01063  * are met:
01064  * 
01065  * 1. Redistributions of source code must retain the above copyright
01066  *    notice, this list of conditions and the following disclaimer.
01067  * 
01068  * 2. Redistributions in binary form must reproduce the above copyright
01069  *    notice, this list of conditions and the following disclaimer in
01070  *    the documentation and/or other materials provided with the
01071  *    distribution.
01072  * 
01073  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01074  *    and "Vovida Open Communication Application Library (VOCAL)" must
01075  *    not be used to endorse or promote products derived from this
01076  *    software without prior written permission. For written
01077  *    permission, please contact vocal@vovida.org.
01078  *
01079  * 4. Products derived from this software may not be called "VOCAL", nor
01080  *    may "VOCAL" appear in their name, without prior written
01081  *    permission of Vovida Networks, Inc.
01082  * 
01083  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01084  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01085  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01086  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01087  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01088  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01089  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01090  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01091  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01092  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01093  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01094  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01095  * DAMAGE.
01096  * 
01097  * ====================================================================
01098  * 
01099  * This software consists of voluntary contributions made by Vovida
01100  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01101  * Inc.  For more information on Vovida Networks, Inc., please see
01102  * <http://www.vovida.org/>.
01103  *
01104  */