Skip to main content

Automatic handling of CANCEL

24 replies [Last post]
niklasuhrberg
Offline
Joined: 2004-11-02

Hi, this is a call for feeedback on an idea for the SIP RA Type.

Background: When e.g. an INVITE is cancelled (by a CANCEL eing received) the application is supposed to terminate the cancelled transaction by sending a 487 (Request Terminated)
Also the CANCEL request itself is to be answered with a 200 OK.

Problem: How can this be supported by the SIP RA Type?
Without any support the work must be done manually which amounts to
1. Looking up the transaction to be cancelled.
2. Sending the 487 error message.
(These two assume already that the event for the CANCEL has been delivered to the correct Sbb which can only be assured (in the current version of the SIP RA) by providin a suitable initial event selector method for a root Sbb.)
3. Send the OK in response for the CANCEL message.

For applications that simply don't do anything special as a consequence of a cancelled request ti would be easiest if the RA just cancelled the request.

For applications that do want to know that the request has been cancelled it should suffice that the corresponding event be delivered and the RA take care of the rest.

If we assume a SIP RA Type including a dialog activity and that we are dealing with an application that creates a dialog on the INVITE that is to be cancelled it seems theoretically possible to circumvent the need for getting the cancel event directed to a root sbb by means of an initial event seletor if the CANCEL is delivered on the dialog activity.

Now we need somewhere to put a handleCancellation method. Without introducing a new interface in the SIP RA Type the JainSipResourceAdaptorSbbInterface seems to be the choice:

handleCancellation(RequestEvent)

That is:
onInviteEvent(RequestEvent, ActivityContextInterface) {
Dialog obtained and corresponding ACI
Provisional response sent
}

onCancelEvent(RequestEvent event, ActivityContextInterface) {
The ACI has the dialog as activity
JainSipResourceAdaptorSbbInterface intf = ...
intf.handleCancellation(event)
}

The status of the dialog will of course depend on the situation in which the CANCEL was received. (If it's a cancellation of an initial INVITE the dialog will terminate)

Comments?

I'm especially interested in opinions about the suggested way for dialog based applications to get the CANCEL delivered on the dialog ACI thus eliminating the need for initial event selectors solely for this purpose.
Note that the situation is a little special because there need not be a SIP dialog yet (not even an early one) because a CANCEL can be sent after a provisional response has been received and a 100 Trying may not contain dialog state information (To tag).

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jbemmel
Offline
Joined: 2005-03-01

> 2a. If there is also an associated dialog activity,
> the RA generates the 487 response and ends the dialog
> activity.

only if it's not established yet, so not for reINVITE

> The CANCEL event is fired on the
> ServerTransaction activity to inform the app. The app
> does not need to do anything else.

ben_evans
Offline
Joined: 2003-08-14

> > 2a. If there is also an associated dialog activity,
> > the RA generates the 487 response and ends the dialog
> > activity.
>
> only if it's not established yet, so not for reINVITE

Correct. The RA can still generate the 487 response for the re-INVITE, but the dialog activity would not be ended in this case. The dialog activity only ends if the initial INVITE is cancelled.

ivelin
Offline
Joined: 2003-07-13

Ben, can you please update the SIP RA wiki with the latest consensus on CANCEL?
http://wiki.java.net/bin/view/Communications/DialogExtensionMemo

niklasuhrberg
Offline
Joined: 2004-11-02

I just updated the Wiki page with the result detailed by Ben above.

During this operation I spotted (painful to admit that I didn't notice this before) the very same "feature" that I have posted a question about on the JAIN SLEE interest list, related to

3. If there is no match, the CANCEL event must be passed up statelessly to the app - a proxy will need to statelessly forward this downstream. Here there is no activity to fire the event on, so the RA will need to create a "one-shot" dummy activity that ends immediately after the event is fired.

I think this is a bit too sloppy (pardon the formulation) to be in the material, what exactly is a "one-shot" dummy activity?

This stems from a potential need to operate statelessly and this is clearly not appropriately supported in the 1.0 SIP RA nor in out proposal here....

I think it would be cleaner at this stage to exclude the (3) alternative.
If it is included I'd like also to specify the mechanism for getting to this state (having no server transaction activity).
The current RA implementation always creates server transaction activitites.

Earlier on we discussed this and one suggestion is simply to let the request itself be the default activit and let the application decide to be transaction or dialog stateful.

I feel that this a bit too big change at this stage though...

baranowb
Offline
Joined: 2006-01-09

Hmm so how this issue had been solved?
Im following wiki letter by letter,so :)

I had chat with Ranga about 481 response. According to what he said 481 is never used in CANCEL scenarios.
Moreover, if we respond 200 to CANCEL - on its TX how can we after that respond with 481?? - as other Tx does not exist?

About that dummy activity - we need something that is commonly accesible, right ? Like something that implements javax.sip.ServerTransaction right? It will be implementation dependable how it will be handled in RA.
Or should it be just java.lang.Object object as activity? I mean this would give some degree of freedom to implementation.
Second issue to firing that CANCEL - should CANCEL Tx be available through fired event ?? Is there any good reason it should?

For javax.sip.Timeout.DIALOG, net.java, 1.2 event object - there seems to be no good event here either.
IT has to be also commonly available - one option is to set it to java.util.EventObject.

Any comments?

niklasuhrberg
Offline
Joined: 2004-11-02

> Hmm so how this issue had been solved?
> Im following wiki letter by letter,so :)
>
> I had chat with Ranga about 481 response. According
> to what he said 481 is never used in CANCEL
> scenarios.
> Moreover, if we respond 200 to CANCEL - on its TX how
> can we after that respond with 481?? - as other Tx
> does not exist?

It looks as if you have confused 487 (which is documented in the memo) for 481.
Check it out!

The CANCEL is sent in a transaction of its own, to which is responded 200 OK.

Then a 487 Request terminated is responded to the original INVITE which is being cancelled. It exists until it has been terminated.

All this is documented in RFC3261.

niklasuhrberg
Offline
Joined: 2004-11-02

> 2 remarks:
> - JAIN SIP does handle CANCEL specially: the
> ServerTransaction passed to the listener in
> processRequest() is the INVITE ServerTransaction
> being cancelled, not a ServerTransaction for the
> CANCEL (!)

Yes, this has been recognized before (don't remember where in the forum or if it was offline...).

> - the behavior you are describing is appropriate only
> for endpoint applications. A stateless proxy
> application would forward the CANCEL and *not* send a
> 487, a stateful proxy would iterate over all
> branches

Yes, the behaviour of a stateless proxy is known.
If you look at the RA as recommended in JAIN SLEE 1.0 Appendix D (which is the base for the implementation) you can see that the only activities are ServerTransaction and ClientTransaction, moreover the activity cannot be null when an event is fired.

This implies that it is not possible to implement a transaction stateless service as a SLEE application.

This is a limitation currently under discussion.
Please give your opinion on the importance of the possibility to write transaction stateless services.

jbemmel
Offline
Joined: 2005-03-01

> > - the behavior you are describing is appropriate
> only
> > for endpoint applications. A stateless proxy
> > application would forward the CANCEL and *not* send
> a
> > 487, a stateful proxy would iterate over all
> > branches
>
> Yes, the behaviour of a stateless proxy is known.
> If you look at the RA as recommended in JAIN SLEE 1.0
> Appendix D (which is the base for the implementation)
> you can see that the only activities are
> ServerTransaction and ClientTransaction, moreover the
> activity cannot be null when an event is fired.
>
> This implies that it is not possible to implement a
> transaction stateless service as a SLEE application.
>
>
> This is a limitation currently under discussion.
> Please give your opinion on the importance of the
> possibility to write transaction stateless services.

The behavior that you were talking about is not appropriate for *any* proxy, stateful or stateless. You cannot build an IMS system without proxies

Regarding transaction stateless services: for scalability it is important that the application may decide whether to create a ServerTransaction for a given request or not. For example, authentication challenges are best handled statelessly. This does not mean that the whole service needs to be stateless

niklasuhrberg
Offline
Joined: 2004-11-02

> The behavior that you were talking about is not
> appropriate for *any* proxy, stateful or stateless.
> You cannot build an IMS system without proxies

Could you please clarify what is not appropriate in the described behaviour for transaction stateful services?

Please note that if you implement a stateful proxy application step 3 (in the second post in this thread) should be the place to iterate over all branches.
This is up to the application, not the responsibility of the RA.
IMO the behaviour is appropriate for implementing a stateful proxy, CACNCEL being a hop-by-hop request.

jbemmel
Offline
Joined: 2005-03-01

> Could you please clarify what is not appropriate in
> the described behaviour for transaction stateful
> services?
>

The sending of a 487 response on the INVITE servertransaction. This will happen automatically when the proxy receives this response from an upstream element (coming from the UAS)

> Please note that if you implement a stateful proxy
> application step 3 (in the second post in this
> thread) should be the place to iterate over all
> branches.
> This is up to the application, not the responsibility
> of the RA.

Yes, you could leave this up to the application, but it is very common behavior in which the application really doesn't have much choice. Leaving this to the application complicates things for the application

> IMO the behaviour is appropriate for implementing a
> stateful proxy, CACNCEL being a hop-by-hop request.

Sending an OK response to the CANCEL is ok, the application has no choice here.

Sending 487 on the INVITE ST is appropriate for endpoint applications, but not for proxies.

Terminating the dialog is appropriate for initial INVITEs, but not for reINVITEs

niklasuhrberg
Offline
Joined: 2004-11-02

> > Could you please clarify what is not appropriate
> in
> > the described behaviour for transaction stateful
> > services?
> >
>
> The sending of a 487 response on the INVITE
> servertransaction. This will happen automatically
> when the proxy receives this response from an
> upstream element (coming from the UAS)

In my view a stateful proxy works according to:

INVITE ---> Proxy ---> INVITE (Branch 1)
---> INVITE (Branch 2)

CANCEL ---> Proxy
OK <---
487 <--- (Response to the INVITE)
---> CANCEL (Branch 1)
---> CANCEL (Brnch 2)

I.e. the stateful proxy does not wait until it gets a 487 response from a UAS before it responds 487 to the initial INVITE.

If you think this is wrong please point to the relevant part of RFC 3261. I looked (briefly) at section 16 but I didn't find anything that determined this explicitly.

> > Please note that if you implement a stateful proxy
> > application step 3 (in the second post in this
> > thread) should be the place to iterate over all
> > branches.
> > This is up to the application, not the
> responsibility
> > of the RA.
>
> Yes, you could leave this up to the application, but
> it is very common behavior in which the application
> really doesn't have much choice. Leaving this to the
> application complicates things for the application

There is no notion of a proxy in the current SIP RA Type so this would be complicated (or impossible, haven't digged into this) to achieve.
An Sbb can do anything as a result of an incoming INVITE and need not necessarily cancel outstanding branches (although this is of course a natural thing to do)

But there has been a discussion to add support for proxying in a way similar to the Ã…roxy interface in the SIP Servlet spec. This could be done with a special proxy activity and the proxying would be done according to the choice of the application (statelessly/statefully e.t.c.)

> Terminating the dialog is appropriate for initial
> INVITEs, but not for reINVITEs

This is known.

jbemmel
Offline
Joined: 2005-03-01

> In my view a stateful proxy works according to:
>
> INVITE ---> Proxy ---> INVITE (Branch 1)
> ---> INVITE (Branch 2)
>
> CANCEL ---> Proxy
> OK <---
> 487 <--- (Response to the INVITE)
> ---> CANCEL (Branch 1)
> ---> CANCEL (Brnch 2)
>
> I.e. the stateful proxy does not wait until it gets a
> 487 response from a UAS before it responds 487 to the
> initial INVITE.
>
> If you think this is wrong please point to the
> relevant part of RFC 3261. I looked (briefly) at
> section 16 but I didn't find anything that determined
> this explicitly.
>

This is definitely wrong. The proxy needs to wait for the final responses from all branches as usual, sending the CANCELs triggers immediate 487s unless another final response has been sent by the time the CANCEL reaches the UAS

Relevant part in RFC3261 is section 16.10. Question to ask is: where does it say to generate a 487 response?

> > > Please note that if you implement a stateful
> proxy
> > > application step 3 (in the second post in this
> > > thread) should be the place to iterate over all
> > > branches.
> > > This is up to the application, not the
> > responsibility
> > > of the RA.
> >
> > Yes, you could leave this up to the application,
> but
> > it is very common behavior in which the
> application
> > really doesn't have much choice. Leaving this to
> the
> > application complicates things for the application
>
> There is no notion of a proxy in the current SIP RA
> Type so this would be complicated (or impossible,
> haven't digged into this) to achieve.
> An Sbb can do anything as a result of an incoming
> INVITE and need not necessarily cancel outstanding
> branches (although this is of course a natural thing
> to do)
>
> But there has been a discussion to add support for
> proxying in a way similar to the Ã…roxy interface in
> the SIP Servlet spec. This could be done with a
> special proxy activity and the proxying would be done
> according to the choice of the application
> (statelessly/statefully e.t.c.)
>
>

IMS is all about proxies, so I would suggest to add this if you want to support IMS

niklasuhrberg
Offline
Joined: 2004-11-02

> > In my view a stateful proxy works according to:
> >
> > INVITE ---> Proxy ---> INVITE (Branch 1)
> > ---> INVITE (Branch 2)
> >
> > CANCEL ---> Proxy
> > OK <---
> > 487 <--- (Response to the INVITE)
> > ---> CANCEL (Branch 1)
> > ---> CANCEL (Brnch 2)
> >
> > I.e. the stateful proxy does not wait until it gets
> a
> > 487 response from a UAS before it responds 487 to
> the
> > initial INVITE.
> >
> > If you think this is wrong please point to the
> > relevant part of RFC 3261. I looked (briefly) at
> > section 16 but I didn't find anything that
> determined
> > this explicitly.
> >
>
> This is definitely wrong. The proxy needs to wait for
> the final responses from all branches as usual,
> sending the CANCELs triggers immediate 487s unless
> another final response has been sent by the time the
> CANCEL reaches the UAS
>

OK, I'm convinced. Having given it some thought it makes a lot of sense because if the proxy does not wait for the final responses there is a race condition if a 200 OK arrives at the proxy after the 487 has been sent.

Thanks for pointing this out.

I guess the original proposal could be amended by:
1. Specifying that the RA only respond 487 to the original INVITE iff there is an associated dialog ACI.

2. Clarifying that the dialog is only ended if it is an initial INVITE that is being cancelled. (I saw that the 2nd posting is not detailed enough about this.)

> Relevant part in RFC3261 is section 16.10. Question
> to ask is: where does it say to generate a 487
> response?

As I said, there is no explicit information about this in 16.10 :=)

You are welcome to give your opinion on the behaviour of support for proxying in the SIP RA. This has not been discussed in detail yet but I suspect that something equivalent to the Proxy interface in the SIP Servlet spec is a good starting point.

Jeroen, how familiar are you with the core JSLEE constructs such as Activiy, Activity Context Interface and the like?

ben_evans
Offline
Joined: 2003-08-14

My earlier proposal was trying to be like SIP Servlet's cancel handling, where the container (or RA in this case) does all the work. However it has been correctly pointed out that this fails if the app needs to be a proxy.

It would be possible to handle cancels automatically if there was some support for proxying in the RA, like SIP Servlet's Proxy interface as Niklas suggests. A proxy activity perhaps? In this case the RA would know that a transaction is being proxied and handle the CANCEL appropriately. I think this is desirable but probably a bit too much to specify now, and there is no equivalent in JAIN SIP so it would be a big change. Maybe this can come in a later version of the RA type.

So at the moment I don't think we can have CANCELs handled fully automatically in the RA. There will have to be application involvement in some cases. I think Niklas' suggestion of having the RA respond to the CANCEL if there is an associated dialog activity is a good idea. How about this for a revised proposal:

1. CANCEL arrives at RA. RA checks to see if it matches a previous ServerTransaction. If there is a match, go to (2), else (3)

2. The CANCEL matches a previous ServerTransaction, here the RA can send a 200 OK response for the CANCEL.

2a. If there is also an associated dialog activity, the RA generates the 487 response and ends the dialog activity. The CANCEL event is fired on the ServerTransaction activity to inform the app. The app does not need to do anything else.

2b. If no dialog activity is present, then fire the CANCEL event on the ServerTransaction activity. The app must handle this as appropriately, ie. send a 487 if it is a UAS, or cancel pending branches if it is a proxy.

3. If there is no match, the CANCEL event must be passed up statelessly to the app - a proxy will need to statelessly forward this downstream. Here there is no activity to fire the event on, so the RA will need to create a "one-shot" dummy activity that ends immediately after the event is fired.

4. If the CANCEL did not match any previous ServerTransaction, and the CANCEL event in (3) was not processed by any SBBs (the RA can detect this in the event processing callbacks in the SLEE 1.1 RA API), then I think in this case the RA is safe to respond with "481 Call/Transaction Does Not Exist".

mranga
Offline
Joined: 2003-06-06

> My earlier proposal was trying to be like SIP
> Servlet's cancel handling, where the container (or RA
> in this case) does all the work. However it has been
> correctly pointed out that this fails if the app
> needs to be a proxy.
>
> It would be possible to handle cancels automatically
> if there was some support for proxying in the RA,
> like SIP Servlet's Proxy interface as Niklas
> suggests. A proxy activity perhaps? In this case the
> RA would know that a transaction is being proxied and
> handle the CANCEL appropriately. I think this is
> desirable but probably a bit too much to specify now,
> and there is no equivalent in JAIN SIP

But there is ..

sipProvider.setAutomaticDialogSupportEnabled(true)

Which tells the Stack that you want to behave like a User Agent for all requests associated with a given provider.

You may want to download the latest jain-sip 1.2 from the NIST repository and take a look.

I dont understand step 4. I think the SBB should be responsible for the 481 response in all cases.

> so it would be
> a big change. Maybe this can come in a later version
> of the RA type.
>
> So at the moment I don't think we can have CANCELs
> handled fully automatically in the RA. There will
> have to be application involvement in some cases. I
> think Niklas' suggestion of having the RA respond to
> the CANCEL if there is an associated dialog activity
> is a good idea. How about this for a revised
> proposal:
>
> 1. CANCEL arrives at RA. RA checks to see if it
> matches a previous ServerTransaction. If there is a
> match, go to (2), else (3)
>
> 2. The CANCEL matches a previous ServerTransaction,
> here the RA can send a 200 OK response for the
> CANCEL.
>
> 2a. If there is also an associated dialog activity,
> the RA generates the 487 response and ends the dialog
> activity. The CANCEL event is fired on the
> ServerTransaction activity to inform the app. The app
> does not need to do anything else.
>
> 2b. If no dialog activity is present, then fire the
> CANCEL event on the ServerTransaction activity. The
> app must handle this as appropriately, ie. send a 487
> if it is a UAS, or cancel pending branches if it is a
> proxy.
>
> 3. If there is no match, the CANCEL event must be
> passed up statelessly to the app - a proxy will need
> to statelessly forward this downstream. Here there is
> no activity to fire the event on, so the RA will need
> to create a "one-shot" dummy activity that ends
> immediately after the event is fired.
>
> 4. If the CANCEL did not match any previous
> ServerTransaction, and the CANCEL event in (3) was
> not processed by any SBBs (the RA can detect this in
> the event processing callbacks in the SLEE 1.1 RA
> API), then I think in this case the RA is safe to
> respond with "481 Call/Transaction Does Not Exist".

ben_evans
Offline
Joined: 2003-08-14

> > My earlier proposal was trying to be like SIP
> > Servlet's cancel handling, where the container (or
> RA
> > in this case) does all the work. However it has
> been
> > correctly pointed out that this fails if the app
> > needs to be a proxy.
> >
> > It would be possible to handle cancels
> automatically
> > if there was some support for proxying in the RA,
> > like SIP Servlet's Proxy interface as Niklas
> > suggests. A proxy activity perhaps? In this case
> the
> > RA would know that a transaction is being proxied
> and
> > handle the CANCEL appropriately. I think this is
> > desirable but probably a bit too much to specify
> now,
> > and there is no equivalent in JAIN SIP
>
>
> But there is ..
>
>
> sipProvider.setAutomaticDialogSupportEnabled(true)
>
> Which tells the Stack that you want to behave like a
> User Agent for all requests associated with a given
> provider.

But this is not equivalent to SIP Servlet's Proxy behaviour though, that is what I meant. In SIP Servlet, the container knows that a request is being proxied, and when the CANCEL arrives, it can automatically cancel any pending branches, no application involement is required. We cannot do this currently in a JAIN SIP RA because the RA does not know if a request has been proxied or not. It potentially could know this if there was an equivalent Proxy API.

> I dont understand step 4. I think the SBB should be
> responsible for the 481 response in all cases.

This was to handle the case where the CANCEL event was fired but was not processed by any SBBs, eg. the SBB was poorly written and did not have a CANCEL event handler.
Maybe it is not necessary to specify this, it is really an implementation detail. We could just say "make sure you write your SBBs properly and handle CANCEL etc" and leave it up to the RA implementation to clean up as best it can if events are not processed.

niklasuhrberg
Offline
Joined: 2004-11-02

> Because the CANCEL is fired on the INVITE's
> ServerTransaction activity, it does not matter
> whether the app is using Dialogs or not (assuming the
> app stays attached to the ServerTransaction, which it
> should). Also the behaviour will be the same for
> out-of-dialog and in-dialog CANCELs.
>
> I think NIST-SIP does something like this already
> (fires a CANCEL RequestEvent with the INVITE's
> ServerTransaction) but this behaviour is not
> explicitly specified in the JAIN SIP API (I think -
> Ranga?)
> Either way, the JAIN SIP RA Type does not have to map
> exactly to JAIN SIP, the RA Type should specify
> behaviour that is most useful for SBBs.
>

Looking back at our off-line discussion on this it seems you have changed this since then:

"CANCEL is a tricky one because it is not an in-dialog request. In the current OC
implementation it will be delivered on a separate ServerTransaction activity,
and the application must correlate it with a previous INVITE. JAIN SIP does not
have any special treatment of CANCEL requests. You will see in our demo proxy
SBB that we use an initial event selector method so that the CANCEL event goes
to the same root SBB entity as the previous INVITE. This is a bit messy, ideally
the API would do this correlation for us."

Firing the CANCEL on the ServerTransaction activity removes the problem of having to correlate the two transactions with an initial event selector which is good.

Please clarify on your current view of CANCEL for (in-dialog) re-INVITEs.

ben_evans
Offline
Joined: 2003-08-14

What I described in our earlier conversation is how the current OC implementation handles CANCELs, and this is still true.

The behaviour I described above is how I think it should work ideally, in a future standard SIP RA Type. It makes more sense to always deliver the CANCEL on the cancelled ServerTransaction activity (be it INVITE or any other method). This would be the same for in-dialog and out-of-dialog CANCELs.

We do not care about the ServerTransaction of the CANCEL itself, because a UAS should only ever send 200 OK, or 481 , in response to the CANCEL. The RA can easily do this automatically using the procedure above.

