Skip to main content

Automatic dialog support per provider & SIP RA Type

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

If I may continue from offline conversation:

>After talking to Ranga for a while it turned out that the >dialog support has to be anabled or disabled per >provider. This means that if you want to have an RA with >dialog support and another faster one (for
>proxies) without dialog support, then you would need to >have 2 sip providers listening to two different ports. >Potentially all UAs will initially connect to the fast >provider without dialog support and if needed they will >be either redirected to the other one or a server
>side forward will be used. The latter adds overhead >because each future UA request will have to be marshalled >to java objects and back to the network twice.

1. Spontaneously I think it's rather awkward to introduce listeners on different ports just to differentiate the dialog support for different applications. It seems you are on the same road.

2. Up until now, before I knew that automatic dialog support is configured per provider in JSIP 1.2, I had just assumed that no applications would assume that this is enabled in a JSLEE container. This is because it is easy to obtain the dialogs anyway and the performance penalty should not be acceptable if there are applications that do not need it.
But of course there can be situations where all applications use dialogs.

I just want to stress that using JSIP 1.2 with automatic dialog support disabled should not be a big problem at all. All you have to do as an application writer is to obtain the dialog before the request is sent (if you're the client transaction) and, correspondiingly obtain the dialog before any response is sent (if you're the server transaction).

Comments?

I have the idea that instead we can configure the JSLEE to "prepare the dialogs" for the application instead of using JSIP for this. I realize though that the architecture may not be optimal for this in that the RA related responsibilities are not per service...

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mranga
Offline
Joined: 2003-06-06

> > I'm not familiar with the internals of the JAIN
> SIP
> > 1.2 RI, but in the OC stack we still do all the
> > dialog checking for dialogs that apps have
> created,
> > even with automatic dialog support off. I assumed
> > the RI/Mobicents RA did something similar but
> maybe
> > not?
>
> OK, now for the fundamental question:
>
> Does JAIN SIP specify the behaviour in this regard?
> This is a very important question.

The only question at hand is what to do when a request that must belong to a dialog in the case of a UA comes to the stack and the stack does not know what to do when such a message arrives -- i.e. should it respond with an error or pass it to the application. I think we have decided that in case automatic dialog support is turned off for a given provider, the application will see the request and is responsible for sending the appropriate error responses if needed.

>
> That is: Should the sip stack act the same way for an
> existing dialog irrespectively of the automatic
> dialog support for the provider?
> This is the OC interpretation and the opposite logic
> is implementd in the RI.

Niklas, your interpretation is correct. Why do you state that the opposite logic is implemented in the RI? (what leads you to that conclusion?)

niklasuhrberg
Offline
Joined: 2004-11-02

> > OK, now for the fundamental question:
> >
> > Does JAIN SIP specify the behaviour in this
> regard?
> > This is a very important question.
>
>
> The only question at hand is what to do when a
> request that must belong to a dialog in the case of a
> UA comes to the stack and the stack does not know
> what to do when such a message arrives -- i.e. should
> it respond with an error or pass it to the
> application. I think we have decided that in case
> automatic dialog support is turned off for a given
> provider, the application will see the request and is
> responsible for sending the appropriate error
> responses if needed.

>
> >
> > That is: Should the sip stack act the same way for
> an
> > existing dialog irrespectively of the automatic
> > dialog support for the provider?
> > This is the OC interpretation and the opposite
> logic
> > is implementd in the RI.
>
> Niklas, your interpretation is correct. Why do you
> state that the opposite logic is implemented in the
> RI? (what leads you to that conclusion?)

Because the checking logic in the NistSipMessageHandlerImpl class does some checking only if automatic dialog support is enabled. It does not check if there is an existing dialog that the request is a part of and acts dialog statefully irrespective of whether automatic dialog support is enabled or not.

mranga
Offline
Joined: 2003-06-06

Niklas and Ben,

I think I have a better idea of what you guys are proposing now that I have seen the details of your arguments. In matters of programming, I dont have a religious point of view so I'll go along with the single provider proposal whith some caveats.

The conclusion I have is this. Your scheme would work but the application may see some requests that would not be seen with automatic dialog support enabled and one would just need to write the application to handle these requests. Briefly, here is an enumeration of he cases that are being checked in the code and for which you either have to provide an equivalent mechansm or you have to provide clear instructions to programmers of SBBS. OK fine, lets go with the single provider model but lets come up with mechansms to handle the following (i.e. either mechanisms or clear documentation of behavior so as to make applications portable across RA vendors ).

1. PRACK - if a Prack comes in and a dialog is not found for the PRACK. If the Dialog does not exist (or has never existed) for the PRACK, then pass up to the application. I dont think it is a good idea to expect either the stack or RA to keep memory of dialogs that have been terminated. IN this case it shall be the Application's responsibility to deliver the 481.

2. BYE - if a Dialog does not exist for the BYE, same as above -- i.e. pass to te application and let the application be responsible for the 481 if needed.

3. CANCEL -- this should always be passed to the listener (i.e. RA) if an INVITE Transaction corresponding to the CANCEL is not found. A CANCEL should be proxied by a proxy server even if it does have a matching INVITE. If the application wants to be a UA, then it is responsible for the 481.

4. ACK -- Dropped iff Dialog exists and ACK has already been processed by application. Pass up to the application otherwise.

5. NOTIFY -- If a Dialog exists for the NOTIFY, check if the request is consumable (ie. check sequence number) and drop if request is not consumable. Else, pass up to the application. The application must remember if there is a pending subscription and return the appropriate error if there is no such subscription. i.e. it is responsible for the 481.

5. Any other in-dialog and out of sequence Request is dropped iff a Dialog exists for the Request.

There are probably some cases I missed but hows that for a start.

Ranga

