reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
TransactionState.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
37#include "rutil/ResipAssert.h"
38#include "rutil/DnsUtil.hxx"
39#include "rutil/Logger.hxx"
40#include "rutil/Socket.hxx"
41#include "rutil/Random.hxx"
43
44using namespace resip;
45
46#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION
47
48uint64_t TransactionState::DnsGreylistDurationMs = 32000; // default to 32 seconds, application can override
49uint32_t TransactionState::StatelessIdCounter = 0;
50
51TransactionState::TransactionState(TransactionController& controller, Machine m,
52 State s, const Data& id, MethodTypes method, const Data& methodText, TransactionUser* tu) :
53 mController(controller),
54 mMachine(m),
55 mState(s),
56 mIsAbandoned(false),
57 mPendingCancelReasons(0),
58 mIsReliable(true), // !jf!
59 mNextTransmission(0),
60 mDnsResult(0),
61 mId(id),
62 mMethod(method),
63 mMethodText(method==UNKNOWN ? new Data(methodText) : 0),
64 mCurrentMethodType(UNKNOWN),
65 mCurrentResponseCode(0),
66 mAckIsValid(false),
67 mPendingOperation(None),
68 mTransactionUser(tu),
69 mFailureReason(TransportFailure::None),
70 mFailureSubCode(0),
71 mTcpConnectTimerStarted(false)
72{
73 StackLog (<< "Creating new TransactionState: " << *this);
74}
75
76
78TransactionState::makeCancelTransaction(TransactionState* tr, Machine machine, const Data& tid)
79{
80 TransactionState* cancel = new TransactionState(tr->mController,
81 machine,
82 Trying,
83 tid,
84 CANCEL,
86 tr->mTransactionUser);
87 // !jf! don't set this since it will be set by TransactionState::processReliability()
88 //cancel->mIsReliable = tr->mIsReliable;
89 cancel->mResponseTarget = tr->mResponseTarget;
90 cancel->mTarget = tr->mTarget;
91 cancel->add(tid);
92
93 // !jf! don't call processServerNonInvite since it will delete
94 // the sip message which needs to get sent to the TU
95 cancel->processReliability(tr->mTarget.getType());
96 return cancel;
97}
98
99void
100TransactionState::handleInternalCancel(SipMessage* cancel,
101 TransactionState& clientInvite)
102{
103 TransactionState* state = TransactionState::makeCancelTransaction(&clientInvite, ClientNonInvite, clientInvite.mId+"cancel");
104 // Make sure the branch in the CANCEL matches the current
105 // branch of the INVITE, in case we have done a DNS failover (the transport
106 // sequences could be different by now)
107 cancel->header(h_Vias).front().param(p_branch) = clientInvite.mNextTransmission->const_header(h_Vias).front().param(p_branch);
108 state->processClientNonInvite(cancel);
109 // for the INVITE in case we never get a 487
110 clientInvite.mController.mTimers.add(Timer::TimerCleanUp, clientInvite.mId, 128*Timer::T1);
111}
112
113bool
114TransactionState::handleBadRequest(const resip::SipMessage& badReq, TransactionController& controller)
115{
116 resip_assert(badReq.isRequest() && badReq.method() != ACK);
117 try
118 {
119 SipMessage* error = Helper::makeResponse(badReq,400);
120 if(badReq.getReason())
121 {
122 error->header(h_StatusLine).reason()+="(" + *(badReq.getReason())+ ")";
123 }
124 Tuple target(badReq.getSource());
125
126 if(badReq.isExternal())
127 {
128 controller.mTransportSelector.transmit(error,target);
129 delete error;
130 return true;
131 }
132 else
133 {
134 // ?bwc? Should we put together a TransactionState here so we can
135 // send a 400 to the TU?
136 // TODO if we send the error to the TU, don't delete the error
137 delete error;
138 return false;
139 }
140 }
141 catch(resip::BaseException& e)
142 {
143 ErrLog(<< "Exception thrown in TransactionState::handleBadRequest."
144 " This shouldn't happen. " << e);
145 return false;
146 }
147}
148
150{
151 resip_assert(mState != Bogus);
152
153 if (mDnsResult)
154 {
155 mDnsResult->destroy();
156 }
157
158 //StackLog (<< "Deleting TransactionState " << mId << " : " << this);
159 erase(mId);
160
161 delete mNextTransmission;
162 delete mMethodText;
163 mNextTransmission = 0;
164 mMethodText = 0;
165
166 setPendingCancelReasons(0);
167
168 mState = Bogus;
169}
170
171bool
172TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& controller, const Data& tid)
173{
174 MethodTypes method=sip->method();
175 StackLog (<< "No matching transaction for " << sip->brief());
176 TransactionUser* tu = 0;
177 if (sip->isExternal())
178 {
179 if (controller.mTuSelector.haveTransactionUsers() && sip->isRequest())
180 {
181 tu = controller.mTuSelector.selectTransactionUser(*sip);
182 if (!tu)
183 {
184 //InfoLog (<< "Didn't find a TU for " << sip->brief());
185 // !bwc! We really should do something other than a 500 here.
186 // If none of the TUs liked the request because of the Request-
187 // Uri scheme, we should be returning a 416, for example.
188 // ?bwc? Um, should we _really_ be doing this statelessly?
189 InfoLog( << "No TU found for message: " << sip->brief());
190 SipMessage* noMatch = Helper::makeResponse(*sip, 500);
191 Tuple target(sip->getSource());
192
193 controller.mTransportSelector.transmit(noMatch, target);
194 delete noMatch;
195 return false;
196 }
197 else
198 {
199 //InfoLog (<< "Found TU for " << sip->brief());
200 }
201 }
202 }
203 else
204 {
205 tu = sip->getTransactionUser();
206 if (!tu)
207 {
208 //InfoLog (<< "No TU associated with " << sip->brief());
209 }
210 }
211
212 if (sip->isRequest())
213 {
214 // create a new state object and insert in the TransactionMap
215
216 if (sip->isExternal()) // new sip msg from transport
217 {
218 if (method == INVITE)
219 {
220 // !rk! This might be needlessly created. Design issue.
221 TransactionState* state = new TransactionState(controller,
222 ServerInvite,
223 Trying,
224 tid,
225 INVITE,
227 tu);
228
229 state->mNextTransmission = state->make100(sip);
230 state->mResponseTarget = sip->getSource(); // UACs source address
231 // since we don't want to reply to the source port if rport present
232 state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
233 state->mIsReliable = isReliable(state->mResponseTarget.getType());
234 state->add(tid);
235
236 if (Timer::T100 == 0)
237 {
238 state->sendCurrentToWire(); // will get deleted when this is deleted
239 state->mState = Proceeding;
240 }
241 else
242 {
243 //StackLog(<<" adding T100 timer (INV)");
244 controller.mTimers.add(Timer::TimerTrying, tid, Timer::T100);
245 }
246 state->sendToTU(sip);
247 return true;
248 }
249 else if (method == CANCEL)
250 {
251 // Note: For cancel requests the tid member passed in will have the token "cancel" appended
252 // to it, so that the cancel request can be treated as it's own transaction. sip->getTransactionId()
253 // will be the original tid from the wire and should match the tid of the INVITE request being
254 // cancelled.
255 TransactionState* matchingInvite = controller.mServerTransactionMap.find(sip->getTransactionId());
256 if (matchingInvite == 0)
257 {
258 InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas");
259 //was TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 481));
260 SipMessage* response = Helper::makeResponse(*sip, 481);
261 Tuple target(sip->getSource());
262 controller.mTransportSelector.transmit(response, target);
263
264 delete response;
265 return false;
266 }
267 else
268 {
269 resip_assert(matchingInvite);
270 TransactionState* state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid);
271 state->startServerNonInviteTimerTrying(*sip,tid);
272 state->sendToTU(sip);
273 return true;
274 }
275 }
276 else if (method != ACK)
277 {
278 TransactionState* state = new TransactionState(controller,
279 ServerNonInvite,
280 Trying,
281 tid,
282 method,
283 sip->methodStr(),
284 tu);
285 state->mResponseTarget = sip->getSource();
286 // since we don't want to reply to the source port if rport present
287 state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
288 state->add(tid);
289 state->mIsReliable = isReliable(state->mResponseTarget.getType());
290 state->startServerNonInviteTimerTrying(*sip,tid);
291 state->sendToTU(sip);
292 return true;
293 }
294
295 // Incoming ACK just gets passed to the TU
296 //StackLog(<< "Adding incoming message to TU fifo " << tid);
297 TransactionState::sendToTU(tu, controller, sip);
298 }
299 else // new sip msg from the TU
300 {
301 if (method == INVITE)
302 {
303 TransactionState* state = new TransactionState(controller,
304 ClientInvite,
305 Calling,
306 tid,
307 INVITE,
309 tu);
310 state->add(state->mId);
311 state->processClientInvite(sip);
312 }
313 else if (method == ACK)
314 {
315 TransactionState* state = new TransactionState(controller,
316 Stateless,
317 Calling,
318 tid,
319 ACK,
321 tu);
322 state->add(state->mId);
323 state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
324 state->processStateless(sip);
325 }
326 else if (method == CANCEL)
327 {
328 TransactionState* matchingInvite = controller.mClientTransactionMap.find(sip->getTransactionId());
329
330 if (matchingInvite == 0)
331 {
332 InfoLog (<< "No matching INVITE for incoming (from TU) CANCEL to uac");
333 TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip,481));
334 return false;
335 }
336 else if (matchingInvite->mState == Calling) // CANCEL before 1xx received
337 {
338 WarningLog(<< "You can't CANCEL a request until a provisional has been received");
339 StackLog (<< *matchingInvite);
340 StackLog (<< *sip);
341
342 matchingInvite->mIsAbandoned = true;
343 // If there are reason headers on the cancel we store them for use later when the
344 // cancel is able to be sent out.
345 if (sip->exists(h_Reasons))
346 {
347 matchingInvite->setPendingCancelReasons(&sip->header(h_Reasons));
348 }
349 return false;
350 }
351 else if (matchingInvite->mState == Completed)
352 {
353 // A final response was already seen for this INVITE transaction
354 matchingInvite->sendToTU(Helper::makeResponse(*sip, 200));
355 return false;
356 }
357 else
358 {
359 handleInternalCancel(sip, *matchingInvite);
360 }
361 }
362 else
363 {
364 TransactionState* state = new TransactionState(controller,
365 ClientNonInvite,
366 Trying,
367 tid,
368 method,
369 sip->methodStr(),
370 tu);
371 state->add(tid);
372 state->processClientNonInvite(sip);
373 }
374 }
375 }
376 else if (sip->isResponse()) // stray response
377 {
378 if (controller.mDiscardStrayResponses)
379 {
380 InfoLog (<< "discarding stray response: " << sip->brief());
381 return false;
382 }
383 else
384 {
385 StackLog (<< "forwarding stateless response: " << sip->brief());
386 TransactionState* state =
387 new TransactionState(controller,
388 Stateless,
389 Calling,
390 Data(StatelessIdCounter++),
391 method,
392 sip->methodStr(),
393 tu);
394 state->add(state->mId);
395 state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
396 state->processStateless(sip);
397 }
398 }
399 else // wasn't a request or a response
400 {
401 ErrLog (<< "Got a SipMessage that was neither a request nor response!"
402 << sip->brief());
403 return false;
404 }
405
406 return true;
407}
408
409void
410TransactionState::setPendingCancelReasons(const Tokens* reasons)
411{
412 if (reasons)
413 {
414 if (mPendingCancelReasons)
415 {
416 *mPendingCancelReasons = *reasons; // copy
417 }
418 else
419 {
420 mPendingCancelReasons = new Tokens(*reasons); // create and copy
421 }
422 }
423 else
424 {
425 delete mPendingCancelReasons;
426 mPendingCancelReasons = 0;
427 }
428}
429
430void
432 TransactionMessage* message)
433{
434 // Note: KeepAliveMessage is a special SipMessage - check for it first
435 KeepAliveMessage* keepAlive = dynamic_cast<KeepAliveMessage*>(message);
436 if (keepAlive)
437 {
438 StackLog ( << "Sending keep alive to: " << keepAlive->getDestination());
439 controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination());
440 delete keepAlive;
441 return;
442 }
443
444 SipMessage* sip = dynamic_cast<SipMessage*>(message);
445 if(!sip)
446 {
447 KeepAlivePong* pong = dynamic_cast<KeepAlivePong*>(message);
448 if (pong)
449 {
450 controller.mTuSelector.add(pong);
451 delete pong;
452 return;
453 }
454
455 ConnectionTerminated* term = dynamic_cast<ConnectionTerminated*>(message);
456 if (term)
457 {
458 controller.mTuSelector.add(term);
459 delete term;
460 return;
461 }
462
463 TerminateFlow* termFlow = dynamic_cast<TerminateFlow*>(message);
464 if(termFlow)
465 {
466 controller.mTransportSelector.terminateFlow(termFlow->getFlow());
467 delete termFlow;
468 return;
469 }
470
471 EnableFlowTimer* enableFlowTimer = dynamic_cast<EnableFlowTimer*>(message);
472 if(enableFlowTimer)
473 {
474 controller.mTransportSelector.enableFlowTimer(enableFlowTimer->getFlow());
475 delete enableFlowTimer;
476 return;
477 }
478
479 ZeroOutStatistics* zeroOutStatistics = dynamic_cast<ZeroOutStatistics*>(message);
480 if(zeroOutStatistics)
481 {
482 controller.mStatsManager.zeroOut();
483 delete zeroOutStatistics;
484 return;
485 }
486
487 PollStatistics* pollStatistics = dynamic_cast<PollStatistics*>(message);
488 if(pollStatistics)
489 {
490 controller.mStatsManager.poll();
491 delete pollStatistics;
492 return;
493 }
494
495 AddTransport* addTransport = dynamic_cast<AddTransport*>(message);
496 if(addTransport)
497 {
498 controller.mTransportSelector.addTransport(addTransport->getTransport(), true /* isStackRunning */);
499 delete addTransport;
500 return;
501 }
502
503 RemoveTransport* removeTransport = dynamic_cast<RemoveTransport*>(message);
504 if(removeTransport)
505 {
506 controller.mTransportSelector.removeTransport(removeTransport->getTransportKey());
507 delete removeTransport;
508 return;
509 }
510
511 InvokeAfterSocketCreationFunc* invokeAfterSocketCreationFunc = dynamic_cast<InvokeAfterSocketCreationFunc*>(message);
512 if(invokeAfterSocketCreationFunc)
513 {
514 controller.mTransportSelector.invokeAfterSocketCreationFunc(invokeAfterSocketCreationFunc->getTransportType());
515 }
516 }
517
518 // .bwc. We can't do anything without a tid here. Check this first.
519 Data tid;
520 try
521 {
522 tid = message->getTransactionId();
523 }
525 {
526 // .bwc This is not our error. Do not ErrLog.
527 DebugLog( << "TransactionState::process dropping message with invalid tid " << message->brief());
528 delete message;
529 return;
530 }
531
532 MethodTypes method = UNKNOWN;
533
534 if(sip)
535 {
536 method=sip->method();
537 // ?bwc? Should this come after checking for error conditions?
538 if(controller.mStack.statisticsManagerEnabled() && sip->isExternal())
539 {
540 controller.mStatsManager.received(sip);
541 }
542
543 // .bwc. Check for error conditions we can respond to.
544 if(sip->isRequest() && method != ACK)
545 {
546 // .bwc. If we are going to statelessly send a 503, we should do it
547 // in the transport, before we do expensive stuff like basicCheck and
548 // stampReceived. If the TU fifo is backed up, we should send a
549 // _stateful_ 503 below. (And only if the specific TU that can handle
550 // this message is backed up; if other TUs are congested, we should let
551 // it pass.)
552 /*
553 if(sip->isExternal() && (controller.isTUOverloaded() || controller.mStateMacFifo.isRejecting()))
554 {
555 SipMessage* tryLater = Helper::makeResponse(*sip, 503);
556 if( controller.mStateMacFifo.isRejecting() )
557 tryLater->header(h_RetryAfter).value() = controller.mStateMacFifo.getRetryAfter();
558 else
559 tryLater->header(h_RetryAfter).value() = 32 + (Random::getRandom() % 32);
560
561 //tryLater->header(h_RetryAfter).comment() = "Server busy TRANS";
562 Tuple target(sip->getSource());
563 delete sip;
564 controller.mTransportSelector.transmit(tryLater, target);
565 delete tryLater;
566 return;
567 }
568 */
569
570 if(sip->isInvalid())
571 {
572 handleBadRequest(*sip,controller);
573 delete sip;
574 return;
575 }
576 }
577
578#ifdef PEDANTIC_STACK
579 try
580 {
581 sip->parseAllHeaders();
582 }
583 catch(resip::BaseException& e)
584 {
585 if(sip->isRequest() && method!=ACK)
586 {
587 handleBadRequest(*sip,controller);
588 }
589
590 InfoLog(<< "Exception caught by pedantic stack: " << e);
591 }
592#endif
593
594 // This ensures that CANCEL requests form unique transactions
595 if (method == CANCEL)
596 {
597 tid += "cancel";
598 }
599 }
600
601 TransactionState* state = 0;
602 if (message->isClientTransaction())
603 {
604 state = controller.mClientTransactionMap.find(tid);
605 }
606 else
607 {
608 state = controller.mServerTransactionMap.find(tid);
609 }
610
611 if (state && sip && sip->isExternal())
612 {
613 // Various kinds of response fixup.
614 if(sip->isResponse() &&
615 state->mNextTransmission)
616 {
617 // .bwc. This code (if enabled) ensures that responses have the same
618 // CallId and tags as the request did (excepting the introduction of a
619 // remote tag). This is to protect dialog-stateful TUs that don't react
620 // gracefully when a stupid/malicious endpoint fiddles with the tags
621 // and/or CallId when it isn't supposed to. (DUM is one such TU)
622 if(state->mController.getFixBadDialogIdentifiers())
623 {
625 {
626 if(!(sip->const_header(h_CallId) ==
627 state->mNextTransmission->const_header(h_CallId)))
628 {
629 InfoLog(<< "Other end modified our Call-Id... correcting.");
630 sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId);
631 }
632 }
633 else
634 {
635 InfoLog(<< "Other end corrupted our CallId... correcting.");
636 sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId);
637 }
638
639 const NameAddr& from = state->mNextTransmission->const_header(h_From);
640 if(sip->const_header(h_From).isWellFormed())
641 {
642 // Overwrite tag.
643 if(from.exists(p_tag))
644 {
645 if(!sip->const_header(h_From).exists(p_tag) ||
646 sip->const_header(h_From).param(p_tag) != from.param(p_tag))
647 {
648 InfoLog(<<"Other end modified our local tag... correcting.");
649 sip->header(h_From).param(p_tag) = from.param(p_tag);
650 }
651 }
652 else if(sip->const_header(h_From).exists(p_tag))
653 {
654 InfoLog(<<"Other end added a local tag for us... removing.");
655 sip->header(h_From).remove(p_tag);
656 }
657 }
658 else
659 {
660 InfoLog(<<"Other end corrupted our From header... replacing.");
661 // Whole header is hosed, overwrite.
662 sip->header(h_From) = from;
663 }
664
665 const NameAddr& to = state->mNextTransmission->const_header(h_To);
666 if(sip->const_header(h_To).isWellFormed())
667 {
668 // Overwrite tag.
669 if(to.exists(p_tag))
670 {
671 if(!sip->const_header(h_To).exists(p_tag) ||
672 sip->const_header(h_To).param(p_tag) != to.param(p_tag))
673 {
674 InfoLog(<<"Other end modified the (existing) remote tag... "
675 "correcting.");
676 sip->header(h_To).param(p_tag) = to.param(p_tag);
677 }
678 }
679 }
680 else
681 {
682 InfoLog(<<"Other end corrupted our To header... replacing.");
683 // Whole header is hosed, overwrite.
684 sip->header(h_To) = to;
685 }
686 }
687
688 // .bwc. This code (if enabled) ensures that responses have the same
689 // CSeq number as the request did. This is to protect TUs that don't
690 // react gracefully when a stupid/malicious endpoint fiddles with the
691 // CSeq number. (This is a very cheap check; we already parse the CSeq
692 // for incoming messages)
693 if(state->mController.getFixBadCSeqNumbers())
694 {
695 unsigned int old=state->mNextTransmission->const_header(h_CSeq).sequence();
696 if(sip->const_header(h_CSeq).sequence() != old)
697 {
698 InfoLog(<<"Other end changed our CSeq number... replacing.");
699 sip->header(h_CSeq).sequence()=old;
700 }
701 }
702 }
703 // .bwc. This code ensures that the transaction state-machine can recover
704 // from ACK/200 with the same tid as the original INVITE. This problem is
705 // stupidly common.
706 if(sip->isRequest() && method == ACK && !state->mAckIsValid)
707 {
708 // Must have received an ACK to a 200;
709 // We will never respond to this, so nothing will need this tid for
710 // driving transaction state. Additionally,
711 InfoLog(<<"Someone sent us an ACK/200 with the same tid as the "
712 "original INVITE. This is bad behavior, and should be "
713 "corrected in the client.");
714 sip->mIsBadAck200=true;
715 // .bwc. This is a new stateless transaction, despite its tid.
716 state=0;
717 }
718 }
719
720 if(state && sip)
721 {
722 switch(state->mMethod)
723 {
724 case INVITE:
725 if(method != INVITE && method != ACK)
726 {
727 // Maybe respond if a request?
728 delete sip;
729 return;
730 }
731 break;
732 case UNKNOWN:
733 if(!state->mMethodText || *(state->mMethodText) != sip->methodStr())
734 {
735 // Maybe respond if a request?
736 delete sip;
737 return;
738 }
739 break;
740 default:
741 if(state->mMethod != method)
742 {
743 // Maybe respond if a request?
744 delete sip;
745 return;
746 }
747 break;
748 }
749
750 // .bwc. in private email 1 Feb 2013:
751 // According to the spec, there is no such thing as a reliable NIT
752 // retransmission; what we have just observed is a transaction id collision
753 // technically. Maybe a reliable NIT transaction collision needs special
754 // handling? It is probably a lot more common that this is a confused client,
755 // than a client that has innocently used the same tid as some other client,
756 // though. Maybe we should just ignore such requests?
757 if(sip->isExternal() && sip->isRequest() &&
758 method != ACK &&
759 state->mIsReliable)
760 {
761 InfoLog(<<"Someone sent us a request with a repeated transaction ID "
762 "over a reliable transport. Discarding the request.");
763 delete sip;
764 return;
765 }
766 }
767
768 if (state) // found transaction for sip msg
769 {
770 StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state);
771
772 switch (state->mMachine)
773 {
774 case ClientNonInvite:
775 state->processClientNonInvite(message);
776 break;
777 case ClientInvite:
778 // ACK from TU will be Stateless
779 resip_assert (!sip || !(state->isFromTU(sip) && sip->isRequest() && method == ACK));
780 state->processClientInvite(message);
781 break;
782 case ServerNonInvite:
783 state->processServerNonInvite(message);
784 break;
785 case ServerInvite:
786 state->processServerInvite(message);
787 break;
788 case Stateless:
789 state->processStateless(message);
790 break;
791 case ClientStale:
792 state->processClientStale(message);
793 break;
794 case ServerStale:
795 state->processServerStale(message);
796 break;
797 default:
798 CritLog(<<"internal state error");
799 resip_assert(0);
800 return;
801 }
802 }
803 else if (sip) // new transaction
804 {
805 try
806 {
807 bool processed = processSipMessageAsNew(sip, controller, tid);
808 if (!processed)
809 {
810 delete sip;
811 }
812 }
813 catch(resip::BaseException& e)
814 {
815 StackLog ( << "Got badly formatted sip message, error: " << e.what());
816 if(sip->isRequest() && sip->method()!=ACK)
817 {
818 handleBadRequest(*sip, controller);
819 }
820 delete sip;
821 }
822 catch(std::exception& err)
823 {
824 StackLog ( << "Got error: " << err.what());
825 delete sip;
826 }
827 }
828 else // timer or other non-sip msg
829 {
830 //StackLog (<< "discarding non-sip message: " << message->brief());
831 delete message;
832 }
833}
834
835void
837 TimerMessage* message)
838{
839 Data tid = message->getTransactionId();
840
842 {
843 // .bwc. State machine fifo is backed up; we probably should not be
844 // retransmitting anything right now. If we have a retransmit timer,
845 // reschedule for later, but don't retransmit.
846 switch(message->getType())
847 {
848 case Timer::TimerA: // doubling
849 controller.mTimers.add(Timer::TimerA,
850 tid,
851 message->getDuration()*2);
852 delete message;
853 return;
854 case Timer::TimerE1:// doubling, until T2
855 case Timer::TimerG: // doubling, until T2
856 controller.mTimers.add(message->getType(),
857 tid,
858 resipMin(message->getDuration()*2,
859 Timer::T2));
860 delete message;
861 return;
862 case Timer::TimerE2:// just reset
863 controller.mTimers.add(Timer::TimerE2,
864 tid,
865 Timer::T2);
866 delete message;
867 return;
868 default:
869 ; // let it through
870 }
871 }
872
873 TransactionState* state = 0;
874 if (message->isClientTransaction()) state = controller.mClientTransactionMap.find(tid);
875 else state = controller.mServerTransactionMap.find(tid);
876
877 if (state) // found transaction for timer
878 {
879 StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state);
880
881 switch (state->mMachine)
882 {
883 case ClientNonInvite:
884 state->processClientNonInvite(message);
885 break;
886 case ClientInvite:
887 state->processClientInvite(message);
888 break;
889 case ServerNonInvite:
890 state->processServerNonInvite(message);
891 break;
892 case ServerInvite:
893 state->processServerInvite(message);
894 break;
895 case Stateless:
896 state->processStateless(message);
897 break;
898 case ClientStale:
899 state->processClientStale(message);
900 break;
901 case ServerStale:
902 state->processServerStale(message);
903 break;
904 default:
905 CritLog(<<"internal state error");
906 resip_assert(0);
907 return;
908 }
909 }
910 else
911 {
912 delete message;
913 }
914
915}
916
917void
918TransactionState::startServerNonInviteTimerTrying(SipMessage& sip, const Data& tid)
919{
920 unsigned int duration = 3500;
921 if(Timer::T1 != 500) // optimzed for T1 == 500
922 {
923 // Iteratively calculate how much time before TimerE reaches T2 (RFC4320) - could be improved
924 duration = Timer::T1;
925 while(duration*2<Timer::T2) duration = duration * 2;
926 }
927 resetNextTransmission(make100(&sip)); // Store for use when timer expires
928 mController.mTimers.add(Timer::TimerTrying, tid, duration ); // Start trying timer so that we can send 100 to NITs as recommened in RFC4320
929}
930
931void
932TransactionState::processStateless(TransactionMessage* message)
933{
934 // for ACK messages from the TU, there is no transaction, send it directly
935 // to the wire // rfc3261 17.1 Client Transaction
936 SipMessage* sip = dynamic_cast<SipMessage*>(message);
937 StackLog (<< "TransactionState::processStateless: " << message->brief() << " -> " << *this);
938
939 // !jf! There is a leak for Stateless transactions associated with ACK to 200
940 if (isFromTU(message))
941 {
942 resetNextTransmission(sip);
943 sendCurrentToWire();
944 }
945 else if(sip && isFromWire(sip))
946 {
947 InfoLog (<< "Received message from wire on a stateless transaction");
948 StackLog (<< *sip);
949 //assert(0);
950 sendToTU(sip);
951 }
952 else if (isTransportError(message))
953 {
954 processTransportFailure(message);
955
956 delete message;
957 delete this;
958 }
959 else if (isTcpConnectState(message))
960 {
961 // stateless mode is not supported
962 //processTcpConnectState(message);
963 delete message;
964 }
965 else if (isTimer(message))
966 {
967 TimerMessage* timer = dynamic_cast<TimerMessage*>(message);
968 if (timer->getType() == Timer::TimerStateless)
969 {
970 delete message;
971 delete this;
972 }
973 else
974 {
975 delete timer;
976 //resip_assert(0); // Don't assert a poorly behaving client can cause this, ie: client sends an ACK in response to response on a non-INVITE transaction
977 }
978 }
979 else if(dynamic_cast<DnsResultMessage*>(message))
980 {
981 handleSync(mDnsResult);
982 delete message;
983 }
984 else if (isAbandonServerTransaction(message))
985 {
986 // ?
987 delete message;
988 }
989 else
990 {
991 delete message;
992 resip_assert(0);
993 }
994}
995
996void
997TransactionState::saveOriginalContactAndVia(const SipMessage& sip)
998{
999 if(sip.exists(h_Contacts) && sip.const_header(h_Contacts).size() == 1 &&
1000 sip.const_header(h_Contacts).front().isWellFormed())
1001 {
1002 mOriginalContact = std::unique_ptr<NameAddr>(new NameAddr(sip.header(h_Contacts).front()));
1003 }
1004 mOriginalVia = std::unique_ptr<Via>(new Via(sip.header(h_Vias).front()));
1005}
1006
1007void TransactionState::restoreOriginalContactAndVia()
1008{
1009 if (mNextTransmission)
1010 {
1011 if (mOriginalContact.get())
1012 {
1013 mNextTransmission->header(h_Contacts).front() = *mOriginalContact;
1014 }
1015 if (mOriginalVia.get())
1016 {
1017 mOriginalVia->param(p_branch).incrementTransportSequence();
1018 mNextTransmission->header(h_Vias).front() = *mOriginalVia;
1019 }
1020 }
1021}
1022
1023void
1024TransactionState::processClientNonInvite(TransactionMessage* msg)
1025{
1026 StackLog (<< "TransactionState::processClientNonInvite: " << msg->brief() << " -> " << *this);
1027
1028 if (isRequest(msg) && isFromTU(msg))
1029 {
1030 //StackLog (<< "received new non-invite request");
1031 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1032 resetNextTransmission(sip);
1033 saveOriginalContactAndVia(*sip);
1034 mController.mTimers.add(Timer::TimerF, mId, Timer::TF);
1035 sendCurrentToWire();
1036 }
1037 else if (isResponse(msg) && isFromWire(msg)) // from the wire
1038 {
1039 //StackLog (<< "received response from wire");
1040
1041 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1042 int code = sip->const_header(h_StatusLine).responseCode();
1043 if (code >= 100 && code < 200) // 1XX
1044 {
1045 if (mState == Trying || mState == Proceeding)
1046 {
1047 //?slg? if we set the timer in Proceeding, then every 1xx response will cause another TimerE2 to be set and many retransmissions will occur - which is not correct
1048 // Should we restart the E2 timer though? If so, we need to use somekind of timer sequence number so that previous E2 timers get discarded.
1049 if (!mIsReliable && mState == Trying)
1050 {
1051 mController.mTimers.add(Timer::TimerE2, mId, Timer::T2 );
1052 }
1053 mState = Proceeding;
1054 sendToTU(msg); // don't delete
1055 }
1056 else
1057 {
1058 // ignore
1059 delete msg;
1060 }
1061 }
1062 else if (code >= 200)
1063 {
1064 // don't notify the TU of retransmissions
1065 if (mState == Trying || mState == Proceeding)
1066 {
1067 sendToTU(msg); // don't delete
1068 }
1069 else if (mState == Completed)
1070 {
1071 delete msg;
1072 }
1073 else
1074 {
1075 resip_assert(0);
1076 delete sip;
1077 }
1078
1079 if (mIsReliable)
1080 {
1081 terminateClientTransaction(mId);
1082 delete this;
1083 }
1084 else if (mState != Completed) // prevent TimerK reproduced
1085 {
1086 mState = Completed;
1087 mController.mTimers.add(Timer::TimerK, mId, Timer::T4 );
1088 // !bwc! Got final response in NIT. We don't need to do anything
1089 // except quietly absorb retransmissions. Dump all state.
1090 if(mDnsResult)
1091 {
1092 mDnsResult->destroy();
1093 mDnsResult=0;
1094 mPendingOperation=None;
1095 }
1096 resetNextTransmission(0);
1097 }
1098 }
1099 else
1100 {
1101 resip_assert(0);
1102 delete sip;
1103 }
1104 }
1105 else if (isTimer(msg))
1106 {
1107 //StackLog (<< "received timer in client non-invite transaction");
1108
1109 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1110 switch (timer->getType())
1111 {
1112 case Timer::TimerE1:
1113 if (mState == Trying)
1114 {
1115 unsigned long d = timer->getDuration();
1116 if (d < Timer::T2) d *= 2;
1117 mController.mTimers.add(Timer::TimerE1, mId, d);
1118 StackLog (<< "Transmitting current message");
1119 sendCurrentToWire();
1120 delete timer;
1121 }
1122 else
1123 {
1124 // ignore
1125 delete msg;
1126 }
1127 break;
1128
1129 case Timer::TimerE2:
1130 if (mState == Proceeding)
1131 {
1132 mController.mTimers.add(Timer::TimerE2, mId, Timer::T2);
1133 StackLog (<< "Transmitting current message");
1134 sendCurrentToWire();
1135 delete timer;
1136 }
1137 else
1138 {
1139 // ignore
1140 delete msg;
1141 }
1142 break;
1143
1145 if (mTcpConnectTimerStarted) // Ignore timer if we went connected (note: when we connect we set mTcpConnectTimerStarted to false)
1146 {
1148 processTransportFailure(&failure);
1149 }
1150 delete msg;
1151 break;
1152
1153 case Timer::TimerF:
1154 if (mState == Trying || mState == Proceeding)
1155 {
1156 // !bwc! We hold onto this until we get a response from the wire
1157 // in client transactions, for this contingency.
1158 resip_assert(mNextTransmission);
1159 if(mPendingOperation == Dns)
1160 {
1161 WarningLog(<< "Transaction timed out while waiting for DNS "
1162 "result uri=" <<
1163 mNextTransmission->const_header(h_RequestLine).uri());
1164 sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1165 }
1166 else
1167 {
1168 sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1169 }
1170 terminateClientTransaction(mId);
1171 delete this;
1172 }
1173
1174 delete msg;
1175 break;
1176
1177 case Timer::TimerK:
1178 terminateClientTransaction(mId);
1179 delete msg;
1180 delete this;
1181 break;
1182
1183 default:
1184 //InfoLog (<< "Ignoring timer: " << *msg);
1185 delete msg;
1186 break;
1187 }
1188 }
1189 else if (isTransportError(msg))
1190 {
1191 processTransportFailure(msg);
1192 delete msg;
1193 }
1194 else if (isTcpConnectState(msg))
1195 {
1196 processTcpConnectState(msg);
1197 delete msg;
1198 }
1199 else if(dynamic_cast<DnsResultMessage*>(msg))
1200 {
1201 handleSync(mDnsResult);
1202 delete msg;
1203 }
1204 else if (isAbandonServerTransaction(msg))
1205 {
1206 // ?
1207 delete msg;
1208 }
1209 else
1210 {
1211 //StackLog (<< "TransactionState::processClientNonInvite: message unhandled");
1212 delete msg;
1213 }
1214}
1215
1216void
1217TransactionState::processClientInvite(TransactionMessage* msg)
1218{
1219 StackLog(<< "TransactionState::processClientInvite: " << msg->brief() << " -> " << *this);
1220 if (isRequest(msg) && isFromTU(msg))
1221 {
1222 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1223 switch (sip->method())
1224 {
1225 // Received INVITE request from TU="Transaction User", Start Timer B which controls
1226 // transaction timeouts.
1227 case INVITE:
1228 if(mState==Calling && !mNextTransmission && mMsgToRetransmit.empty())
1229 {
1230 resetNextTransmission(sip);
1231 saveOriginalContactAndVia(*sip);
1232 mController.mTimers.add(Timer::TimerB, mId, Timer::TB );
1233 sendCurrentToWire();
1234 }
1235 else
1236 {
1237 WarningLog(<< "TU sent us a duplicate INVITE: fix this!");
1238 delete sip;
1239 }
1240 break;
1241
1242 case CANCEL:
1243 resip_assert(0);
1244 delete msg;
1245 break;
1246
1247 default:
1248 WarningLog(<< "TU sent us an erroneous request inside a Client"
1249 " INVITE transaction: fix this!");
1250 delete msg;
1251 break;
1252 }
1253 }
1254 else if (isResponse(msg) && isFromWire(msg))
1255 {
1256 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1257 int code = sip->const_header(h_StatusLine).responseCode();
1258 switch (sip->method())
1259 {
1260 case INVITE:
1261 /* If the client transaction receives a provisional response while in
1262 the "Calling" state, it transitions to the "Proceeding" state. In the
1263 "Proceeding" state, the client transaction SHOULD NOT retransmit the
1264 request any longer (this will be Handled in "else if (isTimer(msg))")
1265 The Retransmissions will be stopped, Not by Cancelling Timers but
1266 by Ignoring the fired Timers depending upon the State which stack is in.
1267 */
1268 if (code >= 100 && code < 200) // 1XX
1269 {
1270 if (mState == Calling || mState == Proceeding)
1271 {
1272 mState = Proceeding;
1273 if(mIsAbandoned)
1274 {
1275 SipMessage* cancel = Helper::makeCancel(*mNextTransmission);
1276 if (mPendingCancelReasons)
1277 {
1278 cancel->header(h_Reasons) = *mPendingCancelReasons;
1279 setPendingCancelReasons(0); // release memory
1280 }
1281 // Iterate through message decorators on the INVITE and see if any need to be copied to the CANCEL
1282 mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel);
1283 handleInternalCancel(cancel, *this);
1284 mIsAbandoned=false;
1285 }
1286 // !bwc! We have gotten a response. We don't need to
1287 // retransmit the original INVITE anymore (so we clear mMsgToRetransmit),
1288 // but we do need to retain the full original INVITE until we get a final
1289 // response, in case we need to forge an ACK.
1290 mMsgToRetransmit.clear();
1291 sendToTU(sip); // don't delete msg
1292 }
1293 else
1294 {
1295 delete msg;
1296 }
1297 }
1298
1299 /* When in either the "Calling" or "Proceeding" states, reception of a
1300 2xx response MUST cause the client transaction to enter the
1301 "Terminated" state, and the response MUST be passed up to the TU
1302 State Machine is changed to Stale since, we wanted to ensure that
1303 all 2xx gets to TU
1304 */
1305 else if (code >= 200 && code < 300)
1306 {
1307 mIsAbandoned=false;
1308 sendToTU(sip); // don't delete msg
1309 //terminateClientTransaction(mId);
1310 mMachine = ClientStale;
1311 mState = Completed;
1312 // !bwc! We have a final response. We don't need either of
1313 // mMsgToRetransmit or mNextTransmission. We ignore further
1314 // traffic.
1315 resetNextTransmission(0);
1316 if(mDnsResult)
1317 {
1318 mDnsResult->destroy();
1319 mDnsResult=0;
1320 mPendingOperation=None;
1321 }
1322 StackLog (<< "Received 2xx on client invite transaction");
1323 StackLog (<< *this);
1324 mController.mTimers.add(Timer::TimerStaleClient, mId, Timer::TS );
1325 }
1326 else if (code >= 300)
1327 {
1328 mIsAbandoned=false;
1329 // When in either the "Calling" or "Proceeding" states, reception of a
1330 // response with status code from 300-699 MUST cause the client
1331 // transaction to transition to "Completed".
1332 if (mIsReliable)
1333 {
1334 // Stack MUST pass the received response up to the TU, and the client
1335 // transaction MUST generate an ACK request, even if the transport is
1336 // reliable
1337 SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip);
1338 mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack);
1339 resetNextTransmission(ack);
1340
1341 // want to use the same transport as was selected for Invite
1343 sendCurrentToWire();
1344 sendToTU(sip); // don't delete msg
1345 terminateClientTransaction(mId);
1346
1347 // !bwc! We only do this because we are assured the ACK
1348 // will make it to the other end; if we are using an
1349 // unreliable transport, we need to stick around to absorb
1350 // retransmissions of the response.
1351 delete this;
1352 }
1353 else
1354 {
1355 if (mState == Calling || mState == Proceeding)
1356 {
1357 // MUST pass the received response up to the TU, and the client
1358 // transaction MUST generate an ACK request, even if the transport is
1359 // reliable, if transport is Unreliable then Fire the Timer D which
1360 // take care of re-Transmission of ACK
1361 mState = Completed;
1362 mController.mTimers.add(Timer::TimerD, mId, Timer::TD );
1363 SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip);
1364 mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack);
1365 resetNextTransmission(ack);
1366 sendCurrentToWire();
1367 sendToTU(sip); // don't delete msg
1368 if (mDnsResult)
1369 {
1370 mDnsResult->destroy();
1371 mDnsResult = 0;
1372 mPendingOperation = None;
1373 }
1374 }
1375 else if (mState == Completed)
1376 {
1377 // Any retransmissions of the final response that
1378 // are received while in the "Completed" state MUST
1379 // cause the ACK to be re-passed to the transport
1380 // layer for retransmission.
1381 sendCurrentToWire();
1382 delete sip;
1383 }
1384 else
1385 {
1386 /* This should never Happen if it happens we should have a plan
1387 what to do here?? for now assert will work
1388 */
1389 CritLog( << "State invalid");
1390 // !ah! syslog
1391 resip_assert(0);
1392 delete sip;
1393 }
1394 }
1395 }
1396 else
1397 {
1398 delete sip;
1399 resip_assert(0);
1400 }
1401 break;
1402
1403 case CANCEL:
1404 resip_assert(0);
1405 delete sip;
1406 break;
1407
1408 default:
1409 delete msg;
1410 break;
1411 }
1412 }
1413 else if (isTimer(msg))
1414 {
1415 /* Handle Transaction Timers , Retransmission Timers which were set and Handle
1416 Cancellation of Timers for Re-transmissions here */
1417
1418 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1419 StackLog (<< "timer fired: " << *timer);
1420
1421 switch (timer->getType())
1422 {
1423 case Timer::TimerA:
1424 if (mState == Calling && !mIsAbandoned)
1425 {
1426 unsigned long d = timer->getDuration()*2;
1427 // TimerA is supposed to double with each retransmit RFC3261 17.1.1
1428
1429 mController.mTimers.add(Timer::TimerA, mId, d);
1430 DebugLog (<< "Retransmitting INVITE ");
1431 sendCurrentToWire();
1432 }
1433 delete msg;
1434 break;
1435
1437 if (mTcpConnectTimerStarted) // Ignore timer if we went connected (note: when we connect we set mTcpConnectTimerStarted to false)
1438 {
1440 processTransportFailure(&failure);
1441 }
1442 delete msg;
1443 break;
1444
1445 case Timer::TimerB:
1446 if (mState == Calling)
1447 {
1448 resip_assert(mNextTransmission && mNextTransmission->isRequest() &&
1449 mNextTransmission->method()==INVITE);
1450 if(mPendingOperation == Dns)
1451 {
1452 WarningLog(<< "Transaction timed out while waiting for DNS "
1453 "result uri=" <<
1454 mNextTransmission->const_header(h_RequestLine).uri());
1455 sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1456 }
1457 else
1458 {
1459 sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1460 }
1461 terminateClientTransaction(mId);
1462 delete this;
1463 }
1464 delete msg;
1465 break;
1466
1467 case Timer::TimerD:
1468 terminateClientTransaction(mId);
1469 delete msg;
1470 delete this;
1471 break;
1472
1474 // !ah! Cancelled Invite Cleanup Timer fired.
1475 if (mState == Proceeding)
1476 {
1477 resip_assert(mNextTransmission && mNextTransmission->isRequest() &&
1478 mNextTransmission->method() == INVITE);
1479 StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mNextTransmission);
1480 InfoLog(<<"Making 408 for canceled invite that received no response: "<< mNextTransmission->brief());
1481 if(mPendingOperation == Dns)
1482 {
1483 WarningLog(<< "Transaction timed out while waiting for DNS "
1484 "result uri=" <<
1485 mNextTransmission->const_header(h_RequestLine).uri());
1486 sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1487 }
1488 else
1489 {
1490 sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1491 }
1492 terminateClientTransaction(msg->getTransactionId());
1493 delete this;
1494 }
1495 delete msg;
1496 break;
1497
1498 default:
1499 delete msg;
1500 break;
1501 }
1502 }
1503 else if (isTransportError(msg))
1504 {
1505 processTransportFailure(msg);
1506 delete msg;
1507 }
1508 else if (isTcpConnectState(msg))
1509 {
1510 processTcpConnectState(msg);
1511 delete msg;
1512 }
1513 else if (isCancelClientTransaction(msg))
1514 {
1515 CancelClientInviteTransaction* pCancelMsg = dynamic_cast<CancelClientInviteTransaction*>(msg);
1516
1517 // TU wants to CANCEL this transaction. See if we can...
1518 if(mState==Proceeding)
1519 {
1520 // We can send the CANCEL now.
1521 SipMessage* cancel = Helper::makeCancel(*mNextTransmission);
1522 if (pCancelMsg->getReasons())
1523 {
1524 cancel->header(h_Reasons) = *pCancelMsg->getReasons();
1525 }
1526 mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel);
1527 TransactionState::handleInternalCancel(cancel, *this);
1528 }
1529 else if(mState==Calling)
1530 {
1531 // We can't send the CANCEL yet, remember to.
1532 mIsAbandoned = true;
1533 setPendingCancelReasons(pCancelMsg->getReasons());
1534 }
1535 delete msg;
1536 }
1537 else if(dynamic_cast<DnsResultMessage*>(msg))
1538 {
1539 handleSync(mDnsResult);
1540 delete msg;
1541 }
1542 else
1543 {
1544 //StackLog ( << "TransactionState::processClientInvite: message unhandled");
1545 delete msg;
1546 }
1547}
1548
1549void
1550TransactionState::processServerNonInvite(TransactionMessage* msg)
1551{
1552 StackLog (<< "TransactionState::processServerNonInvite: " << msg->brief() << " -> " << *this);
1553
1554 if (isRequest(msg) && !isInvite(msg) && isFromWire(msg)) // retransmission from the wire
1555 {
1556 if (mState == Trying)
1557 {
1558 // ignore
1559 delete msg;
1560 }
1561 else if (mState == Proceeding || mState == Completed)
1562 {
1563 if(mIsAbandoned)
1564 {
1565 resip_assert(mState == Completed);
1566 mIsAbandoned=false;
1567 // put a 500 in mNextTransmission
1568 SipMessage* req = dynamic_cast<SipMessage*>(msg);
1569 resetNextTransmission(Helper::makeResponse(*req, 500));
1570 sendCurrentToWire();
1571 }
1572 else
1573 {
1574 // We have already sent a 100, but we have just received a retransmission. Requests
1575 // likely crossed on the wire. We need to respond with another 100, but the last one was
1576 // cleared so re-create the 100 now.
1577 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1578 if (sip && mMsgToRetransmit.empty() && !mNextTransmission)
1579 {
1580 resetNextTransmission(make100(sip));
1581 }
1582 sendCurrentToWire();
1583 }
1584 delete msg;
1585 }
1586 else
1587 {
1588 CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
1589 << msg->brief()
1590 << " state=" << *this);
1591 resip_assert(0);
1592 delete msg;
1593 return;
1594 }
1595 }
1596 else if (isResponse(msg) && isFromTU(msg))
1597 {
1598 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1599 int code = sip->const_header(h_StatusLine).responseCode();
1600 if (code >= 100 && code < 200) // 1XX
1601 {
1602 if (mState == Trying || mState == Proceeding)
1603 {
1604 resetNextTransmission(sip);
1605 mState = Proceeding;
1606 sendCurrentToWire(); // don't delete msg
1607 }
1608 else
1609 {
1610 // ignore
1611 delete msg;
1612 }
1613 }
1614 else if (code >= 200 && code <= 699)
1615 {
1616 if (mIsReliable)
1617 {
1618 resetNextTransmission(sip);
1619 sendCurrentToWire();
1620 terminateServerTransaction(mId);
1621
1622 // !bwc! We can only do this because we are in a reliable
1623 // transport, and do not need to hang around to soak up
1624 // retransmissions.
1625 delete this;
1626 }
1627 else
1628 {
1629 if (mState == Trying || mState == Proceeding)
1630 {
1631 mState = Completed;
1632 mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 );
1633 resetNextTransmission(sip);
1634 sendCurrentToWire();
1635 }
1636 else if (mState == Completed)
1637 {
1638 // ignore
1639 delete sip;
1640 }
1641 else
1642 {
1643 CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
1644 << msg->brief()
1645 << " state=" << *this);
1646 resip_assert(0);
1647 delete sip;
1648 return;
1649 }
1650 }
1651 }
1652 else
1653 {
1654 // ignore
1655 delete msg;
1656 }
1657 }
1658 else if (isTimer(msg))
1659 {
1660 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1661 resip_assert(timer);
1662 switch (timer->getType())
1663 {
1664 case Timer::TimerJ:
1665 if (mState == Completed)
1666 {
1667 terminateServerTransaction(mId);
1668 delete this;
1669 }
1670 delete msg;
1671 break;
1672
1673 case Timer::TimerTrying:
1674 if (mState == Trying)
1675 {
1676 // Timer E has reached T2 - send a 100 as recommended by RFC4320 NIT-Problem-Actions
1677 sendCurrentToWire();
1678 mState = Proceeding;
1679 }
1680 delete msg;
1681 break;
1682
1683 default:
1684 delete msg;
1685 break;
1686 }
1687 }
1688 else if (isTransportError(msg))
1689 {
1690 // Failed to send response - transport has likely been removed
1691 WarningLog (<< "Failed to send response to server transaction (transport was likely removed)." << *this);
1692 delete msg;
1693 terminateServerTransaction(mId);
1694 delete this;
1695 }
1696 else if (isAbandonServerTransaction(msg))
1697 {
1698 if(mState==Trying || mState==Proceeding)
1699 {
1700 mIsAbandoned = true;
1701
1702 // !bwc! We could check to see if we have a 100 lying around, and
1703 // convert it into a 500 for immediate transmission, but it is not
1704 // clear that this is a good idea, especially if the TU has abandoned
1705 // this transaction after the remote endpoint has stopped
1706 // retransmitting. Maybe we could use a time-stamp to help here? Would
1707 // it be worth the extra memory footprint?
1708
1709 if (mIsReliable)
1710 {
1711 // If we haven't sent a 500 yet, we never will (no retransmissions
1712 // to make the response with).
1713 terminateServerTransaction(mId);
1714 delete this;
1715 }
1716 else
1717 {
1718 // If we haven't sent a 500 yet, we'll do so when the next
1719 // retransmission comes in. In the meantime, set up timers for
1720 // transaction termination.
1721 mState = Completed;
1722 mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 );
1723 }
1724 }
1725 delete msg;
1726 }
1727 else if(dynamic_cast<DnsResultMessage*>(msg))
1728 {
1729 handleSync(mDnsResult);
1730 delete msg;
1731 }
1732 else
1733 {
1734 //StackLog (<< "TransactionState::processServerNonInvite: message unhandled");
1735 delete msg;
1736 }
1737}
1738
1739
1740void
1741TransactionState::processServerInvite(TransactionMessage* msg)
1742{
1743 StackLog (<< "TransactionState::processServerInvite: " << msg->brief() << " -> " << *this);
1744 if (isRequest(msg) && isFromWire(msg))
1745 {
1746 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1747 switch (sip->method())
1748 {
1749 case INVITE:
1750 // note: handling of initial INVITE message is done in TransactionState:process
1751 if(mIsAbandoned)
1752 {
1753 mIsAbandoned=false;
1754 mAckIsValid=true;
1755 resetNextTransmission(Helper::makeResponse(*sip, 500));
1756 mState = Completed;
1757 mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1758 if (!mIsReliable)
1759 {
1760 mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1761 }
1762 sendCurrentToWire();
1763 delete msg;
1764 return;
1765 }
1766
1767 if (mState == Proceeding || mState == Completed)
1768 {
1769 /*
1770 The server transaction has already been constructed so this
1771 message is a retransmission. The server transaction must
1772 respond with a 100 Trying _or_ the last provisional response
1773 passed from the TU for this transaction.
1774 */
1775 //StackLog (<< "Received invite from wire - forwarding to TU state=" << mState);
1776
1777 // !bwc! If we have nothing to respond with, make something.
1778 if (mMsgToRetransmit.empty() && !mNextTransmission)
1779 {
1780 resetNextTransmission(make100(sip));
1781 }
1782 delete sip;
1783 sendCurrentToWire();
1784 }
1785 else
1786 {
1787 //StackLog (<< "Received invite from wire - ignoring state=" << mState);
1788 delete msg;
1789 }
1790 break;
1791
1792 case ACK:
1793 /*
1794 If an ACK is received while the server transaction is in the
1795 "Completed" state, the server transaction MUST transition to the
1796 "Confirmed" state.
1797 */
1798 if (mState == Completed)
1799 {
1800 if (mIsReliable)
1801 {
1802 //StackLog (<< "Received ACK in Completed (reliable) - delete transaction");
1803 terminateServerTransaction(mId);
1804 delete this;
1805 delete msg;
1806 }
1807 else
1808 {
1809 //StackLog (<< "Received ACK in Completed (unreliable) - confirmed, start Timer I");
1810 mState = Confirmed;
1811 mController.mTimers.add(Timer::TimerI, mId, Timer::T4 );
1812 // !bwc! Got an ACK/failure; we can stop retransmitting
1813 // our failure response now.
1814 resetNextTransmission(0);
1815 delete sip;
1816 }
1817 }
1818 else
1819 {
1820 //StackLog (<< "Ignore ACK not in Completed state");
1821 delete msg;
1822 }
1823 break;
1824
1825 case CANCEL:
1826 resip_assert(0);
1827 delete sip;
1828 break;
1829
1830 default:
1831 //StackLog (<< "Received unexpected request. Ignoring message");
1832 delete msg;
1833 break;
1834 }
1835 }
1836 else if (isResponse(msg, 100, 699) && isFromTU(msg))
1837 {
1838 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1839 int code = sip->const_header(h_StatusLine).responseCode();
1840 switch (sip->method())
1841 {
1842 case INVITE:
1843 if (code == 100)
1844 {
1845 if (mState == Trying || mState == Proceeding)
1846 {
1847 //StackLog (<< "Received 100 in Trying or Proceeding. Send over wire");
1848 resetNextTransmission(sip); // may be replacing the 100
1849 mState = Proceeding;
1850 sendCurrentToWire(); // don't delete msg
1851 }
1852 else
1853 {
1854 //StackLog (<< "Ignoring 100 - not in Trying or Proceeding.");
1855 delete msg;
1856 }
1857 }
1858 else if (code > 100 && code < 200)
1859 {
1860 if (mState == Trying || mState == Proceeding)
1861 {
1862 //StackLog (<< "Received 1xx in Trying or Proceeding. Send over wire");
1863 resetNextTransmission(sip); // may be replacing the 100
1864 mState = Proceeding;
1865 sendCurrentToWire(); // don't delete msg
1866 }
1867 else
1868 {
1869 //StackLog (<< "Received 100 when not in Trying State. Ignoring");
1870 delete msg;
1871 }
1872 }
1873 else if (code >= 200 && code < 300)
1874 {
1875 if (mState == Trying || mState == Proceeding)
1876 {
1877 StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction");
1878 StackLog (<< *this);
1879 resetNextTransmission(sip); // may be replacing the 100
1880 sendCurrentToWire();
1881
1882 // Keep the StaleServer transaction around, so we can keep the
1883 // source Tuple that the request was received on.
1884 //terminateServerTransaction(mId);
1885 mMachine = ServerStale;
1886 mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS );
1887 }
1888 else
1889 {
1890 //StackLog (<< "Received 2xx when not in Trying or Proceeding State. Ignoring");
1891 delete msg;
1892 }
1893 }
1894 else if (code >= 300)
1895 {
1896 /*
1897 While in the "Proceeding" state, if the TU passes a response with
1898 status code from 300 to 699 to the server transaction, For unreliable
1899 transports,timer G is set to fire in T1 seconds, and is not set to
1900 fire for reliable transports.when the "Completed" state is entered,
1901 timer H MUST be set to fire in 64*T1 seconds for all transports.
1902 Timer H determines when the server transaction abandons retransmitting
1903 the response
1904 */
1905
1906 if (mState == Trying || mState == Proceeding)
1907 {
1908 mAckIsValid=true;
1909 StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this);
1910 resetNextTransmission(sip);
1911 mState = Completed;
1912 mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1913 if (!mIsReliable)
1914 {
1915 mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1916 }
1917 sendCurrentToWire(); // don't delete msg
1918 }
1919 else
1920 {
1921 //StackLog (<< "Received Final response when not in Trying or Proceeding State. Ignoring");
1922 delete msg;
1923 }
1924 }
1925 else
1926 {
1927 //StackLog (<< "Received Invalid response line. Ignoring");
1928 delete msg;
1929 }
1930 break;
1931
1932 case CANCEL:
1933 resip_assert(0);
1934 delete sip;
1935 break;
1936
1937 default:
1938 //StackLog (<< "Received response to non invite or cancel. Ignoring");
1939 delete msg;
1940 break;
1941 }
1942 }
1943 else if (isTimer(msg))
1944 {
1945 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1946 switch (timer->getType())
1947 {
1948 case Timer::TimerG:
1949 if (mState == Completed)
1950 {
1951 StackLog (<< "TimerG fired. retransmit, and re-add TimerG");
1952 sendCurrentToWire();
1953 mController.mTimers.add(Timer::TimerG, mId, resipMin(Timer::T2, timer->getDuration()*2) ); // TimerG is supposed to double - up until a max of T2 RFC3261 17.2.1
1954 }
1955 break;
1956
1957 /*
1958 If timer H fires while in the "Completed" state, it implies that the
1959 ACK was never received. In this case, the server transaction MUST
1960 transition to the "Terminated" state, and MUST indicate to the TU
1961 that a transaction failure has occurred. WHY we need to inform TU
1962 for Failure cases ACK ? do we really need to do this ???
1963
1964 !jf! this used to re-add TimerH if there was an associated CANCEL
1965 transaction. Don't know why.
1966 */
1967 case Timer::TimerH:
1968 case Timer::TimerI:
1969 if (timer->getType() == Timer::TimerH)
1970 {
1971 InfoLog (<< "No ACK was received on a server transaction (Timer H)");
1972 }
1973 terminateServerTransaction(mId);
1974 delete this;
1975 break;
1976
1977 case Timer::TimerTrying:
1978 if (mState == Trying)
1979 {
1980 //StackLog (<< "TimerTrying fired. Send a 100");
1981 sendCurrentToWire(); // will get deleted when this is deleted
1982 mState = Proceeding;
1983 }
1984 else
1985 {
1986 //StackLog (<< "TimerTrying fired. Not in Trying state. Ignoring");
1987 }
1988 break;
1989
1990 default:
1991 CritLog(<<"unexpected timer fired: " << timer->getType());
1992 resip_assert(0); // programming error if any other timer fires
1993 break;
1994 }
1995 delete timer;
1996 }
1997 else if (isTransportError(msg))
1998 {
1999 // Failed to send response - transport has likely been removed
2000 WarningLog (<< "Failed to send response to server transaction (transport was likely removed)." << *this);
2001 delete msg;
2002 terminateServerTransaction(mId);
2003 delete this;
2004 }
2005 else if (isAbandonServerTransaction(msg))
2006 {
2007 if((mState == Trying || mState == Proceeding) && !mIsAbandoned)
2008 {
2009 // We need to schedule teardown, and 500 the next retransmission.
2010 if(mNextTransmission)
2011 {
2012 mMsgToRetransmit.clear();
2013 // hey, we had a 1xx laying around! Turn it into a 500 and send.
2014 resip_assert(mNextTransmission->isResponse());
2015 resip_assert(mNextTransmission->const_header(h_StatusLine).statusCode()/100==1);
2016 mNextTransmission->header(h_StatusLine).statusCode()=500;
2017 mNextTransmission->header(h_StatusLine).reason()="Server Error";
2018 sendCurrentToWire();
2019 mAckIsValid=true;
2020 StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this);
2021 mState = Completed;
2022 mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
2023 if (!mIsReliable)
2024 {
2025 mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
2026 }
2027 }
2028 else
2029 {
2030 // !bwc! TODO try to convert mMsgToRetransmit if present.
2031 if(mIsReliable)
2032 {
2033 // We will never see another retransmission of the INVITE. We
2034 // need to bail.
2035 terminateServerTransaction(mId);
2036 delete this;
2037 }
2038 else
2039 {
2040 // We should see a retransmission of the INVITE shortly, or we
2041 // will time out eventually. Be patient...
2042 mIsAbandoned = true;
2043 }
2044 }
2045 }
2046 delete msg;
2047 }
2048 else if(dynamic_cast<DnsResultMessage*>(msg))
2049 {
2050 handleSync(mDnsResult);
2051 delete msg;
2052 }
2053 else
2054 {
2055 //StackLog (<< "TransactionState::processServerInvite: message unhandled");
2056 delete msg;
2057 }
2058}
2059
2060
2061void
2062TransactionState::processClientStale(TransactionMessage* msg)
2063{
2064 StackLog (<< "TransactionState::processClientStale: " << msg->brief() << " -> " << *this);
2065
2066 if (isTimer(msg))
2067 {
2068 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
2069 if (timer->getType() == Timer::TimerStaleClient)
2070 {
2071 terminateClientTransaction(mId);
2072 delete this;
2073 delete msg;
2074 }
2075 else
2076 {
2077 delete msg;
2078 }
2079 }
2080 else if (isTransportError(msg))
2081 {
2082 WarningLog (<< "Got a transport error in Stale Client state");
2083 StackLog (<< *this);
2084 processTransportFailure(msg);
2085 delete msg;
2086 }
2087 else if(isResponse(msg, 200, 299))
2088 {
2089 resip_assert(isFromWire(msg));
2090 sendToTU(msg);
2091 }
2092 else if(dynamic_cast<DnsResultMessage*>(msg))
2093 {
2094 handleSync(mDnsResult);
2095 delete msg;
2096 }
2097 else if (isAbandonServerTransaction(msg))
2098 {
2099 // ?
2100 delete msg;
2101 }
2102 else if (isCancelClientTransaction(msg))
2103 {
2104 // ?
2105 delete msg;
2106 }
2107 else
2108 {
2109 // might have received some other response because a downstream UAS is
2110 // misbehaving. For instance, sending a 487/INVITE after already
2111 // sending a 200/INVITE. It could also be some other message type.
2112 StackLog (<< "Discarding extra message: " << *msg);
2113 delete msg;
2114 }
2115}
2116
2117void
2118TransactionState::processServerStale(TransactionMessage* msg)
2119{
2120 StackLog (<< "TransactionState::processServerStale: " << msg->brief() << " -> " << *this);
2121
2122 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2123 if (isTimer(msg))
2124 {
2125 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
2126 if (timer->getType() == Timer::TimerStaleServer)
2127 {
2128 delete msg;
2129 terminateServerTransaction(mId);
2130 delete this;
2131 }
2132 else
2133 {
2134 delete msg;
2135 }
2136 }
2137 else if (isTransportError(msg))
2138 {
2139 WarningLog (<< "Got a transport error in Stale Server state");
2140 StackLog (<< *this);
2141 processTransportFailure(msg);
2142 delete msg;
2143 }
2144 else if (sip && isRequest(sip) && sip->method() == ACK)
2145 {
2146 // .bwc. We should never fall into this block. There is code in process
2147 // that should prevent it.
2148 resip_assert(isFromWire(msg));
2149 InfoLog (<< "Passing ACK directly to TU: " << sip->brief());
2150 sendToTU(msg);
2151 }
2152 else if (sip && isRequest(sip) && sip->method() == INVITE)
2153 {
2154 // this can happen when an upstream UAC never received the 200 and
2155 // retransmits the INVITE when using unreliable transport
2156 // Drop the INVITE since the 200 will get retransmitted by the downstream UAS
2157 StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief());
2158 delete msg;
2159 }
2160 else if (isResponse(msg) && isFromTU(msg))
2161 {
2162 resetNextTransmission(sip);
2163 sendCurrentToWire();
2164 }
2165 else if(dynamic_cast<DnsResultMessage*>(msg))
2166 {
2167 handleSync(mDnsResult);
2168 delete msg;
2169 }
2170 else if (isAbandonServerTransaction(msg))
2171 {
2172 // ?
2173 delete msg;
2174 }
2175 else
2176 {
2177 // .bwc. This can very easily be triggered by a stupid/malicious
2178 // endpoint. This is not an error in our code. Do not ErrLog this.
2179 InfoLog(<<"ServerStale unexpected condition, dropping message.");
2180 if (sip)
2181 {
2182 InfoLog(<<sip->brief());
2183 }
2184 delete msg;
2185 }
2186}
2187
2188void
2189TransactionState::processNoDnsResults()
2190{
2191 if(!mNextTransmission || mNextTransmission->method()==ACK)
2192 {
2193 // This is probably an ACK; since we know we will never need to send a
2194 // response to an ACK, we delete mNextTransmission as soon as we
2195 // serialize it.
2196 return;
2197 }
2198
2199 WarningCategory warning;
2200 SipMessage* response = Helper::makeResponse(*mNextTransmission, 503);
2201 warning.hostname() = mController.mHostname;
2202 warning.code() = 399;
2203 warning.text().reserve(100);
2204
2205 if(mDnsResult)
2206 {
2207 InfoLog (<< "Ran out of dns entries for " << mDnsResult->target() << ". Send 503");
2208 resip_assert(mDnsResult->available() == DnsResult::Finished);
2209 oDataStream warnText(warning.text());
2210 warnText << "No other DNS entries to try ("
2211 << mFailureReason << "," << mFailureSubCode << ")";
2212 }
2213 else
2214 {
2215 oDataStream warnText(warning.text());
2216 warnText << "Transport failure ("
2217 << mFailureReason << "," << mFailureSubCode << ")";
2218 }
2219
2220 switch(mFailureReason)
2221 {
2223 response->header(h_StatusLine).reason() = "No DNS results";
2224 break;
2225
2231 response->header(h_StatusLine).reason() = "Transport failure: no transports left to try";
2232 break;
2234 response->header(h_StatusLine).reason() = "No matching transport found";
2235 break;
2237 response->header(h_StatusLine).reason() = "No route to host";
2238 break;
2240 response->header(h_StatusLine).reason() = "Certificate Name Mismatch";
2241 break;
2243 response->header(h_StatusLine).reason() = "Certificate Validation Failure";
2244 break;
2247 {
2248 response->header(h_StatusLine).statusCode() = 430;
2249 }
2250 else
2251 {
2252 response->header(h_StatusLine).statusCode() = 410;
2253 }
2254 response->header(h_StatusLine).reason() = "Flow failed";
2255 warning.text() = "Flow no longer exists";
2256 break;
2258 response->header(h_StatusLine).reason() = "Transport shutdown: no transports left to try";
2259 break;
2260 }
2261
2262 response->header(h_Warnings).push_back(warning);
2263
2264 sendToTU(response);
2265 terminateClientTransaction(mId);
2266 if (mMachine != Stateless)
2267 {
2268 delete this;
2269 }
2270}
2271
2272void
2273TransactionState::processTransportFailure(TransactionMessage* msg)
2274{
2275 TransportFailure* failure = dynamic_cast<TransportFailure*>(msg);
2276 resip_assert(failure);
2277 resip_assert(mState!=Bogus);
2278
2279 // We come here if the tcp connect timer expires, so we reset the flag incase we are
2280 // going to try another DNS entry that is also TCP.
2281 mTcpConnectTimerStarted = false;
2282
2283 // Store failure reasons
2284 if (failure->getFailureReason() > mFailureReason)
2285 {
2286 mFailureReason = failure->getFailureReason();
2287 mFailureSubCode = failure->getFailureSubCode();
2288 }
2289
2290 if (mNextTransmission && // Note: If we just transmitted an ACK then mNextTransmission is cleared, so this check is necessary
2291 mNextTransmission->isRequest() &&
2292 mNextTransmission->method() == CANCEL &&
2293 mState != Completed &&
2294 mState != Terminated)
2295 {
2296 WarningLog (<< "Failed to deliver a CANCEL request");
2297 StackLog (<< *this);
2298 resip_assert(mMethod==CANCEL);
2299
2300 // In the case of a client-initiated CANCEL, we don't want to
2301 // try other transports in the case of transport error as the
2302 // CANCEL MUST be sent to the same IP/PORT as the orig. INVITE.
2303 //?dcm? insepct failure enum?
2304 SipMessage* response = Helper::makeResponse(*mNextTransmission, 503);
2305 WarningCategory warning;
2306 warning.hostname() = mController.mHostname;
2307 warning.code() = 399;
2308 warning.text() = "Failed to deliver CANCEL using the same transport as the INVITE was used";
2309 response->header(h_Warnings).push_back(warning);
2310
2311 sendToTU(response);
2312 return;
2313 }
2314
2315 if(!mDnsResult)
2316 {
2317 InfoLog(<< "Transport failure on send that did not use DNS.");
2318 processNoDnsResults();
2319 }
2320 // else If we did DNS resolution, then check if we should try to failover to another DNS entry
2321 else if(mDnsResult)
2322 {
2323 // .bwc. Greylist for 32s
2325
2326 // .bwc. We should only try multiple dns results if we are originating a
2327 // request. Additionally, there are (potential) cases where it would not
2328 // be appropriate to fail over even then.
2329 bool shouldFailover=false;
2330 if(mMachine==ClientNonInvite)
2331 {
2332 if(mState==Completed || mState==Terminated)
2333 {
2334 WarningLog(<<"Got a TransportFailure message in a " << mState <<
2335 " ClientNonInvite transaction. How did this happen? Since we have"
2336 " already completed the transaction, we shouldn't try"
2337 " additional DNS results.");
2338 }
2339 else
2340 {
2341 shouldFailover=true;
2342 }
2343 }
2344 else if(mMachine==ClientInvite)
2345 {
2346 if(mState==Completed || mState==Terminated)
2347 {
2348 // .bwc. Perhaps the attempted transmission of the ACK failed here.
2349 // (assuming this transaction got a failure response; not sure what
2350 // might have happened if this is not the case)
2351 // In any case, we should not try sending the INVITE anywhere else.
2352 InfoLog(<<"Got a TransportFailure message in a " << mState <<
2353 " ClientInvite transaction. Since we have"
2354 " already completed the transaction, we shouldn't try"
2355 " additional DNS results.");
2356 }
2357 else
2358 {
2359 if(mState==Proceeding)
2360 {
2361 // .bwc. We need to revert our state back to Calling, since we are
2362 // going to be sending the INVITE to a new endpoint entirely.
2363
2364 // !bwc!
2365 // An interesting consequence occurs if our failover ultimately
2366 // sends to the same instance of a resip stack; we increment the
2367 // transport sequence in our branch parameter, but any resip-based
2368 // stack will ignore this change, and process this "new" request as
2369 // a retransmission! Furthermore, our state will be out of phase
2370 // with the state at the remote endpoint, and if we have sent a
2371 // PRACK, it will know (and stuff will break)!
2372 // TODO What else needs to be done here to safely revert our state?
2373 mState=Calling;
2374 }
2375 shouldFailover=true;
2376 }
2377 }
2378
2379 if(shouldFailover)
2380 {
2381 InfoLog (<< "Try sending request to a different dns result");
2382 resip_assert(mMethod!=CANCEL);
2383
2384 switch (mDnsResult->available())
2385 {
2387 InfoLog(<< "We have another DNS result to try.");
2388 restoreOriginalContactAndVia();
2389 mTarget = mDnsResult->next();
2390 mMsgToRetransmit.clear();
2391 processReliability(mTarget.getType());
2392 sendCurrentToWire();
2393 break;
2394
2395 case DnsResult::Pending:
2396 InfoLog(<< "We have a DNS query pending.");
2397 mPendingOperation=Dns;
2398 restoreOriginalContactAndVia();
2399 mMsgToRetransmit.clear();
2400 break;
2401
2403 InfoLog(<< "No DNS results remain.");
2404 processNoDnsResults();
2405 break;
2406
2408 default:
2409 InfoLog (<< "Bad state: " << *this);
2410 resip_assert(0);
2411 }
2412 }
2413 else
2414 {
2415 InfoLog(<< "Transport failure on send, and failover is disabled.");
2416 processNoDnsResults();
2417 }
2418 }
2419}
2420
2421void
2422TransactionState::processTcpConnectState(TransactionMessage* msg)
2423{
2424 TcpConnectState* tcpConnectState = dynamic_cast<TcpConnectState*>(msg);
2425 resip_assert(tcpConnectState);
2426
2427 if (tcpConnectState->getState() == TcpConnectState::ConnectStarted &&
2428 !mTcpConnectTimerStarted && Timer::TcpConnectTimeout != 0 &&
2429 (mState == Trying || mState == Calling))
2430 {
2431 // Start Timer
2432 mController.mTimers.add(Timer::TcpConnectTimer, mId, Timer::TcpConnectTimeout);
2433 mTcpConnectTimerStarted = true;
2434 }
2435 else if (tcpConnectState->getState() == TcpConnectState::Connected &&
2436 (mState == Trying || mState == Calling))
2437 {
2438 mTcpConnectTimerStarted = false;
2439 }
2440}
2441
2442// called by DnsResult
2443void
2444TransactionState::rewriteRequest(const Uri& rewrite)
2445{
2446 // !bwc! TODO We need to address the race-conditions caused by callbacks
2447 // into a class whose thread-safety is accomplished through message-passing.
2448 // This function could very easily be called while other processing is
2449 // taking place due to a message from the state-machine fifo. In the end, I
2450 // imagine that we will need to have the callback place a message onto the
2451 // queue, and move all the code below into a function that handles that
2452 // message.
2453
2454 resip_assert(mNextTransmission->isRequest());
2455 if (mNextTransmission->const_header(h_RequestLine).uri() != rewrite)
2456 {
2457 InfoLog (<< "Rewriting request-uri to " << rewrite);
2458 mNextTransmission->header(h_RequestLine).uri() = rewrite;
2459 // !bwc! Changing mNextTransmission invalidates mMsgToRetransmit.
2460 mMsgToRetransmit.clear();
2461 }
2462}
2463
2464void
2465TransactionState::handle(DnsResult* result)
2466{
2467 // ?bwc? Maybe optmize this to use handleSync() directly when running in
2468 // single-threaded mode?
2469 DnsResultMessage* dns = new DnsResultMessage(mId,isClient());
2470 mController.mStateMacFifo.add(static_cast<TransactionMessage*>(dns));
2471}
2472
2473void
2474TransactionState::handleSync(DnsResult* result) // !slg! it is strange that we pass the result in here, then more or less ignore it in the method
2475{
2476 StackLog (<< *this << " got DNS result: " << *result);
2477
2478 // .bwc. Were we expecting something from mDnsResult?
2479 if (mPendingOperation == Dns)
2480 {
2481 resip_assert(mDnsResult);
2482 switch (mDnsResult->available())
2483 {
2485 mPendingOperation=None;
2486 mTarget = mDnsResult->next();
2487 // below allows TU to know which transport we send on
2488 // (The Via mechanism for setting transport doesn't work for TLS)
2489 mTarget.mTransportKey = mNextTransmission->getDestination().mTransportKey;
2490 processReliability(mTarget.getType());
2491 sendCurrentToWire();
2492 break;
2493
2495 mPendingOperation=None;
2496 processNoDnsResults();
2497 break;
2498
2499 case DnsResult::Pending:
2500 break;
2501
2503 default:
2504 resip_assert(0);
2505 break;
2506 }
2507 }
2508}
2509
2510void
2511TransactionState::processReliability(TransportType type)
2512{
2513 switch (type)
2514 {
2515 case UDP:
2516 case DCCP:
2517 if (mIsReliable)
2518 {
2519 mIsReliable = false;
2520 StackLog (<< "Unreliable transport: " << *this);
2521 switch (mMachine)
2522 {
2523 case ClientNonInvite:
2524 mController.mTimers.add(Timer::TimerE1, mId, Timer::T1 );
2525 break;
2526
2527 case ClientInvite:
2528 mController.mTimers.add(Timer::TimerA, mId, Timer::T1 );
2529 break;
2530
2531 default:
2532 break;
2533 }
2534 }
2535 break;
2536
2537 default:
2538 if (!mIsReliable)
2539 {
2540 mIsReliable = true;
2541 }
2542 break;
2543 }
2544}
2545
2546// !ah! only used one place, so leaving it here instead of making a helper.
2547// !ah! broken out for clarity -- only used for forceTargets.
2548// Expects that host portion is IP address notation.
2549
2550static const Tuple
2552{
2553 const Data& host = uri.host();
2554 int port = uri.port();
2555
2557
2558 if (uri.exists(p_transport))
2559 {
2560 transport = Tuple::toTransport(uri.param(p_transport));
2561 }
2562
2563 if (transport == UNKNOWN_TRANSPORT)
2564 {
2565 transport = UDP;
2566 }
2567 if (port == 0)
2568 {
2569 switch(transport)
2570 {
2571 case TLS:
2573 break;
2574 case UDP:
2575 case TCP:
2576 default:
2578 break;
2579 // !ah! SCTP?
2580
2581 }
2582 }
2583
2584 return Tuple(host,port,transport);
2585}
2586
2587void
2588TransactionState::sendCurrentToWire()
2589{
2590 if(!mMsgToRetransmit.empty())
2591 {
2592 if(mController.mStack.statisticsManagerEnabled())
2593 {
2594 mController.mStatsManager.retransmitted(mCurrentMethodType,
2595 isClient(),
2596 mCurrentResponseCode);
2597 }
2598
2599 mController.mTransportSelector.retransmit(mMsgToRetransmit);
2600 }
2601 else if(mNextTransmission) // initial transmission; need to determine target
2602 {
2603 SipMessage* sip=mNextTransmission;
2605
2606 if(isClient())
2607 {
2608 if(mTarget.getType() != UNKNOWN_TRANSPORT) // mTarget is set, so just send.
2609 {
2610 transmitState=mController.mTransportSelector.transmit(
2611 sip,
2612 mTarget,
2613 mIsReliable ? 0 : &mMsgToRetransmit);
2614 }
2615 else // mTarget isn't set...
2616 {
2617 if (sip->getDestination().mFlowKey) //...but sip->getDestination() will work
2618 {
2619 // ?bwc? Maybe we should be nice to the TU and do DNS in this case?
2621
2622 // .bwc. We have the FlowKey. This completely specifies our
2623 // Transport (and Connection, if applicable). No DNS required.
2624 DebugLog(<< "Sending to tuple: " << sip->getDestination());
2625 mTarget = sip->getDestination();
2626 processReliability(mTarget.getType());
2627 transmitState=mController.mTransportSelector.transmit(
2628 sip,
2629 mTarget,
2630 mIsReliable ? 0 : &mMsgToRetransmit);
2631 }
2632 else // ...so DNS is required...
2633 {
2634 if(mDnsResult == 0) // ... and we haven't started a DNS query yet.
2635 {
2636 StackLog (<< "sendToWire with no dns result: " << *this);
2637 resip_assert(sip->isRequest());
2638 resip_assert(mMethod!=CANCEL); // .bwc. mTarget should be set in this case.
2639 mDnsResult = mController.mTransportSelector.createDnsResult(this);
2640 mPendingOperation=Dns;
2641 mController.mTransportSelector.dnsResolve(mDnsResult, sip);
2642 }
2643 else // ... but our DNS query isn't done yet.
2644 {
2645 // .bwc. While the resolver was attempting to find a target, another
2646 // request came down from the TU. This could be a bug in the TU, or
2647 // could be a retransmission of an ACK/200. Either way, we cannot
2648 // expect to ever be able to send this request (nowhere to store it
2649 // temporarily).
2650 // ?bwc? Higher log-level?
2651 DebugLog(<< "Received a second request from the TU for a transaction"
2652 " that already existed, before the DNS subsystem was done "
2653 "resolving the target for the first request. Either the TU"
2654 " has messed up, or it is retransmitting ACK/200 (the only"
2655 " valid case for this to happen)");
2656 }
2657 }
2658 }
2659 }
2660 else // server transaction
2661 {
2662 resip_assert(mDnsResult == 0);
2663 resip_assert(sip->exists(h_Vias));
2664 resip_assert(!sip->const_header(h_Vias).empty());
2665
2666 // .bwc. Code that tweaks mResponseTarget based on stuff in the SipMessage.
2667 // ?bwc? Why?
2668 if (sip->hasForceTarget())
2669 {
2670 // ?bwc? Override the target for a single response? Should we even
2671 // allow this? What about client transactions? Should we overwrite
2672 // mResponseTarget here? I don't think this has been thought out properly.
2673 Tuple target = simpleTupleForUri(sip->getForceTarget());
2674 StackLog(<<"!ah! response with force target going to : "<<target);
2675 transmitState=mController.mTransportSelector.transmit(
2676 sip,
2677 target,
2678 mIsReliable ? 0 : &mMsgToRetransmit);
2679 }
2680 else
2681 {
2682 if (sip->const_header(h_Vias).front().exists(p_rport) && sip->const_header(h_Vias).front().param(p_rport).hasValue())
2683 {
2684 // ?bwc? This was not setting the port in mResponseTarget before. Why would
2685 // the rport be different than the port in mResponseTarget? Didn't we
2686 // already set this? Maybe the TU messed with it? If so, why should we pay
2687 // attention to it? Again, this hasn't been thought out.
2688 mResponseTarget.setPort(sip->const_header(h_Vias).front().param(p_rport).port());
2689 StackLog(<< "rport present in response: " << mResponseTarget.getPort());
2690 }
2691
2692 StackLog(<< "tid=" << sip->getTransactionId() << " sending to : " << mResponseTarget);
2693 transmitState=mController.mTransportSelector.transmit(
2694 sip,
2695 mResponseTarget,
2696 mIsReliable ? 0 : &mMsgToRetransmit);
2697 }
2698 }
2699
2700 // !bwc! If we don't have DNS results yet, or TransportSelector::transmit
2701 // fails, we hang on to the full original SipMessage, in the hope that
2702 // next time it works.
2703 if (transmitState == TransportSelector::Sent)
2704 {
2705 onSendSuccess();
2706 }
2707 }
2708 else
2709 {
2710 resip_assert(0);
2711 }
2712}
2713
2714void
2715TransactionState::onSendSuccess()
2716{
2717 SipMessage* sip=mNextTransmission;
2718
2719 if(mController.mStack.statisticsManagerEnabled())
2720 {
2721 mController.mStatsManager.sent(sip);
2722 }
2723
2724 mCurrentMethodType = sip->method();
2725 if(sip->isResponse())
2726 {
2727 mCurrentResponseCode = sip->const_header(h_StatusLine).statusCode();
2728 }
2729
2730 // !bwc! If mNextTransmission is a non-ACK request, we need to save the
2731 // initial request in case we need to send a simulated 408 or a 503 to
2732 // the TU (at least, until we get a response back)
2733 if(!mNextTransmission->isRequest() || mNextTransmission->method()==ACK)
2734 {
2735 delete mNextTransmission;
2736 mNextTransmission=0;
2737 }
2738}
2739
2740void
2741TransactionState::sendToTU(TransactionMessage* msg)
2742{
2743 SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg);
2744 if (sipMsg && sipMsg->isResponse() && mDnsResult)
2745 {
2746 // whitelisting rules.
2747 switch (sipMsg->const_header(h_StatusLine).statusCode())
2748 {
2749 case 503:
2750 // blacklist last target.
2751 // .bwc. If there is no Retry-After, we do not blacklist
2752 // (see RFC 3261 sec 21.5.4 para 1)
2753 if(sipMsg->exists(resip::h_RetryAfter) &&
2754 sipMsg->const_header(resip::h_RetryAfter).isWellFormed())
2755 {
2756 unsigned int relativeExpiry= sipMsg->const_header(resip::h_RetryAfter).value();
2757
2758 if(relativeExpiry!=0)
2759 {
2760 mDnsResult->blacklistLast(resip::Timer::getTimeMs()+relativeExpiry*1000);
2761 }
2762 }
2763
2764 break;
2765 case 408:
2766 if(!sipMsg->isFromWire() && (mState == Trying || mState==Calling)) // only greylist if internally generated and we haven't received any responses yet
2767 {
2768 // greylist last target.
2770 }
2771
2772 break;
2773 default:
2774 // !bwc! Debatable.
2775 mDnsResult->whitelistLast();
2776 break;
2777 }
2778 }
2779
2781 behavior=mController.mTuSelector.getRejectionBehavior(mTransactionUser);
2782
2783 if(behavior!=CongestionManager::NORMAL)
2784 {
2785 if(sipMsg)
2786 {
2787 resip_assert(sipMsg->isExternal());
2788 if(sipMsg->isRequest())
2789 {
2790 // .bwc. This could be an initial request, or an ACK/200.
2791 if(sipMsg->method()==ACK)
2792 {
2793 // ACK/200 is a continuation of old work. We only reject if
2794 // we're really hosed.
2796 {
2797 delete msg;
2798 return;
2799 }
2800 }
2801 else
2802 {
2803 // .bwc. This is new work. Reject.
2804 SipMessage* response(Helper::makeResponse(*sipMsg, 503));
2805 delete sipMsg;
2806
2807 uint16_t retryAfter=mController.mTuSelector.getExpectedWait(mTransactionUser);
2808 response->header(h_RetryAfter).value()=retryAfter;
2809 response->setFromTU();
2810 if(mMethod==INVITE)
2811 {
2812 processServerInvite(response);
2813 }
2814 else
2815 {
2816 processServerNonInvite(response);
2817 }
2818 return;
2819 }
2820 }
2821 else
2822 {
2823 // .bwc. This could be a response from the wire, or an internally
2824 // generated pseudo-response. This is always a continuation of
2825 // old work.
2827 mTransactionUser &&
2828 !mTransactionUser->responsesMandatory())
2829 {
2830 delete sipMsg;
2831 return;
2832 }
2833 }
2834 }
2835 else
2836 {
2837 // .bwc. This is some sort of timer, or other message. If we don't know
2838 // any better, we need to assume this is essential for the safe
2839 // operation of the TU.
2840 }
2841 }
2842
2843 TransactionState::sendToTU(mTransactionUser, mController, msg);
2844}
2845
2846void
2847TransactionState::sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg)
2848{
2849 msg->setTransactionUser(tu);
2850 controller.mTuSelector.add(msg, TimeLimitFifo<Message>::InternalElement);
2851}
2852
2854TransactionState::make100(SipMessage* request) const
2855{
2856 return (Helper::makeResponse(*request, 100));
2857}
2858
2859void
2860TransactionState::add(const Data& tid)
2861{
2862 if (isClient())
2863 {
2864 mController.mClientTransactionMap.add(tid, this);
2865 }
2866 else
2867 {
2868 mController.mServerTransactionMap.add(tid, this);
2869 }
2870}
2871
2872void
2873TransactionState::erase(const Data& tid)
2874{
2875 if (isClient())
2876 {
2877 mController.mClientTransactionMap.erase(tid);
2878 }
2879 else
2880 {
2881 mController.mServerTransactionMap.erase(tid);
2882 }
2883}
2884
2885bool
2886TransactionState::isRequest(TransactionMessage* msg) const
2887{
2888 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2889 return sip && sip->isRequest();
2890}
2891
2892bool
2893TransactionState::isInvite(TransactionMessage* msg) const
2894{
2895 if (isRequest(msg))
2896 {
2897 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2898 return (sip->method()) == INVITE;
2899 }
2900 return false;
2901}
2902
2903bool
2904TransactionState::isResponse(TransactionMessage* msg, int lower, int upper) const
2905{
2906 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2907 if (sip && sip->isResponse())
2908 {
2909 int c = sip->const_header(h_StatusLine).responseCode();
2910 return (c >= lower && c <= upper);
2911 }
2912 return false;
2913}
2914
2915bool
2916TransactionState::isTimer(TransactionMessage* msg) const
2917{
2918 return dynamic_cast<TimerMessage*>(msg) != 0;
2919}
2920
2921bool
2922TransactionState::isFromTU(TransactionMessage* msg) const
2923{
2924 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2925 return sip && !sip->isExternal();
2926}
2927
2928bool
2929TransactionState::isFromWire(TransactionMessage* msg) const
2930{
2931 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2932 return sip && sip->isExternal();
2933}
2934
2935bool
2936TransactionState::isTransportError(TransactionMessage* msg) const
2937{
2938 return dynamic_cast<TransportFailure*>(msg) != 0;
2939}
2940
2941bool
2942TransactionState::isTcpConnectState(TransactionMessage* msg) const
2943{
2944 return dynamic_cast<TcpConnectState*>(msg) != 0;
2945}
2946
2947bool
2948TransactionState::isAbandonServerTransaction(TransactionMessage* msg) const
2949{
2950 return dynamic_cast<AbandonServerTransaction*>(msg) != 0;
2951}
2952
2953bool
2954TransactionState::isCancelClientTransaction(TransactionMessage* msg) const
2955{
2956 return dynamic_cast<CancelClientInviteTransaction*>(msg) != 0;
2957}
2958
2959
2960const Data&
2961TransactionState::tid(SipMessage* sip) const
2962{
2963 resip_assert(0);
2964 resip_assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty()));
2965 resip_assert (mMachine == Stateless || (mMachine != Stateless && sip));
2966 return (mId.empty() && sip) ? sip->getTransactionId() : mId;
2967}
2968
2969void
2970TransactionState::terminateClientTransaction(const Data& tid)
2971{
2972 mState = Terminated;
2973 if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) &&
2974 mTransactionUser->isRegisteredForTransactionTermination())
2975 {
2976 //StackLog (<< "Terminate client transaction " << tid);
2977 sendToTU(new TransactionTerminated(tid, true, mTransactionUser));
2978 }
2979}
2980
2981void
2982TransactionState::terminateServerTransaction(const Data& tid)
2983{
2984 mState = Terminated;
2985 if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) &&
2986 mTransactionUser->isRegisteredForTransactionTermination())
2987 {
2988 //StackLog (<< "Terminate server transaction " << tid);
2989 sendToTU(new TransactionTerminated(tid, false, mTransactionUser));
2990 }
2991}
2992
2993bool
2994TransactionState::isClient() const
2995{
2996 switch(mMachine)
2997 {
2998 case ClientNonInvite:
2999 case ClientInvite:
3000 case ClientStale:
3001 case Stateless:
3002 return true;
3003 case ServerNonInvite:
3004 case ServerInvite:
3005 case ServerStale:
3006 return false;
3007 default:
3008 resip_assert(0);
3009 }
3010 return false;
3011}
3012
3014resip::operator<<(EncodeStream& strm, const resip::TransactionState& state)
3015{
3016 strm << "tid=" << state.mId << " [ ";
3017 switch (state.mMachine)
3018 {
3019 case TransactionState::ClientNonInvite:
3020 strm << "ClientNonInvite";
3021 break;
3022 case TransactionState::ClientInvite:
3023 strm << "ClientInvite";
3024 break;
3025 case TransactionState::ServerNonInvite:
3026 strm << "ServerNonInvite";
3027 break;
3028 case TransactionState::ServerInvite:
3029 strm << "ServerInvite";
3030 break;
3031 case TransactionState::Stateless:
3032 strm << "Stateless";
3033 break;
3034 case TransactionState::ClientStale:
3035 strm << "ClientStale";
3036 break;
3037 case TransactionState::ServerStale:
3038 strm << "ServerStale";
3039 break;
3040 }
3041
3042 strm << "/";
3043 switch (state.mState)
3044 {
3045 case TransactionState::Calling:
3046 strm << "Calling";
3047 break;
3048 case TransactionState::Trying:
3049 strm << "Trying";
3050 break;
3051 case TransactionState::Proceeding:
3052 strm << "Proceeding";
3053 break;
3054 case TransactionState::Completed:
3055 strm << "Completed";
3056 break;
3057 case TransactionState::Confirmed:
3058 strm << "Confirmed";
3059 break;
3060 case TransactionState::Terminated:
3061 strm << "Terminated";
3062 break;
3063 case TransactionState::Bogus:
3064 strm << "Bogus";
3065 break;
3066 }
3067
3068 strm << (state.mIsReliable ? " reliable" : " unreliable");
3069 strm << " target=" << state.mResponseTarget;
3070 //if (state.mTransactionUser) strm << " tu=" << *state.mTransactionUser;
3071 //else strm << "default TU";
3072 strm << "]";
3073 return strm;
3074}
3075
3076
3077/* Local Variables: */
3078/* c-file-style: "ellemtel" */
3079/* End: */
3080
3081/* ====================================================================
3082 * The Vovida Software License, Version 1.0
3083 *
3084 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
3085 *
3086 * Redistribution and use in source and binary forms, with or without
3087 * modification, are permitted provided that the following conditions
3088 * are met:
3089 *
3090 * 1. Redistributions of source code must retain the above copyright
3091 * notice, this list of conditions and the following disclaimer.
3092 *
3093 * 2. Redistributions in binary form must reproduce the above copyright
3094 * notice, this list of conditions and the following disclaimer in
3095 * the documentation and/or other materials provided with the
3096 * distribution.
3097 *
3098 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
3099 * and "Vovida Open Communication Application Library (VOCAL)" must
3100 * not be used to endorse or promote products derived from this
3101 * software without prior written permission. For written
3102 * permission, please contact vocal@vovida.org.
3103 *
3104 * 4. Products derived from this software may not be called "VOCAL", nor
3105 * may "VOCAL" appear in their name, without prior written
3106 * permission of Vovida Networks, Inc.
3107 *
3108 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
3109 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3110 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
3111 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
3112 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
3113 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
3114 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3115 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3116 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
3117 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3118 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
3119 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
3120 * DAMAGE.
3121 *
3122 * ====================================================================
3123 *
3124 * This software consists of voluntary contributions made by Vovida
3125 * Networks, Inc. and many individuals on behalf of Vovida Networks,
3126 * Inc. For more information on Vovida Networks, Inc., please see
3127 * <http://www.vovida.org/>.
3128 *
3129 * vi: set shiftwidth=3 expandtab:
3130 */
#define DebugLog(args_)
Definition Logger.hxx:128
#define StackLog(args_)
Definition Logger.hxx:125
#define InfoLog(args_)
Definition Logger.hxx:131
#define CritLog(args_)
Definition Logger.hxx:140
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
static const Tuple simpleTupleForUri(const Uri &uri)
std::unique_ptr< Transport > getTransport()
The abstract base-class for all exceptions thrown by resip code.
const char * what() const noexcept override
@ NORMAL
Not rejecting any work.
@ REJECTING_NON_ESSENTIAL
Rejecting all work that is non-essential to the health of the system (ie, if dropping something is li...
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
void reserve(size_type capacity)
Guarantees that the underlying buffer used by the Data is at least the number of bytes specified.
Definition Data.cxx:1049
bool greylistLast(uint64_t expiry)
bool blacklistLast(uint64_t expiry)
Data target() const
const Tuple & getFlow() const
static SipMessage * makeCancel(const SipMessage &request)
Make a new Cancel request for the specified request.
Definition Helper.cxx:261
static int getPortForReply(SipMessage &request)
Definition Helper.cxx:1741
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
Definition Helper.cxx:412
static SipMessage * makeFailureAck(const SipMessage &request, const SipMessage &response)
This interface should be used by the stack (TransactionState) to create an AckMsg to a failure respon...
Definition Helper.cxx:296
static int getOutboundVersion()
bool isWellFormed() const
Returns true iff this element was parsed successfully, according to the implementation of parse().
virtual Brief brief() const
return a facet for brief encoding of message
Definition Message.cxx:16
TransactionUser * getTransactionUser()
Definition Message.hxx:49
void setTransactionUser(TransactionUser *t)
Definition Message.hxx:48
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
bool exists(const Param< NameAddr > &paramType) const
Definition NameAddr.cxx:477
const Data & param(const ExtensionParameter &param) const
Const accessor for non-natively-supported parameter types.
unsigned int getTransportKey()
const Uri & uri() const
bool empty() const
Definition SendData.hxx:65
Represents a SIP message.
void copyOutboundDecoratorsToStackFailureAck(SipMessage &ack)
Tuple & getDestination()
bool isRequest() const
Returns true if message is a request, false otherwise.
bool hasForceTarget() const
const Data & methodStr() const
Returns a string containing the SIP method for the message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
virtual const Data & getTransactionId() const
Returns the transaction id from the branch or if 2543, the computed hash.
bool isResponse() const
Returns true if message is a response, false otherwise.
const RequestLine & const_header(const RequestLineType &l) const
const resip::Data * getReason() const
Returns a string containing the response reason text.
const Uri & getForceTarget() const
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
const Tuple & getSource() const
Returns the source tuple that the message was received from only makes sense for messages received fr...
bool isFromWire() const
Check if SipMessage came off the wire.
void copyOutboundDecoratorsToStackCancel(SipMessage &cancel)
bool isExternal() const
Check if SipMessage is to be treated as it came off the wire.
bool isInvalid() const
Returns true if message failed to parse, false otherwise.
resip::MethodTypes method() const
returns the method type of the message
void setFromTU()
Mark message as internally generated.
static const int DefaultSipsPort
Definition Symbols.hxx:85
static const int DefaultSipPort
Definition Symbols.hxx:81
This message is used to indicate to the transaction state that a TCP based transport is trying to TCP...
const Tuple & getFlow() const
bool isClientTransaction() const
virtual const Data & getTransactionId() const
unsigned long getDuration() const
Timer::Type getType() const
static unsigned long T100
Definition Timer.hxx:117
static unsigned long TF
Definition Timer.hxx:121
static unsigned long TcpConnectTimeout
Definition Timer.hxx:127
static unsigned long TS
Definition Timer.hxx:125
static unsigned long T1
Definition Timer.hxx:114
@ TimerStateless
Definition Timer.hxx:51
@ TimerStaleClient
Definition Timer.hxx:49
@ TcpConnectTimer
Definition Timer.hxx:54
@ TimerStaleServer
Definition Timer.hxx:50
static unsigned long TB
Definition Timer.hxx:119
static unsigned long TH
Definition Timer.hxx:122
static uint64_t getTimeMs()
Returns the current clock time in milliseconds.
Definition Timer.hxx:72
static unsigned long T4
Definition Timer.hxx:116
static unsigned long T2
Definition Timer.hxx:115
static unsigned long TD
Definition Timer.hxx:124
CongestionManager::RejectionBehavior getRejectionBehavior() const
void erase(const Data &transactionId)
void add(const Data &transactionId, TransactionState *state)
TransactionState * find(const Data &transactionId) const
virtual const Data & getTransactionId() const =0
virtual bool isClientTransaction() const =0
static void processTimer(TransactionController &controller, TimerMessage *timer)
static uint64_t DnsGreylistDurationMs
static void process(TransactionController &controller, TransactionMessage *message)
uint64_t add(Timer::Type type, const Data &transactionId, unsigned long msOffset)
The base-class for an RFC 3261 Transaction User.
bool isRegisteredForTransactionTermination() const
virtual bool responsesMandatory() const
This message is used to indicate that the TransportSelector has sent a sip message using either relia...
FailureReason getFailureReason() const
void removeTransport(unsigned int transportKey)
void addTransport(std::unique_ptr< Transport > transport, bool isStackRunning)
Add/Remove a transport.
DnsResult * createDnsResult(DnsHandler *handler)
DNS Resolution.
TransmitState
transmit results in msg->resolve() being called to either kick off dns resolution or to pick the next...
void enableFlowTimer(const resip::Tuple &flow)
void terminateFlow(const resip::Tuple &flow)
TransmitState transmit(SipMessage *msg, Tuple &target, SendData *sendData=0)
void invokeAfterSocketCreationFunc(TransportType type)
void dnsResolve(DnsResult *result, SipMessage *msg)
void retransmit(const SendData &msg)
Resend to the same transport as last time.
TransactionUser * selectTransactionUser(const SipMessage &msg)
bool haveTransactionUsers() const
CongestionManager::RejectionBehavior getRejectionBehavior(TransactionUser *tu) const
void add(Message *msg, TimeLimitFifo< Message >::DepthUsage usage)
uint32_t getExpectedWait(TransactionUser *tu) const
bool isTransactionUserStillRegistered(const TransactionUser *) const
Represents a network address.
Definition Tuple.hxx:59
void setPort(int port)
Definition Tuple.cxx:449
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
Definition Tuple.hxx:189
int getPort() const
Definition Tuple.cxx:466
TransportType getType() const
Definition Tuple.hxx:122
static TransportType toTransport(const Data &)
Converts a string representation of transport type, i.e.
Definition Tuple.cxx:921
TransportKey mTransportKey
Definition Tuple.hxx:190
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
int & port()
Definition Uri.hxx:145
bool exists(const Param< Uri > &paramType) const
Definition Uri.cxx:1701
Data & host()
Definition Uri.hxx:40
const Data & param(const ExtensionParameter &param) const
Const accessor for non-natively-supported parameter types.
Represents the "via-parm" element in the RFC 3261 grammar.
Definition Via.hxx:18
Represents the "warning-value" element in the RFC 3261 grammar.
An ostream that operates on an existing Data.
volatile bool & statisticsManagerEnabled()
Enable Statistics Manager.
dcm! – add UnusedChecking(_enum) below;
const _Tp & resipMin(const _Tp &__a, const _Tp &__b)
Definition compat.hxx:182
StatusLineType h_StatusLine
Definition Headers.cxx:348
ParserContainer< Token > Tokens
Definition Headers.hxx:114
TransportType
An enumeration of transport protocols.
@ UNKNOWN_TRANSPORT
RequestLineType h_RequestLine
Definition Headers.cxx:347
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
bool isReliable(TransportType type)
Returns true if passed in transport type is a reliable transport protocol.
H_CallId h_CallId
Definition Headers.cxx:266
#define EncodeStream
unsigned short uint16_t
Definition stdint.h:84
unsigned int uint32_t
Definition stdint.h:85
unsigned __int64 uint64_t
Definition stdint.h:95