niklasuhrberg
Offline
Joined: 2004-11-02

> What I described in our earlier conversation is how
> the current OC implementation handles CANCELs, and
> this is still true.
>

OK, sorry for the misunderstanding.

> The behaviour I described above is how I think it
> should work ideally, in a future standard SIP RA
> Type. It makes more sense to always deliver the
> CANCEL on the cancelled ServerTransaction activity
> (be it INVITE or any other method). This would be the
> same for in-dialog and out-of-dialog CANCELs.
>
> We do not care about the ServerTransaction of the
> CANCEL itself, because a UAS should only ever send
> 200 OK, or 481 , in response to the CANCEL. The RA
> can easily do this automatically using the procedure
> above.

This makes a lot of sense to mee too.

I have spelled out the contents of our conversation in a document that I would like us to use to describe the behaviour of a SIP RA Type.
I'll point you to it soon for comments.
It's kind if a draft now.

jbemmel
Offline
Joined: 2005-03-01

2 remarks:
- JAIN SIP does handle CANCEL specially: the ServerTransaction passed to the listener in processRequest() is the INVITE ServerTransaction being cancelled, not a ServerTransaction for the CANCEL (!)

- the behavior you are describing is appropriate only for endpoint applications. A stateless proxy application would forward the CANCEL and *not* send a 487, a stateful proxy would iterate over all branches