> Now I think it's clear that we have different view on
>
>
> 1. The actual work that is performed by the RA
> (meaning it's contract to the Sbbs) when the
> application creates the dialogs with
> SipProvider.getNewDialog.
>
> 2. The problems that can/cannot be solved with the
> model described in the draft proposal. (Dialog
> related issued with a single provider model)
>
> In the Mobicents RA the checking logic is performed
> by the stack and this logic is performed iff
> automatic dialog support is enabled.
> Ben, you said you go along the lines of
> interpretation no 2 in my distinction above. Does
> this mean that this is what you have implemented
> already or is it what you would like to see?
>
> I would prefer the sip stack to do the dialog
> specific checking logic even if automatic dialog
> support is disabled (for the logic that is applicable
> given that a request/response is aimed for an
> existing/previously existing dialog).
> Are there any arguments against this?
> It may be that we have different implementations of
> JAIN SIP in this regard here.
>
> To get forward I suggest that we get more into detail
> for point 2 above.
>
> Let's try to come up with a event proposal to answer
> Rangas questions about how to handle forked
> subscriptions and invites for example.
>
> Now suppose that it is possible to appropriately
> support all that situations claimed problematic with
> a single provider model, is there any other argument
> in favour of the two provider model?
>
> One of my objections with the two provider model is
> that clients directing SIP messages agains a JSLEE
> app server cannot simply send them onto it. They must
> choose one of two ports depending on whether the
> message is to be handled dialog statefully or not.
>
> This situation can be dealt with by redirecting or
> forwarding from the transaction stateful provider to
> the dialog stateful provider but it is nevertheless a
> disadvantage.
>
> I did go through some of the code in
> NistSipMessageHandlerImpl. Although well documentened
> on a low level it was not trivial for me to follow.
> (the processRequest method is 588 lines)
> Ranga, to aid the debate here, would it be possible
> for you to compile a list if the scenarios (with a
> proper categorization of their "nature") managed by
> this class concerning dialog statefulness.
>
> If we agree that some of the checking logic ought to
> be done even with automatic dialog support disabled,
> would it be easy to do this change?

niklasuhrberg
Offline
Joined: 2004-11-02

> 3. CANCEL -- this should always be passed to the
> listener (i.e. RA) if an INVITE Transaction
> corresponding to the CANCEL is not found. A CANCEL
> should be proxied by a proxy server even if it does
> have a matching INVITE. If the application wants to
> be a UA, then it is responsible for the 481.

I don't follow this part.
Did you have a look at the dialog extension proposal about CANCEL?

It specifies that the RA respond 200 OK to the CANCEL request and a 487 Request terminated to the cancelled transaction.

As I understand it this only assumes that the RA is not acting as a stateless proxy. This is because for stateful proxies the CANCEL is hop-by-hop.

An Sbb gets a Cancel event fired but only as a notification, it never has to do the responding only take care of its outstanding transaction or whatever is the situation.

ben_evans
Offline
Joined: 2003-08-14

> > > With dynamic dialog creation under application
> > control,
> > > you would be burdening the applicaton with all
> this
> >
> > > checking logic which is in the stack already.
> >
> > What is "all this checking logic"?
>
> I'll point you at some code.
> NistSipMessageHandlerImpl.java in the jain-sip-1.2 RI
> if you have the time. Its not complicated.

Thanks, I've had a look but I don't think it changes anything. The stack knows about dialogs that apps have created, so it can still do all the dialog-related processing for those dialogs.

> Once the
> > application has initially created the dialog, the
> RA
> > is still responsible for the dialog state, and can
> > handle retransmits and out-of-order messages etc.
> The
> > only difference is that the application has the
> extra
> > step of creating the dialog. I don't see this as
> > creating much work for the application at all.
> >
> > Another potential problem raised earlier was what
> > happens if a BYE arrives for a dialog that has
> > already ended? Well, an RA could look at the
> request,
> > see that it was intended for a UA at this host (by
> > looking at the Request-URI and Route), and if it
> > can't find a matching dialog activity then it can
> > safely conclude that the BYE was intended for a
> > dialog that no longer exists and send a "481 Call
> > does not exist" response.
>
>
> This is precisely what the stack is doing. Why do
> you want to duplicate in the RA the function that the
> stack is already doing?

The RA is not duplicating this function. Assuming you have an RA that includes a JAIN SIP stack, if the SBB calls getNewDialog() on the RA, the RA would presumably call getNewDialog() on the stack, so that the dialog is created in the stack. So from that point the stack knows that the dialog exists and can handle subsequent messages appropriately. Once the dialog has ended in the stack, it must pass messages up to the RA. At that point the RA can be a bit "smarter" and decide if it needs to send a 481 response etc.

But the RA implementation could be anything, it does not even need to use a JAIN SIP stack, as long as it implements the interfaces required by the RA Type.

> What if the application
> decides it does not want to be dialog stateful? Then
> this would be the wrong thing to do.

Do you mean if we have an application/SBB that does not use dialogs but externally looks like it does, ie. it generates the same responses & tags that a dialog stateful app would? This is a tricky one and it would break my BYE idea above. I think this could be handled in 2 ways:

(1) The RA Type specification could say "don't do this", since it is much easier for the SBB developer to use a dialog anyway, they don't have to keep track of tags and sequence numbers etc.

(2) The RA implementation could detect dialogs that have been created by an SBB calling getNewDialog(), perhaps inserting a special token in a tag, which will be preserved in all future requests in this dialog. If the BYE comes along and the stack does not have a dialog for it, it can pass it up to the RA, who can look for the token and detect that this request is for a dialog that no longer exists, and send the 481 response. Otherwise it just passes the BYE up to the SLEE, as a RequestEvent on a ServerTransaction activity, so our non-dialog-stateful app can still receive it.

> What will you do if a NOTIFY which does not belong to
> any dialog comes your way?

Same as above, if it does not match any current dialog and was not from a SBB-created dialog that has already ended, then just pass the NOTIFY up to the SLEE.

If the SBB is dialog-stateful, it must already have created the dialog before it sent the SUBSCRIBE. If the NOTIFY arrived before the 200 OK for the SUBSCRIBE, then the stack can tell that the NOTIFY is part of that dialog, and make the dialog "confirmed".

> What will you do about forked SUBSCRIPTIONS?

For any forked request we will need an event that tells the SBB that a fork has occurred and there is a new dialog created. This would be required whether or not automatic dialog support is enabled.

In the case of the forked SUBSCRIBE, this event (or similar) will also have to be fired if a NOTIFY is received on a forked dialog first.

>
>
> The application is not
> > involved.
> >
> > Forking is another complication but this is
> difficult
> > whether or not you have automatic dialog support
> > enabled. If the application creates a dialog, then
> it
> > must be prepared to handle additional dialogs
> > resulting from a forked request. This extra
> > complexity is a requirement of the SIP protocol -
> all
> > user agents must be able to handle this case.
>
>
> Your RA does not know whether the application wants
> to be a User agent or a Proxy server and in your
> model you have no mechanism by means of which you
> tell the Stack apriori. Why would you go ahead and
> create dialogs for proxy servers that are handling
> forked requests?

I am not suggesting creating dialogs for proxy servers. The above would only apply if the application had created a dialog - it would then receive events informing it about the new "forked" dialogs. A proxy server would just receive response events with no dialog state, since it never created a dialog.

The stack/RA can know apriori how the application wants to behave. By the time a response or mid-dialog request arrives, the application must have already created the dialog if it wanted to.

> The RA
> > Type should make it easy for the app to detect
> this
> > (eg. a seperate event signalling that a new dialog
> > was created) and the application can choose to use
> or
> > end these dialogs.
> >
> > So I think you are imagining creating dialogs to
> > cause much more work for the application, when
> this
> > is not the case. The RA can still do all the
> > low-level dialog state stuff.
>
> No it cant because it does not know apriori whether
> the application wants to be dialog stateful or not.

I hope I have shown that it does, because if the application wants to be dialog-stateful it must call getNewDialog() before sending the request or any responses. So when subsequent messages arrive, the stack/RA will know if there is a dialog present and how the messages should be handled.

Cheers
Ben

> Perhaps I dont understand how you propose to handle
> the cases above. In any case, those are my thoughts.
>
>
> Ranga

ben_evans
Offline
Joined: 2003-08-14

> Actually there is more than just out of order bye
> processing. Consider other cases than just INVITE
> processing. SUBSCRIBE NOTIFY is notorious. Also dont
> forget that INVITE and SUBSCRIBE can be forked.

I am thinking responses to forked requests that create new dialogs should be another type of dialog event, like the Early/Confirmed events in Niklas' draft RA type spec. With SUBSCRIBE/NOTIFY (I assume you are talking about the requirement for a NOTIFY to create a dialog if it arrives before the SUBSCRIBE's 200 OK response - man I love SIP! ;) ) this can probably be dealt with in a similar manner... I'll need to think about this some more...

> Perhaps Ben can explain why dialog and non-dialog
> applications cannot co-exist in my proposal of having
> multiple providers with specified roles. What is
> wrong with that proposal? Any gotchas?

Maybe I don't understand your proposal properly, but I can't see how the SBB "chooses" the provider in advance. In the SBB deployment descriptor you can specify a JNDI binding to a particular RA Entity, which implements an RA Type. Do you create 2 RA entities and let the SBB deployer choose one? Or I suppose you could have a single RA Entity that implemented different RA Types, and have the SBB bind to the dialog-stateful or non-dialog-stateful RA Type.

I am sure you can make it work, it just seems unnecessarily complicated to me.

> I like a nice clean declarative model where you tell
> the stack as much as possible about your intended
> behavior apriori on a provider (i.e. I want to be a
> ua vs proxy) so the stack can do as much processing
> and filtering as possible before the application sees
> a request.

I would like to see a single model that all types of SIP applications can use. You are effectively creating 2 slightly different models, and creating an unnecessary dependency between the RA Type and the implementation. The RA Type should provide a clean model where the SBB does not need to know how it is implemented.

If we have a single model for handling dialogs (automatic dialog support always off, SBBs create dialogs when needed) the RA can still do dialog processing etc, but it only does this for dialogs that SBBs have created.

mranga
Offline
Joined: 2003-06-06

>

> Maybe I don't understand your proposal properly, but
> I can't see how the SBB "chooses" the provider in
> advance. In the SBB deployment descriptor you can
> specify a JNDI binding to a particular RA Entity,
> which implements an RA Type. Do you create 2 RA
> entities and let the SBB deployer choose one? Or I
> suppose you could have a single RA Entity that
> implemented different RA Types, and have the SBB bind
> to the dialog-stateful or non-dialog-stateful RA
> Type.

Or both I suppose if you expect to act like a UA on some requests and a proxy on others.

One of these schemes would work. Sorry I have not been looking at SLEE for some time so my SLEEze is a bit rusty.

>
> I am sure you can make it work, it just seems
> unnecessarily complicated to me.

Would you rather that the application deal with more complex processing in order to handle the error conditions we have been talkng about?

>
> I would like to see a single model that all types of
> SIP applications can use. You are effectively
> creating 2 slightly different models, and creating an
> unnecessary dependency between the RA Type and the
> implementation. The RA Type should provide a clean
> model where the SBB does not need to know how it is
> implemented.

There are two markedly different behaviors in SIP - user agents and Proxy servers. So you provide two different RA types or something like that. I dont see an issue.

>
> If we have a single model for handling dialogs
> (automatic dialog support always off, SBBs create
> dialogs when needed) the RA can still do dialog
> processing etc, but it only does this for dialogs
> that SBBs have created.

With dynamic dialog creation under application control, you would be burdening the applicaton with all this checking logic which is in the stack already. I am not sure I got it all right after some years of looking at SIP. Seems like a good place to handle possible errors would be as low in the processng as possible.

ben_evans
Offline
Joined: 2003-08-14

I think we are visualizing different things when we think about SBBs creating and using dialogs. You say:

> With dynamic dialog creation under application control,
> you would be burdening the applicaton with all this
> checking logic which is in the stack already.

What is "all this checking logic"? Once the application has initially created the dialog, the RA is still responsible for the dialog state, and can handle retransmits and out-of-order messages etc. The only difference is that the application has the extra step of creating the dialog. I don't see this as creating much work for the application at all.

Another potential problem raised earlier was what happens if a BYE arrives for a dialog that has already ended? Well, an RA could look at the request, see that it was intended for a UA at this host (by looking at the Request-URI and Route), and if it can't find a matching dialog activity then it can safely conclude that the BYE was intended for a dialog that no longer exists and send a "481 Call does not exist" response. The application is not involved.

