Subject: Comedia/reuse motivations

From: "David Yon" <[email-masked]>
Date: Tue, 18 Dec 2001 08:53:06 -0500

For the moment I think it's worthwhile to explore the motivations that
originally begat direction:reuse, and do so separately from the solution
to the motivation.  I'm sorry if I'm being a bit dense, but I'm just not
getting it.

Most of your concern seems to be about scalability.  Let's address this
first, and feel free to chime in with other concerns I may have missed.
In particular, I take some issue this this statement:

	In the comedia tcp case, I have to keep a listener active
listening for
	new connections on the port. Then for each connection, I have to
keep a
	receiver active receiving packets. So in thread based
implementation,
	instead of one thread for receiving, I need a minimum of two -
possibly
	more if I receive multiple connections. This will make using
comedia
	*significantly* more expensive than using UDP, over and above
the
	inherent extra cost of a TCP connection.

So you're saying that compared to UDP, a TCP implementation is a 2X hit
on resources, because you need twice as many threads.  The assertion is
that you need one thread to be a listener and 2nd thread to be a media
pump once the connection has been established.  Again, I don't get it.
Once you've accepting the connection advertised in the SDP, why is the
listener thread needed?  You've fulfilled your promise to the endpoint
and are under no obligation to accept another connection.  In fact, why
two threads?  Just have a single thread to do listen, accept, close
listener, then pump media.

If I'm missing something, and you really do need to dedicate a listener
for the lifetime of the session, this *still* isn't a 2X hit.  Any
implementation with scalability in mind could simply adopt an
inetd-style approach and use a single thread to do listen/accept for a
group of listener sockets, turning the problem into a much more
palatable X+1 scaling problem rather than 2X.

So:

	- Is this the only problem that motivated reuse?

	- Am I missing something on your concern for threading?

---

From: Paul Kyzivat <[email-masked]>
Date: Tue, 18 Dec 2001 11:53:14 -0500

Comments below.

	Paul

> listener, then pump media.

This is exactly what I would like to do!

But doing this requires that all parties agree on when connections may
be established and when they may not. It is uncertainty over when this
is that forces a listener to be active at all times. What I am trying to
do is get verbage in the comedia specification that permits this kind of
behavior.

The most obvious problem is with reinvites:

Suppose I do as you suggest on the initial invite. As soon as I get a
connection, I stop listening and start receiving media. 
- suppose there is a subsequent reinvite that isn't intended to 
  affect this media stream. So I have to duplicate all the SDP
  from the prior invite.
- MUST the other end now make a new connection? (hopefully not)
- MAY the other end now make a new connection? 
  (recovery scenarios may require this)
- must I now listen again on the listening port?
- how long should I wait for a new connection before I cease listening?

The added verbage that you reported last week makes things even worse,
because it seems to imply that anybody should be able to connect to the
port at any time. I suppose that makes the functionality more like the
UDP case, where any number of sources can potentially send packets at
the published UDP destination. And it makes some sense SIP multicast and
non-sip (e.g. SAP) publishings of SDP. But it makes the receiver very
heavyweight - probably unsuitable for use in SIP point-to-point
applications.

> palatable X+1 scaling problem rather than 2X.

Yes, I know it needn't be quite so bad given the proper development
environment. But there are still environments where this isn't a viable
technique. And even when it is, the listening ports can become a scarce
resource. Effectively I need twice as many ports.

>         - Am I missing something on your concern for threading?

Ports as a scarce resource is another concern.

This would not be an issue if a server could use a single listening port
for all comedia sessions it negotiates. But this requires a way to
associate a connection on that port to a particular media description
published in SDP. And guaranteeing a way to do this has proven to be an
insurmoutable problem.

---

From: Joerg Ott <[email-masked]>
Date: Fri, 21 Dec 2001 18:55:28 +0100

(A side remark: I'd prefer that we discuss concepts and take into account
implementation issues rather than discussing implementations and may be
lucky that some concept falls out, too :-)

The more I read and think about this stuff the more I get to the conclusion
that the current comedia "model" (if any) is somewhat broken.  Not because the
the attributes and procedures specified don't make sense but because we have
not defined a proper mapping of the SDP and, in particular, RTP session
model for connection-oriented operation.

I think Paul's concerns are reasonable -- but right now the focus of the
discussion seems to be about hacking even more upon a hack than trying to
get the hack (sorry for the term, David :-) right in the first place.

Let's take a step back.  In RTP, a unicast session is defined by the
respective receiving peer's transport addresses which are conveyed as part
of the SDP description.

An offer/answer exchange in SIP or a SETUP/DESCRIBE combination in RTSP
are used to indicate to a peer to which port to send which media stream
using which codecs and which parameters.  Typically, this information is
exchanged (directly) between the involved parties, i.e. there is no
out-of-band mechanism by which the information would magically reach a 
third party.  Even in the centralized SIP conferencing model with decentralized
media transmitted via multi-unicast we have this kind of (peerwise) exchange
of session information to set up multiple point-to-point sessions.
This is only different for SAP-style announcements -- but those inherently
assume multicast data distribution.

In summary, in interactive scenarios, for each unicast RTP session, one SDP
exchange is carried out to instantiate (and later on modify) this session.

In case of a multi-unicast conference, we have potentially fewer exchanges
but nevertheless, in the symmetric case, one session established for each
peer (since the endpoint needs to know where to send media to).

That is, in a well-setup environment you DO NOT receive media from another
endpoint than the one(s) you have an explicitly established RTP session to
(you need to send RTCP to your peer).  Hence the point that you receive
RTP on the same UDP port from different peers is true ONLY if you also
have set up session to them.  And so the point that anybody may set up
a (or any number of) TCP connection(s) does not apply.  Whatever model
we come up with for TCP should mirror this behavior properly.  Apparently,
so far we hve only taken the first step towards connection-oriented media
without thinking this to the very end.

Further comments below.

> do is get verbage in the comedia specification that permits this kind of

This is exactly wht should be possible.  

> - how long should I wait for a new connection before I cease listening?

Obviously, there are a number of things one can do with an INVITE:

1. Let the other party know your transport address to enable media
   exchange; this is typically what the initial INVITE does.

--> instantiate NEW state in remote peer
--> initiate a connection setup in remote peer and accept an
    incoming connection, respectively
--> The initiator of the TCP connection is likely to do exactly
    one connect() per INVITE and TCP media session; the passive
    peer is expected to accept exactly one TCP connection per
    peer an INVITE is sent to.  This is a problem for centralized
    conferencing with distributed media; hence we include the
    number of connections to be set up (i.e. the number of peers
    to talk to).
--> (enable media exchange after setup)

   Note that if, by accident, we set up two TCP connections, both
   of these need to be dealt with subsequently.

2. Let the other party know to cease transmitting data ("on hold")
   With RTP/AVP/UDP, this is done by using e.g. a=inactive

--> Suspend media flow via the TCP connection(s)
--> Need to indicate whether or not the connection shall be kept or
    whether disconnect should be initiated.

    In case we send reliable data over the TCP connection, we may
    need to find a way to synchronization application media flow
    with tearing down the connection to avoid losing data.
    (but we may find this by far too specific and just do not worry)

3. Taking a remote party "off-hold"
   With RTP/AVP/UDP, this is done by changing from a=inactive back
   to e.g. a=sendrecv.

--> Re-use the existing TCP connection or establish a new one.
--> Depends on what we decide for 2.

4. Redirecting a media stream to a different address.  With RTP/AVP/UDP
   this is simply achieved by putting a different transport address in.

--> Conceptually to be treated differently from 2. and 3. but may be 
    used in conjunction e.g. for switching to and from music-on-hold.
--> Obviously, this means closing the TCP connection and opening a new
    one or by terminating the call or streaming session (or by no longer
    transmitting RTP and RTCP).

5. Changing the acceptable capabilities for a media stream needs to
   be possible without tearing down the TCP connection and bringing
   up a new one.  Depending on the specific application, however, this
   may be necessary (as soon as the mode of operation changes).
   
--> Something like "reuse" is required here.
--> In case a "codec" change requires tearing down the old and setting
    up a new connection, this should also be signaled via some mechanism.

   Strictly speaking, the type of transport is, particularly when we
   are talking about RTP, also just another media stream capability.
   Hence the same m= would need to be used.  Or FID would need to
   specify a grouping that indicates that TCP as well as UDP are
   available for a certain stream.

6. Terminating a media stream is implicitly provided by rejecting the
   media description with port=0.

--> This implies closing all TCP connections associated with this stream.
    Should be possible to signal this.

7. For RTP we support layered coding; something similar may need to be
   provided for TCP, e.g. if you want to allow for independently flow-
   controlled streams belonging to the same application.

--> TCP connections may be set up to the same port if distinguishing
    them is support by the application layer protocol.  If so, we only
    need to specify how many TCP connections should be expected.
--> Alternatively, different ports may be used to distinguish them;
    in this case, we need to allow for multiple transport addresses
    (not just port numbers!), too.
--> Think of it, conceptually, but specify it now only if really needed.
--> How much does this resemle requirements for 

8. ... (Anything important missing in this list?)

It is important to keep in mind that each SDP should be self-describing;
so there should not be something like "if the address changes, then do X".

--

So, in principle, what we need are a few "primitives" as part of the
(re-)INVITE to control the operation.  The basic primitives include

a)  create a new connection to some destination
b)  close an existing connection
c)  pause media flowing across a connection
d)  re-instantiate a media stream across a connection

Initially, a) is required, hence this should be the default behavior
(which also makes it reasonably backward compatible).  At least the
following permutations are conceivable:

- a) and b) may be combined to redirect a media stream
- b) and c) may be combined to stop a media flow
- a) and d) may be combined to resume a media flow 
- a), b), and d) may be combined to resume a media flow and direct it
  to a different target

In addition, we need to signal how many connections shall be created
or created, possibly subdivided into "maximum # of connections",
"current # number of connections", "# connections to be opened/closed".