It would be good to shield JAIN SLEE applications from this. I am not familiar with the architecture, but what I would expect is some kind of application descriptor in which the application states `I need X SIP ports, and per SIP port which transports and whether it wants to be proxy or endpoint application´. The RA would then assign concrete ports (5060, 5061, etc), and create the required SipProviders, ListeningPoints, etc
The RA would also set the automatic dialog property appropriately on each SipProvider it creates for the app

How do you currently demultiplex SIP messages to applications?

Drop me an email if you would like to discuss this further

Regards,

jeroen

mranga
Offline
Joined: 2003-06-06

> 2 remarks:

> - the behavior you are describing is appropriate only
> for endpoint applications. A stateless proxy
> application would forward the CANCEL and *not* send a
> 487, a stateful proxy would iterate over all
> branches
>

Jeroen,

Finally some supporter of the automatic dialog suport multiple provider idea! I agree this is a better way to do things but I think popular opinion is contrary to this approach (I really wonder why). Ref: "Automatic dialog support " thread to which you have already posted I see.

> It would be good to shield JAIN SLEE applications
> from this. I am not familiar with the architecture,
> but what I would expect is some kind of application
> descriptor in which the application states `I need X
> SIP ports, and per SIP port which transports and
> whether it wants to be proxy or endpoint
> application´. The RA would then assign concrete ports
> (5060, 5061, etc), and create the required
> SipProviders, ListeningPoints, etc
> The RA would also set the automatic dialog property
> appropriately on each SipProvider it creates for the
> app
>
> How do you currently demultiplex SIP messages to
> applications?
>
> Drop me an email if you would like to discuss this
> further
>
> Regards,
>
> jeroen