Forking is another complication but this is difficult whether or not you have automatic dialog support enabled. If the application creates a dialog, then it must be prepared to handle additional dialogs resulting from a forked request. This extra complexity is a requirement of the SIP protocol - all user agents must be able to handle this case. The RA Type should make it easy for the app to detect this (eg. a seperate event signalling that a new dialog was created) and the application can choose to use or end these dialogs.

So I think you are imagining creating dialogs to cause much more work for the application, when this is not the case. The RA can still do all the low-level dialog state stuff.

mranga
Offline
Joined: 2003-06-06

> I think we are visualizing different things when we
> think about SBBs creating and using dialogs. You
> say:
>
> > With dynamic dialog creation under application
> control,
> > you would be burdening the applicaton with all this
>
> > checking logic which is in the stack already.
>
> What is "all this checking logic"?

I'll point you at some code. NistSipMessageHandlerImpl.java in the jain-sip-1.2 RI if you have the time. Its not complicated.

Once the
> application has initially created the dialog, the RA
> is still responsible for the dialog state, and can
> handle retransmits and out-of-order messages etc. The
> only difference is that the application has the extra
> step of creating the dialog. I don't see this as
> creating much work for the application at all.
>
> Another potential problem raised earlier was what
> happens if a BYE arrives for a dialog that has
> already ended? Well, an RA could look at the request,
> see that it was intended for a UA at this host (by
> looking at the Request-URI and Route), and if it
> can't find a matching dialog activity then it can
> safely conclude that the BYE was intended for a
> dialog that no longer exists and send a "481 Call
> does not exist" response.

This is precisely what the stack is doing. Why do you want to duplicate in the RA the function that the stack is already doing? What if the application decides it does not want to be dialog stateful? Then this would be the wrong thing to do.

What will you do if a NOTIFY which does not belong to any dialog comes your way?

What will you do about forked SUBSCRIPTIONS?

The application is not
> involved.
>
> Forking is another complication but this is difficult
> whether or not you have automatic dialog support
> enabled. If the application creates a dialog, then it
> must be prepared to handle additional dialogs
> resulting from a forked request. This extra
> complexity is a requirement of the SIP protocol - all
> user agents must be able to handle this case.

Your RA does not know whether the application wants to be a User agent or a Proxy server and in your model you have no mechanism by means of which you tell the Stack apriori. Why would you go ahead and create dialogs for proxy servers that are handling forked requests?

The RA
> Type should make it easy for the app to detect this
> (eg. a seperate event signalling that a new dialog
> was created) and the application can choose to use or
> end these dialogs.
>
> So I think you are imagining creating dialogs to
> cause much more work for the application, when this
> is not the case. The RA can still do all the
> low-level dialog state stuff.

No it cant because it does not know apriori whether the application wants to be dialog stateful or not.

Perhaps I dont understand how you propose to handle the cases above. In any case, those are my thoughts.

Ranga

niklasuhrberg
Offline
Joined: 2004-11-02

Now I think it's clear that we have different view on

1. The actual work that is performed by the RA (meaning it's contract to the Sbbs) when the application creates the dialogs with SipProvider.getNewDialog.

2. The problems that can/cannot be solved with the model described in the draft proposal. (Dialog related issued with a single provider model)

In the Mobicents RA the checking logic is performed by the stack and this logic is performed iff automatic dialog support is enabled.
Ben, you said you go along the lines of interpretation no 2 in my distinction above. Does this mean that this is what you have implemented already or is it what you would like to see?

I would prefer the sip stack to do the dialog specific checking logic even if automatic dialog support is disabled (for the logic that is applicable given that a request/response is aimed for an existing/previously existing dialog).
Are there any arguments against this?
It may be that we have different implementations of JAIN SIP in this regard here.

To get forward I suggest that we get more into detail for point 2 above.

Let's try to come up with a event proposal to answer Rangas questions about how to handle forked subscriptions and invites for example.

Now suppose that it is possible to appropriately support all that situations claimed problematic with a single provider model, is there any other argument in favour of the two provider model?

One of my objections with the two provider model is that clients directing SIP messages agains a JSLEE app server cannot simply send them onto it. They must choose one of two ports depending on whether the message is to be handled dialog statefully or not.

This situation can be dealt with by redirecting or forwarding from the transaction stateful provider to the dialog stateful provider but it is nevertheless a disadvantage.

I did go through some of the code in NistSipMessageHandlerImpl. Although well documentened on a low level it was not trivial for me to follow. (the processRequest method is 588 lines)
Ranga, to aid the debate here, would it be possible for you to compile a list if the scenarios (with a proper categorization of their "nature") managed by this class concerning dialog statefulness.

If we agree that some of the checking logic ought to be done even with automatic dialog support disabled, would it be easy to do this change?

ben_evans
Offline
Joined: 2003-08-14

Hi Niklas, I didn't see your message before posting my last one. It describes an approach you could potentially use to handle tricky stuff like forking. Obviously there is much more detail required but I don't see any big problems. Note I have not implemented this handling of forking and SUBSCRIBE/NOTIFY yet, those are just ideas off the top of my head.

> In the Mobicents RA the checking logic is performed
> by the stack and this logic is performed iff
> automatic dialog support is enabled.
> Ben, you said you go along the lines of
> interpretation no 2 in my distinction above. Does
> this mean that this is what you have implemented
> already or is it what you would like to see?

In the OC RA, automatic dialog support is always off, but for dialogs that have been created by applications, the stack still does the necessary checking logic for those dialogs. So yes we have implemented it this way, and I would prefer to see the future SIP RA Type do something similar so that dialog-statful and non-dialog-stateful apps can be supported with a single RA Type.

> I would prefer the sip stack to do the dialog
> specific checking logic even if automatic dialog
> support is disabled (for the logic that is applicable
> given that a request/response is aimed for an
> existing/previously existing dialog).
> Are there any arguments against this?
> It may be that we have different implementations of
> JAIN SIP in this regard here.

I'm not familiar with the internals of the JAIN SIP 1.2 RI, but in the OC stack we still do all the dialog checking for dialogs that apps have created, even with automatic dialog support off. I assumed the RI/Mobicents RA did something similar but maybe not?

niklasuhrberg
Offline
Joined: 2004-11-02

> > In the Mobicents RA the checking logic is
> performed
> > by the stack and this logic is performed iff
> > automatic dialog support is enabled.
> > Ben, you said you go along the lines of
> > interpretation no 2 in my distinction above. Does
> > this mean that this is what you have implemented
> > already or is it what you would like to see?
>
> In the OC RA, automatic dialog support is always off,
> but for dialogs that have been created by
> applications, the stack still does the necessary
> checking logic for those dialogs. So yes we have
> implemented it this way, and I would prefer to see
> the future SIP RA Type do something similar so that
> dialog-statful and non-dialog-stateful apps can be
> supported with a single RA Type.
>
> > I would prefer the sip stack to do the dialog
> > specific checking logic even if automatic dialog
> > support is disabled (for the logic that is
> applicable
> > given that a request/response is aimed for an
> > existing/previously existing dialog).
> > Are there any arguments against this?
> > It may be that we have different implementations
> of
> > JAIN SIP in this regard here.
>
> I'm not familiar with the internals of the JAIN SIP
> 1.2 RI, but in the OC stack we still do all the
> dialog checking for dialogs that apps have created,
> even with automatic dialog support off. I assumed
> the RI/Mobicents RA did something similar but maybe
> not?

OK, now for the fundamental question:

Does JAIN SIP specify the behaviour in this regard? This is a very important question.

That is: Should the sip stack act the same way for an existing dialog irrespectively of the automatic dialog support for the provider?
This is the OC interpretation and the opposite logic is implementd in the RI.

ivelin
Offline
Joined: 2003-07-13

Is it reasonable to think that we can come to an agreement by the end of next week - May 26? The timing will be good for updating the draf and sending a proposal for appendix to JSR 240.

Is anyone not going to be able to participate in the discussion next week, but feels strongly about being part of the design decisions?

Ivelin

ivelin
Offline
Joined: 2003-07-13

> [Niklas]: Let's see if I interpret Ivelins suggestion
> correctly:
>
> In order to combine simple application writing (not
> having to take care of the error management for
> dialogs) and the goal of running the SIP RA on only
> one port there are two RAs sharing one SipProvider.
>
> This SipProvider is configured with no automatic
> dialog support.
>
> It is up to the Dialog SIP RA to implement the dialog
> specific mechanisms now implemented in
> NistSipMessageHandlerImpl.
>
> The two RAs running in a JSLEE container would have
> to be registered as SipListeners in some event
> dispatcher because of the unicast event model in JAIN
> SIP.

Yes. This is exactly what I am suggesting.

>
> The question now is what situations could benefit
> from this.
> Take for instance the BYE which does not belong to a
> dialog. Rangas point in this example is that the
> stack should handle this and send a "Call not found"
> response.
> This would be the behaviour of the Dialog SIP RA but
> then (if the Dialog SIP RA gets the request first)
> the Transaction SIP RA (or its interested Sbbs) could
> not handle the request at all because the transaction
> has already terminated.
> In this example things could maybe be fixed by
> changing the invocation order.

Good use case.

Can you elaborate what you mean by changing the invocation order?

Simply saying that the SIP Tx RA receives from the underlying SIP Provider events before the SIP Dialog RA, does not help much. Even if the SIP Tx RA fires a BYE to the SLEE, the SIP Dialog RA can receive its copy and respond before any of the SBBs interested in the BYE have a chance to process it.

More generally this BYE use case falls in the class of feature interaction problems that are best resolved at SBB design or deployment time.

Similar problem can occur when there are two root SBBs listening to JAIN SIP 1.1 RA events. One responding to a Request event can potentially put the other one in a situation where it cannot do much about the state of the SIP transaction.

Well designed and documented SBBs is the way to resolve this kind of issues as well as channels for interaction between them, such as shared attributes and priorities.

The main point of the Watchdog example was to make sure that we make *possible* to implement as many use cases as we can.

Even though the suggestion was about two separate RAs, if it would be more convenient we could just have a single RA Type that creates two types of activities - SIP TX and SIP Dialog.

Ivelin

niklasuhrberg
Offline
Joined: 2004-11-02

> Can you elaborate what you mean by changing the
> invocation order?
>
> Simply saying that the SIP Tx RA receives from the
> underlying SIP Provider events before the SIP Dialog
> RA, does not help much. Even if the SIP Tx RA fires a
> BYE to the SLEE, the SIP Dialog RA can receive its
> copy and respond before any of the SBBs interested in
> the BYE have a chance to process it.
>
> More generally this BYE use case falls in the class
> of feature interaction problems that are best
> resolved at SBB design or deployment time.
>
> Similar problem can occur when there are two root
> SBBs listening to JAIN SIP 1.1 RA events. One
> responding to a Request event can potentially put the
> other one in a situation where it cannot do much
> about the state of the SIP transaction.
>
> Well designed and documented SBBs is the way to
> resolve this kind of issues as well as channels for
> interaction between them, such as shared attributes
> and priorities.

Yes, I meant simply changing the order in which the RAs get the BYE request and I am aware of that this does not solve the problem by itself.

But it at least lets us the opportunity to manage the situation by taking appropriate action. In this particular case, if the BYE was forwarded by a proxy like appication the Dialog SIP RA should probably not receive the event at all.

Right now I'd like to achieve consensus on what exactly the difference is between using SipProvider.getNewDialog and having automatic dialog support enabled. The focus should be on what complexities the application must manage itself. (Will take a look at the source code referred to by Ranga next step)

niklasuhrberg
Offline
Joined: 2004-11-02

> Niklas,
>
> You are right. You would have to wait till the
> listener either calls
> SipProvider.createDialog(transaction) or not. i.e.
> you have to wait till the listener completes
> execution.

Isn't it even worse?

Suppose that an original INVITE arrives at the RA and a invite event is fired.
The Sbb can now use a timer to schedule a timerevent to be fired in say a few fractions of a second and return from the onInviteEvent method without having sent a response or created a dialog.

When the timerevent is fired it can proceed by creating a dialog and sent a response to the invite.
The RA would have to monitor the sending of a response (not the return from the SipListener.processRequest method) to know the applications decision about dialog creation.

Do you agree with this example?

> Actually there are further issues to consider. The
> automatic dialog support flag is essentially telling
> the stack "I will behave like a user agent on this
> provider" which means that the stack will
> automatically generate error responses under certain
> conditions which are not errors for a proxy server
> but are errors for a user agent. For example,
> consider a bye. If the bye is associated with an
> "automatic dialog supported" provider then the stack
> should generate and send a "Call not found" response
> if a dialog cannot be found for the bye. However, if
> it is associated with a "automatic dialog support
> disabled" provider, then you are telling the stack
> that "i am a proxy server on this provider" which
> means the stack knows to send the request up to the
> listener. Take a look at
> NistSipMessageHandlerImpl.java (I should change its
> name) to see all the dialog specific error handling
> that happens there. Look for the various places where
> I check for isAutomaticDialogSupportEnabled and you
> can see what I mean. Basically, if you let dialogs be
> created entirely under applicatin control, all of
> this error handling would have to be done by the
> application. This is fine but it would make the
> application be a lot more complex.

Now I must admit that I was not aware of the error handling services performed by NistSipMessageHandlerImpl.

This changes the situation quite a bit.

Just a question: We have proxies and user agents. Are these the only modes that any application should act as?
For example the situation with a BYE that should be responded to according to your example. Is it simply illegal to decline to do this?

> No you dont have to increase the complexity of
> deployment or configuration. Each Sip Sbb gets access
> to exactly two providers ( one with autodialog
> support enabled and another without). Alternatively,
> you can define a SipProvider factory that can be used
> to create either dialogStateful or dialogStateless
> (Wrapped) provider. So hide
> SipStack.createSipProvider (by wrapping the stack)
> and allow Sbb to only access these two kinds of
> providers using Jndi to get at them. You will have to
> wrap SipProvider to restrict being able to
> createDialog under application control.
>

Yes, I simply assumed that the single getSipProvider should be kept. What you describe or two separate methods (getDialogSupportingSipProvider, getSipProvider) on the JainSipResourceAdapterSbbInterface object) is better.

I think I prefer this to a JNDI binding of the actual SipProviders.

(To be continued, in a hurry now...)

ivelin
Offline
Joined: 2003-07-13

> > Niklas,
> >
> > You are right. You would have to wait till the
> > listener either calls
> > SipProvider.createDialog(transaction) or not. i.e.
> > you have to wait till the listener completes
> > execution.
>
> Isn't it even worse?
>
> Suppose that an original INVITE arrives at the RA and
> a invite event is fired.
> The Sbb can now use a timer to schedule a timerevent
> to be fired in say a few fractions of a second and
> return from the onInviteEvent method without having
> sent a response or created a dialog.
>
> When the timerevent is fired it can proceed by
> creating a dialog and sent a response to the invite.
>
> The RA would have to monitor the sending of a
> response (not the return from the
> SipListener.processRequest method) to know the
> applications decision about dialog creation.
>
> Do you agree with this example?
>

Yes. Major headache rising on this end...

ben_evans
Offline
Joined: 2003-08-14

Wow, you guys had a busy weekend ;) You've already moved past it but I'd like to come back to Ranga's point about the potential race condition, I don't think it is valid...

> Automatic dialog support is quite useful for
> constructing user agents. The race condition in
> question is for dialog creating requests. If you
> manage your own dialog layer, there is a window of
> time during which the stack is not sure about what
> you want to do - i.e. create a dialog or not. If an
> intervening request comes in in the meanwhile, you
> have trouble deciding what to do with it while the
> application code is executing. To further elaborate,
> for example, what will you do if an out of sequence
> message arrives? Will you drop it or pass it up to
> the listener? If the app decides to be dialog
> stateful, you may need to drop the request and if the
> app decides to be dialog stateless, then you need to
> pass it up to the listener. No way for the stack to
> decide this until the app has completed its
> processing. So one has to resort to holding the
> request until that time (Ugh!).

There no race condition if we specify that dialog-stateful apps must call getNewDialog() before sending a dialog creating response. If the app has not yet sent any responses, there is no way that a subsequent mid-dialog request can arrive from the other party, so the RA does not have the problem of deciding what to do with out of order messages etc, since there can't be any yet!

Once the app has called getNewDialog(), it can send responses, and the RA will be able to deal with subsequent mid-dialog requests. If the app tries to call getNewDialog() after it has already sent a response, this should cause an IllegalStateException.

When constructing a user agent in this way, with automatic dialog support disabled, the only thing the app has to differently is the call to getNewDialog() while processing the initial request. After that the RA knows there is a dialog and can handle subsequent requests appropriately.

Ben

niklasuhrberg
Offline
Joined: 2004-11-02

> There no race condition if we specify that
> dialog-stateful apps must call getNewDialog() before
> sending a dialog creating response. If the app has
> not yet sent any responses, there is no way that a
> subsequent mid-dialog request can arrive from the
> other party, so the RA does not have the problem of
> deciding what to do with out of order messages etc,
> since there can't be any yet!
>
Apps must already call getNewDialog before sending responses according to JSIP (as of course you know).
I think the race condition (maybe we use the term slightly differently) is exactly this. See also my example on how an Sbb could prolong the time frame for this by postponing the sending of a response until after the event handler for the dialog creating request has returned.

> Once the app has called getNewDialog(), it can send
> responses, and the RA will be able to deal with
> subsequent mid-dialog requests. If the app tries to
> call getNewDialog() after it has already sent a
> response, this should cause an
> IllegalStateException.
>
> When constructing a user agent in this way, with
> automatic dialog support disabled, the only thing the
> app has to differently is the call to getNewDialog()
> while processing the initial request. After that the
> RA knows there is a dialog and can handle subsequent
> requests appropriately.

This can be interpreted in two ways, I was thinking about the second interpretation and I'd like you to comment on it.

Interpretation 1: If the application requests a dialog to be created by calling SipProvider.getNewDialog it must handle all dialog specific processing itself. This work is done by the stack if automatic dialog support is enabled.

