[reSIProcate] A suggestion about shifting responsibility of retransmissions of 2xx responses
yuhuicai
yuhuicai at vip.163.com
Sun Jul 11 17:15:43 CDT 2004
Since the ServerStale machine state has been introduced into the Server Invite Transaction(in transactionstate.cxx), and that type of Transaction will stayed for Timer::TS millisecond (equals T2), I think the responsibility of retransmitting 2xx could shift to the library, as a result, the TU can utilize the timing mechanism in the library.
To achive this goal,at first, the 2xx response should retained in mMsgToRetransmit:
// In Transactionstate::processServerInvite():
else if (code >= 200 && code < 300)
{
if (mState == Trying || mState == Proceeding)
{
StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction");
StackLog (<< *this);
if (mMsgToRetransmit) delete mMsgToRetransmit; //cyh2
mMsgToRetransmit = sip;//cyh2
sendToWire(msg);
// Keep the StaleServer transaction around, so we can keep the
// source Tuple that the request was received on.
terminateServerTransaction(mId);
mMachine = ServerStale;
mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS );
delete msg;
//Should change to:
else if (code >= 200 && code < 300)
{
if (mState == Trying || mState == Proceeding)
{
StackLog (<< "Received 2xx when in Trying or Proceeding State of server invite transaction");
StackLog (<< *this);
if (mMsgToRetransmit) delete mMsgToRetransmit; //added by yuhuicai
mMsgToRetransmit = sip; //added by yuhuicai
sendToWire(msg);
// Keep the StaleServer transaction around, so we can keep the
// source Tuple that the request was received on.
terminateServerTransaction(mId);
mMachine = ServerStale;
mController.mTimers.add(Timer::TimerStaleServer, mId, Timer::TS );
// delete msg; // Modified by yuhuicai
Second, when the reinvite msg come, the saved 2xx could be send:
//In TransactionState::processServerStale():
else if (sip && isRequest(sip) && sip->header(h_RequestLine).getMethod() == INVITE)
{
// this can happen when an upstream UAC never received the 200 and
// retransmits the INVITE when using unreliable transport
// Drop the INVITE since the 200 will get retransmitted by the downstream UAS
StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief());
delete msg;
}
//Should change to:
else if (sip && isRequest(sip) && sip->header(h_RequestLine).getMethod() == INVITE)
{
// this can happen when an upstream UAC never received the 200 and
// retransmits the INVITE when using unreliable transport
// Drop the INVITE since the 200 will get retransmitted by the downstream UAS
StackLog (<< "Dropping retransmitted INVITE in stale server transaction" << sip->brief());
sendToWire(mMsgToRetransmit); //added by yuhuicai
delete msg;
}
Maybe an interface should be added to let user choose rertansmit 2xx by TU or by library, and the default behavior is rertansmit by TU.
I have tested these codes and it works well. But it do not according to RFC3261(17.2.1):
"If, while in the "Proceeding" state, the TU passes a 2xx response to the server transaction, the server transaction MUST pass this response to the transport layer for transmission. It is not retransmitted by the server transaction; retransmissions of 2xx responses are handled by the TU. The server transaction MUST then transition to the "Terminated" state."
So, if you think it's unreasonable, just disregard it. :-)
More information about the resiprocate-devel
mailing list