jbemmel
Offline
Joined: 2005-03-01

Mobicents wants to be the 'open source IMS platform'. I don't see how you can host e.g. a P-CSCF and S-CSCF on one machine using a single SipProvider

ben_evans
Offline
Joined: 2003-08-14

Hi Niklas, I agree that handling CANCELs could be made much easier for SBBs. The RA should do as much work as possible, where the protocol allows it, to make SBBs simpler.
I think that the CANCEL event should be handled as follows:

1. RA receives the CANCEL request.
- if it matches a previous INVITE ServerTransaction, then send a 200 OK response for the CANCEL. Go to (2).
- if it does not match a previous INVITE ServerTransaction, then send a "481 Call leg/Transaction Does Not Exist" response for the CANCEL and stop processing here.

2. If the INVITE ServerTransaction has already sent a final response, then drop the CANCEL, as it is too late.
Otherwise, send a 487 response on the INVITE ServerTransaction, and fire a CANCEL RequestEvent on the INVITE ServerTransaction activity.
If the INVITE transaction had initiated a Dialog activity, the RA should end the Dialog activity too.

3. When the SBB receives the CANCEL event, it takes appropriate action, such as cancelling any ClientTransactions that it initiated.
It does not need to do anything else with the CANCEL event (it is just a notification), as the RA has already generated the responses.

I think having a generic "handleCancellation" method on the RA is not necessary since the RA can generate the required responses (on the UAS side), and the SBB must still decide what to with it's ClientTransactions. We know a proxy must cancel its branches but a B2BUA could potentially do anything it likes.

In step (2) there is a potential race between the SBB sending a final response and the RA firing the CANCEL event. It must be up to the RA implementation to resolve this. For example, if the SBB tries to send after the RA has fired the CANCEL event, the RA could detect this and throw an IllegalStateException.

Because the CANCEL is fired on the INVITE's ServerTransaction activity, it does not matter whether the app is using Dialogs or not (assuming the app stays attached to the ServerTransaction, which it should). Also the behaviour will be the same for out-of-dialog and in-dialog CANCELs.

I think NIST-SIP does something like this already (fires a CANCEL RequestEvent with the INVITE's ServerTransaction) but this behaviour is not explicitly specified in the JAIN SIP API (I think - Ranga?)
Either way, the JAIN SIP RA Type does not have to map exactly to JAIN SIP, the RA Type should specify behaviour that is most useful for SBBs.

Ben

niklasuhrberg
Offline
Joined: 2004-11-02

Hi Ben, your suggestion about the RA behaviour for CANCEL looks good to me.

I brought up the alternative with the application invoking the helper method (handleCancellation) partly because there could be other methods than INVITE that are cancelled the behaviour of which we don't know. (INVITE is the only method commonly referred to and the only core SIP method suitable for cancellation)
The RA could then easily be adapted to take care of these methods.
This may be too cautious...

(Also note that the handleCancellation method was only meant to do perform standard duties as responding 487 to the cancelled transaction, not application specific logic like cancelling branches in the proxy case)

> Because the CANCEL is fired on the INVITE's
> ServerTransaction activity, it does not matter
> whether the app is using Dialogs or not (assuming the
> app stays attached to the ServerTransaction, which it
> should). Also the behaviour will be the same for
> out-of-dialog and in-dialog CANCELs.

This seems to contradict an earlier statement made off-line:

"The javax.sip.message.Request.CANCEL will be fired when an initial INVITE is cancelled. The activity will be the ServerTransaction that the CANCEL was received on. If an in-dialog re-INVITE is cancelled then that will cause a
javax.sip.dialog.Request.CANCEL to be fired on the Dialog activity, because it is an in-dialog request."

Has there been a change here since this conversation?