Interpretation 2: If the application requests a dialog to be created by calling SipProvider.getNewDialog the stack starts to manage the dialog specific processing [i]for this particular dialog[/i]. This way the application does not have to be any more complex than if automatic dialog support is enabled [i]and[/i] both dialog statefulness and transaction statefulness can be combined on the same SipProvider.

There are of course some mechanisms that can't be catered for. For example the (by now famous) "out-of-dialog BYE" that a dialog stateful provider will respond "Call not found" to.

ben_evans
Offline
Joined: 2003-08-14

> > There no race condition if we specify that
> > dialog-stateful apps must call getNewDialog()
> before
> > sending a dialog creating response. If the app has
> > not yet sent any responses, there is no way that a
> > subsequent mid-dialog request can arrive from the
> > other party, so the RA does not have the problem
> of
> > deciding what to do with out of order messages
> etc,
> > since there can't be any yet!
> >
> Apps must already call getNewDialog before sending
> responses according to JSIP (as of course you know).
>
> I think the race condition (maybe we use the term
> slightly differently) is exactly this. See also my
> example on how an Sbb could prolong the time frame
> for this by postponing the sending of a response
> until after the event handler for the dialog creating
> request has returned.

This is not really a race condition because the application has complete control over when it sends a response or creates the dialog. The programmer can make sure that the operations are performed in the correct order.

> > Once the app has called getNewDialog(), it can
> send
> > responses, and the RA will be able to deal with
> > subsequent mid-dialog requests. If the app tries
> to
> > call getNewDialog() after it has already sent a
> > response, this should cause an
> > IllegalStateException.
> >
> > When constructing a user agent in this way, with
> > automatic dialog support disabled, the only thing
> the
> > app has to differently is the call to
> getNewDialog()
> > while processing the initial request. After that
> the
> > RA knows there is a dialog and can handle
> subsequent
> > requests appropriately.
>
>
> This can be interpreted in two ways, I was thinking
> about the second interpretation and I'd like you to
> comment on it.
>
> Interpretation 1: If the application requests a
> dialog to be created by calling
> SipProvider.getNewDialog it must handle all dialog
> specific processing itself. This work is done by the
> stack if automatic dialog support is enabled.
>
> Interpretation 2: If the application requests a
> dialog to be created by calling
> SipProvider.getNewDialog the stack starts to manage
> the dialog specific processing [i]for this particular
> dialog[/i]. This way the application does not have to
> be any more complex than if automatic dialog support
> is enabled [i]and[/i] both dialog statefulness and
> transaction statefulness can be combined on the same
> SipProvider.
>
> There are of course some mechanisms that can't be
> catered for. For example the (by now famous)
> "out-of-dialog BYE" that a dialog stateful provider
> will respond "Call not found" to.

Yes, I use the 2nd interpretation when I think of the app creating its own dialogs. This is obviously much easier for writing dialog-stateful applications, and can coexist with non-dialog apps using the same RA.

Message was edited by: ben_evans
Missed a bit about the race condition

mranga
Offline
Joined: 2003-06-06

I see that I have opened up a hornets nest or and the hornets are heading my way :-)

> > > There no race condition if we specify that
> > > dialog-stateful apps must call getNewDialog()
> > before
> > > sending a dialog creating response. If the app
> has
> > > not yet sent any responses, there is no way that
> a
> > > subsequent mid-dialog request can arrive from
> the
> > > other party, so the RA does not have the problem
> > of
> > > deciding what to do with out of order messages
> > etc,
> > > since there can't be any yet!
> > >
> > Apps must already call getNewDialog before sending
> > responses according to JSIP (as of course you
> know).
> >
> > I think the race condition (maybe we use the term
> > slightly differently) is exactly this. See also my
> > example on how an Sbb could prolong the time frame
> > for this by postponing the sending of a response
> > until after the event handler for the dialog
> creating
> > request has returned.
>
> This is not really a race condition because the
> application has complete control over when it sends a
> response or creates the dialog. The programmer can
> make sure that the operations are performed in the
> correct order.

Race condition is possibly a bad word in this context.

One of the key things is repeatability of the behavior of services. I guess the point is you can have sequence number dependent non-determinism with poorly programmed applications. An extreme case (for illustrative purposes). An application can do things like

if ( cseq == 1 )-- dont call getNewDialog.

if (cseq == 5 ) -- dont call getNewDialog.

if (cseq == 3 ) -- call getNewDialog.

Lets say that you repeat the expriment and the cseq ordering of messages is 1,5,3. The application will see all three requests.

What do you do with cseq 5 that you have just allowed the application to see? You cant do anything of course.

But if the experiment is repeated and requests arrive in order 1,3,5 then 5 gets dropped. So application behavior is a function of ordering of messages.

Do you care about such anamoloies?

> >
> > Interpretation 2: If the application requests a
> > dialog to be created by calling
> > SipProvider.getNewDialog the stack starts to
> manage
> > the dialog specific processing [i]for this
> particular
> > dialog[/i]. This way the application does not have
> to
> > be any more complex than if automatic dialog
> support
> > is enabled [i]and[/i] both dialog statefulness and
> > transaction statefulness can be combined on the
> same
> > SipProvider.
> >
> > There are of course some mechanisms that can't be
> > catered for. For example the (by now famous)
> > "out-of-dialog BYE" that a dialog stateful
> provider
> > will respond "Call not found" to.
>
> Yes, I use the 2nd interpretation when I think of the
> app creating its own dialogs. This is obviously much
> easier for writing dialog-stateful applications, and
> can coexist with non-dialog apps using the same RA.

Actually there is more than just out of order bye processing. Consider other cases than just INVITE processing. SUBSCRIBE NOTIFY is notorious. Also dont forget that INVITE and SUBSCRIBE can be forked.

Perhaps Ben can explain why dialog and non-dialog applications cannot co-exist in my proposal of having multiple providers with specified roles. What is wrong with that proposal? Any gotchas?

I like a nice clean declarative model where you tell the stack as much as possible about your intended behavior apriori on a provider (i.e. I want to be a ua vs proxy) so the stack can do as much processing and filtering as possible before the application sees a request.

[ This is purely *speculative* but it might be possible to make this declarative behavior more fine grained in a future release of JSIP (i.e. tell the stack on an request-URI address basis what you want to do etc. ). ]

>
>
> Message was edited by: ben_evans
> Missed a bit about the race condition

ben_evans
Offline
Joined: 2003-08-14

> Race condition is possibly a bad word in this
> context.
>
> One of the key things is repeatability of the
> behavior of services. I guess the point is you can
> have sequence number dependent non-determinism with
> poorly programmed applications. An extreme case (for
> illustrative purposes). An application can do things
> like
>
> if ( cseq == 1 )-- dont call getNewDialog.
>
> if (cseq == 5 ) -- dont call getNewDialog.
>
> if (cseq == 3 ) -- call getNewDialog.
>
> Lets say that you repeat the expriment and the cseq
> ordering of messages is 1,5,3. The application will
> see all three requests.
>
> What do you do with cseq 5 that you have just allowed
> the application to see? You cant do anything of
> course.
>
> But if the experiment is repeated and requests arrive
> in order 1,3,5 then 5 gets dropped. So application
> behavior is a function of ordering of messages.
>
> Do you care about such anamoloies?

I care ;) but just so I am clear - are requests 1, 3 and 5 supposed to be in the same dialog? If so, the app should have called getNewDialog on request 1 - to call it on a subsequent mid-dialog message should be illegal. I don't think this is unreasonable, the application programmer should know in advance if they want to use dialog activities or not.

mranga
Offline
Joined: 2003-06-06

> > Race condition is possibly a bad word in this
> > context.
> >
> > One of the key things is repeatability of the
> > behavior of services. I guess the point is you can
> > have sequence number dependent non-determinism
> with
> > poorly programmed applications. An extreme case
> (for
> > illustrative purposes). An application can do
> things
> > like
> >
> > if ( cseq == 1 )-- dont call getNewDialog.
> >
> > if (cseq == 5 ) -- dont call getNewDialog.
> >
> > if (cseq == 3 ) -- call getNewDialog.
> >
> > Lets say that you repeat the expriment and the
> cseq
> > ordering of messages is 1,5,3. The application
> will
> > see all three requests.
> >
> > What do you do with cseq 5 that you have just
> allowed
> > the application to see? You cant do anything of
> > course.
> >
> > But if the experiment is repeated and requests
> arrive
> > in order 1,3,5 then 5 gets dropped. So
> application
> > behavior is a function of ordering of messages.
> >
> > Do you care about such anamoloies?
>
> I care ;) but just so I am clear - are requests 1, 3
> and 5 supposed to be in the same dialog? If so, the
> app should have called getNewDialog on request 1 - to
> call it on a subsequent mid-dialog message should be
> illegal. I don't think this is unreasonable, the
> application programmer should know in advance if they
> want to use dialog activities or not.

