1
#if defined(HAVE_CONFIG_H)
5
#include "resip/stack/AbandonServerTransaction.hxx"
6
#include "resip/stack/CancelClientInviteTransaction.hxx"
7
#include "resip/stack/TerminateFlow.hxx"
8
#include "resip/stack/EnableFlowTimer.hxx"
9
#include "resip/stack/ZeroOutStatistics.hxx"
10
#include "resip/stack/PollStatistics.hxx"
11
#include "resip/stack/ConnectionTerminated.hxx"
12
#include "resip/stack/KeepAlivePong.hxx"
13
#include "resip/stack/DnsInterface.hxx"
14
#include "resip/stack/DnsResultMessage.hxx"
15
#include "resip/stack/DnsResult.hxx"
16
#include "resip/stack/Helper.hxx"
17
#include "resip/stack/MethodTypes.hxx"
18
#include "resip/stack/SipMessage.hxx"
19
#include "resip/stack/SendData.hxx"
20
#include "resip/stack/SipStack.hxx"
21
#include "resip/stack/StatisticsManager.hxx"
22
#include "resip/stack/TimerMessage.hxx"
23
#include "resip/stack/TransactionController.hxx"
24
#include "resip/stack/TransactionMessage.hxx"
25
#include "resip/stack/TransactionState.hxx"
26
#include "resip/stack/TransactionTerminated.hxx"
27
#include "resip/stack/TransportFailure.hxx"
28
#include "resip/stack/TransactionUserMessage.hxx"
29
#include "resip/stack/TransportFailure.hxx"
30
#include "resip/stack/TransportSelector.hxx"
31
#include "resip/stack/TransactionUser.hxx"
32
#include "resip/stack/TuSelector.hxx"
33
#include "resip/stack/InteropHelper.hxx"
34
#include "resip/stack/KeepAliveMessage.hxx"
35
#include "rutil/DnsUtil.hxx"
36
#include "rutil/Logger.hxx"
37
#include "rutil/MD5Stream.hxx"
38
#include "rutil/Socket.hxx"
39
#include "rutil/Random.hxx"
40
#include "rutil/WinLeakCheck.hxx"
42
using namespace resip;
44
#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION
46
unsigned long TransactionState::StatelessIdCounter = 0;
48
TransactionState::TransactionState(TransactionController& controller, Machine m,
49
State s, const Data& id, MethodTypes method, const Data& methodText, TransactionUser* tu) :
50
mController(controller),
54
mIsReliable(true), // !jf!
59
mMethodText(method==UNKNOWN ? new Data(methodText) : 0),
60
mCurrentMethodType(UNKNOWN),
61
mCurrentResponseCode(0),
63
mWaitingForDnsResult(false),
65
mFailureReason(TransportFailure::None),
68
StackLog (<< "Creating new TransactionState: " << *this);
73
TransactionState::makeCancelTransaction(TransactionState* tr, Machine machine, const Data& tid)
75
TransactionState* cancel = new TransactionState(tr->mController,
81
tr->mTransactionUser);
82
// !jf! don't set this since it will be set by TransactionState::processReliability()
83
//cancel->mIsReliable = tr->mIsReliable;
84
cancel->mResponseTarget = tr->mResponseTarget;
85
cancel->mTarget = tr->mTarget;
88
// !jf! don't call processServerNonInvite since it will delete
89
// the sip message which needs to get sent to the TU
90
cancel->processReliability(tr->mTarget.getType());
95
TransactionState::handleInternalCancel(SipMessage* cancel,
96
TransactionState& clientInvite)
98
TransactionState* state = TransactionState::makeCancelTransaction(&clientInvite, ClientNonInvite, clientInvite.mId+"cancel");
99
// Make sure the branch in the CANCEL matches the current
100
// branch of the INVITE, in case we have done a DNS failover (the transport
101
// sequences could be different by now)
102
cancel->header(h_Vias).front().param(p_branch)=clientInvite.mNextTransmission->const_header(h_Vias).front().param(p_branch);
103
state->processClientNonInvite(cancel);
104
// for the INVITE in case we never get a 487
105
clientInvite.mController.mTimers.add(Timer::TimerCleanUp, clientInvite.mId, 128*Timer::T1);
109
TransactionState::handleBadRequest(const resip::SipMessage& badReq, TransactionController& controller)
111
assert(badReq.isRequest() && badReq.method() != ACK);
114
SipMessage* error = Helper::makeResponse(badReq,400);
115
if(badReq.getReason())
117
error->header(h_StatusLine).reason()+="(" + *(badReq.getReason())+ ")";
119
Tuple target(badReq.getSource());
121
if(badReq.isExternal())
123
controller.mTransportSelector.transmit(error,target);
129
// ?bwc? Should we put together a TransactionState here so we can
130
// send a 400 to the TU?
131
// TODO if we send the error to the TU, don't delete the error
136
catch(resip::BaseException& e)
138
ErrLog(<< "Exception thrown in TransactionState::handleBadRequest."
139
" This shouldn't happen. " << e);
144
TransactionState::~TransactionState()
146
assert(mState != Bogus);
150
mDnsResult->destroy();
153
//StackLog (<< "Deleting TransactionState " << mId << " : " << this);
156
delete mNextTransmission;
158
mNextTransmission = 0;
165
TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& controller, const Data& tid)
167
MethodTypes method=sip->method();
168
StackLog (<< "No matching transaction for " << sip->brief());
169
TransactionUser* tu = 0;
170
if (sip->isExternal())
172
if (controller.mTuSelector.haveTransactionUsers() && sip->isRequest())
174
tu = controller.mTuSelector.selectTransactionUser(*sip);
177
//InfoLog (<< "Didn't find a TU for " << sip->brief());
178
// !bwc! We really should do something other than a 500 here.
179
// If none of the TUs liked the request because of the Request-
180
// Uri scheme, we should be returning a 416, for example.
181
// ?bwc? Um, should we _really_ be doing this statelessly?
182
InfoLog( << "No TU found for message: " << sip->brief());
183
SipMessage* noMatch = Helper::makeResponse(*sip, 500);
184
Tuple target(sip->getSource());
186
controller.mTransportSelector.transmit(noMatch, target);
192
//InfoLog (<< "Found TU for " << sip->brief());
198
tu = sip->getTransactionUser();
201
//InfoLog (<< "No TU associated with " << sip->brief());
205
if (sip->isRequest())
207
// create a new state object and insert in the TransactionMap
209
if (sip->isExternal()) // new sip msg from transport
211
if (method == INVITE)
213
// !rk! This might be needlessly created. Design issue.
214
TransactionState* state = new TransactionState(controller,
222
state->mNextTransmission = state->make100(sip);
223
state->mResponseTarget = sip->getSource(); // UACs source address
224
// since we don't want to reply to the source port if rport present
225
state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
226
state->mIsReliable = isReliable(state->mResponseTarget.getType());
229
if (Timer::T100 == 0)
231
state->sendCurrentToWire(); // will get deleted when this is deleted
232
state->mState = Proceeding;
236
//StackLog(<<" adding T100 timer (INV)");
237
controller.mTimers.add(Timer::TimerTrying, tid, Timer::T100);
239
state->sendToTU(sip);
242
else if (method == CANCEL)
244
TransactionState* matchingInvite =
245
controller.mServerTransactionMap.find(sip->getTransactionId());
246
if (matchingInvite == 0)
248
InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas");
249
//was TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 481));
250
SipMessage* response = Helper::makeResponse(*sip, 481);
251
Tuple target(sip->getSource());
252
controller.mTransportSelector.transmit(response, target);
259
assert(matchingInvite);
260
TransactionState* state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid);
261
state->startServerNonInviteTimerTrying(*sip,tid);
262
state->sendToTU(sip);
266
else if (method != ACK)
268
TransactionState* state = new TransactionState(controller,
275
state->mResponseTarget = sip->getSource();
276
// since we don't want to reply to the source port if rport present
277
state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
279
state->mIsReliable = isReliable(state->mResponseTarget.getType());
280
state->startServerNonInviteTimerTrying(*sip,tid);
281
state->sendToTU(sip);
285
// Incoming ACK just gets passed to the TU
286
//StackLog(<< "Adding incoming message to TU fifo " << tid);
287
TransactionState::sendToTU(tu, controller, sip);
289
else // new sip msg from the TU
291
if (method == INVITE)
293
TransactionState* state = new TransactionState(controller,
300
state->add(state->mId);
301
state->processClientInvite(sip);
303
else if (method == ACK)
305
TransactionState* state = new TransactionState(controller,
312
state->add(state->mId);
313
state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
314
state->processStateless(sip);
316
else if (method == CANCEL)
318
TransactionState* matchingInvite = controller.mClientTransactionMap.find(sip->getTransactionId());
320
if (matchingInvite == 0)
322
InfoLog (<< "No matching INVITE for incoming (from TU) CANCEL to uac");
323
TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip,481));
326
else if (matchingInvite->mState == Calling) // CANCEL before 1xx received
328
WarningLog(<< "You can't CANCEL a request until a provisional has been received");
329
StackLog (<< *matchingInvite);
332
matchingInvite->mIsAbandoned = true;
335
else if (matchingInvite->mState == Completed)
337
// A final response was already seen for this INVITE transaction
338
matchingInvite->sendToTU(Helper::makeResponse(*sip, 200));
343
handleInternalCancel(sip, *matchingInvite);
348
TransactionState* state = new TransactionState(controller,
356
state->processClientNonInvite(sip);
360
else if (sip->isResponse()) // stray response
362
if (controller.mDiscardStrayResponses)
364
InfoLog (<< "discarding stray response: " << sip->brief());
369
StackLog (<< "forwarding stateless response: " << sip->brief());
370
TransactionState* state =
371
new TransactionState(controller,
374
Data(StatelessIdCounter++),
378
state->add(state->mId);
379
state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
380
state->processStateless(sip);
383
else // wasn't a request or a response
385
ErrLog (<< "Got a SipMessage that was neither a request nor response!"
394
TransactionState::process(TransactionController& controller,
395
TransactionMessage* message)
398
KeepAliveMessage* keepAlive = dynamic_cast<KeepAliveMessage*>(message);
401
StackLog ( << "Sending keep alive to: " << keepAlive->getDestination());
402
controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination());
407
ConnectionTerminated* term = dynamic_cast<ConnectionTerminated*>(message);
410
if(term->hasTransactionUser())
412
controller.mTuSelector.add(term);
416
// .bwc. This means we are using this message to close a connection.
417
controller.mTransportSelector.closeConnection(term->getFlow());
423
KeepAlivePong* pong = dynamic_cast<KeepAlivePong*>(message);
426
controller.mTuSelector.add(pong);
431
TerminateFlow* termFlow = dynamic_cast<TerminateFlow*>(message);
434
controller.mTransportSelector.terminateFlow(termFlow->getFlow());
439
EnableFlowTimer* enableFlowTimer = dynamic_cast<EnableFlowTimer*>(message);
442
controller.mTransportSelector.enableFlowTimer(enableFlowTimer->getFlow());
443
delete enableFlowTimer;
447
ZeroOutStatistics* zeroOutStatistics = dynamic_cast<ZeroOutStatistics*>(message);
448
if(zeroOutStatistics)
450
controller.mStatsManager.zeroOut();
451
delete zeroOutStatistics;
455
PollStatistics* pollStatistics = dynamic_cast<PollStatistics*>(message);
458
controller.mStatsManager.poll();
459
delete pollStatistics;
464
// .bwc. We can't do anything without a tid here. Check this first.
468
tid = message->getTransactionId();
470
catch(SipMessage::Exception&)
472
// .bwc This is not our error. Do not ErrLog.
473
DebugLog( << "TransactionState::process dropping message with invalid tid " << message->brief());
478
SipMessage* sip = dynamic_cast<SipMessage*>(message);
479
MethodTypes method = UNKNOWN;
483
method=sip->method();
484
// ?bwc? Should this come after checking for error conditions?
485
if(controller.mStack.statisticsManagerEnabled() && sip->isExternal())
487
controller.mStatsManager.received(sip);
490
// .bwc. Check for error conditions we can respond to.
491
if(sip->isRequest() && method != ACK)
493
// .bwc. If we are going to statelessly send a 503, we should do it
494
// in the transport, before we do expensive stuff like basicCheck and
495
// stampReceived. If the TU fifo is backed up, we should send a
496
// _stateful_ 503 below. (And only if the specific TU that can handle
497
// this message is backed up; if other TUs are congested, we should let
500
if(sip->isExternal() && (controller.isTUOverloaded() || controller.mStateMacFifo.isRejecting()))
502
SipMessage* tryLater = Helper::makeResponse(*sip, 503);
503
if( controller.mStateMacFifo.isRejecting() )
504
tryLater->header(h_RetryAfter).value() = controller.mStateMacFifo.getRetryAfter();
506
tryLater->header(h_RetryAfter).value() = 32 + (Random::getRandom() % 32);
508
//tryLater->header(h_RetryAfter).comment() = "Server busy TRANS";
509
Tuple target(sip->getSource());
511
controller.mTransportSelector.transmit(tryLater, target);
519
handleBadRequest(*sip,controller);
525
#ifdef PEDANTIC_STACK
528
sip->parseAllHeaders();
530
catch(resip::ParseException& e)
532
if(sip->isRequest() && method!=ACK)
534
handleBadRequest(*sip,controller);
537
InfoLog(<< "Exception caught by pedantic stack: " << e);
541
// This ensures that CANCEL requests form unique transactions
542
if (method == CANCEL)
548
TransactionState* state = 0;
549
if (message->isClientTransaction())
550
state = controller.mClientTransactionMap.find(tid);
552
state = controller.mServerTransactionMap.find(tid);
554
if (state && sip && sip->isExternal())
556
// Various kinds of response fixup.
557
if(sip->isResponse() &&
558
state->mNextTransmission)
560
// .bwc. This code (if enabled) ensures that responses have the same
561
// CallId and tags as the request did (excepting the introduction of a
562
// remote tag). This is to protect dialog-stateful TUs that don't react
563
// gracefully when a stupid/malicious endpoint fiddles with the tags
564
// and/or CallId when it isn't supposed to. (DUM is one such TU)
565
if(state->mController.getFixBadDialogIdentifiers())
567
if(sip->const_header(h_CallId).isWellFormed())
569
if(!(sip->const_header(h_CallId) ==
570
state->mNextTransmission->const_header(h_CallId)))
572
InfoLog(<< "Other end modified our Call-Id... correcting.");
573
sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId);
578
InfoLog(<< "Other end corrupted our CallId... correcting.");
579
sip->header(h_CallId) = state->mNextTransmission->const_header(h_CallId);
582
const NameAddr& from = state->mNextTransmission->const_header(h_From);
583
if(sip->const_header(h_From).isWellFormed())
586
if(from.exists(p_tag))
588
if(sip->const_header(h_From).param(p_tag) != from.param(p_tag))
590
InfoLog(<<"Other end modified our local tag... correcting.");
591
sip->header(h_From).param(p_tag) = from.param(p_tag);
594
else if(sip->const_header(h_From).exists(p_tag))
596
if(sip->const_header(h_From).exists(p_tag))
598
InfoLog(<<"Other end added a local tag for us... removing.");
599
sip->header(h_From).remove(p_tag);
605
InfoLog(<<"Other end corrupted our From header... replacing.");
606
// Whole header is hosed, overwrite.
607
sip->header(h_From) = from;
610
const NameAddr& to = state->mNextTransmission->const_header(h_To);
611
if(sip->const_header(h_To).isWellFormed())
616
if(sip->const_header(h_To).param(p_tag) != to.param(p_tag))
618
InfoLog(<<"Other end modified the (existing) remote tag... "
620
sip->header(h_To).param(p_tag) = to.param(p_tag);
626
InfoLog(<<"Other end corrupted our To header... replacing.");
627
// Whole header is hosed, overwrite.
628
sip->header(h_To) = to;
632
// .bwc. This code (if enabled) ensures that responses have the same
633
// CSeq number as the request did. This is to protect TUs that don't
634
// react gracefully when a stupid/malicious endpoint fiddles with the
635
// CSeq number. (This is a very cheap check; we already parse the CSeq
636
// for incoming messages)
637
if(state->mController.getFixBadCSeqNumbers())
639
unsigned int old=state->mNextTransmission->const_header(h_CSeq).sequence();
640
if(sip->const_header(h_CSeq).sequence()!=old)
642
InfoLog(<<"Other end changed our CSeq number... replacing.");
643
sip->header(h_CSeq).sequence()=old;
646
if(state->mNextTransmission->exists(h_RAck))
648
if(!(sip->const_header(h_RAck)==state->mNextTransmission->const_header(h_RAck)))
650
InfoLog(<<"Other end changed our RAck... replacing.");
651
sip->header(h_RAck)=state->mNextTransmission->const_header(h_RAck);
656
// .bwc. This code ensures that the transaction state-machine can recover
657
// from ACK/200 with the same tid as the original INVITE. This problem is
659
if(sip->isRequest() && method == ACK && !state->mAckIsValid)
661
// Must have received an ACK to a 200;
662
// We will never respond to this, so nothing will need this tid for
663
// driving transaction state. Additionally,
664
InfoLog(<<"Someone sent us an ACK/200 with the same tid as the "
665
"original INVITE. This is bad behavior, and should be "
666
"corrected in the client.");
667
sip->mIsBadAck200=true;
668
// .bwc. This is a new stateless transaction, despite its tid.
675
switch(state->mMethod)
678
if(method != INVITE && method != ACK)
680
// Maybe respond if a request?
686
if(!state->mMethodText || *(state->mMethodText) != sip->methodStr())
688
// Maybe respond if a request?
694
if(state->mMethod != method)
696
// Maybe respond if a request?
704
if (state) // found transaction for sip msg
706
StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state);
708
switch (state->mMachine)
710
case ClientNonInvite:
711
state->processClientNonInvite(message);
714
// ACK from TU will be Stateless
715
assert (!sip || !(state->isFromTU(sip) && sip->isRequest() && method == ACK));
716
state->processClientInvite(message);
718
case ServerNonInvite:
719
state->processServerNonInvite(message);
722
state->processServerInvite(message);
725
state->processStateless(message);
728
state->processClientStale(message);
731
state->processServerStale(message);
734
CritLog(<<"internal state error");
739
else if (sip) // new transaction
743
bool processed = processSipMessageAsNew(sip, controller, tid);
749
catch(resip::ParseException& e)
751
StackLog ( << "Got badly formatted sip message, error: " << e.what());
752
if(sip->isRequest() && sip->method()!=ACK)
754
handleBadRequest(*sip, controller);
758
catch(std::exception& err)
760
StackLog ( << "Got error: " << err.what());
764
else // timer or other non-sip msg
766
//StackLog (<< "discarding non-sip message: " << message->brief());
772
TransactionState::processTimer(TransactionController& controller,
773
TimerMessage* message)
775
Data tid = message->getTransactionId();
777
if(controller.getRejectionBehavior()==CongestionManager::REJECTING_NON_ESSENTIAL)
779
// .bwc. State machine fifo is backed up; we probably should not be
780
// retransmitting anything right now. If we have a retransmit timer,
781
// reschedule for later, but don't retransmit.
782
switch(message->getType())
784
case Timer::TimerA: // doubling
785
controller.mTimers.add(Timer::TimerA,
787
message->getDuration()*2);
790
case Timer::TimerE1:// doubling, until T2
791
case Timer::TimerG: // doubling, until T2
792
controller.mTimers.add(message->getType(),
794
resipMin(message->getDuration()*2,
798
case Timer::TimerE2:// just reset
799
controller.mTimers.add(Timer::TimerE2,
809
TransactionState* state = 0;
810
if (message->isClientTransaction()) state = controller.mClientTransactionMap.find(tid);
811
else state = controller.mServerTransactionMap.find(tid);
813
if (state) // found transaction for timer
815
StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state);
817
switch (state->mMachine)
819
case ClientNonInvite:
820
state->processClientNonInvite(message);
823
state->processClientInvite(message);
825
case ServerNonInvite:
826
state->processServerNonInvite(message);
829
state->processServerInvite(message);
832
state->processStateless(message);
835
state->processClientStale(message);
838
state->processServerStale(message);
841
CritLog(<<"internal state error");
854
TransactionState::startServerNonInviteTimerTrying(SipMessage& sip, const Data& tid)
856
unsigned int duration = 3500;
857
if(Timer::T1 != 500) // optimzed for T1 == 500
859
// Iteratively calculate how much time before TimerE reaches T2 (RFC4320) - could be improved
860
duration = Timer::T1;
861
while(duration*2<Timer::T2) duration = duration * 2;
863
resetNextTransmission(make100(&sip)); // Store for use when timer expires
864
mController.mTimers.add(Timer::TimerTrying, tid, duration ); // Start trying timer so that we can send 100 to NITs as recommened in RFC4320
868
TransactionState::processStateless(TransactionMessage* message)
870
// for ACK messages from the TU, there is no transaction, send it directly
871
// to the wire // rfc3261 17.1 Client Transaction
872
SipMessage* sip = dynamic_cast<SipMessage*>(message);
873
StackLog (<< "TransactionState::processStateless: " << message->brief());
875
// !jf! There is a leak for Stateless transactions associated with ACK to 200
876
if (isFromTU(message))
878
resetNextTransmission(sip);
881
else if(sip && isFromWire(sip))
883
InfoLog (<< "Received message from wire on a stateless transaction");
888
else if (isTransportError(message))
890
processTransportFailure(message);
895
else if (isTimer(message))
897
TimerMessage* timer = dynamic_cast<TimerMessage*>(message);
898
if (timer->getType() == Timer::TimerStateless)
909
else if(dynamic_cast<DnsResultMessage*>(message))
911
handleSync(mDnsResult);
914
else if (isAbandonServerTransaction(message))
927
TransactionState::saveOriginalContactAndVia(const SipMessage& sip)
929
if(sip.exists(h_Contacts) && sip.const_header(h_Contacts).size() == 1 &&
930
sip.const_header(h_Contacts).front().isWellFormed())
932
mOriginalContact = std::auto_ptr<NameAddr>(new NameAddr(sip.header(h_Contacts).front()));
934
mOriginalVia = std::auto_ptr<Via>(new Via(sip.header(h_Vias).front()));
937
void TransactionState::restoreOriginalContactAndVia()
939
if (mOriginalContact.get())
941
mNextTransmission->header(h_Contacts).front() = *mOriginalContact;
943
if (mOriginalVia.get())
945
mOriginalVia->param(p_branch).incrementTransportSequence();
946
mNextTransmission->header(h_Vias).front() = *mOriginalVia;
951
TransactionState::processClientNonInvite(TransactionMessage* msg)
953
StackLog (<< "TransactionState::processClientNonInvite: " << msg->brief());
955
if (isRequest(msg) && isFromTU(msg))
957
//StackLog (<< "received new non-invite request");
958
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
959
resetNextTransmission(sip);
960
saveOriginalContactAndVia(*sip);
961
mController.mTimers.add(Timer::TimerF, mId, Timer::TF);
964
else if (isResponse(msg) && isFromWire(msg)) // from the wire
966
//StackLog (<< "received response from wire");
968
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
969
int code = sip->const_header(h_StatusLine).responseCode();
970
if (code >= 100 && code < 200) // 1XX
972
if (mState == Trying || mState == Proceeding)
974
//?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
975
// 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.
976
if (!mIsReliable && mState == Trying)
978
mController.mTimers.add(Timer::TimerE2, mId, Timer::T2 );
981
sendToTU(msg); // don't delete
989
else if (code >= 200)
991
// don't notify the TU of retransmissions
992
if (mState == Trying || mState == Proceeding)
994
sendToTU(msg); // don't delete
996
else if (mState == Completed)
1008
terminateClientTransaction(mId);
1011
else if (mState != Completed) // prevent TimerK reproduced
1014
mController.mTimers.add(Timer::TimerK, mId, Timer::T4 );
1015
// !bwc! Got final response in NIT. We don't need to do anything
1016
// except quietly absorb retransmissions. Dump all state.
1019
mDnsResult->destroy();
1021
mWaitingForDnsResult=false;
1023
resetNextTransmission(0);
1032
else if (isTimer(msg))
1034
//StackLog (<< "received timer in client non-invite transaction");
1036
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1037
switch (timer->getType())
1039
case Timer::TimerE1:
1040
if (mState == Trying)
1042
unsigned long d = timer->getDuration();
1043
if (d < Timer::T2) d *= 2;
1044
mController.mTimers.add(Timer::TimerE1, mId, d);
1045
StackLog (<< "Transmitting current message");
1046
sendCurrentToWire();
1056
case Timer::TimerE2:
1057
if (mState == Proceeding)
1059
mController.mTimers.add(Timer::TimerE2, mId, Timer::T2);
1060
StackLog (<< "Transmitting current message");
1061
sendCurrentToWire();
1072
if (mState == Trying || mState == Proceeding)
1074
// !bwc! We hold onto this until we get a response from the wire
1075
// in client transactions, for this contingency.
1076
assert(mNextTransmission);
1077
if(mWaitingForDnsResult)
1079
WarningLog(<< "Transaction timed out while waiting for DNS "
1081
mNextTransmission->const_header(h_RequestLine).uri());
1082
sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1086
sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1088
terminateClientTransaction(mId);
1096
terminateClientTransaction(mId);
1102
//InfoLog (<< "Ignoring timer: " << *msg);
1107
else if (isTransportError(msg))
1109
processTransportFailure(msg);
1112
else if(dynamic_cast<DnsResultMessage*>(msg))
1114
handleSync(mDnsResult);
1117
else if (isAbandonServerTransaction(msg))
1124
//StackLog (<< "TransactionState::processClientNonInvite: message unhandled");
1130
TransactionState::processClientInvite(TransactionMessage* msg)
1132
StackLog(<< "TransactionState::processClientInvite: " << msg->brief() << " " << *this);
1133
if (isRequest(msg) && isFromTU(msg))
1135
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1136
switch (sip->method())
1138
// Received INVITE request from TU="Transaction User", Start Timer B which controls
1139
// transaction timeouts.
1141
if(mState==Calling && !mNextTransmission && mMsgToRetransmit.empty())
1143
resetNextTransmission(sip);
1144
saveOriginalContactAndVia(*sip);
1145
mController.mTimers.add(Timer::TimerB, mId, Timer::TB );
1146
sendCurrentToWire();
1150
WarningLog(<< "TU sent us a duplicate INVITE: fix this!");
1161
WarningLog(<< "TU sent us an erroneous request inside a Client"
1162
" INVITE transaction: fix this!");
1167
else if (isResponse(msg) && isFromWire(msg))
1169
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1170
int code = sip->const_header(h_StatusLine).responseCode();
1171
switch (sip->method())
1174
/* If the client transaction receives a provisional response while in
1175
the "Calling" state, it transitions to the "Proceeding" state. In the
1176
"Proceeding" state, the client transaction SHOULD NOT retransmit the
1177
request any longer (this will be Handled in "else if (isTimer(msg))")
1178
The Retransmissions will be stopped, Not by Cancelling Timers but
1179
by Ignoring the fired Timers depending upon the State which stack is in.
1181
if (code >= 100 && code < 200) // 1XX
1183
if (mState == Calling || mState == Proceeding)
1185
mState = Proceeding;
1188
SipMessage* cancel = Helper::makeCancel(*mNextTransmission);
1189
// Iterate through message decorators on the INVITE and see if any need to be copied to the CANCEL
1190
mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel);
1191
handleInternalCancel(cancel, *this);
1194
// !bwc! We have gotten a response. We don't need to
1195
// retransmit the original INVITE anymore (so we clear mMsgToRetransmit),
1196
// but we do need to retain the full original INVITE until we get a final
1197
// response, in case we need to forge an ACK.
1198
mMsgToRetransmit.clear();
1199
sendToTU(sip); // don't delete msg
1207
/* When in either the "Calling" or "Proceeding" states, reception of a
1208
2xx response MUST cause the client transaction to enter the
1209
"Terminated" state, and the response MUST be passed up to the TU
1210
State Machine is changed to Stale since, we wanted to ensure that
1213
else if (code >= 200 && code < 300)
1216
sendToTU(sip); // don't delete msg
1217
//terminateClientTransaction(mId);
1218
mMachine = ClientStale;
1219
// !bwc! We have a final response. We don't need either of
1220
// mMsgToRetransmit or mNextTransmission. We ignore further
1222
resetNextTransmission(0);
1225
mDnsResult->destroy();
1227
mWaitingForDnsResult=false;
1229
StackLog (<< "Received 2xx on client invite transaction");
1230
StackLog (<< *this);
1231
mController.mTimers.add(Timer::TimerStaleClient, mId, Timer::TS );
1233
else if (code >= 300)
1236
// When in either the "Calling" or "Proceeding" states, reception of a
1237
// response with status code from 300-699 MUST cause the client
1238
// transaction to transition to "Completed".
1241
// Stack MUST pass the received response up to the TU, and the client
1242
// transaction MUST generate an ACK request, even if the transport is
1244
SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip);
1245
mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack);
1246
resetNextTransmission(ack);
1248
// want to use the same transport as was selected for Invite
1249
assert(mTarget.getType() != UNKNOWN_TRANSPORT);
1250
sendCurrentToWire();
1251
sendToTU(sip); // don't delete msg
1252
terminateClientTransaction(mId);
1254
// !bwc! We only do this because we are assured the ACK
1255
// will make it to the other end; if we are using an
1256
// unreliable transport, we need to stick around to absorb
1257
// retransmissions of the response.
1262
if (mState == Calling || mState == Proceeding)
1264
// MUST pass the received response up to the TU, and the client
1265
// transaction MUST generate an ACK request, even if the transport is
1266
// reliable, if transport is Unreliable then Fire the Timer D which
1267
// take care of re-Transmission of ACK
1269
mController.mTimers.add(Timer::TimerD, mId, Timer::TD );
1270
SipMessage* ack = Helper::makeFailureAck(*mNextTransmission, *sip);
1271
mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack);
1272
resetNextTransmission(ack);
1273
sendCurrentToWire();
1276
mDnsResult->destroy();
1278
mWaitingForDnsResult=false;
1280
sendToTU(sip); // don't delete msg
1282
else if (mState == Completed)
1284
// Any retransmissions of the final response that
1285
// are received while in the "Completed" state MUST
1286
// cause the ACK to be re-passed to the transport
1287
// layer for retransmission.
1288
sendCurrentToWire();
1293
/* This should never Happen if it happens we should have a plan
1294
what to do here?? for now assert will work
1296
CritLog( << "State invalid");
1320
else if (isTimer(msg))
1322
/* Handle Transaction Timers , Retransmission Timers which were set and Handle
1323
Cancellation of Timers for Re-transmissions here */
1325
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1326
StackLog (<< "timer fired: " << *timer);
1328
switch (timer->getType())
1331
if (mState == Calling && !mIsAbandoned)
1333
unsigned long d = timer->getDuration()*2;
1334
// TimerA is supposed to double with each retransmit RFC3261 17.1.1
1336
mController.mTimers.add(Timer::TimerA, mId, d);
1337
DebugLog (<< "Retransmitting INVITE ");
1338
sendCurrentToWire();
1344
if (mState == Calling)
1346
assert(mNextTransmission && mNextTransmission->isRequest() &&
1347
mNextTransmission->method()==INVITE);
1348
if(mWaitingForDnsResult)
1350
WarningLog(<< "Transaction timed out while waiting for DNS "
1352
mNextTransmission->const_header(h_RequestLine).uri());
1353
sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1357
sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1359
terminateClientTransaction(mId);
1366
terminateClientTransaction(mId);
1371
case Timer::TimerCleanUp:
1372
// !ah! Cancelled Invite Cleanup Timer fired.
1373
StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mNextTransmission);
1374
if (mState == Proceeding)
1376
assert(mNextTransmission && mNextTransmission->isRequest() &&
1377
mNextTransmission->method() == INVITE);
1378
InfoLog(<<"Making 408 for canceled invite that received no response: "<< mNextTransmission->brief());
1379
if(mWaitingForDnsResult)
1381
WarningLog(<< "Transaction timed out while waiting for DNS "
1383
mNextTransmission->const_header(h_RequestLine).uri());
1384
sendToTU(Helper::makeResponse(*mNextTransmission, 503, "DNS Timeout"));
1388
sendToTU(Helper::makeResponse(*mNextTransmission, 408));
1390
terminateClientTransaction(msg->getTransactionId());
1401
else if (isTransportError(msg))
1403
processTransportFailure(msg);
1406
else if (isCancelClientTransaction(msg))
1408
// TU wants to CANCEL this transaction. See if we can...
1409
if(mState==Proceeding)
1411
// We can send the CANCEL now.
1412
SipMessage* cancel=Helper::makeCancel(*mNextTransmission);
1413
mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel);
1414
TransactionState::handleInternalCancel(cancel, *this);
1416
else if(mState==Calling)
1418
// We can't send the CANCEL yet, remember to.
1419
mIsAbandoned = true;
1423
else if(dynamic_cast<DnsResultMessage*>(msg))
1425
handleSync(mDnsResult);
1430
//StackLog ( << "TransactionState::processClientInvite: message unhandled");
1436
TransactionState::processServerNonInvite(TransactionMessage* msg)
1438
StackLog (<< "TransactionState::processServerNonInvite: " << msg->brief());
1440
if (isRequest(msg) && !isInvite(msg) && isFromWire(msg)) // retransmission from the wire
1442
if (mState == Trying)
1447
else if (mState == Proceeding || mState == Completed)
1451
assert(mState == Completed);
1453
// put a 500 in mNextTransmission
1454
SipMessage* req = dynamic_cast<SipMessage*>(msg);
1455
resetNextTransmission(Helper::makeResponse(*req, 500));
1456
sendCurrentToWire();
1460
sendCurrentToWire();
1466
CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
1468
<< " state=" << *this);
1474
else if (isResponse(msg) && isFromTU(msg))
1476
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1477
int code = sip->const_header(h_StatusLine).responseCode();
1478
if (code >= 100 && code < 200) // 1XX
1480
if (mState == Trying || mState == Proceeding)
1482
resetNextTransmission(sip);
1483
mState = Proceeding;
1484
sendCurrentToWire(); // don't delete msg
1492
else if (code >= 200 && code <= 699)
1496
resetNextTransmission(sip);
1497
sendCurrentToWire();
1498
terminateServerTransaction(mId);
1500
// !bwc! We can only do this because we are in a reliable
1501
// transport, and do not need to hang around to soak up
1507
if (mState == Trying || mState == Proceeding)
1510
mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 );
1511
resetNextTransmission(sip);
1512
sendCurrentToWire();
1514
else if (mState == Completed)
1521
CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
1523
<< " state=" << *this);
1536
else if (isTimer(msg))
1538
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1540
switch (timer->getType())
1543
if (mState == Completed)
1545
terminateServerTransaction(mId);
1551
case Timer::TimerTrying:
1552
if (mState == Trying)
1554
// Timer E has reached T2 - send a 100 as recommended by RFC4320 NIT-Problem-Actions
1555
sendCurrentToWire();
1556
mState = Proceeding;
1566
else if (isTransportError(msg))
1568
processTransportFailure(msg);
1571
else if (isAbandonServerTransaction(msg))
1573
if(mState==Trying || mState==Proceeding)
1575
mIsAbandoned = true;
1577
// !bwc! We could check to see if we have a 100 lying around, and
1578
// convert it into a 500 for immediate transmission, but it is not
1579
// clear that this is a good idea, especially if the TU has abandoned
1580
// this transaction after the remote endpoint has stopped
1581
// retransmitting. Maybe we could use a time-stamp to help here? Would
1582
// it be worth the extra memory footprint?
1586
// If we haven't sent a 500 yet, we never will (no retransmissions
1587
// to make the response with).
1588
terminateServerTransaction(mId);
1593
// If we haven't sent a 500 yet, we'll do so when the next
1594
// retransmission comes in. In the meantime, set up timers for
1595
// transaction termination.
1597
mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 );
1602
else if(dynamic_cast<DnsResultMessage*>(msg))
1604
handleSync(mDnsResult);
1609
//StackLog (<< "TransactionState::processServerNonInvite: message unhandled");
1616
TransactionState::processServerInvite(TransactionMessage* msg)
1618
StackLog (<< "TransactionState::processServerInvite: " << msg->brief());
1619
if (isRequest(msg) && isFromWire(msg))
1621
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1622
switch (sip->method())
1625
// note: handling of initial INVITE message is done in TransactionState:process
1630
resetNextTransmission(Helper::makeResponse(*sip, 500));
1632
mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1635
mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1637
sendCurrentToWire();
1642
if (mState == Proceeding || mState == Completed)
1645
The server transaction has already been constructed so this
1646
message is a retransmission. The server transaction must
1647
respond with a 100 Trying _or_ the last provisional response
1648
passed from the TU for this transaction.
1650
//StackLog (<< "Received invite from wire - forwarding to TU state=" << mState);
1652
// !bwc! If we have nothing to respond with, make something.
1653
if (mMsgToRetransmit.empty() && !mNextTransmission)
1655
resetNextTransmission(make100(sip));
1658
sendCurrentToWire();
1662
//StackLog (<< "Received invite from wire - ignoring state=" << mState);
1669
If an ACK is received while the server transaction is in the
1670
"Completed" state, the server transaction MUST transition to the
1673
if (mState == Completed)
1677
//StackLog (<< "Received ACK in Completed (reliable) - delete transaction");
1678
terminateServerTransaction(mId);
1684
//StackLog (<< "Received ACK in Completed (unreliable) - confirmed, start Timer I");
1686
mController.mTimers.add(Timer::TimerI, mId, Timer::T4 );
1687
// !bwc! Got an ACK/failure; we can stop retransmitting
1688
// our failure response now.
1689
resetNextTransmission(0);
1695
//StackLog (<< "Ignore ACK not in Completed state");
1706
//StackLog (<< "Received unexpected request. Ignoring message");
1711
else if (isResponse(msg, 100, 699) && isFromTU(msg))
1713
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1714
int code = sip->const_header(h_StatusLine).responseCode();
1715
switch (sip->method())
1720
if (mState == Trying || mState == Proceeding)
1722
//StackLog (<< "Received 100 in Trying or Proceeding. Send over wire");
1723
resetNextTransmission(sip); // may be replacing the 100
1724
mState = Proceeding;
1725
sendCurrentToWire(); // don't delete msg
1729
//StackLog (<< "Ignoring 100 - not in Trying or Proceeding.");
1733
else if (code > 100 && code < 200)
1735
if (mState == Trying || mState == Proceeding)
1737
//StackLog (<< "Received 1xx in Trying or Proceeding. Send over wire");
1738
resetNextTransmission(sip); // may be replacing the 100
1739
mState = Proceeding;
1740
sendCurrentToWire(); // don't delete msg
1744
//StackLog (<< "Received 100 when not in Trying State. Ignoring");
1748
else if (code >= 200 && code < 300)
1750
if (mState == Trying || mState == Proceeding)
1752
StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction");
1753
StackLog (<< *this);
1754
resetNextTransmission(sip); // may be replacing the 100
1755
sendCurrentToWire();
1757
// Keep the StaleServer transaction around, so we can keep the
1758
// source Tuple that the request was received on.
1759
//terminateServerTransaction(mId);
1760
mMachine = ServerStale;
1761
mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS );
1765
//StackLog (<< "Received 2xx when not in Trying or Proceeding State. Ignoring");
1769
else if (code >= 300)
1772
While in the "Proceeding" state, if the TU passes a response with
1773
status code from 300 to 699 to the server transaction, For unreliable
1774
transports,timer G is set to fire in T1 seconds, and is not set to
1775
fire for reliable transports.when the "Completed" state is entered,
1776
timer H MUST be set to fire in 64*T1 seconds for all transports.
1777
Timer H determines when the server transaction abandons retransmitting
1781
if (mState == Trying || mState == Proceeding)
1784
StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this);
1785
resetNextTransmission(sip);
1787
mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1790
mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1792
sendCurrentToWire(); // don't delete msg
1796
//StackLog (<< "Received Final response when not in Trying or Proceeding State. Ignoring");
1802
//StackLog (<< "Received Invalid response line. Ignoring");
1813
//StackLog (<< "Received response to non invite or cancel. Ignoring");
1818
else if (isTimer(msg))
1820
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1821
switch (timer->getType())
1824
if (mState == Completed)
1826
StackLog (<< "TimerG fired. retransmit, and re-add TimerG");
1827
sendCurrentToWire();
1828
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
1833
If timer H fires while in the "Completed" state, it implies that the
1834
ACK was never received. In this case, the server transaction MUST
1835
transition to the "Terminated" state, and MUST indicate to the TU
1836
that a transaction failure has occurred. WHY we need to inform TU
1837
for Failure cases ACK ? do we really need to do this ???
1839
!jf! this used to re-add TimerH if there was an associated CANCEL
1840
transaction. Don't know why.
1844
if (timer->getType() == Timer::TimerH)
1846
InfoLog (<< "No ACK was received on a server transaction (Timer H)");
1848
terminateServerTransaction(mId);
1852
case Timer::TimerTrying:
1853
if (mState == Trying)
1855
//StackLog (<< "TimerTrying fired. Send a 100");
1856
sendCurrentToWire(); // will get deleted when this is deleted
1857
mState = Proceeding;
1861
//StackLog (<< "TimerTrying fired. Not in Trying state. Ignoring");
1866
CritLog(<<"unexpected timer fired: " << timer->getType());
1867
assert(0); // programming error if any other timer fires
1872
else if (isTransportError(msg))
1874
processTransportFailure(msg);
1877
else if (isAbandonServerTransaction(msg))
1879
if((mState == Trying || mState == Proceeding) && !mIsAbandoned)
1881
// We need to schedule teardown, and 500 the next retransmission.
1882
if(mNextTransmission)
1884
mMsgToRetransmit.clear();
1885
// hey, we had a 1xx laying around! Turn it into a 500 and send.
1886
assert(mNextTransmission->isResponse());
1887
assert(mNextTransmission->const_header(h_StatusLine).statusCode()/100==1);
1888
mNextTransmission->header(h_StatusLine).statusCode()=500;
1889
mNextTransmission->header(h_StatusLine).reason()="Server Error";
1890
sendCurrentToWire();
1892
StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this);
1894
mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1897
mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1902
// !bwc! TODO try to convert mMsgToRetransmit if present.
1905
// We will never see another retransmission of the INVITE. We
1907
terminateServerTransaction(mId);
1912
// We should see a retransmission of the INVITE shortly, or we
1913
// will time out eventually. Be patient...
1914
mIsAbandoned = true;
1920
else if(dynamic_cast<DnsResultMessage*>(msg))
1922
handleSync(mDnsResult);
1927
//StackLog (<< "TransactionState::processServerInvite: message unhandled");
1934
TransactionState::processClientStale(TransactionMessage* msg)
1936
StackLog (<< "TransactionState::processClientStale: " << msg->brief());
1940
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1941
if (timer->getType() == Timer::TimerStaleClient)
1943
terminateClientTransaction(mId);
1952
else if (isTransportError(msg))
1954
WarningLog (<< "Got a transport error in Stale Client state");
1955
StackLog (<< *this);
1956
processTransportFailure(msg);
1959
else if(isResponse(msg, 200, 299))
1961
assert(isFromWire(msg));
1964
else if(dynamic_cast<DnsResultMessage*>(msg))
1966
handleSync(mDnsResult);
1969
else if (isAbandonServerTransaction(msg))
1974
else if (isCancelClientTransaction(msg))
1981
// might have received some other response because a downstream UAS is
1982
// misbehaving. For instance, sending a 487/INVITE after already
1983
// sending a 200/INVITE. It could also be some other message type.
1984
StackLog (<< "Discarding extra message: " << *msg);
1990
TransactionState::processServerStale(TransactionMessage* msg)
1992
StackLog (<< "TransactionState::processServerStale: " << msg->brief());
1994
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1997
TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1998
if (timer->getType() == Timer::TimerStaleServer)
2001
terminateServerTransaction(mId);
2009
else if (isTransportError(msg))
2011
WarningLog (<< "Got a transport error in Stale Server state");
2012
StackLog (<< *this);
2013
processTransportFailure(msg);
2016
else if (sip && isRequest(sip) && sip->method() == ACK)
2018
// .bwc. We should never fall into this block. There is code in process
2019
// that should prevent it.
2020
assert(isFromWire(msg));
2021
InfoLog (<< "Passing ACK directly to TU: " << sip->brief());
2024
else if (sip && isRequest(sip) && sip->method() == INVITE)
2026
// this can happen when an upstream UAC never received the 200 and
2027
// retransmits the INVITE when using unreliable transport
2028
// Drop the INVITE since the 200 will get retransmitted by the downstream UAS
2029
StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief());
2032
else if (isResponse(msg) && isFromTU(msg))
2034
resetNextTransmission(sip);
2035
sendCurrentToWire();
2037
else if(dynamic_cast<DnsResultMessage*>(msg))
2039
handleSync(mDnsResult);
2042
else if (isAbandonServerTransaction(msg))
2049
// .bwc. This can very easily be triggered by a stupid/malicious
2050
// endpoint. This is not an error in our code. Do not ErrLog this.
2051
InfoLog(<<"ServerStale unexpected condition, dropping message.");
2054
InfoLog(<<sip->brief());
2062
TransactionState::processNoDnsResults()
2064
if(!mNextTransmission || mNextTransmission->method()==ACK)
2066
// This is probably an ACK; since we know we will never need to send a
2067
// response to an ACK, we delete mNextTransmission as soon as we
2072
WarningCategory warning;
2073
SipMessage* response = Helper::makeResponse(*mNextTransmission, 503);
2074
warning.hostname() = mController.mHostname;
2075
warning.code() = 399;
2076
warning.text().reserve(100);
2080
InfoLog (<< "Ran out of dns entries for " << mDnsResult->target() << ". Send 503");
2081
assert(mDnsResult->available() == DnsResult::Finished);
2082
oDataStream warnText(warning.text());
2083
warnText << "No other DNS entries to try ("
2084
<< mFailureReason << "," << mFailureSubCode << ")";
2088
oDataStream warnText(warning.text());
2089
warnText << "Transport failure ("
2090
<< mFailureReason << "," << mFailureSubCode << ")";
2093
switch(mFailureReason)
2095
case TransportFailure::None:
2096
response->header(h_StatusLine).reason() = "No DNS results";
2099
case TransportFailure::Failure:
2100
case TransportFailure::TransportNoSocket:
2101
case TransportFailure::TransportBadConnect:
2102
case TransportFailure::ConnectionUnknown:
2103
case TransportFailure::ConnectionException:
2104
response->header(h_StatusLine).reason() = "Transport failure: no transports left to try";
2106
case TransportFailure::NoTransport:
2107
response->header(h_StatusLine).reason() = "No matching transport found";
2109
case TransportFailure::NoRoute:
2110
response->header(h_StatusLine).reason() = "No route to host";
2112
case TransportFailure::CertNameMismatch:
2113
response->header(h_StatusLine).reason() = "Certificate Name Mismatch";
2115
case TransportFailure::CertValidationFailure:
2116
response->header(h_StatusLine).reason() = "Certificate Validation Failure";
2118
case TransportFailure::TransportNoExistConn:
2119
if(InteropHelper::getOutboundVersion() >= 5)
2121
response->header(h_StatusLine).statusCode() = 430;
2125
response->header(h_StatusLine).statusCode() = 410;
2127
response->header(h_StatusLine).reason() = "Flow failed";
2128
warning.text() = "Flow no longer exists";
2130
case TransportFailure::TransportShutdown:
2131
response->header(h_StatusLine).reason() = "Transport shutdown: no transports left to try";
2135
response->header(h_Warnings).push_back(warning);
2138
terminateClientTransaction(mId);
2139
if (mMachine != Stateless)
2146
TransactionState::processTransportFailure(TransactionMessage* msg)
2148
TransportFailure* failure = dynamic_cast<TransportFailure*>(msg);
2150
assert(mState!=Bogus);
2152
// Store failure reasons
2153
if (failure->getFailureReason() > mFailureReason)
2155
mFailureReason = failure->getFailureReason();
2156
mFailureSubCode = failure->getFailureSubCode();
2159
if (mNextTransmission && // Note: If we just transmitted an ACK then mNextTransmission is cleared, so this check is necessary
2160
mNextTransmission->isRequest() &&
2161
mNextTransmission->method() == CANCEL &&
2162
mState != Completed &&
2163
mState != Terminated)
2165
WarningLog (<< "Failed to deliver a CANCEL request");
2166
StackLog (<< *this);
2167
assert(mMethod==CANCEL);
2169
// In the case of a client-initiated CANCEL, we don't want to
2170
// try other transports in the case of transport error as the
2171
// CANCEL MUST be sent to the same IP/PORT as the orig. INVITE.
2172
//?dcm? insepct failure enum?
2173
SipMessage* response = Helper::makeResponse(*mNextTransmission, 503);
2174
WarningCategory warning;
2175
warning.hostname() = mController.mHostname;
2176
warning.code() = 399;
2177
warning.text() = "Failed to deliver CANCEL using the same transport as the INVITE was used";
2178
response->header(h_Warnings).push_back(warning);
2186
InfoLog(<< "Transport failure on send that did not use DNS.");
2187
processNoDnsResults();
2189
// else If we did DNS resolution, then check if we should try to failover to another DNS entry
2192
// .bwc. Greylist for 32s
2193
// !bwc! TODO make this duration configurable.
2194
mDnsResult->greylistLast(Timer::getTimeMs()+32000);
2196
// .bwc. We should only try multiple dns results if we are originating a
2197
// request. Additionally, there are (potential) cases where it would not
2198
// be appropriate to fail over even then.
2199
bool shouldFailover=false;
2200
if(mMachine==ClientNonInvite)
2202
if(mState==Completed || mState==Terminated)
2204
WarningLog(<<"Got a TransportFailure message in a " << mState <<
2205
" ClientNonInvite transaction. How did this happen? Since we have"
2206
" already completed the transaction, we shouldn't try"
2207
" additional DNS results.");
2211
shouldFailover=true;
2214
else if(mMachine==ClientInvite)
2216
if(mState==Completed || mState==Terminated)
2218
// .bwc. Perhaps the attempted transmission of the ACK failed here.
2219
// (assuming this transaction got a failure response; not sure what
2220
// might have happened if this is not the case)
2221
// In any case, we should not try sending the INVITE anywhere else.
2222
InfoLog(<<"Got a TransportFailure message in a " << mState <<
2223
" ClientInvite transaction. Since we have"
2224
" already completed the transaction, we shouldn't try"
2225
" additional DNS results.");
2229
if(mState==Proceeding)
2231
// .bwc. We need to revert our state back to Calling, since we are
2232
// going to be sending the INVITE to a new endpoint entirely.
2235
// An interesting consequence occurs if our failover ultimately
2236
// sends to the same instance of a resip stack; we increment the
2237
// transport sequence in our branch parameter, but any resip-based
2238
// stack will ignore this change, and process this "new" request as
2239
// a retransmission! Furthermore, our state will be out of phase
2240
// with the state at the remote endpoint, and if we have sent a
2241
// PRACK, it will know (and stuff will break)!
2242
// TODO What else needs to be done here to safely revert our state?
2245
shouldFailover=true;
2251
InfoLog (<< "Try sending request to a different dns result");
2252
assert(mMethod!=CANCEL);
2254
switch (mDnsResult->available())
2256
case DnsResult::Available:
2257
InfoLog(<< "We have another DNS result to try.");
2258
restoreOriginalContactAndVia();
2259
mTarget = mDnsResult->next();
2260
mMsgToRetransmit.clear();
2261
processReliability(mTarget.getType());
2262
sendCurrentToWire();
2265
case DnsResult::Pending:
2266
InfoLog(<< "We have a DNS query pending.");
2267
mWaitingForDnsResult=true;
2268
restoreOriginalContactAndVia();
2269
mMsgToRetransmit.clear();
2272
case DnsResult::Finished:
2273
InfoLog(<< "No DNS results remain.");
2274
processNoDnsResults();
2277
case DnsResult::Destroyed:
2279
InfoLog (<< "Bad state: " << *this);
2285
InfoLog(<< "Transport failure on send, and failover is disabled.");
2286
processNoDnsResults();
2291
// called by DnsResult
2293
TransactionState::rewriteRequest(const Uri& rewrite)
2295
// !bwc! TODO We need to address the race-conditions caused by callbacks
2296
// into a class whose thread-safety is accomplished through message-passing.
2297
// This function could very easily be called while other processing is
2298
// taking place due to a message from the state-machine fifo. In the end, I
2299
// imagine that we will need to have the callback place a message onto the
2300
// queue, and move all the code below into a function that handles that
2303
assert(mNextTransmission->isRequest());
2304
if (mNextTransmission->const_header(h_RequestLine).uri() != rewrite)
2306
InfoLog (<< "Rewriting request-uri to " << rewrite);
2307
mNextTransmission->header(h_RequestLine).uri() = rewrite;
2308
// !bwc! Changing mNextTransmission invalidates mMsgToRetransmit.
2309
mMsgToRetransmit.clear();
2314
TransactionState::handle(DnsResult* result)
2316
// ?bwc? Maybe optmize this to use handleSync() directly when running in
2317
// single-threaded mode?
2318
DnsResultMessage* dns = new DnsResultMessage(mId,isClient());
2319
mController.mStateMacFifo.add(static_cast<TransactionMessage*>(dns));
2323
TransactionState::handleSync(DnsResult* result)
2325
StackLog (<< *this << " got DNS result: " << *result);
2327
// .bwc. Were we expecting something from mDnsResult?
2328
if (mWaitingForDnsResult)
2331
switch (mDnsResult->available())
2333
case DnsResult::Available:
2334
mWaitingForDnsResult=false;
2335
mTarget = mDnsResult->next();
2336
assert( mTarget.transport==0 );
2337
// below allows TU to which transport we send on
2338
// (The Via mechanism for setting transport doesn't work for TLS)
2339
mTarget.transport = mNextTransmission->getDestination().transport;
2340
processReliability(mTarget.getType());
2341
sendCurrentToWire();
2344
case DnsResult::Finished:
2345
mWaitingForDnsResult=false;
2346
processNoDnsResults();
2349
case DnsResult::Pending:
2352
case DnsResult::Destroyed:
2361
TransactionState::processReliability(TransportType type)
2369
mIsReliable = false;
2370
StackLog (<< "Unreliable transport: " << *this);
2373
case ClientNonInvite:
2374
mController.mTimers.add(Timer::TimerE1, mId, Timer::T1 );
2378
mController.mTimers.add(Timer::TimerA, mId, Timer::T1 );
2396
// !ah! only used one place, so leaving it here instead of making a helper.
2397
// !ah! broken out for clarity -- only used for forceTargets.
2398
// Expects that host portion is IP address notation.
2401
simpleTupleForUri(const Uri& uri)
2403
const Data& host = uri.host();
2404
int port = uri.port();
2406
resip::TransportType transport = UNKNOWN_TRANSPORT;
2408
if (uri.exists(p_transport))
2410
transport = Tuple::toTransport(uri.param(p_transport));
2413
if (transport == UNKNOWN_TRANSPORT)
2422
port = Symbols::DefaultSipsPort;
2427
port = Symbols::DefaultSipPort;
2434
return Tuple(host,port,transport);
2438
TransactionState::sendCurrentToWire()
2440
if(!mMsgToRetransmit.empty())
2442
if(mController.mStack.statisticsManagerEnabled())
2444
mController.mStatsManager.retransmitted(mCurrentMethodType,
2446
mCurrentResponseCode);
2449
mController.mTransportSelector.retransmit(mMsgToRetransmit);
2451
else if(mNextTransmission) // initial transmission; need to determine target
2453
SipMessage* sip=mNextTransmission;
2454
bool transmitted=false;
2458
if(mTarget.getType() != UNKNOWN_TRANSPORT) // mTarget is set, so just send.
2460
transmitted=mController.mTransportSelector.transmit(
2463
mIsReliable ? 0 : &mMsgToRetransmit);
2465
else // mTarget isn't set...
2467
if (sip->getDestination().mFlowKey) //...but sip->getDestination() will work
2469
// ?bwc? Maybe we should be nice to the TU and do DNS in this case?
2470
assert(sip->getDestination().getType() != UNKNOWN_TRANSPORT);
2472
// .bwc. We have the FlowKey. This completely specifies our
2473
// Transport (and Connection, if applicable). No DNS required.
2474
DebugLog(<< "Sending to tuple: " << sip->getDestination());
2475
mTarget = sip->getDestination();
2476
processReliability(mTarget.getType());
2477
transmitted=mController.mTransportSelector.transmit(
2480
mIsReliable ? 0 : &mMsgToRetransmit);
2482
else // ...so DNS is required...
2484
if(mDnsResult == 0) // ... and we haven't started a DNS query yet.
2486
StackLog (<< "sendToWire with no dns result: " << *this);
2487
assert(sip->isRequest());
2488
assert(mMethod!=CANCEL); // .bwc. mTarget should be set in this case.
2489
mDnsResult = mController.mTransportSelector.createDnsResult(this);
2490
mWaitingForDnsResult=true;
2491
mController.mTransportSelector.dnsResolve(mDnsResult, sip);
2493
else // ... but our DNS query isn't done yet.
2495
// .bwc. While the resolver was attempting to find a target, another
2496
// request came down from the TU. This could be a bug in the TU, or
2497
// could be a retransmission of an ACK/200. Either way, we cannot
2498
// expect to ever be able to send this request (nowhere to store it
2500
// ?bwc? Higher log-level?
2501
DebugLog(<< "Received a second request from the TU for a transaction"
2502
" that already existed, before the DNS subsystem was done "
2503
"resolving the target for the first request. Either the TU"
2504
" has messed up, or it is retransmitting ACK/200 (the only"
2505
" valid case for this to happen)");
2510
else // server transaction
2512
assert(mDnsResult == 0);
2513
assert(sip->exists(h_Vias));
2514
assert(!sip->const_header(h_Vias).empty());
2516
// .bwc. Code that tweaks mResponseTarget based on stuff in the SipMessage.
2518
if (sip->hasForceTarget())
2520
// ?bwc? Override the target for a single response? Should we even
2521
// allow this? What about client transactions? Should we overwrite
2522
// mResponseTarget here? I don't think this has been thought out properly.
2523
Tuple target = simpleTupleForUri(sip->getForceTarget());
2524
StackLog(<<"!ah! response with force target going to : "<<target);
2525
transmitted=mController.mTransportSelector.transmit(
2528
mIsReliable ? 0 : &mMsgToRetransmit);
2532
if (sip->const_header(h_Vias).front().exists(p_rport) && sip->const_header(h_Vias).front().param(p_rport).hasValue())
2534
// ?bwc? This was not setting the port in mResponseTarget before. Why would
2535
// the rport be different than the port in mResponseTarget? Didn't we
2536
// already set this? Maybe the TU messed with it? If so, why should we pay
2537
// attention to it? Again, this hasn't been thought out.
2538
mResponseTarget.setPort(sip->const_header(h_Vias).front().param(p_rport).port());
2539
StackLog(<< "rport present in response: " << mResponseTarget.getPort());
2542
StackLog(<< "tid=" << sip->getTransactionId() << " sending to : " << mResponseTarget);
2543
transmitted=mController.mTransportSelector.transmit(
2546
mIsReliable ? 0 : &mMsgToRetransmit);
2550
// !bwc! If we don't have DNS results yet, or TransportSelector::transmit
2551
// fails, we hang on to the full original SipMessage, in the hope that
2552
// next time it works.
2555
if(mController.mStack.statisticsManagerEnabled())
2557
mController.mStatsManager.sent(sip);
2560
mCurrentMethodType = sip->method();
2561
if(sip->isResponse())
2563
mCurrentResponseCode = sip->const_header(h_StatusLine).statusCode();
2566
// !bwc! If mNextTransmission is a non-ACK request, we need to save the
2567
// initial request in case we need to send a simulated 408 or a 503 to
2568
// the TU (at least, until we get a response back)
2569
if(!mNextTransmission->isRequest() || mNextTransmission->method()==ACK)
2571
delete mNextTransmission;
2572
mNextTransmission=0;
2583
TransactionState::sendToTU(TransactionMessage* msg)
2585
SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg);
2586
if (sipMsg && sipMsg->isResponse() && mDnsResult)
2588
// whitelisting rules.
2589
switch (sipMsg->const_header(h_StatusLine).statusCode())
2592
// blacklist last target.
2593
// .bwc. If there is no Retry-After, we do not blacklist
2594
// (see RFC 3261 sec 21.5.4 para 1)
2595
if(sipMsg->exists(resip::h_RetryAfter) &&
2596
sipMsg->const_header(resip::h_RetryAfter).isWellFormed())
2598
unsigned int relativeExpiry= sipMsg->const_header(resip::h_RetryAfter).value();
2600
if(relativeExpiry!=0)
2602
mDnsResult->blacklistLast(resip::Timer::getTimeMs()+relativeExpiry*1000);
2608
if(sipMsg->getReceivedTransport() == 0 &&
2609
(mState == Trying || mState==Calling)) // only greylist if internally generated and we haven't received any responses yet
2611
// greylist last target.
2612
// ?bwc? How long do we greylist this for? Probably should make
2613
// this configurable. TODO
2614
mDnsResult->greylistLast(resip::Timer::getTimeMs() + 32000);
2620
mDnsResult->whitelistLast();
2625
CongestionManager::RejectionBehavior behavior=CongestionManager::NORMAL;
2626
behavior=mController.mTuSelector.getRejectionBehavior(mTransactionUser);
2628
if(behavior!=CongestionManager::NORMAL)
2632
assert(sipMsg->isExternal());
2633
if(sipMsg->isRequest())
2635
// .bwc. This could be an initial request, or an ACK/200.
2636
if(sipMsg->method()==ACK)
2638
// ACK/200 is a continuation of old work. We only reject if
2639
// we're really hosed.
2640
if(behavior==CongestionManager::REJECTING_NON_ESSENTIAL)
2648
// .bwc. This is new work. Reject.
2649
SipMessage* response(Helper::makeResponse(*sipMsg, 503));
2652
UInt16 retryAfter=mController.mTuSelector.getExpectedWait(mTransactionUser);
2653
response->header(h_RetryAfter).value()=retryAfter;
2654
response->setFromTU();
2657
processServerInvite(response);
2661
processServerNonInvite(response);
2668
// .bwc. This could be a response from the wire, or an internally
2669
// generated pseudo-response. This is always a continuation of
2671
if(behavior==CongestionManager::REJECTING_NON_ESSENTIAL &&
2673
!mTransactionUser->responsesMandatory())
2682
// .bwc. This is some sort of timer, or other message. If we don't know
2683
// any better, we need to assume this is essential for the safe
2684
// operation of the TU.
2688
TransactionState::sendToTU(mTransactionUser, mController, msg);
2692
TransactionState::sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg)
2694
msg->setTransactionUser(tu);
2695
controller.mTuSelector.add(msg, TimeLimitFifo<Message>::InternalElement);
2699
TransactionState::make100(SipMessage* request) const
2701
return (Helper::makeResponse(*request, 100));
2705
TransactionState::add(const Data& tid)
2709
mController.mClientTransactionMap.add(tid, this);
2713
mController.mServerTransactionMap.add(tid, this);
2718
TransactionState::erase(const Data& tid)
2722
mController.mClientTransactionMap.erase(tid);
2726
mController.mServerTransactionMap.erase(tid);
2731
TransactionState::isRequest(TransactionMessage* msg) const
2733
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2734
return sip && sip->isRequest();
2738
TransactionState::isInvite(TransactionMessage* msg) const
2742
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2743
return (sip->method()) == INVITE;
2749
TransactionState::isResponse(TransactionMessage* msg, int lower, int upper) const
2751
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2752
if (sip && sip->isResponse())
2754
int c = sip->const_header(h_StatusLine).responseCode();
2755
return (c >= lower && c <= upper);
2761
TransactionState::isTimer(TransactionMessage* msg) const
2763
return dynamic_cast<TimerMessage*>(msg) != 0;
2767
TransactionState::isFromTU(TransactionMessage* msg) const
2769
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2770
return sip && !sip->isExternal();
2774
TransactionState::isFromWire(TransactionMessage* msg) const
2776
SipMessage* sip = dynamic_cast<SipMessage*>(msg);
2777
return sip && sip->isExternal();
2781
TransactionState::isTransportError(TransactionMessage* msg) const
2783
return dynamic_cast<TransportFailure*>(msg) != 0;
2787
TransactionState::isAbandonServerTransaction(TransactionMessage* msg) const
2789
return dynamic_cast<AbandonServerTransaction*>(msg) != 0;
2793
TransactionState::isCancelClientTransaction(TransactionMessage* msg) const
2795
return dynamic_cast<CancelClientInviteTransaction*>(msg) != 0;
2800
TransactionState::tid(SipMessage* sip) const
2803
assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty()));
2804
assert (mMachine == Stateless || (mMachine != Stateless && sip));
2805
return (mId.empty() && sip) ? sip->getTransactionId() : mId;
2809
TransactionState::terminateClientTransaction(const Data& tid)
2811
mState = Terminated;
2812
if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) &&
2813
mTransactionUser->isRegisteredForTransactionTermination())
2815
//StackLog (<< "Terminate client transaction " << tid);
2816
sendToTU(new TransactionTerminated(tid, true, mTransactionUser));
2821
TransactionState::terminateServerTransaction(const Data& tid)
2823
mState = Terminated;
2824
if (mController.mTuSelector.isTransactionUserStillRegistered(mTransactionUser) &&
2825
mTransactionUser->isRegisteredForTransactionTermination())
2827
//StackLog (<< "Terminate server transaction " << tid);
2828
sendToTU(new TransactionTerminated(tid, false, mTransactionUser));
2833
TransactionState::isClient() const
2837
case ClientNonInvite:
2842
case ServerNonInvite:
2853
resip::operator<<(EncodeStream& strm, const resip::TransactionState& state)
2855
strm << "tid=" << state.mId << " [ ";
2856
switch (state.mMachine)
2858
case TransactionState::ClientNonInvite:
2859
strm << "ClientNonInvite";
2861
case TransactionState::ClientInvite:
2862
strm << "ClientInvite";
2864
case TransactionState::ServerNonInvite:
2865
strm << "ServerNonInvite";
2867
case TransactionState::ServerInvite:
2868
strm << "ServerInvite";
2870
case TransactionState::Stateless:
2871
strm << "Stateless";
2873
case TransactionState::ClientStale:
2874
strm << "ClientStale";
2876
case TransactionState::ServerStale:
2877
strm << "ServerStale";
2882
switch (state.mState)
2884
case TransactionState::Calling:
2887
case TransactionState::Trying:
2890
case TransactionState::Proceeding:
2891
strm << "Proceeding";
2893
case TransactionState::Completed:
2894
strm << "Completed";
2896
case TransactionState::Confirmed:
2897
strm << "Confirmed";
2899
case TransactionState::Terminated:
2900
strm << "Terminated";
2902
case TransactionState::Bogus:
2907
strm << (state.mIsReliable ? " reliable" : " unreliable");
2908
strm << " target=" << state.mResponseTarget;
2909
//if (state.mTransactionUser) strm << " tu=" << *state.mTransactionUser;
2910
//else strm << "default TU";
2916
/* Local Variables: */
2917
/* c-file-style: "ellemtel" */
2920
/* ====================================================================
2921
* The Vovida Software License, Version 1.0
2923
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
2925
* Redistribution and use in source and binary forms, with or without
2926
* modification, are permitted provided that the following conditions
2929
* 1. Redistributions of source code must retain the above copyright
2930
* notice, this list of conditions and the following disclaimer.
2932
* 2. Redistributions in binary form must reproduce the above copyright
2933
* notice, this list of conditions and the following disclaimer in
2934
* the documentation and/or other materials provided with the
2937
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
2938
* and "Vovida Open Communication Application Library (VOCAL)" must
2939
* not be used to endorse or promote products derived from this
2940
* software without prior written permission. For written
2941
* permission, please contact vocal@vovida.org.
2943
* 4. Products derived from this software may not be called "VOCAL", nor
2944
* may "VOCAL" appear in their name, without prior written
2945
* permission of Vovida Networks, Inc.
2947
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
2948
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2949
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
2950
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
2951
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
2952
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
2953
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2954
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2955
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2956
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2957
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
2958
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2961
* ====================================================================
2963
* This software consists of voluntary contributions made by Vovida
2964
* Networks, Inc. and many individuals on behalf of Vovida Networks,
2965
* Inc. For more information on Vovida Networks, Inc., please see
2966
* <http://www.vovida.org/>.
2968
* vi: set shiftwidth=3 expandtab: