Subject: [Simple] I-D ACTION:draft-campbell-simple-cpimmsg-sessions-00.txt

From: [email-masked]
Date: Tue, 29 Oct 2002 06:17:47 -0500

A New Internet-Draft is available from the on-line Internet-Drafts directories.

	Title		: Instant Message Transport Sessions using the CPIM 
                          Message Format
	Author(s)	: B. Campbell et al.
	Filename	: draft-campbell-simple-cpimmsg-sessions-00.txt
	Pages		: 12
	Date		: 2002-10-28
	
Instant Messaging (IM) refers to the transfer of messages between
users in near real-time.  These messages are usually, but not
required to be, short.  IMs are often used in a conversational mode,
that is, the transfer of messages back and forth is fast enough for
participants to maintain an interactive conversation.  Each message
can be sent independently using the SIP MESSAGE method, or messages
can be associated into sessions that are initiated using SIP.  The
first approach is often referred to as pager-mode messaging, due to
its similarity to the behavior of two way pager devices.  The second
approach is often called session-mode messaging, or simply message
sessions.  This document describes a message session mechanism based
on the Common Presence and Instant Messaging message format.

A URL for this Internet-Draft is:
http://www.ietf.org/internet-drafts/draft-campbell-simple-cpimmsg-sessions-00.txt

To remove yourself from the IETF Announcement list, send a message to 
ietf-announce-request with the word unsubscribe in the body of the message.

Internet-Drafts are also available by anonymous FTP. Login with the username
"anonymous" and a password of your e-mail address. After logging in,
type "cd internet-drafts" and then
	"get draft-campbell-simple-cpimmsg-sessions-00.txt".

A list of Internet-Drafts directories can be found in
http://www.ietf.org/shadow.html 
or ftp://ftp.ietf.org/ietf/1shadow-sites.txt

Internet-Drafts can also be obtained by e-mail.

Send a message to:
	[email-masked].
In the body type:
	"FILE /internet-drafts/draft-campbell-simple-cpimmsg-sessions-00.txt".
	
NOTE:	The mail server at ietf.org can return the document in
	MIME-encoded form by using the "mpack" utility.  To use this
	feature, insert the command "ENCODING mime" before the "FILE"
	command.  To decode the response(s), you will need "munpack" or
	a MIME-compliant mail reader.  Different MIME-compliant mail readers
	exhibit different behavior, especially when dealing with
	"multipart" MIME messages (i.e. documents which have been split
	up into multiple messages), so check your local documentation on
	how to manipulate these messages.

Below is the data which will enable a MIME compliant mail reader
implementation to automatically retrieve the ASCII version of the
Internet-Draft.

---

From: Paul Kyzivat <[email-masked]>
Date: Tue, 29 Oct 2002 19:36:00 -0500

Draft-campbell-simple-cpimmsg-sessions-00 defines the protocol in such a way that multiple sessions can be demultiplexed from a single connection. Meanwhile draft-campbell-simple-im-sessions-00 calls for the use of the comedia spec to establish the connections. It also wishes to reuse a single connection for multiple sessions.

This presents a problem, because the comedia draft (ietf-mmusic-sdp-comedia-04) does not provide a way to share a connection among multiple sessions. It was constrained from doing so because it made no assumption about the protocol to be used on the connection. As a result it had to come up with a way to associate connections with sessions without regard to media content. 

Either a way must be found to change comedia to provide this capability, or else comedia must be abandoned in favor of some other arrangement for negotiating a connection. (It would be nice to make comedia work for this.)

Rohan and I talked about this, and began to think we could find an enhancement to comedia that would permit this, but then it got very ugly trying to figure out when connections should go away, especially between a pair of intermediaries. This is going to require some work.

	Paul

---

From: Jonathan Rosenberg <[email-masked]>
Date: Sat, 02 Nov 2002 13:53:48 -0500

Cant we solve this at the cpim-msg-sessions layer?

That draft could simply say something like "when you go to connect to 
the IP address/port that is listed there, first check if you already 
have a connection there. If so, use that again, and ignore any comedia 
stuff in the SDP."

-Jonathan R.

Paul Kyzivat wrote:
> _______________________________________________
> simple mailing list
> [email-masked]
> http://mailman.dynamicsoft.com/mailman/listinfo/simple
> 

-- 
Jonathan D. Rosenberg, Ph.D.                72 Eagle Rock Ave.
Chief Scientist                             First Floor
dynamicsoft                                 East Hanover, NJ 07936
[email-masked]                     FAX:   (973) 952-5050
http://www.jdrosen.net                      PHONE: (973) 952-5000
http://www.dynamicsoft.com

---

From: Ben Campbell <[email-masked]>
Date: Sun, 03 Nov 2002 10:29:03 -0600

I agree we should do that, and avoid a dependency on getting the issue 
fixed in comedia.

It does, however, seem like a generalized issue that _should_ be handled 
in the comedia specification as well, but that does not seem to be in 
scope for this wg.

Jonathan Rosenberg wrote:
>> Draft-campbell-simple-cpimmsg-sessions-00 defines the protocol in such 
>> a way that multiple sessions can be demultiplexed from a single 
>> connection. Meanwhile draft-campbell-simple-im-sessions-00 calls for 
>> the use of the comedia spec to establish the connections. It also 
>> wishes to reuse a single connection for multiple sessions.
>>
>> This presents a problem, because the comedia draft 
>> (ietf-mmusic-sdp-comedia-04) does not provide a way to share a 
>> connection among multiple sessions. It was constrained from doing so 
>> because it made no assumption about the protocol to be used on the 
>> connection. As a result it had to come up with a way to associate 
>> connections with sessions without regard to media content.
>> Either a way must be found to change comedia to provide this 
>> capability, or else comedia must be abandoned in favor of some other 
>> arrangement for negotiating a connection. (It would be nice to make 
>> comedia work for this.)
>>
>> Rohan and I talked about this, and began to think we could find an 
>> enhancement to comedia that would permit this, but then it got very 
>> ugly trying to figure out when connections should go away, especially 
>> between a pair of intermediaries. This is going to require some work.
>>
>>     Paul

---

From: Rohan Mahy <[email-masked]>
Date: Sun, 3 Nov 2002 22:05:09 -0800

Ben,

I think the right question to ask is:  how do a pair of intermediaries 
decide when they can terminate a connection?  this could be reference 
counting, or idle timeouts, or something else, but I think a lot of 
stuff will fall out from that decision.

thanks,
-rohan

On Sunday, November 3, 2002, at 08:29 AM, Ben Campbell wrote:

> It does, however, seem like a generalized issue that _should_ be 
> handled in the comedia specification as well, but that does not seem 
> to be in scope for this wg.
>
>> have a connection there. If so, use that again, and ignore any 
>> comedia stuff in the SDP."
>> -Jonathan R.
>> Paul Kyzivat wrote:
>>> Draft-campbell-simple-cpimmsg-sessions-00 defines the protocol in 
>>> such a way that multiple sessions can be demultiplexed from a single 
>>> ugly trying to figure out when connections should go away, 
>>> especially between a pair of intermediaries. This is going to 
>>> require some work.
>>>
>>>     Paul

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 04 Nov 2002 11:03:27 -0500

Jonathan, Ben,

I would be pleased if we can find a way to finesse this. The problem is that comedia requires some way to infer, from the sip signaling and SDP content, when connections should be made/dropped. Both sides must make the same inference, or else the connection establishment will fail. As soon as we start to pool connections there starts to be the potential for race conditions. 

This is especially a problem with connections between two intermediaries. The hard question is: when can you ever drop a connection between two intermediaries? Of course an intermediary never knows if its peer in the connection is also an intermediary or not, so it must act as if the peer is a UA following the comedia spec plus whatever additional rules we can come up with for simple. We can't drop a connection until we know that there are no sessions using it. A corollary to that is that we can't reuse a connection that has no sessions using it, because it might be dropped. And so we should drop a connection as soon as there are no sessions using it, because it is then worthless.

That already starts looking suboptimal, because we must drop connections between pairs of high traffic intermediaries any time there doesn't happen to be some session traversing them.

But I'm not sure this is workable even with that limitation. I have a hunch there is still a race condition when one end will think there is a connection and attempt to reuse it, while the other end has decided there is no session using the connection and tries to drop it or establish a new one. This is tricky, and probably impossible to decide in general except with respect to a precise rule for reuse. But here is one case that seems simpler than some others:

Suppose we are in the process of establishing a call between

	A-----I1-----I2-----B

and there was no connection between I1 and I2. A includes an offer in the invite, so I1 and I2 will each rewrite the SDP as the invite goes by. But neither I1 nor I2 yet knows if the invite will succeed, so don't know if this will result in establishing a connection.

Meanwhile, we start to establish a new call

	C-----I1-----I2-----D

C includes an offer in the invite. I1 needs to rewrite the SDP in the offer, and would like to reuse the connection it has proposed establishing with I2. But it doesn't yet know if that call will succeed and so doesn't know if the connection will be established. Hence I believe it must assume there will be no connection to reuse, and so must arrange things to establish a separate connection. Yet it is possible that both calls will succeed, so it must be prepared to establish both connections, and to discriminate them from one another. So I think it must offer a separate port in this invite.

This scenario doesn't fail, but again it is suboptimal because it may require intermediaries to listen for connections on multiple ports, and may result in redundant connections between a pair of intermediaries.

It will take more work to demonstrate a case that actually fails, or to demonstrate a reuse rule that can be proved does not fail.

	Paul

---

From: Jonathan Rosenberg <[email-masked]>
Date: Wed, 06 Nov 2002 11:58:58 -0500

inline.

Paul Kyzivat wrote:
 > Jonathan, Ben,
 >
 > I would be pleased if we can find a way to finesse this. The problem
 > is that comedia requires some way to infer, from the sip signaling
 > and SDP content, when connections should be made/dropped. Both sides
 > must make the same inference, or else the connection establishment
 > will fail. As soon as we start to pool connections there starts to be
 > the potential for race conditions.
 >
 > This is especially a problem with connections between two
 > intermediaries. The hard question is: when can you ever drop a
 > connection between two intermediaries?

I don't see this as that critical. I would guess that the passive side 
of a connection can always close, and the active side would just reopen 
if the session isn't terminated. No? I think comedia says you shouldnt 
close the connection before the session ends, but sometimes that happens 
for a variety of reasons. It should say something about retrying.

f course an intermediary
 > never knows if its peer in the connection is also an intermediary or
 > not, so it must act as if the peer is a UA following the comedia spec
 > plus whatever additional rules we can come up with for simple.

Right.

 > We
 > can't drop a connection until we know that there are no sessions
 > using it. A corollary to that is that we can't reuse a connection
 > that has no sessions using it, because it might be dropped. And so we
 > should drop a connection as soon as there are no sessions using it,
 > because it is then worthless.
 >
 > That already starts looking suboptimal, because we must drop
 > connections between pairs of high traffic intermediaries any time
 > there doesn't happen to be some session traversing them.

I think you want to decouple the connection lifetimes from the session 
lifetimes.

 >
 > But I'm not sure this is workable even with that limitation. I have a
 > hunch there is still a race condition when one end will think there
 > is a connection and attempt to reuse it, while the other end has
 > decided there is no session using the connection and tries to drop it
 > or establish a new one. This is tricky, and probably impossible to
 > decide in general except with respect to a precise rule for reuse.
 > But here is one case that seems simpler than some others:
 >
 > and there was no connection between I1 and I2. A includes an offer in
 > the invite, so I1 and I2 will each rewrite the SDP as the invite goes
 > by. But neither I1 nor I2 yet knows if the invite will succeed, so
 > don't know if this will result in establishing a connection.
 >
 > C includes an offer in the invite. I1 needs to rewrite the SDP in the
 > offer, and would like to reuse the connection it has proposed
 > establishing with I2. But it doesn't yet know if that call will
 > succeed and so doesn't know if the connection will be established.
 > Hence I believe it must assume there will be no connection to reuse,