Right. They are all in the same Dialog. If they know that they want to use dialog activities, why not then assign them the Dialog-stateful provider. And there is still the infamous BYE which arrives after dialog termination - what do you do with that. And there are some hairy issues with forked INVITES and SUBSCRIBEs. If you get a NOTIFY out of the blue, and you dont have a pending SUBSCRBE, then if you are Dialog Stateful, it is correct to drop the NOTIFY and if you are not dialog stateful, it is correct to pass the NOTIFY to the application. Thus if the stack gets a NOTIFY out of the blue and it finds no dialog, then it has to pass it up to the application if Automatic dialog support is disabled for the provider. The application has the responsibility to do the right thing - i.e. track if it has a pending subscribe and return error if not. For Forked Subscriptions, it has to repeat some of the error checking that happens in the Stack.

The point is simple - the more you can tell the stack about the application's behavior apriori (before the stack ever sees a request), the better job the stack can do in assisting the application.

Its almost like the arguments in favor of strong typing and declaratve programming isnt -- it the more you tell the compiler how you intend to use a variable, the more it helps you avoid mistakes - you dont need it but it helps to write better programs (please please dont invite Perl programmers to this thread :-) ).

Perhaps Ben can explain why dialog and non-dialog applications cannot co-exist in my proposal of having multiple providers with specified roles. What is wrong with that proposal? Any gotchas?

I know it's the proposer's burden to defend the proposal but do answer to the above query if you wish.

Message was edited by: mranga

mranga
Offline
Joined: 2003-06-06

Standardize with it off and allow dialog oriented apps to enable it on a per provider basis is the best choice.

This way you dont have to decide and that is always a good decision :-)

Ranga

ben_evans
Offline
Joined: 2003-08-14

> For readers that are not aquainted with a dialog
> extension of the JAIN SIP RA Type: I suppose you
> think of a behaviour where automatic dialog support
> is enabled and the Sbbs get attached to dialog ACIs
> automatically?

Yes, the RA would always create dialog activities, and fire request events on them.

> This would be convenient for dialog oriented Sbbs but
> incompatible for Sbbs not using dialogs.

Correct.

> However it is perfeclty possible to let automatic
> dialog support be turned on and let dialog oriented
> Sbbs obtain and attach to dialog ACIs themselves,
> making it possible for the two styles of Sbbs to
> coexist. (This approach is not desirable for
> performance reasons due to the overhead of
> unnecessary dialogs)

Also, if the RA is automatically creating dialogs then it is not possible to write a true proxy app. If a dialog is present, the RA could be silently handling retransmits of 200/ACK, when a proxy should be passing these messages through. You effectively have a B2BUA, not a proxy. The RA could also be rejecting messages due to invalid dialog sequence numbers etc, when these should be getting passed through in the proxy case.

> My idea briefly described above was simply a small
> convenience mechanism making it possible for Sbbs to
> obtain a dialog the same way irrespective of the
> automatic dialog support setting in the stack.
>
> That is using the Transaction.getDialog /
> RequestEvent.getDialog or ResponseEvent.getDialog
> methods.
> It is possible to achieve this while letting
> automatic dialog support be disabled in the stack if
> the JSLEE somehow calls SipProvier.getNewDialog
> before the Sbb code is entered.

This is the sort of thing I wanted to avoid by specifying a single way for dialogs to be created, ie. using SipProvider.getNewDialog(). Apps that call those methods above should expect to see null if they did not explicitly create a dialog themselves. This may break some existing apps, but since there isn't a standard SIP RA Type yet, I don't think we need to worry too much about backward compatibility.

> As I pointed out this should be configurable per
> service.
>
> I wrote the corresponding code for the 3pcc example
> application which is able to handle both automatic
> dialog support on and off which was a little awkward.
> You then have to try one of the ways and resort to
> the other if it didn't work.
>
> It seems we agree that standardizing on automatic
> dialog support off is the most attractive path.

Yes, agreed. Trying to support both is painful as you have seen, and having automatic dialog support enabled creates more problems.

mranga
Offline
Joined: 2003-06-06

Ben,

Automatic dialog support is quite useful for constructing user agents. The race condition in question is for dialog creating requests. If you manage your own dialog layer, there is a window of time during which the stack is not sure about what you want to do - i.e. create a dialog or not. If an intervening request comes in in the meanwhile, you have trouble deciding what to do with it while the application code is executing. To further elaborate, for example, what will you do if an out of sequence message arrives? Will you drop it or pass it up to the listener? If the app decides to be dialog stateful, you may need to drop the request and if the app decides to be dialog stateless, then you need to pass it up to the listener. No way for the stack to decide this until the app has completed its processing. So one has to resort to holding the request until that time (Ugh!).

You will no doubt agree that Automatic Dialog support is very useful in certain instances. (This is what lead to JAIN-SIP lite coming into being.) Sometimes, it is almost a necessity to avoid a lot of application complexity. For user agents, consider the case of forked invitations or forked subscriptions. For such cases, there is a lot of complexity that is avoided by allowing the stack to manage your dialog layer. Of course, you may not care about a user agent that does forked invitations running as a SLEE SBB ( unless of course, you are writing a conferencing server hmm... ).

However, clearly automatic dialog support does no good for proxy servers ( and in fact causes them to misbehave).

To conveniantly support both Dialog oriented and non-dialog oriented applications (i.e. proxy -like sbbs) running on a single stack, there are a few options (1) manage your own dialog layer and use SipProvider.getDialog(Transaction) which may lead to blocking to avoid race conditions or (2) enable or disable automatic dialog support on a per-provider basis (overriding the stack wide configuration property) for the provider. The latter is less error prone and IMHO results in avoiding one nasty situation (i.e. potential race) which one may need to block processing on requests for.

Further, when you consider the way in which services are generally referenced by the outside world, you think in terms of IP address, port and transport to refer to the service (i.e. you have a (dialog stateless) proxy server running on 129.6.55.62 on port 5060 and a (dialog stateful) 3PCC service running on 129.6.55.62 on port 6050 (dialog stateful) ) it makes sense to break things down on a per provider basis as [ip,port,transport] refers to a provider in the current version of JSIP.

I hope this all makes sense.

Ranga.

Ranga.

Message was edited by: mranga

Message was edited by: mranga

niklasuhrberg
Offline
Joined: 2004-11-02

> Automatic dialog support is quite useful for
> constructing user agents. The race condition in
> question is for dialog creating requests. If you
> manage your own dialog layer, there is a window of
> time during which the stack is not sure about what
> you want to do - i.e. create a dialog or not. If an
> intervening request comes in in the meanwhile, you
> have trouble deciding what to do with it while the
> application code is executing. To further elaborate,
> for example, what will you do if an out of sequence
> message arrives? Will you drop it or pass it up to
> the listener? If the app decides to be dialog
> stateful, you may need to drop the request and if the
> app decides to be dialog stateless, then you need to
> pass it up to the listener. No way for the stack to
> decide this until the app has completed its
> processing. So one has to resort to holding the
> request until that time (Ugh!).

Could you explain this a little more in detail?
I'd like to understand (an example is probably the best way) what is means by "an intervening request".

Also, for a dialog creating request, what is the situation with an out of sequence request?

I would interpret it like this:

<--- INVITE arrives at the RA sith CSeq x
Invite event fired on the Sbb
<--- INVITE arrives at the RA with CSeq x-1

Is it then correct to pass the second INVITE to the SipListener iff no dialog exists?

The solution you suggest would then amount to having the RA wait until a response is sent because this is when it can know for sure that the dialog decision must have taken place in the application code, right?

> Further, when you consider the way in which services
> are generally referenced by the outside world, you
> think in terms of IP address, port and transport to
> refer to the service (i.e. you have a (dialog
> stateless) proxy server running on 129.6.55.62 on
> port 5060 and a (dialog stateful) 3PCC service
> running on 129.6.55.62 on port 6050 (dialog stateful)
> ) it makes sense to break things down on a per
> provider basis as [ip,port,transport] refers to a
> provider in the current version of JSIP.

One thing is how applications are deployed with designated ports, but is this how we would like it to be?
The event router mechanism and inital event selection mechanism are there (partly) to let us split physical ports and the routing of messages as they should have little to do with each other (IMHO).

Using exactly two ports could be a compromise though it would introduce more configuration issues. You must somehow tell the RA/JSLEE which services are dialog stateful and which are not.

mranga
Offline
Joined: 2003-06-06

Niklas,

You are right. You would have to wait till the listener either calls SipProvider.createDialog(transaction) or not. i.e. you have to wait till the listener completes execution. You would have to do this for every request that could potentially create a dialog which arrives when a request of that same kind is being handled by the listener. Unless of course, you place a condition that it is the applications job to worry about such out of sequence requests - which takes away some of the utility of the dialog layer.

Actually there are further issues to consider. The automatic dialog support flag is essentially telling the stack "I will behave like a user agent on this provider" which means that the stack will automatically generate error responses under certain conditions which are not errors for a proxy server but are errors for a user agent. For example, consider a bye. If the bye is associated with an "automatic dialog supported" provider then the stack should generate and send a "Call not found" response if a dialog cannot be found for the bye. However, if it is associated with a "automatic dialog support disabled" provider, then you are telling the stack that "i am a proxy server on this provider" which means the stack knows to send the request up to the listener. Take a look at NistSipMessageHandlerImpl.java (I should change its name) to see all the dialog specific error handling that happens there. Look for the various places where I check for isAutomaticDialogSupportEnabled and you can see what I mean. Basically, if you let dialogs be created entirely under applicatin control, all of this error handling would have to be done by the application. This is fine but it would make the application be a lot more complex.

