⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transactionstate.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
         // create a new state object and insert in the TransactionMap                        if (sip->isExternal()) // new sip msg from transport         {            if (sip->method() == INVITE)            {               // !rk! This might be needlessly created.  Design issue.               TransactionState* state = new TransactionState(controller, ServerInvite, Trying, tid, tu);               state->mMsgToRetransmit = state->make100(sip);               state->mResponseTarget = sip->getSource(); // UACs source address               // since we don't want to reply to the source port if rport present                state->mResponseTarget.setPort(Helper::getPortForReply(*sip));               state->mIsReliable = isReliable(state->mResponseTarget.getType());               state->add(tid);                              if (Timer::T100 == 0)               {                  state->sendToWire(state->mMsgToRetransmit); // will get deleted when this is deleted                  state->mState = Proceeding;               }               else               {                  //StackLog(<<" adding T100 timer (INV)");                  controller.mTimers.add(Timer::TimerTrying, tid, Timer::T100);               }            }            else if (sip->method() == CANCEL)            {               TransactionState* matchingInvite =                   controller.mServerTransactionMap.find(sip->getTransactionId());               if (matchingInvite == 0)               {                  InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas");                  //was TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 481));                  SipMessage* response = Helper::makeResponse(*sip, 481);                  Tuple target(sip->getSource());                  controller.mTransportSelector.transmit(response, target);                  delete sip;                  delete response;                  return;               }               else               {                  assert(matchingInvite);                  state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid);                  state->startServerNonInviteTimerTrying(*sip,tid);               }            }            else if (sip->method() != ACK)            {               TransactionState* state = new TransactionState(controller, ServerNonInvite,Trying, tid, tu);               state->mResponseTarget = sip->getSource();               // since we don't want to reply to the source port if rport present                state->mResponseTarget.setPort(Helper::getPortForReply(*sip));               state->add(tid);               state->mIsReliable = isReliable(state->mResponseTarget.getType());               state->startServerNonInviteTimerTrying(*sip,tid);            }                        // Incoming ACK just gets passed to the TU            //StackLog(<< "Adding incoming message to TU fifo " << tid);            TransactionState::sendToTU(tu, controller, sip);         }         else // new sip msg from the TU         {            if (sip->method() == INVITE)            {               TransactionState* state = new TransactionState(controller, ClientInvite, Calling, tid, tu);               state->add(state->mId);               state->processClientInvite(sip);            }            else if (sip->method() == ACK)            {               //TransactionState* state = new TransactionState(controller, Stateless, Calling, Data(StatelessIdCounter++));               TransactionState* state = new TransactionState(controller, Stateless, Calling, tid, tu);               state->add(state->mId);               state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );               state->processStateless(sip);            }            else if (sip->method() == CANCEL)            {               TransactionState* matchingInvite = controller.mClientTransactionMap.find(sip->getTransactionId());               if (matchingInvite == 0)               {                  InfoLog (<< "No matching INVITE for incoming (from TU) CANCEL to uac");                  TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip,481));                  delete sip;               }               else if (matchingInvite->mState == Calling) // CANCEL before 1xx received               {                  WarningLog(<< "You can't CANCEL a request until a provisional has been received");                  StackLog (<< *matchingInvite);                  StackLog (<< *sip);                  // if no INVITE had been sent out yet. -- i.e. dns result not                  // processed yet                   // The CANCEL was received before the INVITE was sent                  // This can happen in odd cases. Too common to assert.                  // Be graceful.                  TransactionState::sendToTU(tu, controller, Helper::makeResponse(*sip, 200));                  matchingInvite->sendToTU(Helper::makeResponse(*matchingInvite->mMsgToRetransmit, 487));                  matchingInvite->terminateClientTransaction(matchingInvite->mId);                  delete matchingInvite;                  delete sip;               }               else if (matchingInvite->mState == Completed)               {                  // A final response was already seen for this INVITE transaction                  matchingInvite->sendToTU(Helper::makeResponse(*sip, 200));                  delete sip;               }               else               {                  assert(matchingInvite);                  state = TransactionState::makeCancelTransaction(matchingInvite, ClientNonInvite, tid);                  state->processClientNonInvite(sip);                                    // for the INVITE in case we never get a 487                  matchingInvite->mController.mTimers.add(Timer::TimerCleanUp, sip->getTransactionId(), 128*Timer::T1);               }            }            else             {               TransactionState* state = new TransactionState(controller, ClientNonInvite,                                                               Trying, tid, tu);               state->add(tid);               state->processClientNonInvite(sip);            }         }      }      else if (sip->isResponse()) // stray response      {         if (controller.mDiscardStrayResponses)         {            InfoLog (<< "discarding stray response: " << sip->brief());            delete message;         }         else         {            StackLog (<< "forwarding stateless response: " << sip->brief());            TransactionState* state =                new TransactionState(controller, Stateless, Calling,                                     Data(StatelessIdCounter++), tu);            state->add(state->mId);            state->mController.mTimers.add(Timer::TimerStateless, state->mId, Timer::TS );            state->processStateless(sip);         }      }      else // wasn't a request or a response      {         //StackLog (<< "discarding unknown message: " << sip->brief());      }   }    else // timer or other non-sip msg   {      //StackLog (<< "discarding non-sip message: " << message->brief());      delete message;   }}voidTransactionState::startServerNonInviteTimerTrying(SipMessage& sip, Data& tid){   unsigned int duration = 3500;   if(Timer::T1 != 500) // optimzed for T1 == 500   {      // Iteratively calculate how much time before TimerE reaches T2 (RFC4320) - could be improved      duration = Timer::T1;      while(duration*2<Timer::T2) duration = duration * 2;   }   mMsgToRetransmit = make100(&sip);  // Store for use when timer expires   mController.mTimers.add(Timer::TimerTrying, tid, duration );  // Start trying timer so that we can send 100 to NITs as recommened in RFC4320}voidTransactionState::processStateless(TransactionMessage* message){   // for ACK messages from the TU, there is no transaction, send it directly   // to the wire // rfc3261 17.1 Client Transaction   SipMessage* sip = dynamic_cast<SipMessage*>(message);   StackLog (<< "TransactionState::processStateless: " << message->brief());      // !jf! There is a leak for Stateless transactions associated with ACK to 200   if (isFromTU(message))   {      delete mMsgToRetransmit;      mMsgToRetransmit = sip;      sendToWire(sip);   }   else if (isFromWire(message))   {      InfoLog (<< "Received message from wire on a stateless transaction");      StackLog (<< *message);      //assert(0);      sendToTU(sip);   }   else if (isTransportError(message))   {      processTransportFailure(message);            delete message;      delete this;   }   else if (isTimer(message))   {      TimerMessage* timer = dynamic_cast<TimerMessage*>(message);      if (timer->getType() == Timer::TimerStateless)      {         delete message;         delete this;      }   }   else   {      assert(0);   }}void TransactionState::saveOriginalContactAndVia(const SipMessage& sip){   if(sip.exists(h_Contacts) && sip.header(h_Contacts).size() == 1)   {      mOriginalContact = std::auto_ptr<NameAddr>(new NameAddr(sip.header(h_Contacts).front()));   }   mOriginalVia = std::auto_ptr<Via>(new Via(sip.header(h_Vias).front()));}void TransactionState::restoreOriginalContactAndVia(){   if (mOriginalContact.get())   {      mMsgToRetransmit->header(h_Contacts).front() = *mOriginalContact;   }                     if (mOriginalVia.get())   {      mOriginalVia->param(p_branch).incrementTransportSequence();      mMsgToRetransmit->header(h_Vias).front() = *mOriginalVia;   }}voidTransactionState::processClientNonInvite(TransactionMessage* msg){    StackLog (<< "TransactionState::processClientNonInvite: " << msg->brief());   assert(!isInvite(msg));   if (isRequest(msg) && isFromTU(msg))   {      //StackLog (<< "received new non-invite request");      SipMessage* sip = dynamic_cast<SipMessage*>(msg);      delete mMsgToRetransmit;      saveOriginalContactAndVia(*sip);      mMsgToRetransmit = sip;      mController.mTimers.add(Timer::TimerF, mId, Timer::TF);      sendToWire(sip);  // don't delete   }   else if (isResponse(msg) && isFromWire(msg)) // from the wire   {      //StackLog (<< "received response from wire");      SipMessage* sip = dynamic_cast<SipMessage*>(msg);      int code = sip->header(h_StatusLine).responseCode();      if (code >= 100 && code < 200) // 1XX      {         if (mState == Trying || mState == Proceeding)         {            //?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            // 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.            if (!mIsReliable && mState == Trying)            {               mController.mTimers.add(Timer::TimerE2, mId, Timer::T2 );            }            mState = Proceeding;            sendToTU(msg); // don't delete                     }         else         {            // ignore            delete msg;         }      }      else if (code >= 200)      {         // don't notify the TU of retransmissions         if (mState == Trying || mState == Proceeding)         {            sendToTU(msg); // don't delete         }         else if (mState == Completed)         {            delete msg;         }                  if (mIsReliable)         {            terminateClientTransaction(mId);            delete this;         }         else if (mState != Completed) // prevent TimerK reproduced         {            mState = Completed;            mController.mTimers.add(Timer::TimerK, mId, Timer::T4 );                     }      }   }   else if (isTimer(msg))   {      //StackLog (<< "received timer in client non-invite transaction");      TimerMessage* timer = dynamic_cast<TimerMessage*>(msg);      switch (timer->getType())      {         case Timer::TimerE1:            if (mState == Trying)            {               unsigned long d = timer->getDuration();               if (d < Timer::T2) d *= 2;               mController.mTimers.add(Timer::TimerE1, mId, d);               StackLog (<< "Retransmitting: " << mMsgToRetransmit->brief());               sendToWire(mMsgToRetransmit, true);               delete msg;            }            else            {               // ignore               delete msg;            }            break;         case Timer::TimerE2:            if (mState == Proceeding)            {               mController.mTimers.add(Timer::TimerE2, mId, Timer::T2);               StackLog (<< "Retransmitting: " << mMsgToRetransmit->brief());               sendToWire(mMsgToRetransmit, true);               delete msg;            }            else             {               // ignore               delete msg;            }            break;         case Timer::TimerF:            if (mState == Trying || mState == Proceeding)            {               sendToTU(Helper::makeResponse(*mMsgToRetransmit, 408));               terminateClientTransaction(mId);               delete this;            }                        delete msg;            break;         case Timer::TimerK:            terminateClientTransaction(mId);            delete msg;            delete this;            break;         default:            //InfoLog (<< "Ignoring timer: " << *msg);            delete msg;            break;      }   }   else if (isTransportError(msg))   {      processTransportFailure(msg);      delete msg;   }   else   {      //StackLog (<< "TransactionState::processClientNonInvite: message unhandled");      delete msg;   }}voidTransactionState::processClientInvite(TransactionMessage* msg){   StackLog(<< "TransactionState::processClientInvite: " << msg->brief() << " " << *this);   if (isRequest(msg) && isFromTU(msg))   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -