/[resiprocate]/main/sip/resiprocate/TransactionState.cxx
ViewVC logotype

Contents of /main/sip/resiprocate/TransactionState.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4740 - (show annotations) (download)
Tue May 24 21:30:57 2005 UTC (14 years, 6 months ago) by daniel
File size: 58419 byte(s)
AresDns.hxx/cxx: Redefined lookup and ares callback methonds.
DnsInterface.hxx/cxx: Added dns caching support and  methods to (un)register blacklist listener.
DnsResult.hxx/cxx: Modified to use dns caching, blacklisting, and vip; removed dead code.
Makefile: Added dns cache related files.
Security.hxx/cxx: correctly handle default paths in the constructor
SipStack.hxx/cxx: Added blacklist listener registration and unregistration.
StatelessHandler.cxx: Got it to compile with USE_IPV6 defined.
TlsConnection.cxx: Make logging less verbose.
TransactionController.hxx/cxx: Added blacklist listener registration and unregistration.
TransactionState.cxx: Added whitelisting(vip) rules.
TransportSelector.hxx/cxx: Added blacklist listener registration and unregistration; refactor and clarify for IPv6
WinSecurity.hxx/cxx: since certificates are preloaded, don't query the filesystem cert store.
dum/ClientAuthManager.cxx: changed DebugLog to InfoLog in handle method.
dum/DialogUsageManager.cxx: changed DebugLog to InfoLog in internalProcess method.
dum/test/BasicCall.cxx: added keep-alive test case.
dum/test/basicRegister.cxx: updated commandline options and simplified for TLS/IPv6.
dum/test/testIdentity.cxx: added test for identity over TLS/IPv6.
external/ExternalDns.hxx: redefined ExternalDnsHandler and lookup methods in ExternalDns class.
os/Tuple.cxx: fix constructor to copy complete IPv6 address.
os/WinCompat.hxx/cxx: add support to determine local IPv6 address; now only used on Windows platform.
os/compat.hxx: added define for T_A.
1 #if defined(HAVE_CONFIG_H)
2 #include "resiprocate/config.hxx"
3 #endif
4
5 #include "resiprocate/DnsInterface.hxx"
6 #include "resiprocate/DnsResult.hxx"
7 #include "resiprocate/Helper.hxx"
8 #include "resiprocate/MethodTypes.hxx"
9 #include "resiprocate/SipMessage.hxx"
10 #include "resiprocate/SipStack.hxx"
11 #include "resiprocate/StatisticsManager.hxx"
12 #include "resiprocate/TimerMessage.hxx"
13 #include "resiprocate/TransactionController.hxx"
14 #include "resiprocate/TransactionMessage.hxx"
15 #include "resiprocate/TransactionState.hxx"
16 #include "resiprocate/TransactionTerminated.hxx"
17 #include "resiprocate/TransportMessage.hxx"
18 #include "resiprocate/TransactionUserMessage.hxx"
19 #include "resiprocate/TransportSelector.hxx"
20 #include "resiprocate/TransactionUser.hxx"
21 #include "resiprocate/os/DnsUtil.hxx"
22 #include "resiprocate/os/Logger.hxx"
23 #include "resiprocate/os/MD5Stream.hxx"
24 #include "resiprocate/os/Socket.hxx"
25 #include "resiprocate/os/Random.hxx"
26 #include "resiprocate/os/WinLeakCheck.hxx"
27 #include "resiprocate/KeepAliveMessage.hxx"
28
29 using namespace resip;
30
31 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION
32
33 TransactionState::TransactionState(TransactionController& controller, Machine m,
34 State s, const Data& id, TransactionUser* tu) :
35 mController(controller),
36 mMachine(m),
37 mState(s),
38 mIsCancel(false),
39 mIsReliable(true), // !jf!
40 mMsgToRetransmit(0),
41 mDnsResult(0),
42 mId(id),
43 mTransactionUser(tu)
44 {
45 StackLog (<< "Creating new TransactionState: " << *this);
46 }
47
48
49 TransactionState*
50 TransactionState::makeCancelTransaction(TransactionState* tr, Machine machine, const Data& tid)
51 {
52 TransactionState* cancel = new TransactionState(tr->mController, machine, Trying,
53 tid, tr->mTransactionUser);
54 // !jf! don't set this since it will be set by TransactionState::processReliability()
55 //cancel->mIsReliable = tr->mIsReliable;
56 cancel->mResponseTarget = tr->mResponseTarget;
57 cancel->mIsCancel = true;
58 cancel->mTarget = tr->mTarget;
59 cancel->add(tid);
60
61 // !jf! don't call processServerNonInvite since it will delete
62 // the sip message which needs to get sent to the TU
63 cancel->processReliability(tr->mTarget.getType());
64 return cancel;
65 }
66
67 TransactionState::~TransactionState()
68 {
69 assert(mState != Bogus);
70
71 if (mDnsResult)
72 {
73 mDnsResult->destroy();
74 }
75
76 //StackLog (<< "Deleting TransactionState " << mId << " : " << this);
77 erase(mId);
78
79 delete mMsgToRetransmit;
80 mMsgToRetransmit = 0;
81
82 mState = Bogus;
83 }
84
85 void
86 TransactionState::process(TransactionController& controller)
87 {
88 TransactionMessage* message = controller.mStateMacFifo.getNext();
89 {
90 KeepAliveMessage* keepAlive = dynamic_cast<KeepAliveMessage*>(message);
91 if (keepAlive)
92 {
93 InfoLog ( << "Sending keep alive to: " << keepAlive->getDestination());
94 controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination());
95 delete keepAlive;
96 return;
97 }
98 }
99
100 SipMessage* sip = dynamic_cast<SipMessage*>(message);
101
102 RESIP_STATISTICS(sip && sip->isExternal() && controller.mStatsManager.received(sip));
103
104 // !jf! this is a first cut at elementary back pressure. hope it works :)
105 if (sip && sip->isExternal() && sip->isRequest() &&
106 sip->header(h_RequestLine).getMethod() != ACK &&
107 controller.isTUOverloaded())
108 {
109 SipMessage* tryLater = Helper::makeResponse(*sip, 503);
110 tryLater->header(h_RetryAfter).value() = 32 + (Random::getRandom() % 32);
111 tryLater->header(h_RetryAfter).comment() = "Server busy TRANS";
112 Tuple target(sip->getSource());
113 delete sip;
114 controller.mTransportSelector.transmit(tryLater, target);
115 return;
116 }
117
118 if (sip && sip->isExternal() && sip->header(h_Vias).empty())
119 {
120 InfoLog(<< "TransactionState::process dropping message with no Via: " << sip->brief());
121 delete sip;
122 return;
123 }
124
125 Data tid = message->getTransactionId();
126
127 // This ensures that CANCEL requests form unique transactions
128 if (sip && sip->header(h_CSeq).method() == CANCEL)
129 {
130 tid += "cancel";
131 }
132
133 TransactionState* state = 0;
134 if (message->isClientTransaction()) state = controller.mClientTransactionMap.find(tid);
135 else state = controller.mServerTransactionMap.find(tid);
136
137 // this code makes sure that an ACK to a 200 is going to create a new
138 // stateless transaction. In an ACK to a failure response, the mToTag will
139 // have been set in the ServerTransaction as the 4xx passes through so it
140 // will match.
141 if (state && sip && sip->isRequest() && sip->header(h_RequestLine).getMethod() == ACK)
142 {
143 if (sip->header(h_To).exists(p_tag) && sip->header(h_To).param(p_tag) != state->mToTag)
144 {
145 // Must have received an ACK to a 200;
146 tid += "ack";
147 if (message->isClientTransaction()) state = controller.mClientTransactionMap.find(tid);
148 else state = controller.mServerTransactionMap.find(tid);
149 // will be sent statelessly, if from TU
150 }
151 }
152
153 if (state) // found transaction for sip msg
154 {
155 StackLog (<< "Found matching transaction for " << message->brief() << " -> " << *state);
156
157 switch (state->mMachine)
158 {
159 case ClientNonInvite:
160 state->processClientNonInvite(message);
161 break;
162 case ClientInvite:
163 // ACK from TU will be Stateless
164 assert (!(state->isFromTU(sip) && sip->isRequest() && sip->header(h_RequestLine).getMethod() == ACK));
165 state->processClientInvite(message);
166 break;
167 case ServerNonInvite:
168 state->processServerNonInvite(message);
169 break;
170 case ServerInvite:
171 state->processServerInvite(message);
172 break;
173 case Stateless:
174 state->processStateless(message);
175 break;
176 case ClientStale:
177 state->processClientStale(message);
178 break;
179 case ServerStale:
180 state->processServerStale(message);
181 break;
182 default:
183 CritLog(<<"internal state error");
184 assert(0);
185 return;
186 }
187 }
188 else if (sip) // new transaction
189 {
190 StackLog (<< "No matching transaction for " << sip->brief());
191 TransactionUser* tu = 0;
192 if (sip->isExternal())
193 {
194 if (controller.mTuSelector.haveTransactionUsers() && sip->isRequest())
195 {
196 tu = controller.mTuSelector.selectTransactionUser(*sip);
197 if (!tu)
198 {
199 //InfoLog (<< "Didn't find a TU for " << sip->brief());
200
201 InfoLog( << "No TU found for message: " << sip->brief());
202 SipMessage* noMatch = Helper::makeResponse(*sip, 500);
203 Tuple target(sip->getSource());
204 delete sip;
205 controller.mTransportSelector.transmit(noMatch, target);
206 return;
207 }
208 else
209 {
210 //InfoLog (<< "Found TU for " << sip->brief());
211 }
212 }
213 }
214 else
215 {
216 tu = sip->getTransactionUser();
217 if (!tu)
218 {
219 //InfoLog (<< "No TU associated with " << sip->brief());
220 }
221 }
222
223 if (sip->isRequest())
224 {
225 // create a new state object and insert in the TransactionMap
226
227 if (sip->isExternal()) // new sip msg from transport
228 {
229 if (sip->header(h_RequestLine).getMethod() == INVITE)
230 {
231 // !rk! This might be needlessly created. Design issue.
232 TransactionState* state = new TransactionState(controller, ServerInvite, Trying, tid, tu);
233 state->mMsgToRetransmit = state->make100(sip);
234 state->mResponseTarget = sip->getSource(); // UACs source address
235 // since we don't want to reply to the source port unless rport present
236 state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
237 state->mState = Proceeding;
238 state->mIsReliable = state->mResponseTarget.transport->isReliable();
239 state->add(tid);
240
241 if (Timer::T100 == 0)
242 {
243 state->sendToWire(state->mMsgToRetransmit); // will get deleted when this is deleted
244 }
245 else
246 {
247 //StackLog(<<" adding T100 timer (INV)");
248 controller.mTimers.add(Timer::TimerTrying, tid, Timer::T100);
249 }
250 }
251 else if (sip->header(h_RequestLine).getMethod() == CANCEL)
252 {
253 TransactionState* matchingInvite =
254 controller.mServerTransactionMap.find(sip->getTransactionId());
255 if (matchingInvite == 0)
256 {
257 InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas");
258 TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 481));
259 delete sip;
260 return;
261 }
262 else
263 {
264 assert(matchingInvite);
265 state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid);
266 }
267 }
268 else if (sip->header(h_RequestLine).getMethod() != ACK)
269 {
270 TransactionState* state = new TransactionState(controller, ServerNonInvite,Trying, tid, tu);
271 state->mResponseTarget = sip->getSource();
272 // since we don't want to reply to the source port unless rport present
273 state->mResponseTarget.setPort(Helper::getPortForReply(*sip));
274 state->add(tid);
275 state->mIsReliable = state->mResponseTarget.transport->isReliable();
276 }
277
278
279 // Incoming ACK just gets passed to the TU
280 //StackLog(<< "Adding incoming message to TU fifo " << tid);
281 TransactionState::sendToTU(tu, controller, sip);
282 }
283 else // new sip msg from the TU
284 {
285 if (sip->header(h_RequestLine).getMethod() == INVITE)
286 {
287 TransactionState* state = new TransactionState(controller, ClientInvite, Calling, tid, tu);
288 state->add(state->mId);
289 state->processClientInvite(sip);
290 }
291 else if (sip->header(h_RequestLine).getMethod() == ACK)
292 {
293 //TransactionState* state = new TransactionState(controller, Stateless, Calling, Data(controller.StatelessIdCounter++));
294 TransactionState* state = new TransactionState(controller, Stateless, Calling, tid, tu);
295 state->add(state->mId);
296 state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
297 state->processStateless(sip);
298 }
299 else if (sip->header(h_RequestLine).getMethod() == CANCEL)
300 {
301 TransactionState* matchingInvite = controller.mClientTransactionMap.find(sip->getTransactionId());
302 if (matchingInvite == 0)
303 {
304 InfoLog (<< "No matching INVITE for incoming (from TU) CANCEL to uac");
305 TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip,481));
306 delete sip;
307 }
308 else if (matchingInvite->mState == Calling) // CANCEL before 1xx received
309 {
310 WarningLog(<< "You can't CANCEL a request until a provisional has been received");
311 StackLog (<< *matchingInvite);
312 StackLog (<< *sip);
313
314 // if no INVITE had been sent out yet. -- i.e. dns result not
315 // processed yet
316
317 // The CANCEL was received before the INVITE was sent
318 // This can happen in odd cases. Too common to assert.
319 // Be graceful.
320 TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 200));
321 matchingInvite->sendToTU(Helper::makeResponse(*matchingInvite->mMsgToRetransmit, 487));
322
323 delete matchingInvite;
324 delete sip;
325
326 }
327 else if (matchingInvite->mState == Completed)
328 {
329 // A final response was already seen for this INVITE transaction
330 matchingInvite->sendToTU(Helper::makeResponse(*sip, 200));
331 delete sip;
332 }
333 else
334 {
335 assert(matchingInvite);
336 state = TransactionState::makeCancelTransaction(matchingInvite, ClientNonInvite, tid);
337 state->processReliability(matchingInvite->mTarget.getType());
338 state->processClientNonInvite(sip);
339
340 // for the INVITE in case we never get a 487
341 matchingInvite->mController.mTimers.add(Timer::TimerCleanUp, sip->getTransactionId(), 128*Timer::T1);
342 }
343 }
344 else
345 {
346 TransactionState* state = new TransactionState(controller, ClientNonInvite,
347 Trying, tid, tu);
348 state->add(tid);
349 state->processClientNonInvite(sip);
350 }
351 }
352 }
353 else if (sip->isResponse()) // stray response
354 {
355 if (controller.mDiscardStrayResponses)
356 {
357 InfoLog (<< "discarding stray response: " << sip->brief());
358 delete message;
359 }
360 else
361 {
362 StackLog (<< "forwarding stateless response: " << sip->brief());
363 TransactionState* state =
364 new TransactionState(controller, Stateless, Calling,
365 Data(controller.StatelessIdCounter++), tu);
366 state->add(state->mId);
367 state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );
368 state->processStateless(sip);
369 }
370 }
371 else // wasn't a request or a response
372 {
373 //StackLog (<< "discarding unknown message: " << sip->brief());
374 }
375 }
376 else // timer or other non-sip msg
377 {
378 //StackLog (<< "discarding non-sip message: " << message->brief());
379 delete message;
380 }
381 }
382
383
384 void
385 TransactionState::processStateless(TransactionMessage* message)
386 {
387 // for ACK messages from the TU, there is no transaction, send it directly
388 // to the wire // rfc3261 17.1 Client Transaction
389 SipMessage* sip = dynamic_cast<SipMessage*>(message);
390 StackLog (<< "TransactionState::processStateless: " << message->brief());
391
392 // !jf! There is a leak for Stateless transactions associated with ACK to 200
393 if (isFromTU(message))
394 {
395 delete mMsgToRetransmit;
396 mMsgToRetransmit = sip;
397 sendToWire(sip);
398 }
399 else if (isFromWire(message))
400 {
401 InfoLog (<< "Received message from wire on a stateless transaction");
402 StackLog (<< *message);
403 //assert(0);
404 sendToTU(sip);
405 }
406 else if (isTransportError(message))
407 {
408 processTransportFailure();
409
410 delete message;
411 delete this;
412 }
413 else if (isTimer(message))
414 {
415 TimerMessage* timer = dynamic_cast<TimerMessage*>(message);
416 if (timer->getType() == Timer::TimerStateless)
417 {
418 delete message;
419 delete this;
420 }
421 }
422 else
423 {
424 assert(0);
425 }
426 }
427
428 void
429 TransactionState::processClientNonInvite(TransactionMessage* msg)
430 {
431 StackLog (<< "TransactionState::processClientNonInvite: " << msg->brief());
432
433 assert(!isInvite(msg));
434
435 if (isRequest(msg) && isFromTU(msg))
436 {
437 //StackLog (<< "received new non-invite request");
438 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
439 delete mMsgToRetransmit;
440 mMsgToRetransmit = sip;
441 mController.mTimers.add(Timer::TimerF, mId, Timer::TF);
442 sendToWire(sip); // don't delete
443 }
444 else if (isResponse(msg) && isFromWire(msg)) // from the wire
445 {
446 //StackLog (<< "received response from wire");
447
448 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
449 int code = sip->header(h_StatusLine).responseCode();
450 if (code >= 100 && code < 200) // 1XX
451 {
452 if (mState == Trying || mState == Proceeding)
453 {
454 //!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
455 // 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.
456 if (!mIsReliable && mState == Trying)
457 {
458 mController.mTimers.add(Timer::TimerE2, mId, Timer::T2 );
459 }
460 mState = Proceeding;
461 sendToTU(msg); // don't delete
462 }
463 else
464 {
465 // ignore
466 delete msg;
467 }
468 }
469 else if (code >= 200)
470 {
471 // don't notify the TU of retransmissions
472 if (mState == Trying || mState == Proceeding)
473 {
474 sendToTU(msg); // don't delete
475 }
476 else if (mState == Completed)
477 {
478 delete msg;
479 }
480
481 if (mIsReliable)
482 {
483 terminateClientTransaction(mId);
484 delete this;
485 }
486 else if (mState != Completed) // prevent TimerK reproduced
487 {
488 mState = Completed;
489 mController.mTimers.add(Timer::TimerK, mId, Timer::T4 );
490 }
491 }
492 }
493 else if (isTimer(msg))
494 {
495 //StackLog (<< "received timer in client non-invite transaction");
496
497 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
498 switch (timer->getType())
499 {
500 case Timer::TimerE1:
501 if (mState == Trying)
502 {
503 unsigned long d = timer->getDuration();
504 if (d < Timer::T2) d *= 2;
505 mController.mTimers.add(Timer::TimerE1, mId, d);
506 StackLog (<< "Retransmitting: " << mMsgToRetransmit->brief());
507 sendToWire(mMsgToRetransmit, true);
508 delete msg;
509 }
510 else
511 {
512 // ignore
513 delete msg;
514 }
515 break;
516
517 case Timer::TimerE2:
518 if (mState == Proceeding)
519 {
520 mController.mTimers.add(Timer::TimerE2, mId, Timer::T2);
521 StackLog (<< "Retransmitting: " << mMsgToRetransmit->brief());
522 sendToWire(mMsgToRetransmit, true);
523 delete msg;
524 }
525 else
526 {
527 // ignore
528 delete msg;
529 }
530 break;
531
532 case Timer::TimerF:
533 if (mState == Trying || mState == Proceeding)
534 {
535 sendToTU(Helper::makeResponse(*mMsgToRetransmit, 408));
536 terminateClientTransaction(mId);
537 delete this;
538 }
539
540 delete msg;
541 break;
542
543 case Timer::TimerK:
544 terminateClientTransaction(mId);
545 delete msg;
546 delete this;
547 break;
548
549 default:
550 //InfoLog (<< "Ignoring timer: " << *msg);
551 delete msg;
552 break;
553 }
554 }
555 else if (isTransportError(msg))
556 {
557 processTransportFailure();
558 delete msg;
559 }
560 else
561 {
562 //StackLog (<< "TransactionState::processClientNonInvite: message unhandled");
563 delete msg;
564 }
565 }
566
567 void
568 TransactionState::processClientInvite(TransactionMessage* msg)
569 {
570 StackLog(<< "TransactionState::processClientInvite: " << msg->brief() << " " << *this);
571 if (isRequest(msg) && isFromTU(msg))
572 {
573 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
574 switch (sip->header(h_RequestLine).getMethod())
575 {
576 // Received INVITE request from TU="Transaction User", Start Timer B which controls
577 // transaction timeouts.
578 case INVITE:
579 delete mMsgToRetransmit;
580 mMsgToRetransmit = sip;
581 mController.mTimers.add(Timer::TimerB, mId, Timer::TB );
582 sendToWire(msg); // don't delete msg
583 break;
584
585 case CANCEL:
586 assert(0);
587 break;
588
589 default:
590 delete msg;
591 break;
592 }
593 }
594 else if (isResponse(msg) && isFromWire(msg))
595 {
596 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
597 int code = sip->header(h_StatusLine).responseCode();
598 switch (sip->header(h_CSeq).method())
599 {
600 case INVITE:
601 /* If the client transaction receives a provisional response while in
602 the "Calling" state, it transitions to the "Proceeding" state. In the
603 "Proceeding" state, the client transaction SHOULD NOT retransmit the
604 request any longer (this will be Handled in "else if (isTimer(msg))")
605 The Retransmissions will be stopped, Not by Cancelling Timers but
606 by Ignoring the fired Timers depending upon the State which stack is in.
607 */
608 if (code >= 100 && code < 200) // 1XX
609 {
610 if (mState == Calling || mState == Proceeding)
611 {
612 mState = Proceeding;
613 sendToTU(sip); // don't delete msg
614 }
615 else
616 {
617 delete msg;
618 }
619 }
620
621 /* When in either the "Calling" or "Proceeding" states, reception of a
622 2xx response MUST cause the client transaction to enter the
623 "Terminated" state, and the response MUST be passed up to the TU
624 State Machine is changed to Stale since, we wanted to ensure that
625 all 2xx gets to TU
626 */
627 else if (code >= 200 && code < 300)
628 {
629 sendToTU(sip); // don't delete msg
630 terminateClientTransaction(mId);
631 mMachine = ClientStale;
632 StackLog (<< "Received 2xx on client invite transaction");
633 StackLog (<< *this);
634 mController.mTimers.add(Timer::TimerStaleClient, mId, Timer::TS );
635 }
636 else if (code >= 300)
637 {
638 // When in either the "Calling" or "Proceeding" states, reception of a
639 // response with status code from 300-699 MUST cause the client
640 // transaction to transition to "Completed".
641 if (mIsReliable)
642 {
643 // Stack MUST pass the received response up to the TU, and the client
644 // transaction MUST generate an ACK request, even if the transport is
645 // reliable
646 SipMessage* invite = mMsgToRetransmit;
647 mMsgToRetransmit = Helper::makeFailureAck(*invite, *sip);
648 delete invite;
649
650 // want to use the same transport as was selected for Invite
651 assert(mTarget.getType() != UNKNOWN_TRANSPORT);
652
653 sendToWire(mMsgToRetransmit);
654 sendToTU(msg); // don't delete msg
655 terminateClientTransaction(mId);
656 delete this;
657 }
658 else
659 {
660 if (mState == Calling || mState == Proceeding)
661 {
662 // MUST pass the received response up to the TU, and the client
663 // transaction MUST generate an ACK request, even if the transport is
664 // reliable, if transport is Unreliable then Fire the Timer D which
665 // take care of re-Transmission of ACK
666 mState = Completed;
667 mController.mTimers.add(Timer::TimerD, mId, Timer::TD );
668 SipMessage* ack;
669 ack = Helper::makeFailureAck(*mMsgToRetransmit, *sip);
670 delete mMsgToRetransmit;
671 mMsgToRetransmit = ack;
672 sendToWire(ack);
673 sendToTU(msg); // don't delete msg
674 }
675 else if (mState == Completed)
676 {
677 // Any retransmissions of the final response that
678 // are received while in the "Completed" state MUST
679 // cause the ACK to be re-passed to the transport
680 // layer for retransmission.
681 assert (mMsgToRetransmit->header(h_RequestLine).getMethod() == ACK);
682 sendToWire(mMsgToRetransmit, true);
683 delete msg;
684 }
685 else
686 {
687 /* This should never Happen if it happens we should have a plan
688 what to do here?? for now assert will work
689 */
690 CritLog( << "State invalid");
691 // !ah! syslog
692 assert(0);
693 }
694 }
695 }
696 break;
697
698 case CANCEL:
699 assert(0);
700 break;
701
702 default:
703 delete msg;
704 break;
705 }
706 }
707 else if (isTimer(msg))
708 {
709 /* Handle Transaction Timers , Retransmission Timers which were set and Handle
710 Cancellation of Timers for Re-transmissions here */
711
712 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
713 StackLog (<< "timer fired: " << *timer);
714
715 switch (timer->getType())
716 {
717 case Timer::TimerA:
718 if (mState == Calling)
719 {
720 unsigned long d = timer->getDuration()*2;
721 //if (d < Timer::T2) d *= 2; !slg! TimerA is supposed to double with each retransmit RFC3261 17.1.1
722
723 mController.mTimers.add(Timer::TimerA, mId, d);
724 InfoLog (<< "Retransmitting INVITE: " << mMsgToRetransmit->brief());
725 sendToWire(mMsgToRetransmit, true);
726 }
727 delete msg;
728 break;
729
730 case Timer::TimerB:
731 if (mState == Calling)
732 {
733 sendToTU(Helper::makeResponse(*mMsgToRetransmit, 408));
734 terminateClientTransaction(mId);
735 delete this;
736 }
737 delete msg;
738 break;
739
740 case Timer::TimerD:
741 terminateClientTransaction(mId);
742 delete msg;
743 delete this;
744 break;
745
746 case Timer::TimerCleanUp:
747 // !ah! Cancelled Invite Cleanup Timer fired.
748 StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mMsgToRetransmit);
749 if (mState == Proceeding)
750 {
751 assert(mMsgToRetransmit && mMsgToRetransmit->header(h_RequestLine).getMethod() == INVITE);
752 InfoLog(<<"Making 408 for canceled invite that received no response: "<< mMsgToRetransmit->brief());
753 sendToTU(Helper::makeResponse(*mMsgToRetransmit, 408));
754 terminateClientTransaction(msg->getTransactionId());
755 delete this;
756 }
757 delete msg;
758 break;
759
760 default:
761 delete msg;
762 break;
763 }
764 }
765 else if (isTransportError(msg))
766 {
767 processTransportFailure();
768 delete msg;
769 }
770 else
771 {
772 //StackLog ( << "TransactionState::processClientInvite: message unhandled");
773 delete msg;
774 }
775 }
776
777
778 void
779 TransactionState::processServerNonInvite(TransactionMessage* msg)
780 {
781 StackLog (<< "TransactionState::processServerNonInvite: " << msg->brief());
782
783 if (isRequest(msg) && !isInvite(msg) && isFromWire(msg)) // from the wire
784 {
785 if (mState == Trying)
786 {
787 // ignore
788 delete msg;
789 }
790 else if (mState == Proceeding || mState == Completed)
791 {
792 sendToWire(mMsgToRetransmit, true);
793 delete msg;
794 }
795 else
796 {
797 CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
798 << msg->brief()
799 << " state=" << *this);
800 assert(0);
801 return;
802 }
803 }
804 else if (isResponse(msg) && isFromTU(msg))
805 {
806 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
807 int code = sip->header(h_StatusLine).responseCode();
808 if (code >= 100 && code < 200) // 1XX
809 {
810 if (mState == Trying || mState == Proceeding)
811 {
812 delete mMsgToRetransmit;
813 mMsgToRetransmit = sip;
814 mState = Proceeding;
815 sendToWire(sip); // don't delete msg
816 }
817 else
818 {
819 // ignore
820 delete msg;
821 }
822 }
823 else if (code >= 200 && code <= 699)
824 {
825 if (mIsReliable)
826 {
827 delete mMsgToRetransmit;
828 mMsgToRetransmit = sip;
829 sendToWire(sip); // don't delete msg
830 terminateServerTransaction(mId);
831 delete this;
832 }
833 else
834 {
835 if (mState == Trying || mState == Proceeding)
836 {
837 mState = Completed;
838 mController.mTimers.add(Timer::TimerJ, mId, 64*Timer::T1 );
839 delete mMsgToRetransmit;
840 mMsgToRetransmit = sip;
841 sendToWire(sip); // don't delete msg
842 }
843 else if (mState == Completed)
844 {
845 // ignore
846 delete msg;
847 }
848 else
849 {
850 CritLog (<< "Fatal error in TransactionState::processServerNonInvite "
851 << msg->brief()
852 << " state=" << *this);
853 assert(0);
854 return;
855 }
856 }
857 }
858 else
859 {
860 // ignore
861 delete msg;
862 }
863 }
864 else if (isTimer(msg))
865 {
866 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
867 assert(timer);
868 if (mState == Completed && timer->getType() == Timer::TimerJ)
869 {
870 terminateServerTransaction(mId);
871 delete this;
872 }
873 delete msg;
874 }
875 else if (isTransportError(msg))
876 {
877 processTransportFailure();
878 delete msg;
879 }
880 else
881 {
882 //StackLog (<< "TransactionState::processServerNonInvite: message unhandled");
883 delete msg;
884 }
885 }
886
887
888 void
889 TransactionState::processServerInvite(TransactionMessage* msg)
890 {
891 StackLog (<< "TransactionState::processServerInvite: " << msg->brief());
892 if (isRequest(msg) && isFromWire(msg))
893 {
894 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
895 switch (sip->header(h_RequestLine).getMethod())
896 {
897 case INVITE:
898 if (mState == Proceeding || mState == Completed)
899 {
900 /*
901 The server transaction has already been constructed so this
902 message is a retransmission. The server transaction must
903 respond with a 100 Trying _or_ the last provisional response
904 passed from the TU for this transaction.
905 */
906 //StackLog (<< "Received invite from wire - forwarding to TU state=" << mState);
907 if (!mMsgToRetransmit)
908 {
909 mMsgToRetransmit = make100(sip); // for when TimerTrying fires
910 }
911 delete msg;
912 sendToWire(mMsgToRetransmit);
913 }
914 else
915 {
916 //StackLog (<< "Received invite from wire - ignoring state=" << mState);
917 delete msg;
918 }
919 break;
920
921 case ACK:
922 /*
923 If an ACK is received while the server transaction is in the
924 "Completed" state, the server transaction MUST transition to the
925 "Confirmed" state.
926 */
927 if (mState == Completed)
928 {
929 if (mIsReliable)
930 {
931 //StackLog (<< "Received ACK in Completed (reliable) - delete transaction");
932 terminateServerTransaction(mId);
933 delete this;
934 delete msg;
935 }
936 else
937 {
938 //StackLog (<< "Received ACK in Completed (unreliable) - confirmed, start Timer I");
939 mState = Confirmed;
940 mController.mTimers.add(Timer::TimerI, mId, Timer::T4 );
941 delete msg;
942 }
943 }
944 else
945 {
946 //StackLog (<< "Ignore ACK not in Completed state");
947 delete msg;
948 }
949 break;
950
951 case CANCEL:
952 assert(0);
953 break;
954
955 default:
956 //StackLog (<< "Received unexpected request. Ignoring message");
957 delete msg;
958 break;
959 }
960 }
961 else if (isResponse(msg, 100, 699) && isFromTU(msg))
962 {
963 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
964 int code = sip->header(h_StatusLine).responseCode();
965 switch (sip->header(h_CSeq).method())
966 {
967 case INVITE:
968 if (code == 100)
969 {
970 if (mState == Trying || mState == Proceeding)
971 {
972 //StackLog (<< "Received 100 in Trying or Proceeding. Send over wire");
973 delete mMsgToRetransmit; // may be replacing the 100
974 mMsgToRetransmit = sip;
975 mState = Proceeding;
976 sendToWire(msg); // don't delete msg
977 }
978 else
979 {
980 //StackLog (<< "Ignoring 100 - not in Trying or Proceeding.");
981 delete msg;
982 }
983 }
984 else if (code > 100 && code < 200)
985 {
986 if (mState == Trying || mState == Proceeding)
987 {
988 //StackLog (<< "Received 1xx in Trying or Proceeding. Send over wire");
989 delete mMsgToRetransmit; // may be replacing the 100
990 mMsgToRetransmit = sip;
991 mState = Proceeding;
992 sendToWire(msg); // don't delete msg
993 }
994 else
995 {
996 //StackLog (<< "Received 100 when not in Trying State. Ignoring");
997 delete msg;
998 }
999 }
1000 else if (code >= 200 && code < 300)
1001 {
1002 if (mState == Trying || mState == Proceeding)
1003 {
1004 StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction");
1005 StackLog (<< *this);
1006 sendToWire(msg);
1007
1008 // Keep the StaleServer transaction around, so we can keep the
1009 // source Tuple that the request was received on.
1010 terminateServerTransaction(mId);
1011 mMachine = ServerStale;
1012 mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS );
1013 delete msg;
1014 }
1015 else
1016 {
1017 //StackLog (<< "Received 2xx when not in Trying or Proceeding State. Ignoring");
1018 delete msg;
1019 }
1020 }
1021 else if (code >= 300)
1022 {
1023 /*
1024 While in the "Proceeding" state, if the TU passes a response with
1025 status code from 300 to 699 to the server transaction, For unreliable
1026 transports,timer G is set to fire in T1 seconds, and is not set to
1027 fire for reliable transports.when the "Completed" state is entered,
1028 timer H MUST be set to fire in 64*T1 seconds for all transports.
1029 Timer H determines when the server transaction abandons retransmitting
1030 the response
1031 */
1032
1033 if (mState == Trying || mState == Proceeding)
1034 {
1035 StackLog (<< "Received failed response in Trying or Proceeding. Start Timer H, move to completed." << *this);
1036 delete mMsgToRetransmit;
1037 mMsgToRetransmit = sip;
1038 mState = Completed;
1039 if (sip->header(h_To).exists(p_tag))
1040 {
1041 mToTag = sip->header(h_To).param(p_tag);
1042 }
1043 mController.mTimers.add(Timer::TimerH, mId, Timer::TH );
1044 if (!mIsReliable)
1045 {
1046 mController.mTimers.add(Timer::TimerG, mId, Timer::T1 );
1047 }
1048 sendToWire(msg); // don't delete msg
1049 }
1050 else
1051 {
1052 //StackLog (<< "Received Final response when not in Trying or Proceeding State. Ignoring");
1053 delete msg;
1054 }
1055 }
1056 else
1057 {
1058 //StackLog (<< "Received Invalid response line. Ignoring");
1059 delete msg;
1060 }
1061 break;
1062
1063 case CANCEL:
1064 assert(0);
1065 break;
1066
1067 default:
1068 //StackLog (<< "Received response to non invite or cancel. Ignoring");
1069 delete msg;
1070 break;
1071 }
1072 }
1073 else if (isTimer(msg))
1074 {
1075 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1076 switch (timer->getType())
1077 {
1078 case Timer::TimerG:
1079 if (mState == Completed)
1080 {
1081 StackLog (<< "TimerG fired. retransmit, and re-add TimerG");
1082 sendToWire(mMsgToRetransmit, true);
1083 mController.mTimers.add(Timer::TimerG, mId, resipMin(Timer::T2, timer->getDuration()*2) ); // !slg! TimerG is supposed to double - up until a max of T2 RFC3261 17.2.1
1084 }
1085 else
1086 {
1087 delete msg;
1088 }
1089 break;
1090
1091 /*
1092 If timer H fires while in the "Completed" state, it implies that the
1093 ACK was never received. In this case, the server transaction MUST
1094 transition to the "Terminated" state, and MUST indicate to the TU
1095 that a transaction failure has occurred. WHY we need to inform TU
1096 for Failure cases ACK ? do we really need to do this ???
1097
1098 !jf! this used to re-add TimerH if there was an associated CANCEL
1099 transaction. Don't know why.
1100 */
1101 case Timer::TimerH:
1102 case Timer::TimerI:
1103 if (timer->getType() == Timer::TimerH)
1104 {
1105 InfoLog (<< "No ACK was received on a server transaction (Timer H)");
1106 }
1107 terminateServerTransaction(mId);
1108 delete this;
1109 delete msg;
1110 break;
1111
1112
1113 case Timer::TimerTrying:
1114 if (mState == Trying)
1115 {
1116 //StackLog (<< "TimerTrying fired. Send a 100");
1117 sendToWire(mMsgToRetransmit); // will get deleted when this is deleted
1118 mState = Proceeding;
1119 delete msg;
1120 }
1121 else
1122 {
1123 //StackLog (<< "TimerTrying fired. Not in Trying state. Ignoring");
1124 delete msg;
1125 }
1126 break;
1127
1128 default:
1129 CritLog(<<"unexpected timer fired: " << timer->getType());
1130 assert(0); // programming error if any other timer fires
1131 delete msg;
1132 break;
1133 }
1134 }
1135 else if (isTransportError(msg))
1136 {
1137 processTransportFailure();
1138 delete msg;
1139 }
1140 else
1141 {
1142 //StackLog (<< "TransactionState::processServerInvite: message unhandled");
1143 delete msg;
1144 }
1145 }
1146
1147
1148 void
1149 TransactionState::processClientStale(TransactionMessage* msg)
1150 {
1151 StackLog (<< "TransactionState::processClientStale: " << msg->brief());
1152
1153 if (isTimer(msg))
1154 {
1155 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1156 if (timer->getType() == Timer::TimerStaleClient)
1157 {
1158 delete this;
1159 delete msg;
1160 }
1161 else
1162 {
1163 delete msg;
1164 }
1165 }
1166 else if (isTransportError(msg))
1167 {
1168 WarningLog (<< "Got a transport error in Stale Client state");
1169 StackLog (<< *this);
1170 processTransportFailure();
1171 delete msg;
1172 }
1173 else
1174 {
1175 if(isResponse(msg, 200, 299))
1176 {
1177 assert(isFromWire(msg));
1178 sendToTU(msg);
1179 }
1180 else
1181 {
1182 // might have received some other response because a downstream UAS is
1183 // misbehaving. For instance, sending a 487/INVITE after already
1184 // sending a 200/INVITE. In this case, discard the response
1185 StackLog (<< "Discarding extra response: " << *msg);
1186 delete msg;
1187 }
1188 }
1189 }
1190
1191 void
1192 TransactionState::processServerStale(TransactionMessage* msg)
1193 {
1194 StackLog (<< "TransactionState::processServerStale: " << msg->brief());
1195
1196 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1197 if (isTimer(msg))
1198 {
1199 TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);
1200 if (timer->getType() == Timer::TimerStaleServer)
1201 {
1202 delete msg;
1203 delete this;
1204 }
1205 else
1206 {
1207 delete msg;
1208 }
1209 }
1210 else if (isTransportError(msg))
1211 {
1212 WarningLog (<< "Got a transport error in Stale Server state");
1213 StackLog (<< *this);
1214 processTransportFailure();
1215 delete msg;
1216 }
1217 else if (sip && isRequest(sip) && sip->header(h_RequestLine).getMethod() == ACK)
1218 {
1219 // this can happen when an upstream UAC sends an ACK with no to-tag when
1220 // it should
1221 assert(isFromWire(msg));
1222 InfoLog (<< "Passing ACK directly to TU: " << sip->brief());
1223 sendToTU(msg);
1224 }
1225 else if (sip && isRequest(sip) && sip->header(h_RequestLine).getMethod() == INVITE)
1226 {
1227 // this can happen when an upstream UAC never received the 200 and
1228 // retransmits the INVITE when using unreliable transport
1229 // Drop the INVITE since the 200 will get retransmitted by the downstream UAS
1230 StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief());
1231 delete msg;
1232 }
1233 else if (isResponse(msg) && isFromTU(msg))
1234 {
1235 sendToWire(msg);
1236 delete msg;
1237 }
1238 else
1239 {
1240 ErrLog(<<"ServerStale unexpected condition, dropping message.");
1241 if (sip)
1242 {
1243 ErrLog(<<sip->brief());
1244 }
1245 delete msg;
1246 }
1247 }
1248
1249
1250 void
1251 TransactionState::processNoDnsResults()
1252 {
1253 InfoLog (<< "Ran out of dns entries for " << mDnsResult->target() << ". Send 503");
1254 assert(mDnsResult->available() == DnsResult::Finished);
1255 SipMessage* response = Helper::makeResponse(*mMsgToRetransmit, 503);
1256 WarningCategory warning;
1257 warning.hostname() = DnsUtil::getLocalHostName();
1258 warning.code() = 499;
1259 warning.text() = "No other DNS entries to try";
1260 response->header(h_Warnings).push_back(warning);
1261
1262 sendToTU(response); // !jf! should be 480?
1263 terminateClientTransaction(mId);
1264 if (mMachine != Stateless)
1265 {
1266 delete this;
1267 }
1268 }
1269
1270 void
1271 TransactionState::processTransportFailure()
1272 {
1273 InfoLog (<< "Try sending request to a different dns result");
1274 assert(mMsgToRetransmit);
1275
1276 if (mMsgToRetransmit->isRequest() && mMsgToRetransmit->header(h_RequestLine).getMethod() == CANCEL)
1277 {
1278 WarningLog (<< "Failed to deliver a CANCEL request");
1279 StackLog (<< *this);
1280 assert(mIsCancel);
1281
1282 // In the case of a client-initiated CANCEL, we don't want to
1283 // try other transports in the case of transport error as the
1284 // CANCEL MUST be sent to the same IP/PORT as the orig. INVITE.
1285 SipMessage* response = Helper::makeResponse(*mMsgToRetransmit, 503);
1286 WarningCategory warning;
1287 warning.hostname() = DnsUtil::getLocalHostName();
1288 warning.code() = 499;
1289 warning.text() = "Failed to deliver CANCEL using the same transport as the INVITE was used";
1290 response->header(h_Warnings).push_back(warning);
1291
1292 sendToTU(Helper::makeResponse(*mMsgToRetransmit, 503));
1293 return;
1294 }
1295
1296 assert(!mIsCancel);
1297 if (mDnsResult)
1298 {
1299 switch (mDnsResult->available())
1300 {
1301 case DnsResult::Available:
1302 mMsgToRetransmit->header(h_Vias).front().param(p_branch).incrementTransportSequence();
1303 mTarget = mDnsResult->next();
1304 processReliability(mTarget.getType());
1305 sendToWire(mMsgToRetransmit);
1306 break;
1307
1308 case DnsResult::Pending:
1309 mMsgToRetransmit->header(h_Vias).front().param(p_branch).incrementTransportSequence();
1310 break;
1311
1312 case DnsResult::Finished:
1313 processNoDnsResults();
1314 break;
1315
1316 case DnsResult::Destroyed:
1317 default:
1318 InfoLog (<< "Bad state: " << *this);
1319 assert(0);
1320 }
1321 }
1322 }
1323
1324 // called by DnsResult
1325 void
1326 TransactionState::handle(DnsResult* result)
1327 {
1328 // got a DNS response, so send the current message
1329 StackLog (<< *this << " got DNS result: " << *result);
1330
1331 if (mTarget.getType() == UNKNOWN_TRANSPORT)
1332 {
1333 assert(mDnsResult);
1334 switch (mDnsResult->available())
1335 {
1336 case DnsResult::Available:
1337 mTarget = mDnsResult->next();
1338 processReliability(mTarget.getType());
1339 mController.mTransportSelector.transmit(mMsgToRetransmit, mTarget);
1340 break;
1341
1342 case DnsResult::Finished:
1343 processNoDnsResults();
1344 break;
1345
1346 case DnsResult::Pending:
1347 break;
1348
1349 case DnsResult::Destroyed:
1350 default:
1351 assert(0);
1352 break;
1353 }
1354 }
1355 else
1356 {
1357 // can't be retransmission
1358 sendToWire(mMsgToRetransmit, false);
1359 }
1360 }
1361
1362 void
1363 TransactionState::processReliability(TransportType type)
1364 {
1365 switch (type)
1366 {
1367 case UDP:
1368 case DCCP:
1369 if (mIsReliable)
1370 {
1371 mIsReliable = false;
1372 StackLog (<< "Unreliable transport: " << *this);
1373 switch (mMachine)
1374 {
1375 case ClientNonInvite:
1376 mController.mTimers.add(Timer::TimerE1, mId, Timer::T1 );
1377 break;
1378
1379 case ClientInvite:
1380 mController.mTimers.add(Timer::TimerA, mId, Timer::T1 );
1381 break;
1382
1383 default:
1384 break;
1385 }
1386 }
1387 break;
1388
1389 default:
1390 if (!mIsReliable)
1391 {
1392 mIsReliable = true;
1393 }
1394 break;
1395 }
1396 }
1397
1398 // !ah! only used one place, so leaving it here instead of making a helper.
1399 // !ah! broken out for clarity -- only used for forceTargets.
1400 // Expects that host portion is IP address notation.
1401
1402 static const Tuple
1403 simpleTupleForUri(const Uri& uri)
1404 {
1405 const Data& host = uri.host();
1406 int port = uri.port();
1407
1408 resip::TransportType transport = UNKNOWN_TRANSPORT;
1409
1410 if (uri.exists(p_transport))
1411 {
1412 transport = Tuple::toTransport(uri.param(p_transport));
1413 }
1414
1415 if (transport == UNKNOWN_TRANSPORT)
1416 {
1417 transport = UDP;
1418 }
1419 if (port == 0)
1420 {
1421 switch(transport)
1422 {
1423 case TLS:
1424 port = Symbols::DefaultSipsPort;
1425 break;
1426 case UDP:
1427 case TCP:
1428 default:
1429 port = Symbols::DefaultSipPort;
1430 break;
1431 // !ah! SCTP?
1432
1433 }
1434 }
1435
1436 return Tuple(host,port,transport);
1437 }
1438
1439 void
1440 TransactionState::sendToWire(TransactionMessage* msg, bool resend)
1441 {
1442 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1443
1444 if (!sip)
1445 {
1446 CritLog(<<"sendToWire: message not a sip message at address " << (void*)msg);
1447 assert(sip);
1448 return;
1449 }
1450
1451 // !jf! for responses, go back to source always (not RFC exactly)
1452 if (mMachine == ServerNonInvite || mMachine == ServerInvite || mMachine == ServerStale)
1453 {
1454 assert(mDnsResult == 0);
1455 assert(sip->exists(h_Vias));
1456 assert(!sip->header(h_Vias).empty());
1457
1458 Tuple target(mResponseTarget);
1459 if (sip->hasForceTarget())
1460 {
1461 target = simpleTupleForUri(sip->getForceTarget());
1462 target.transport = mResponseTarget.transport;
1463 StackLog(<<"!ah! response with force target going to : "<<target);
1464 }
1465 else if (sip->header(h_Vias).front().exists(p_rport) && sip->header(h_Vias).front().param(p_rport).hasValue())
1466 {
1467 target.setPort(sip->header(h_Vias).front().param(p_rport).port());
1468 StackLog(<< "rport present in response, sending to " << target);
1469 }
1470 else
1471 {
1472 StackLog(<< "tid=" << sip->getTransactionId() << " sending to : " << target);
1473 }
1474
1475 if (resend)
1476 {
1477 mController.mTransportSelector.retransmit(sip, target);
1478 }
1479 else
1480 {
1481 mController.mTransportSelector.transmit(sip, target);
1482 }
1483 }
1484 else if (sip->getDestination().transport)
1485 {
1486 mController.mTransportSelector.transmit(sip, sip->getDestination()); // dns not used
1487 }
1488 else if (mDnsResult == 0 && !mIsCancel) // no dns query yet
1489 {
1490 StackLog (<< "sendToWire with no dns result: " << *this);
1491 assert(sip->isRequest());
1492 assert(!mIsCancel);
1493 mDnsResult = mController.mTransportSelector.createDnsResult(this);
1494 mController.mTransportSelector.dnsResolve(mDnsResult, sip);
1495 assert(mDnsResult); // !ah! is this really an assertion or an error?
1496
1497 // do it now, if there is an immediate result
1498 if (mDnsResult->available() == DnsResult::Available)
1499 {
1500 handle(mDnsResult);
1501 }
1502 }
1503 else // reuse the last dns tuple
1504 {
1505 assert(sip->isRequest());
1506 assert(mTarget.getType() != UNKNOWN_TRANSPORT);
1507 if (resend)
1508 {
1509 mController.mTransportSelector.retransmit(sip, mTarget);
1510 }
1511 else
1512 {
1513 mController.mTransportSelector.transmit(sip, mTarget);
1514 }
1515 }
1516
1517 RESIP_STATISTICS(mController.mStatsManager.sent(sip, resend));
1518 }
1519
1520 void
1521 TransactionState::sendToTU(TransactionMessage* msg) const
1522 {
1523 SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg);
1524 if (sipMsg && sipMsg->isResponse())
1525 {
1526 // whitelisting rules.
1527 switch (sipMsg->header(h_StatusLine).statusCode())
1528 {
1529 case 408:
1530 case 500:
1531 case 503:
1532 case 504:
1533 case 600:
1534 break;
1535 default:
1536 mDnsResult->success();
1537 break;
1538 }
1539 }
1540 TransactionState::sendToTU(mTransactionUser, mController, msg);
1541 }
1542
1543 void
1544 TransactionState::sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg)
1545 {
1546 if (!tu)
1547 {
1548 DebugLog(<< "Send to default TU: " << *msg);
1549 }
1550 else
1551 {
1552 DebugLog (<< "Send to TU: " << *tu << " " << *msg);
1553 }
1554
1555 msg->setTransactionUser(tu);
1556 controller.mTuSelector.add(msg, TimeLimitFifo<Message>::InternalElement);
1557 }
1558
1559 SipMessage*
1560 TransactionState::make100(SipMessage* request) const
1561 {
1562 return (Helper::makeResponse(*request, 100));
1563 }
1564
1565 void
1566 TransactionState::add(const Data& tid)
1567 {
1568 if (mMachine == ClientNonInvite || mMachine == ClientInvite || mMachine == ClientStale || mMachine == Stateless )
1569 {
1570 mController.mClientTransactionMap.add(tid, this);
1571 }
1572 else
1573 {
1574 mController.mServerTransactionMap.add(tid, this);
1575 }
1576 }
1577
1578 void
1579 TransactionState::erase(const Data& tid)
1580 {
1581 if (mMachine == ClientNonInvite || mMachine == ClientInvite || mMachine == ClientStale || mMachine == Stateless)
1582 {
1583 mController.mClientTransactionMap.erase(tid);
1584 }
1585 else
1586 {
1587 mController.mServerTransactionMap.erase(tid);
1588 }
1589 }
1590
1591 bool
1592 TransactionState::isRequest(TransactionMessage* msg) const
1593 {
1594 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1595 return sip && sip->isRequest();
1596 }
1597
1598 bool
1599 TransactionState::isInvite(TransactionMessage* msg) const
1600 {
1601 if (isRequest(msg))
1602 {
1603 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1604 return (sip->header(h_RequestLine).getMethod()) == INVITE;
1605 }
1606 return false;
1607 }
1608
1609 bool
1610 TransactionState::isResponse(TransactionMessage* msg, int lower, int upper) const
1611 {
1612 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1613 if (sip && sip->isResponse())
1614 {
1615 int c = sip->header(h_StatusLine).responseCode();
1616 return (c >= lower && c <= upper);
1617 }
1618 return false;
1619 }
1620
1621 bool
1622 TransactionState::isTimer(TransactionMessage* msg) const
1623 {
1624 return dynamic_cast<TimerMessage*>(msg) != 0;
1625 }
1626
1627 bool
1628 TransactionState::isFromTU(TransactionMessage* msg) const
1629 {
1630 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1631 return sip && !sip->isExternal();
1632 }
1633
1634 bool
1635 TransactionState::isFromWire(TransactionMessage* msg) const
1636 {
1637 SipMessage* sip = dynamic_cast<SipMessage*>(msg);
1638 return sip && sip->isExternal();
1639 }
1640
1641 bool
1642 TransactionState::isTransportError(TransactionMessage* msg) const
1643 {
1644 TransportMessage* t = dynamic_cast<TransportMessage*>(msg);
1645 return (t && t->isFailed());
1646 }
1647
1648 const Data&
1649 TransactionState::tid(SipMessage* sip) const
1650 {
1651 assert(0);
1652 assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty()));
1653 assert (mMachine == Stateless || (mMachine != Stateless && sip));
1654 return (mId.empty() && sip) ? sip->getTransactionId() : mId;
1655 }
1656
1657 void
1658 TransactionState::terminateClientTransaction(const Data& tid)
1659 {
1660 mState = Terminated;
1661 if (mController.mRegisteredForTransactionTermination)
1662 {
1663 //StackLog (<< "Terminate client transaction " << tid);
1664 sendToTU(new TransactionTerminated(tid, true, mTransactionUser));
1665 }
1666 }
1667
1668 void
1669 TransactionState::terminateServerTransaction(const Data& tid)
1670 {
1671 mState = Terminated;
1672 if (mController.mRegisteredForTransactionTermination)
1673 {
1674 //StackLog (<< "Terminate server transaction " << tid);
1675 sendToTU(new TransactionTerminated(tid, false, mTransactionUser));
1676 }
1677 }
1678
1679 std::ostream&
1680 resip::operator<<(std::ostream& strm, const resip::TransactionState& state)
1681 {
1682 strm << "tid=" << state.mId << " [ ";
1683 switch (state.mMachine)
1684 {
1685 case TransactionState::ClientNonInvite:
1686 strm << "ClientNonInvite";
1687 break;
1688 case TransactionState::ClientInvite:
1689 strm << "ClientInvite";
1690 break;
1691 case TransactionState::ServerNonInvite:
1692 strm << "ServerNonInvite";
1693 break;
1694 case TransactionState::ServerInvite:
1695 strm << "ServerInvite";
1696 break;
1697 case TransactionState::Stateless:
1698 strm << "Stateless";
1699 break;
1700 case TransactionState::ClientStale:
1701 strm << "ClientStale";
1702 break;
1703 case TransactionState::ServerStale:
1704 strm << "ServerStale";
1705 break;
1706 }
1707
1708 strm << "/";
1709 switch (state.mState)
1710 {
1711 case TransactionState::Calling:
1712 strm << "Calling";
1713 break;
1714 case TransactionState::Trying:
1715 strm << "Trying";
1716 break;
1717 case TransactionState::Proceeding:
1718 strm << "Proceeding";
1719 break;
1720 case TransactionState::Completed:
1721 strm << "Completed";
1722 break;
1723 case TransactionState::Confirmed:
1724 strm << "Confirmed";
1725 break;
1726 case TransactionState::Terminated:
1727 strm << "Terminated";
1728 break;
1729 case TransactionState::Bogus:
1730 strm << "Bogus";
1731 break;
1732 }
1733
1734 strm << (state.mIsReliable ? " reliable" : " unreliable");
1735 strm << " target=" << state.mResponseTarget;
1736 //if (state.mTransactionUser) strm << " tu=" << *state.mTransactionUser;
1737 //else strm << "default TU";
1738 strm << "]";
1739 return strm;
1740 }
1741
1742
1743 /* Local Variables: */
1744 /* c-file-style: "ellemtel" */
1745 /* End: */
1746
1747 /* ====================================================================
1748 * The Vovida Software License, Version 1.0
1749 *
1750 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1751 *
1752 * Redistribution and use in source and binary forms, with or without
1753 * modification, are permitted provided that the following conditions
1754 * are met:
1755 *
1756 * 1. Redistributions of source code must retain the above copyright
1757 * notice, this list of conditions and the following disclaimer.
1758 *
1759 * 2. Redistributions in binary form must reproduce the above copyright
1760 * notice, this list of conditions and the following disclaimer in
1761 * the documentation and/or other materials provided with the
1762 * distribution.
1763 *
1764 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1765 * and "Vovida Open Communication Application Library (VOCAL)" must
1766 * not be used to endorse or promote products derived from this
1767 * software without prior written permission. For written
1768 * permission, please contact vocal@vovida.org.
1769 *
1770 * 4. Products derived from this software may not be called "VOCAL", nor
1771 * may "VOCAL" appear in their name, without prior written
1772 * permission of Vovida Networks, Inc.
1773 *
1774 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1775 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1776 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1777 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1778 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1779 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1780 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1781 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1782 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1783 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1784 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1785 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1786 * DAMAGE.
1787 *
1788 * ====================================================================
1789 *
1790 * This software consists of voluntary contributions made by Vovida
1791 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1792 * Inc. For more information on Vovida Networks, Inc., please see
1793 * <http://www.vovida.org/>.
1794 *
1795 */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27