It makes life a lot simpler (for both the application and the stack) if you can mark providers as "dialog creating" or "not dialog creating"

It is better to do a two port solution - 1. a provider where transactions may be created but no dialogs 2. a provider where transactions for dialog-creating requests result in the automatic creation of a dialog. Wrap the SipProvider to throw exception if the Sbb misbehaves and tries to create a dialog using SipProvider.createDialog. This solution will simplify the design and reduce application complexity.

No you dont have to increase the complexity of deployment or configuration. Each Sip Sbb gets access to exactly two providers ( one with autodialog support enabled and another without). Alternatively, you can define a SipProvider factory that can be used to create either dialogStateful or dialogStateless (Wrapped) provider. So hide SipStack.createSipProvider (by wrapping the stack) and allow Sbb to only access these two kinds of providers using Jndi to get at them. You will have to wrap SipProvider to restrict being able to createDialog under application control.

I think this will simplify the design a lot and make applications more robust as well as simplify the RA design. At least that is my point of view. Do post your thoughts. I am interested in the design of the SIPRA so I will actively participate.

Ranga

Message was edited by: mranga

Message was edited by: mranga

ivelin
Offline
Joined: 2003-07-13

How will the following use case work for the 2 providers design?

1) Do not disturb (DND) service, which acts as UA on behalf of a user.
2) Watchdog service which monitors raw SIP traffic. When it notices a caller which generates a lot of out of sequence INVITEs or other noisy requests it adds the caller to a black list table. Future requests from a caller in the black list are discarded early to avoid extraneous load on the SLEE (e.g. DOD attacks).

The main question here is how to allow two services to coexist. One needs to monitor raw sip even traffic and the other is interested in dialog level activities.

With the 2 provider aproach, the decision for dialog support is made at the RA level. If auto-dialog provider is chosen, I don't see how the watchdog SBB can subscribe to lower level SIP events.

There is some corelation between the issue of colocating JCC (SIP) RA and JAIN SIP RA. It has been discussed and a solution has been agreed upon:
http://forums.java.net/jive/thread.jspa?forumID=92&threadID=15244&messag...

It may be a little too late in the discussion to throw in this suggestion, but here it is anyway - does it make any sense to split the SIP RA in two - SIP Transaction RA and SIP Dialog RA. Both will share the underlying SIP provider and receive the same sip events. The Dialog SIP RA will automatically create dialogs activities and fire events on them. It can use optimizations and not create activities when there is noone interested.

To leverage all the work that has been done in NistSipMessageHandlerImpl, it can probably be refactored to separate out the logic applicable to auto-dialog support.

Ivelin

mranga
Offline
Joined: 2003-06-06

> How will the following use case work for the 2
> providers design?
>
> 1) Do not disturb (DND) service, which acts as UA on
> behalf of a user.
> 2) Watchdog service which monitors raw SIP traffic.
> When it notices a caller which generates a lot of out
> of sequence INVITEs or other noisy requests it adds
> the caller to a black list table. Future requests
> from a caller in the black list are discarded early
> to avoid extraneous load on the SLEE (e.g. DOD
> attacks).

There is no restriction in my proposal that a given service should only access a single provider. Only that you should support a fixed set of providers, each with dialog-behavior pre-defined and take away the ability for an SBB to create its own dialogs. Again, this is because, it is most conveniant to create the Dialog at the same time as the transaction is created and to know apriori whether your application wants user agent behavior on a given provider or proxy behavior ( appplictions can be both user agent and proxy like ).

The RA does not decide about dialog support. The restriction is that you cannot utilize the same provider for non-dialog *and* automatic-dialog behavior. i.e. you mark the provider apriori so the stack knows what you want to do before the event is delivered. You pick whether you want automatic dialog support or not by choosing the appropriate provider (i.e. you pick the provider that gives you automatic dialog support or no dialog support). Any SBB can access either one but cannot use the non-dialog provider and create dialogs under application control.

> It may be a little too late in the discussion to
> throw in this suggestion, but here it is anyway -
> does it make any sense to split the SIP RA in two -
> SIP Transaction RA and SIP Dialog RA. Both will share
> the underlying SIP provider and receive the same sip
> events. The Dialog SIP RA will automatically create
> dialogs activities and fire events on them. It can
> use optimizations and not create activities when
> there is noone interested.
>
Not convinced. I dont think the suggestion above is a clean design. There is just too much apriori knowledge that the installer needs to have about application structure.

> To leverage all the work that has been done in
> NistSipMessageHandlerImpl, it can probably be
> refactored to separate out the logic applicable to
> auto-dialog support.

Sorry but I dont understand what you are suggesting. NistSipMessageHandlerImpl (which should be called DialogFilter), runs before the application ever sees the request. Its main job is to filter out out of sequence requests and return error responses under certain error conditions. This way, the application benifits by becoming much simpler - it can simply focus on its logic without needing to worry about details like sequence numbers and requests that dont match a dialog etc. This is the main utility of dialog support. By allowing applications to create their own dialogs, all this is sort of lost. Perhaps you are suggesting something like

SleeDialog extends SIPDialog implements Dialog

and a function like

SIPDialog.filterRequest(Transaction transaction)

so you can do the same thing at the application level.

Thats a partial solution but it does not address one difficulty:

The other tricky part with dialogs is forked subscriptions and forked invitiations. For such things there is a lot of complex processing that has to take place. You would have to duplicate all this processing in the application -- which is the royal pain in the batooties (forgive my French).

It is best that a dialog-stateful application not see requests that it is not supposed to see and in my mind, having multiple providers and taking away dialog control from the application layer is the best and cleanest solution.

Ranga.

niklasuhrberg
Offline
Joined: 2004-11-02

> > How will the following use case work for the 2
> > providers design?
> >
> > 1) Do not disturb (DND) service, which acts as UA
> on
> > behalf of a user.
> > 2) Watchdog service which monitors raw SIP
> traffic.
> > When it notices a caller which generates a lot of
> out
> > of sequence INVITEs or other noisy requests it
> adds
> > the caller to a black list table. Future requests
> > from a caller in the black list are discarded
> early
> > to avoid extraneous load on the SLEE (e.g. DOD
> > attacks).
>
>
> There is no restriction in my proposal that a given
> service should only access a single provider. Only
> that you should support a fixed set of providers,
> each with dialog-behavior pre-defined and take away
> the ability for an SBB to create its own dialogs.
> Again, this is because, it is most conveniant to
> create the Dialog at the same time as the transaction
> is created and to know apriori whether your
> application wants user agent behavior on a given
> provider or proxy behavior ( appplictions can be both
> user agent and proxy like ).
>

In this example I think the point is that the WatchDog service has no chance to discover "noisy" messages if they arrive at the dialog enabled provider port and the sip stack responds e.g. "Call not found" to a BYE without an existing dialog.
Then it does not matter that the WatchDog service can opt to use both providers.

>
> The RA does not decide about dialog support. The
> restriction is that you cannot utilize the same
> provider for non-dialog *and* automatic-dialog
> behavior. i.e. you mark the provider apriori so the
> stack knows what you want to do before the event is
> delivered. You pick whether you want automatic dialog
> support or not by choosing the appropriate provider
> (i.e. you pick the provider that gives you automatic
> dialog support or no dialog support). Any SBB can
> access either one but cannot use the non-dialog
> provider and create dialogs under application
> control.
>
>
>
> > It may be a little too late in the discussion to
> > throw in this suggestion, but here it is anyway -
> > does it make any sense to split the SIP RA in two
> -
> > SIP Transaction RA and SIP Dialog RA. Both will
> share
> > the underlying SIP provider and receive the same
> sip
> > events. The Dialog SIP RA will automatically
> create
> > dialogs activities and fire events on them. It can
> > use optimizations and not create activities when
> > there is noone interested.
> >
> Not convinced. I dont think the suggestion above is a
> clean design. There is just too much apriori
> knowledge that the installer needs to have about
> application structure.
>
> > To leverage all the work that has been done in
> > NistSipMessageHandlerImpl, it can probably be
> > refactored to separate out the logic applicable to
> > auto-dialog support.
>
>
> Sorry but I dont understand what you are suggesting.
> NistSipMessageHandlerImpl (which should be called
> DialogFilter), runs before the application ever sees
> the request. Its main job is to filter out out of
> sequence requests and return error responses under
> certain error conditions. This way, the application
> benifits by becoming much simpler - it can simply
> focus on its logic without needing to worry about
> details like sequence numbers and requests that dont
> match a dialog etc. This is the main utility of
> dialog support. By allowing applications to create
> their own dialogs, all this is sort of lost.

Let's see if I interpret Ivelins suggestion correctly:

In order to combine simple application writing (not having to take care of the error management for dialogs) and the goal of running the SIP RA on only one port there are two RAs sharing one SipProvider.

This SipProvider is configured with no automatic dialog support.

It is up to the Dialog SIP RA to implement the dialog specific mechanisms now implemented in NistSipMessageHandlerImpl.

