|
reSIProcate/repro
9694
|
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 */
1.7.5.1