Finally, we need a way to convey that multiple connections between the
same two endpoints shall be opened.  Note that in this case, all
operations should be carried out on all connections simultaneously;
otherwiese this gets too messy.

--

Here is a strawman proposal on for the modified procedures to follow:
(there are still some issues -- see below -- but I'd like to get this out
before Christmas) right now only showing examples.  Further text will
follow:

For suspending and resuming media streams, we just use the usual attributes
(senddonly,recvonly,sendrecv,inactive).

The following nwq attributes could then be used in addition to achieve the
above:

    a=new:<k>

    This attribute is used to indicate that a new connection shall be created.
    <k> indicates the number of connections to be newly created or accepted.
    If not present, the value defaults to "a=new:1"

    a=reuse

    The existing connection(s) shall be re-used.

    Note that we could also default to "a=reuse" but then we'd have to mandate
    a=new:1 in the initial INVITE, the SAP announcement, etc.

    a=close:<identification?>

    This attribute is used to indicate that the existing connection(s) shall be
    closed.  Some identification may be needed here.

    a=nconn:<total> <max>

    This attribute is used to indicate how many connections the peer(r) is
    expected have open in total after (or before? need to make a choice here)
    new ones are created and old ones closed) and also the maximum number of 
    simultaneous connections support by the peer.  The value "*" is used to
    indicate infinity.  (This would e.g. be used for SAP announcements or
    whenever many parties are supposed to connect to a single server.)

    The default value are "a=nconn:1 *".

The attributes from the comedia draft are used as specified there:

    a=direction:passive,active,both

Some Issues:

1.  If a close: attribute is present, how does the receiver determine which
    connection to close?  Provide explicitly the IP address + port of the
    peer?  What to do if these are not known?  What to do if a listening
    port has been used to accept multiple connections at the peer? Specify
    the other side as well?  Again, these might not be known.  Introduce
    IDs?  Just saying "all or nothing" is not necessarily appropriate.

    Suggestion: is "all or nothing" enough?

2.  The entire close: may get nasty if separate applications are forked to
    handle the communication via TCP.  How does one synchronize these
    media streams with re-INVITEs?

    Suggestion: do not worry; put in a note that this needs to be solved
    per application.  E.g. if I transmit a fax and put the call on hold
    this may not necessarily be a good idea.

--

1. Simple setup of a connection-oriented media session

   Take the example from the current comedia spec would remain identical
   in the simplest case, e.g. as follows:

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=direction:passive
       [a=new:1]
       [a=nconn:1 *]

2./3. Media-on-hold is signalled similar to RTP by using e.g. a=inactive.
   For media-on-hold the TCP connection MUST be kept open (and thus an
   a=reuse MUST be given) unless a=close is specified; in this case,
   a resume for the media stream MUST NOT contain an a=reuse

   On-hold without closing

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=inactive
        a=reuse

   Off-hold without closing

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
       [a=sendrecv]
        a=reuse

   On-hold with closing

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=inactive
        a=close

   Off-hold after closing

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
       [a=sendrecv]
        a=direction:passive
       [a=new:1]
       [a=nconn:1 *]
        
4. Re-direct to a different address; if a close is specified,
   then new MUST specified if the stream should continue right away

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=close
        a=passive
        a=new:1

   Of course, this may be combined with on-hold/off-hold with closing.

5. Change stream caps

   Initial INVITE

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=passive

   Re-INVITE

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP xyz
        a=reuse
 
6. Stream termination

   Re-INVITE:

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP t38 
        a=close

   (this will allow to re-use the media stream later on)
 
   or

        c=IN IP4 10.1.1.2 
        m=image 0 TCP t38 

   (this will not allow later re-use)

7. Support for multiple connections

   Initial INVITE: set up two connections (max 4 are supported)

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP ftp-data
        a=new:2
        a=passive
        a=nconn:2 4

   Re-INVITE: add another connection (here a=new: is mandatory)

        c=IN IP4 10.1.1.2 
        m=image 54111 TCP ftp-data
        a=new:1
        a=nconn:3 4
        
As noted above, some more detailed spec tex will follow.

Cheers,
Joerg

---

From: Paul Kyzivat <[email-masked]>
Date: Fri, 21 Dec 2001 14:04:54 -0500

Joerg,

I just got this, and want to think about it further before responding in
detail. I think you are on a helpful track. 

One thing I am concerned about is similar to the concerns I already had
with a:reuse. In current SDP offer/answer model, in a reinvite you can
always send the same SDP description of a media stream as last time to
indicate that no change is intended. This is important when handling
calls involving multiple media streams because you are required to
transmit a full set even if you only want to change one. 

This proposal breaks that precedent. If you want to send a reinvite but
not cause any change to a comedia media description you most likely will
have to change the SDP from what was sent last time. Consider support
for session timers: you know your session timer is going to expire and
so need to send a reinvite to renew it. But you can't send the same SDP
as before - you must rewrite it. This can affect layering of an
implementation.

So, I would like to see a design where sending identical SDP implies
that nothing has changed. In this case, I believe that requires some
sort of version stamping of individual media descriptions.

	Paul 

P.S. This ain't going to get done by Xmas.