This is an artifact of a very bad design choice made by comedia.

What you REALLY want is that whenever I1 modifies an INVITE, it *always* 
puts the same port number/IP into the SDP. Multiple connections can be 
established onto that IP/port. Thus, both the INVITE from A and from C, 
I1 would place the same IP/port into the SDP.

Now, if either of those should succeed, I1 will try to open a connection 
to that IP/port. If it already has one there, that gets reused.

So, whats the problem? Well, all intermediaries need to maintain a 
routing table, which tells them what to do with incoming messages. That 
table tells them that if an IM arrives on some specific connection, with 
a specific URI/identifier in the outer envelope, to forward to a 
different connection with a different URI/identifier in the outer 
envelope. THis means that the intermediary has to associate each 
connection with a specific dialog used to set it up (since the dialog is 
used to exchange the SDP that contains the URI/identifiers). How is this 
association done?

Right now, its done with the SOURCE ADDRESS. That is, the SDP sent out 
by A in your example contains the source IP/port it will make the 
connection from. So, when I1 receives the connection request, it can 
determine the source, and then match it to the dialog. The problem is, 
this doesn't work at all through NAT. If you don't want to use the 
source to demux, the intermediary can arrange for each connection to 
occur on a different port, and that means no reuse. So, we have a real 
problem.

I registered this complaint about comedia/NAT to mmusic some time back, 
but it was ignored. IMHO its still a show stopper. Its especially 
heinous when you want to add intermediaries, which wasn't considered at 
the time.

My proposal would be to use connection identifiers separate from 
addresses. The SDP contains some kind of parameter that identifies the 
connection. Its just a random token. Whenever the connection is opened, 
the active side sends, as the first bytes, this identifier. THis way, 
the passive side knows which dialog its associated with, without needing 
to rely on source IP.

So, lets go through an example of how this works with a single 
intermediary. We've got A----I-----B:

* A sends an INVITE. SDP has a connection identifier of CID-A1 and a URI 
of sip:A1. Through comedia it says it can be both active or passive. Of 
course we want it to be active in case its natted. This goes to I.

* I rewrites the SDP. It places a different IP/port (some common one 
used in all requests), and a new connection ID, CID-I1. It rewrites the 
address to sip:I1. It also indicates passive only. Note that, since its 
passive, the connection ID isn't important. This goes to B.

* B sends a 200 OK. It indicates active in its SDP. It includes a 
connection ID of CID-B1 and URI of sip:B1.

* I rewrites the SDP in the 200 OK. It includes the same common IP/port, 
but yet another connection ID, CID-I2 and URI sip:I2. Forwards to A. 
Now, I knows that messages from sip:A1 on either connection CID-I2 or 
CID-A1 go to sip:B1, on either connection CID-I1 or CID-B1. Which 
connection depends on which direction establishes.

* A opens a connection to I. Once opened, it passes CID-A1 on the 
connection. Now, I knows that this connection corresponds to the dialog 
it established with A. Similarly, B opens a connection to I, passes 
CID-B1, and I knows that this connection is associated with the dialog 
opened to B. Forwarding happens.

Now, consider the more complex case, of two intermediaries. So its 
A---I---IJ---B. Lets say there is already a connection opened between I 
and J. I had indicated a connection ID of CID-I1, and J had indicated 
CID-J1.

* A sends an INVITE. connection ID is new, CID-A1. URI is sip:A1. It 
indicates direction:both. Includes some IP/port for receiving connections.

* I gets the INVITE. Rewrites the SDP to CID-I2 (a new ID - since it 
doesn't know who will get this, whether a connection is there already). 
Rewrites the URI to sip:I2. Direction passive. Includes its common 
IP/port. Sends to J.

* J gets the INVITE. Rewrites the SDP to CID-J2, also a new ID. Rewrites 
the URI to sip:J2. Direction, passive. Includes its common IP/port. 
Sends to B.

* B gets the INVITE. Sends a 200 OK. B notices it doesn't have a 
connection to the IP/port indicated by J in the SDP. So, it creates a 
new CID, CID-B1, and places that in its SDP, along with direction:active.

* J gets the 200 OK. J notices that it does have a connection to the 
IP/port in the INVITE it received. So, it decides it can reuse that 
connection. So, it rewrites the SDP in the 200 OK with CID-J1 (the ID it 
had formerly exchanged with I), and indicates a direction of active. 
FOrwards to I.

* I gets the 200 OK. I sees that it DOESNT have a connection to the 
IP/port that A provided, so it creates a new connection ID, CID-I3, and 
places that in the 200 OK. It indicates a direction of passive. Places 
its common IP/port in the SDP, sends to A.

* Now, the SDP that A got indicated passive. So, it opens a connection 
to the IP/port provided by I. It sends its proposed connection ID, 
CID-A1 once the connection is opened.

* The SDP that B got indicated passive. So, it opens a connection to the 
IP/port that J provided. It sends its proposed connection ID, CID-B1, 
once the connection is opened.

* I and J realize that the connection IDs exchanged betwen them relate 
to an existing connection, so they don't open a new one.

If the connection between I and J should close, either side would 
re-initiate, and it would reuse the connection ID it had stored and 
remembered as associated with the destiation IP/port it needs to open a 
connection to.

Now, I *think* this works. I'm a bit hazy on the precise rules of usage 
and reuse of these connection IDs. THe aim is to do something that 
doesnt require a re-INVITE when a new connection is opened. Again - we 
want to separate connection lifetime from session lifetime.

This solution allows for connection reuse and also works smoothly 
through NAT without any pains.

Thoughts?

-Jonathan R.

---

From: Paul Kyzivat <[email-masked]>
Date: Wed, 06 Nov 2002 13:54:22 -0500

Jonathan - comments inline.

	Paul

> for a variety of reasons. It should say something about retrying.

I should have been clearer - I meant that this is a hard question given the current specification of comedia. There may well be modifications to comedia or alternatives to comedia where this isn't hard.

But comedia is the way it is because of assumptions made around its requirements. Those assumptions will need to be changed to get to a different solution.

> I think you want to decouple the connection lifetimes from the session

This is one of those assumtions. *If* you decouple these, then it is necessary to retain a listener for connections on the advertised port even after a connection is established. This gets to be a problem when it is also necessary to dedicate a port for each distinct session in progress. Its all a house of cards.

> heinous when you want to add intermediaries, which wasn't considered at

Once again, this is a matter of conflicting assumptions/requirements.

Sharing of a connection by different sessions, or even sharing of the port to which connections are made, requires that you be able to correlate some unique session identifier passed in the SDP session description with something passed through the resulting connection. But that places a constraint on the kind of protocol that is used over the connection.

The comedia work was already in progress when I discovered it. It was my perception that placing requirements on the protocol to be used over the connection was out of scope. I tried to get some revisions into comedia that would make it more palatable within those constraints. But I must agree with you that the result is pretty ugly - nothing that I would prefer to use.

I think it would be a good thing to revisit the assumptions behind comedia and then come up with something better that satisfies them. I don't know if this should be viewed as a revision to comedia or simply something new. 

My point in bringing this up wrt draft-campbell-simple-*-sessions-00 is that the existing comedia draft (draft-ietf-mmusic-sdp-comedia-04) doesn't provide the needed functionality.

	Paul

---

From: Ben Campbell <[email-masked]>
Date: Wed, 13 Nov 2002 16:05:41 -0600

Sorry for the delayed response.

My gut tells me this is all way more complicated than it appears to be. 
Perhaps I am missing something big. Specific comments inline.

>  > But here is one case that seems simpler than some others:

So, what happens if you attempt to resuse a connection that is dropped? 
Won't that fact quickly become apparent? Can't we just reconnect?

There may be a complication here in that comedia says you can't just 
reconnect, you must renegotiate SDP--but scenario under discussion 
results from an SDP notification, so I am not sure if that requirement 
is constrainint here.

> used to exchange the SDP that contains the URI/identifiers). How is this 