The two RAs running in a JSLEE container would have to be registered as SipListeners in some event dispatcher because of the unicast event model in JAIN SIP.

The question now is what situations could benefit from this.
Take for instance the BYE which does not belong to a dialog. Rangas point in this example is that the stack should handle this and send a "Call not found" response.
This would be the behaviour of the Dialog SIP RA but then (if the Dialog SIP RA gets the request first) the Transaction SIP RA (or its interested Sbbs) could not handle the request at all because the transaction has already terminated.
In this example things could maybe be fixed by changing the invocation order.

ivelin
Offline
Joined: 2003-07-13

> In this example I think the point is that the
> WatchDog service has no chance to discover "noisy"
> messages if they arrive at the dialog enabled
> provider port and the sip stack responds e.g. "Call
> not found" to a BYE without an existing dialog.
> Then it does not matter that the WatchDog service can
> opt to use both providers.

Exactly. That's the question. How to enable both SBBs on the same stream of raw SIP protocol events.

mranga
Offline
Joined: 2003-06-06

I see what you are saying.

You have this problem regardless of how we proceed. Basically, if you look at most of what the SIP Stack does, it filters messages and keeps away noise from the application. Under the current JAIN-SIP API, there is no way to insert a watcher that can listen for all incoming messages. You have a single listener and you can decide at a certain point in the processing if you want to be dialog/tx stateful or not.

Once you have made that decision, the stack will filter nonsensical messages so as to make the application simpler to write. We can change the design to allow a filter to be installed into the stack look at a raw stream of Sip Events, (i.e. Sip messages) regardless of what processing model the application wants to impose but we dont have that facility in the API -- it would have to be a SLEE extension and wait for the next JSIP API rev.

Its fine to standardize on such a filter and I can make it be part of nist-sip on an experimental basis.

Ranga.

jbemmel
Offline
Joined: 2005-03-01

Allow me to give an outsider's view on this. I know little of JAIN SLEE (but some things about JAIN SIP)

How I think it should work, is that an application declares in its deployment descriptor that it needs SIP. It specifies how many SIP ports it needs, and for each which type of SIP application it wants to be: stateless proxy, stateful proxy, or UA. It may also specify specific transports (default: UDP&TCP)

Then, the RA assigns concrete ports (e.g. starting from 5060) to each requested 'SIP port'. It creates ListeningPoints and SipProviders and sets the 'automatic dialog' property according to the declared SIP port type (i.e. true iff UAS)

For UA type of applications you might consider to allow the use of a shared SIP port (say 5060), but then you need some mechanism to demultiplex SIP requests to the right application. One way to do this is to have the application declare a SIP username that should be used to contact it.

Proxy applications cannot share ports like this, except when you build it such that a proxy application gets all requests that don't match an UA application.

I would expect that the majority of applications will be endpoint applications. You could provide a default proxy application in the platform, with registrar functionality (you may already have this, I don't know).

ivelin
Offline
Joined: 2003-07-13

My thinking is along the lines of what you suggest. However Ranga pointed out that obtaining a new Dialog at runtime from a provider may be problematic in case of race condition. There may be a workaround for it. It is probably worth investigating whether the RA can prevent race condition, thus keeping the API for SBBs interested in a dialog as simple as sipTransaction.getDialog().

Ivelin

PS: For people new to this thread, here is a reference to the associated Wiki page with latest status. Created by Niklas.
http://wiki.java.net/bin/view/Communications/SipRADiscussionBase

niklasuhrberg
Offline
Joined: 2004-11-02

I don't think I understand what race condition you refer to. Could you clarify?

I think of the SipProvider.getNewDialog(Transaction) method that must be called in the situations mentioned above.
Is this where there can be a race condition?

This is what I mean the JSLEE container should ideally be able to do to make up for disabled automatic dialog support in the sip stack. Then application writers can safely assume that Transaction.getDialog always works (of there is a dialog).

ben_evans
Offline
Joined: 2003-08-14

Regarding multiple providers/listeners and automatic dialog support, this is not really an issue for the RA Type, but the implementation.

The RA Type describes a contract between the SBBs and the RA. The JAIN SIP RA Type does not need to follow the JAIN SIP API exactly. It should do as much as possible but where there is stuff that does not make sense for SBBs then this should be fixed.
For example an SBB should not be able to call add/deleteListeningPoint() etc - the RA Type should enforce this by specifying that SecurityExceptions are thrown if an SBB tries to manipulate the stack directly.

Similarly with automatic dialog support, the RA Type should specify the behaviour that makes most sense for SBBs and leave it up to the RA implementation to support this however it likes.

I think the JAIN SIP RA Type should specify that automatic dialog support is *always* disabled, as far as SBBs are concerned. Having it enabled does not make sense for SBBs, because then there is no way for non-dialog and dialog-based SBBs to coexist. The RA Type should specify that Dialog activites are only created by calling SipProvider.getNewDialog(). That way there is a single model that non-dialog and dialog-based SBBs can work with.

Basically what I am saying is that any RA Type should specify the behaviour that makes most sense for SBBs, it doesn't need to support every last feature in the original API that you are adapting. If it differs slightly from the original API, then document the differences and have the implementation deal with them.

Having well-defined RA Types is what makes SBBs portable between SLEEs, so it is essential that the RA Type specifies a consistent model for SBB-RA interaction that all implementations can support.

Cheers
Ben

niklasuhrberg
Offline
Joined: 2004-11-02

> For example an SBB should not be able to call
> add/deleteListeningPoint() etc - the RA Type should
> enforce this by specifying that SecurityExceptions
> are thrown if an SBB tries to manipulate the stack
> directly.

One thing that strikes me is that the return type of JainSipResourceAdaptorSbbInterface.getSipProvider could be something different than javax.sip.SipProvider. This would make it explicit that it is a different interface exposed to Sbbs (say javax.slee.sip.SipProvider) that does not contain the methods that are not meant for Sbbs.
This appears to be in line with good design although I don't think it's a big deal.
Any comments on why this path was not chosen?
(The picture is distorted by the fact that the javax.sip.SipProvider is obtainable from the sip stack interfaces too)

> Similarly with automatic dialog support, the RA Type
> should specify the behaviour that makes most sense
> for SBBs and leave it up to the RA implementation to
> support this however it likes.
>
> I think the JAIN SIP RA Type should specify that
> automatic dialog support is *always* disabled, as far
> as SBBs are concerned.

Agree

Having it enabled does not
> make sense for SBBs, because then there is no way for
> non-dialog and dialog-based SBBs to coexist. The RA
> Type should specify that Dialog activites are only
> created by calling SipProvider.getNewDialog(). That
> way there is a single model that non-dialog and
> dialog-based SBBs can work with.
>

For readers that are not aquainted with a dialog extension of the JAIN SIP RA Type: I suppose you think of a behaviour where automatic dialog support is enabled and the Sbbs get attached to dialog ACIs automatically?

This would be convenient for dialog oriented Sbbs but incompatible for Sbbs not using dialogs.

However it is perfeclty possible to let automatic dialog support be turned on and let dialog oriented Sbbs obtain and attach to dialog ACIs themselves, making it possible for the two styles of Sbbs to coexist. (This approach is not desirable for performance reasons due to the overhead of unnecessary dialogs)

My idea briefly described above was simply a small convenience mechanism making it possible for Sbbs to obtain a dialog the same way irrespective of the automatic dialog support setting in the stack.

That is using the Transaction.getDialog / RequestEvent.getDialog or ResponseEvent.getDialog methods.
It is possible to achieve this while letting automatic dialog support be disabled in the stack if the JSLEE somehow calls SipProvier.getNewDialog before the Sbb code is entered.

As I pointed out this should be configurable per service.

I wrote the corresponding code for the 3pcc example application which is able to handle both automatic dialog support on and off which was a little awkward. You then have to try one of the ways and resort to the other if it didn't work.

It seems we agree that standardizing on automatic dialog support off is the most attractive path.

ben_evans
Offline
Joined: 2003-08-14

> One thing that strikes me is that the return type of
> JainSipResourceAdaptorSbbInterface.getSipProvider
> could be something different than
> javax.sip.SipProvider. This would make it explicit
> that it is a different interface exposed to Sbbs (say
> javax.slee.sip.SipProvider) that does not contain the
> methods that are not meant for Sbbs.
> This appears to be in line with good design although
> I don't think it's a big deal.
> Any comments on why this path was not chosen?
> (The picture is distorted by the fact that the
> javax.sip.SipProvider is obtainable from the sip
> stack interfaces too)

I think when we (OC) originally did JainSipResourceAdaptorSbbInterface, it was just done as the simplest way to provide the SBB access to the SipProvider and Address/Header/MessageFactory interfaces in one place.

What you suggest is a good approach, but in the case of JAIN SIP there are a number of places where you can get SipProvider, so you would need to wrap those other interfaces too, if you wanted to make sure that the SBB could only ever see the "safe" interfaces. In the interests of keeping code semi-compatible between standalone JAIN SIP apps and SLEE apps, it is probably best to use the same interfaces where possible. However with other APIs it might certainly make more sense to expose a different interface when it can be done cleanly.