I am not sure I understand the difficulty here. These intermediaries 
surely must be SIP aware, if they are in the business of re-writing SDP. 
Additionally, it seems to me that they must be dialog stateful devices. 
Why can't they just maintain a table that associates a dialog with a 
session, and the session with a connection, where the association 
between session and connection is many-to-one?

If we get SDP describing a new _session_, it will contain address, port, 
and direction information. A device can check the connection table to 
determine whether it currently has a connection opened to that 
particular address and port, can't it? If so, why can't it just start 
interleaving messages for the new session onto the existing connection? 
Maybe I am being dense, but I do not understand what problem the 
connection-id mechanism below is trying to solve.

> occur on a different port, and that means no reuse. So, we have a real 

I will note that comedia says you should _not_ use source address this 
way unless you are certain your network is free of the blight of NATs.

But since a connection can carry more than one session, it makes no 
sense to try to tie a connection request to a particular dialog. The 
cpim-msgfmt session draft has its own mechanism for identifying the 
session. Why can a participating device not relate that to the dialog 
that set upt he session in the first place?

---

From: Paul Kyzivat <[email-masked]>
Date: Thu, 14 Nov 2002 09:59:35 -0500

> results from an SDP notification, so I am not sure if that requirement

Comedia currently says you start listening for a connection when you need one, and you stop listening when you get one. And after you stop, you can recycle the port on which you were listening for the connection. And the connection you got then isn't dropped until a BYE or reinvite.

This logic doesn't work for intermediaries that are multiplexing connections. They need a different rule for when to reuse a connection and when to create one. This is where the race conditions come in.

> connection-id mechanism below is trying to solve.

That's ok on the inbound side, multiplexing traffic. But its not sufficient on the outbound side, where the traffic needs to be demultiplexed. On that side, the intermediary needs to have a mapping between something in the multiplexed media stream and the outbound session.

> that set upt he session in the first place?

What you have done is identify the mismatch between the semantics of comedia and the semantics of cpim.

comedia was faced with the need to set up the media stream without any constraint over the content of that stream. It leads to a different solution that isn't ideal here. (In fact, it may not be ideal for anything.)

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 14 Nov 2002 17:27:55 -0500

inline.

Ben Campbell wrote:

>> routing table, which tells them what to do with incoming messages. 
>> That table tells them that if an IM arrives on some specific 
>> connection, with a specific URI/identifier in the outer envelope, to 
>> forward to a different connection with a different URI/identifier in 
>> the outer envelope. THis means that the intermediary has to associate 
>> each connection with a specific dialog used to set it up (since the 
>> dialog is used to exchange the SDP that contains the URI/identifiers). 
>> How is this association done?
> 
> 

The issue is identifying the connection.

Lets say A calls B through intermediary I. Consider the SDP in the 200 
OK from I to A. The SDP will indicate to A to open a TCP connection to a 
well known port on the single IP address of the intermediary I. This is 
the same port and IP address handed out to every other client. If A is 
active, and initiates the connection to I, when I receives the 
connection request, how does it know its associated with the call that 
was just made? The destination IP provides no information - its to the 
well known address and port. The source address is useless because of 
NAT. So, how does it know?

It can't, unless it uses a distinct port for each connection, which 
doesnt work with intermediaries. And thus our dilemma.

-Jonathan R.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Thu, 14 Nov 2002 17:28:50 -0500

Paul Kyzivat wrote:

 >>  sense to try to tie a connection request to a particular dialog.
 >> The cpim-msgfmt session draft has its own mechanism for identifying
 >> the session. Why can a participating device not relate that to the
 >> dialog that set upt he session in the first place?
 >
 >
 > comedia was faced with the need to set up the media stream without
 > any constraint over the content of that stream. It leads to a
 > different solution that isn't ideal here. (In fact, it may not be
 > ideal for anything.)
 >

Well, thats a problem I think.

I suspect at this point we need to raise these issues in mmusic. At the 
very least, I'd like to be able to EXTEND comedia to meet our 
requirements. Its not even clear to me that we can do that.

-Jonathan R.

---

From: Ben Campbell <[email-masked]>
Date: Thu, 14 Nov 2002 16:47:50 -0600

Jonathan Rosenberg wrote:
>>> dialog is used to exchange the SDP that contains the 
>>> URI/identifiers). How is this association done?
>>
>>
>>
>> surely must be SIP aware, if they are in the business of re-writing 
>> SDP. Additionally, it seems to me that they must be dialog stateful 
>> devices. Why can't they just maintain a table that associates a dialog 
>> with a session, and the session with a connection, where the 
>> association between session and connection is many-to-one?
> 
> 

At the risk of appearing even more hopelessly dense, why does it need to 
know?

If I understand your proposal correctly, it must read the connection-ID 
from the connection after accepting it, which means it cannot decide 
whether or not to accept the connection based on this information. For 
cpim-msgfmt sessions, it does not need to know what connection a message 
arrived on to associate the message with a session--the To: (or msg-ID, 
or whatever) serves that purpose.

Is this just so it can figure out when to stop listening for new 
connections?

---

From: Ben Campbell <[email-masked]>
Date: Thu, 14 Nov 2002 17:10:24 -0600

> This logic doesn't work for intermediaries that are multiplexing connections. They need a different rule for when to reuse a connection and when to create one. This is where the race conditions com…

OK, I _may_ be starting to understand--after the server recycles the 
port, the client cannot just assume that port is still valid for the 
same purpose--heck, it could recycle it for a purpose completely 
unrelated to message sessions. That would explain the comedia 
prohibition against reopening closed connections without a new sdp 
negotiation. But I am not sure I understand why this is different for an 
intermediary and an endpoint.

> That's ok on the inbound side, multiplexing traffic. But its not sufficient on the outbound side, where the traffic needs to be demultiplexed. On that side, the intermediary needs to have a mapping…

Certainly--and that something is, at least for cpim-msgfmt sessions, the 
To header in the envelope (or a MsgID assuming we change that bit.) That 
header tells us all by itself which session a message is associated 
with. I'm not sure it really matters what connection it arrived over. 
Even if you were to send messages on a given session across more than 
one connection, the receiving intermediary could still demux them based 
on the MsgID. (I am _not_ advocating doing that, btw). That intermediary 
would then need to associate the inbound MsgID with an outbound session, 
with an associated connection.

---

From: Paul Kyzivat <[email-masked]>
Date: Thu, 14 Nov 2002 18:35:16 -0500

Ben,

OK, it has been a long time since the details of this were discussed on the list, so I will try to summarize them. This is just for the general case of comedia, nothing to do with simple.

Assume that we have a server (perhaps a gateway) that is going to terminate a bunch of media sessions using comedia. It will be getting lots of concurrent invites with comedia SDP, and responding in kind. It must decide what to put in the sdp it answers with, so that when the connections are made it will be able to associate the connection with corresponding sdp media line.

Now we presume that this must work independent of the content of the media stream - thats a groundrule here. So what can it use to associate an incoming connection? The only thing that works consistently is to assign a separate listening port for media session. If it does this, when the connection comes in it knows that it must be for the session it was assigned to. 

Another possibility we considered was to use a common port for receiving some or all of the incoming connections. But if that is done then some other characteristic of the incoming connection must be used to distinguish one from another. That is where specifying the source address and port in the sdp come in. If they are specified, and used, and unique, and not messed up by NATs, then they can be used to associate connections with sessions. But this list of conditions is so difficult to achieve that this is not a generally practical solution.

So we are back to assigning a separate listening port for each expected incoming session. Now comes another question: how long must the server keep listening on this port? The simple answer is that it must listen as long as there is any possibility that the other end might attempt to connect to it. A simple answer would be to say that listening should continue on the port until the session is ended via a reinvite or a bye. If a single port could be used to listen for all pending connections then this would be a reasonable thing to do. But in a server with many sessions this is an expensive answer. It consumes twice as many ports, and resources to listen on those ports. In the case of Java servers prior to java 1.4 this requires a thread for each. (Its not so bad in 1.4.)

So to make this tolerable, we arranged the connection setup protocol so that when a server doesn't have a connection it knows whether it must listen for connections, and when it gets a connection it knows it doesn't have to listen for more. On average it has about one port/socket per session - either listening for a connection, or waiting for input on a connection. This also means that the ports themselves can be recycled as soon as they will no longer be needed, reducing the total number of ports needed.

One downside (if you consider it that) is that you can only change the connection status by sending a reinvite. I don't consider this a bad thing.

Another downside, which we are seeing here, is that there is no way to multiplex traffic from two or more sessions over a single connection, even if the protocol being carried has enough data to support that demultiplexing. Doing so would require somehow enhancing the sdp so that connections can be identified globally, and so an intent to use a specific preexisting connection could be negotiated. This is probably possible.

But then there comes the problem of deciding when a shared connection can be shut down. (This has to be done via offer/answer exchanges in sdp, because there is no other avaiable mechanism.) This would be subtle, and probably would require some special endpoint behavior, like reinviting with an unshared connection if the use of a shared connection is refused. But that will only work when the connection is between two endpoints. When the connection involves an intermediary, especially between a pair of intermediaries, it is either going to break entirely or be very complex, because they can't control whether reinvites are sent.

Does that make the problem clearer?

Now if you change the groundrules, and assume that there is data in the media stream that can frame media from different media sessions and also provide data that can be correlated with a media stream description in sdp, you can come up with a connection establishment protocol that is very different.

Maybe we need to talk about this in Atlanta.

	Paul

---

From: Jonathan Rosenberg <[email-masked]>
Date: Fri, 15 Nov 2002 13:18:44 -0500

Ben Campbell wrote:

>>
>> Comedia currently says you start listening for a connection when you 
>> need one, and you stop listening when you get one. And after you stop, 
>> you can recycle the port on which you were listening for the 
>> connection. And the connection you got then isn't dropped until a BYE 
>> or reinvite.
>>
>> This logic doesn't work for intermediaries that are multiplexing 
>> connections. They need a different rule for when to reuse a connection 
>> and when to create one. This is where the race conditions come in.
> 
> 

An intermediary wants to receive multiple media sessions on the same 
port. An endpoint doesn't (or may not).

>> That's ok on the inbound side, multiplexing traffic. But its not 
>> sufficient on the outbound side, where the traffic needs to be 
>> demultiplexed. On that side, the intermediary needs to have a mapping 
>> between something in the multiplexed media stream and the outbound 
>> session.
> 
> 

It doesn't. But, it matters what connection it goes TO. And thus the 
problem I've been pointing to, which is how a server knows which session 
an incoming TCP connection is associated with. It cares, since it needs 
to send IMs onto the right connections.

-Jonathan R.

---

From: Ben Campbell <[email-masked]>
Date: Fri, 15 Nov 2002 18:23:45 -0600

Jonathan/Paul

Apologies for my being extra dense this week. Inspiration came to me 
while trying to explain the controversy to a co-worker. I now understand 
the issue with connection identification. I had missed the issue of 
knowing what connection to send an outgoing message on if the connection 
was opened by the opposite end.

We definitely need to discuss it in Atlanta.