Subject: RE: [AVT] Re: RTP/RTCP Port Sharing (SSRC)

From: "Fairlie-Cuninghame, Robert" <[email-masked]>
Date: Tue, 24 Jul 2001 11:00:51 -0700

Hi Jonathan,

I've gave this approach some thought as well. The problem with mandating the
SSRC is that it really breaks the whole RTP model. So I had the idea to have
use a SSRC mask type idea. This means that the different sessions can be
separated but also also allows multiple senders in the same sessions.

For instance, 

a=x-ssrc:1B373xxx

where the sender should replace the masked nibbles with a random number to
form an SSRC with which to send. In this example there are 1024K different
sessions possible (on the same receive port) and 8K different SSRC's within
each session. 

An extension to this idea would be to allow the SDP to include an optional
32-bit random number. Eg.

a=x-ssrc:1B373xxx 4ED2127B

The second number is the random number that will be used when calculating a
SSRC in the reverse direction (and only applies when the SDP is used to form
application-level bidirectional connections). 

For instance, if the other endpoint sends

a=x-ssrc:482783xx DE7B1233

Then you can tell that the SSRC that will be used when sending to the first
endpoint would be 1B373233 and in the other direction 4827837B 

This has now accomplished both RTP port sharing and media flow<->session
correlation/identification in a transport address transparent manner (for
both multiple sessions and multiple participant per session). This are VERY
useful properties!

I'm not too sure if the second extension is "a bridge to far"? There are
still a few issues but nothing insurmountable I think.

You still have the issue where you get a SSRC colision but this is at least
detectable and resolvable. [And this situation has always been a
possibility]

This is now really an MMUSIC issue as well.

Robert.

-----Original Message-----
From: Jonathan Rosenberg
To: 'Michael Thomas'; Colin Perkins
Cc: Fairlie-Cuninghame, Robert; Jonathan Rosenberg; [email-masked]'
Sent: 24/07/01 09:22
Subject: RE: [AVT] Re: RTP/RTCP Port Sharing -> SCTP 

> Colin Perkins writes:
>  > --> "Fairlie-Cuninghame, Robert" writes:
>  > >Hi Jonathan,
>  > >
>  > >> 
>  > >> Well, I would separate firewalls from nats. If the firewall 
>  > >> disallows all
>  > >> UDP, you're SOL and need some ugly, ugly solutions.
>  > >
>  > >A firewall may allow the application (SIP, H.323, etc) 
> through but not allow
>  > >"random" UDP packets to come from outside to "random" RTP 
> ports (since the
>  > >RTP ports are dynamically negotiated by the 
> application-layer). It may
>  > >require that the RTP flow initiate from within the 
> firewall and open a
>  > >five-tuple hole in the firewall as you suggest. I'm only 
> guessing but it
>  > >seems reasonable. 
>  > >
>  > >Of course we could define set of a "standard" RTP port for single
>  > >user-machines which might help  that problem but this is 
> not a general
>  > >solution and perhaps even encouraging undesirable behavior.
>  > 
>  > Section 7 of RFC1890 registers ports 5004 and 5005 for 
> this purpose.
> 
>    Oh. Cool. As I've mentioned to Jonathan before, I think
>    it's an OS/daemon implementation issue whether use of a
>    well known port RTP can be multiplexed for multiple users.
>    Clearly it's not going to be as clean of a design as free
>    floating RTP ports, but a daemon camping on 5004,5005 with
>    a message passing API for users to select SSRC's of interest
>    would probably be doable. The ability to express this in
>    SDP might be problematic though (I haven't looked at what
>    Christian cooked up though...)

Yeah, but the 5004/5005 is just a recommendation, the ports still float
for
multi-session machines, like gateways. Anyway, my experience is that
people
aren't even using these as the starting points for single session
devices.

I would expect that the way to do muxing within a port, using SSRC for
demux, would be to treat the SSRC as a "sub-port". So, when A calls B,
the
SDP from A indicates the port it will receive media on, and the SSRC it
needs B to send with. Similarly, the SDP in the 200 OK indicates the
port B
would like to receive on, the the SSRC it needs A to send with.

So, all we need is an SDP attribute like:

a=ssrc:7659

With this mechanism, the SSRC selection moves from the sender (where it
is
today) to the receiver (where it has to be to avoid collisions on a
port).
Obviously this only works for unicast.

Backwards compatibility is a bit of a pain, though. Near as I can tell
you
would need to rely on SIP Require for this, and back off to floating
ports
if the INVITE fails. 

-Jonathan R.

---
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: Jonathan Rosenberg <[email-masked]>
Date: Tue, 24 Jul 2001 17:55:12 -0400

> From: Fairlie-Cuninghame, Robert [mailto:[email-masked]]
> Sent: Tuesday, July 24, 2001 2:01 PM
> To: 'Jonathan Rosenberg '; ''Michael Thomas' '; 'Colin Perkins '
> Cc: [email-masked]' '; [email-masked]'
> Subject: RE: [AVT] Re: RTP/RTCP Port Sharing (SSRC)
> 
> 
> Hi Jonathan,
> 
> SSRC is that it really breaks the whole RTP model. 

I agree, it puts things in reverse, since now the sender doesn't select
their SSRC, they're told what it is.

> So I had 
> the idea to have

Since we are talking about unicast, in what case do we have multiple
senders? Even for a multiparty conference on a mixer, the mixer still knows
each participant and could assign them non-conflicting SSRC.

> application-level bidirectional connections). 

You've lost me here. Can you provide a complete flow (INV/200/ACK) with how
these are used?

-Jonathan R.
---

---

From: "Fairlie-Cuninghame, Robert" <[email-masked]>
Date: Wed, 25 Jul 2001 03:26:48 -0700

Hi Jonathan,

> their SSRC, they're told what it is.

However, in my mind enforcing this SSRC selection - even in unicast (which
has nothing to do with the number of senders) is going a little too far.
Thus, my proposal is that the SDP advertisement simply restricts the
selectable SSRC range to some subspace of the full 2^^32 values. You now
have a session separation mechanism on the receiving side and yet you do not
destroy the multiple-senders nature of RTP. 

I strongly believe that any solution we come up with should application
generic and not impose limitations that restrict the way in which RTP can be
used.

> > separated but also allows multiple senders in the same 
> sessions.
> 

Well, even in SIP this case is possible - even when not using distributed
conferencing models. For instance, when a request is forked and multiple
endpoints respond with early media, then you will have multiple senders to a
single! If you were to force a single SSRC then all senders would be forced
to use the same SSRC - not very good design IMO. 

The same situation exists when multiple 200's are received (and your new
early media draft doesn't help in this case).

> You've lost me here. Can you provide a complete flow 

Okay here's my proposal:

ssrc-header = "x-ssrc=" rx-ssrc-mask [SP tx-ssrc-seed]
rx-ssrc-mask = *(HEXDIGIT) *("x")
	where rx-ssrc-mask is 1-8 characters in length
tx-ssrc-rnum = 1*(HEXDIGIT)
	where tx-ssrc-rnum is 1-8 characters in length

rx-ssrc-mask is a 32-bit hex number where the trailing nibbles may be masked
with "x"'s. The rx-ssrc-mask is used by a RTP sender to generate an ssrc by
replacing the "x"'s by a random number. Eg

u_long generate_ssrc(char *mask, u_long rand_num)
{
	u_long nibble, ssrc = 0;
	// replace "x"'s in mask with corresponding nibble from rnum
	for(int i=8-strlen(mask);i<8; i++)
	{
		if (mask[i] == 'x')
			nibble = (rand_num >> (7 - i)) & 0xF;
		else
			nibble = hexdigit_to_decimal(mask[i]);
		ssrc |= nibble << (7-i);
	}
	return ssrc;
}

tx-ssrc-rnum is a 32-bit hex number that indicates the random number that
the issuing application will use when generating an SSRC (as per above
function) to send RTP media. This only applies when the SDP will be used to
form a application-level bidirectional channel.

So as a SIP example (random values should normally be used)

INVITE ----->
m=audio 8000 RTP/AVP 0
c=IN IP4 10.0.0.1
a=x-ssrc:123xxxxx 12345678

<----- 200 OK 
m=audio 9000 RTP/AVP 0
c=IN IP4 10.0.0.10
a=x-ssrc:ABCDExxx 89ABCDEF

So now the callee will generate a sending ssrc using
generate_ssrc("123xxxxx", 89ABCDEF) which gives a value of 123BCDEF and
caller will generate a sending ssrc using generate_ssrc("ABCDExxx",
12345678) which gives a value of ABCDE678.

Simple. Both sides can share the same port between multiple sessions (and
multiple senders in each sessions); also the SSRC received on the shared
port can be correlated with the SDP of the corresponding sender -
independent of (unreliable) transport source addresses. 

Simple. These are really powerful properties!

SSRC collision is still possible (if multiple senders are possible) and
could be resolved using standard RTP SSRC collision resolution (or a session
level approach is also possible whereby the issuing side lists collided
SSRC's in the SDP of a re-INVITE/re-advertisement). 

Objections/comments?

Robert.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Wed, 25 Jul 2001 23:48:05 -0400

> Sent: Wednesday, July 25, 2001 6:27 AM
> To: 'Jonathan Rosenberg'; ''Michael Thomas' '; 'Colin Perkins '

Well, you're still telling the sender what SSRC to use, but now its a range
rather than a specific one. I don't see the difference as that important.

> generic and not impose limitations that restrict the way in 

By definition the problem is really restricted to unicast here, though.

> early media draft doesn't help in this case).

Ah, this is a good point. OK. I agree then we will need ranges, or some way
for this to work if the sender still selects his own ssrc.

> Simple. These are really powerful properties!

I get it. Very cute.

> could be resolved using standard RTP SSRC collision 
> resolution 

Only if they're being mixed, though... the case of forked media there is no
mixing. That is, if A calls B, and it forks to X and Y, A is not a mixer in
the SIP sense, since X and Y don't hear each other and won't get each others
SSRC in RTCP packets from A.

I'll note that my early media draft does help this quite a lot, actually;
thats because the called party re-offers the SDP to the caller, so the
caller can answer with a different SDP to each early media stream. This
allows the caller to tell each early media sender to use a different ssrc
for sending to it.

-Jonathan R.
---

---

From: "Fairlie-Cuninghame, Robert" <[email-masked]>
Date: Thu, 26 Jul 2001 03:42:05 -0700

Hi Jonathan,

> By definition the problem is really restricted to unicast 

True but I don't see any reason why it won't provide some benefits to
multicast scenarios as well.

> SSRC in RTCP packets from A.

That's true - traditional RTCP collision detection would not work in the
non-mixer case; however it is still very desirable that the receiver can
request the sender to choose another SSRC so that each sender can be
identified independent of transport source address, that is, by SSRC alone. 

This "collision" resolution is not a problem if the application-layer
protocol 
a) receives an SDP indication from each SDP sender (so that is knows which
senders collided) and
b) can re-issue an SDP advertisement to a particular sender individually (in
which a new SSRC can be forced)

Plain vanilla SIP early media does not exhibit these properties. Your new
early media draft does; multiple 200 OK's does. I can't comment for other
protocols. 

If it is not possible to individually readvertise SDP (eg, multicast
perhaps) then you could list duplicated ssrc's in a re-advertisement
(consequently forcing affected senders to readvertise their SDP) but this is
pretty painful. It would be necessary I think if the primary objective for
using the ssrc attribute stuff is to achieve transport-independent
session-level correlation of media flows in a multicast-like environment.
Still ugly and hopefully not required in most situations.

> allows the caller to tell each early media sender to use a 

Yes, I agree that your draft definitely helps. However one must be careful
to avoid potential pitfalls such as clipped speech when the call is
eventually answer. The caller must be careful that whatever is offered in
the initial INVITE is a superset of what is negotiated in the early media
exchange. 

[BTW, here is Jonathan's early media draft for the causal reader: 
http://www.ietf.org/internet-drafts/draft-rosenberg-sip-early-media-00.txt ]

So an early media example....

INVITE ------>
m=audio 8000 RTP/AVP 0
c=IN IP4 A.A.A.A
a=x-ssrc:3456xxxx 98765432

<------ 183 Session Progress (early media)
m=audio 9000 RTP/AVP 0
c=IN IP4 B.B.B.B
a=x-ssrc:ABCDEFxx 42424242 
a=sendonly

PRACK ------>
m=audio 8000 RTP/AVP 0
c=IN IP4 A.A.A.A
a=x-ssrc:345678xx 98765432 (note SSRC range is subset of initial INVITE) 

<----- 200 OK (PRACK) 

<----- 200 OK (INVITE)
m=audio 9000 RTP/AVP 0
c=IN IP4 B.B.B.B
a=x-ssrc:ABCDEFxx 42424242 

ACK ----->

Notice that the PRACK is a subset of the initial INVITE (and could
theoretically even specify completely the SSRC since there should be only
one sender but I think a small range is better). This means that each early
media responder can be assigned its own SSRC subspace (thereby avoiding
possible SSRC collision) and yet the media stream still satisfies the
original INVITE which is important for continuity when the INVITE 200 OK
eventually arrives. Cool.

In case anyone also hasn't realized this could also provide some small level
of probabilistic protection for RTP traffic from blind attacks (or
systematic errors). When the application-level protocol traffic (eg SIP
messages) are not-visible or encrypted and the attacker is also not able to
see RTP packets in transit, then RTP spoofing will be much more difficult as
their now a specified range of valid SSRC's. 

For instance, an INVITE using

INVITE ------>
m=audio 8000 RTP/AVP 0
c=IN IP4 A.A.A.A
a=x-ssrc:345678xx 98765432 

Means that an attacker only has a 1 in 2^^24 (16 million) chance of choosing
an SSRC that the receiver will not instantly discard. Another helpful
property in addition to shared ports & media-level
correlation/identification. Are you sold yet? :-)

Robert.

---

From: Jim Murphy <[email-masked]>
Date: Fri, 27 Jul 2001 18:29:43 -0700

Robert,

I think you are missing my point, which has nothing to do
with SIP/SDP, firewalls or NATs. I'm just stating that
being able to separate out RTCP and RTP based on the
5-tuple is a good thing, having to go deeper into
the packet is not so good. When a classifier and/or
policer is installed on a router to give QoS to 
some stream, it typically doesn't look any deeper
than the UDP header.

Thanks,

Jim

"Fairlie-Cuninghame, Robert" wrote:
> 
> But Jim you have never been able to assume 5-tuple with standard RTP - this
> proposal does not change that. The source address of a RTP packet cannot be
> enforced under standard SDP rules.
> 
> Jonathan has made a proposal for symmetric RTP as a special case of the
> standard RTP/AVP for NAT-friendly SIP (thereby giving your 5 tuple). I
> believe however this is quite a separate issue to shared ports and SSRC.
> 
> I imagine that allowing all RTP media to come in on a single port would
> actuallly make it MUCH easier to open a firewall hole! The shared port can
> be opened statically and apriori as a 3-tuple (which is not possibly when
> the ports are allocated dynamically with 5-tuples).
> 
> Robert.
> 
> From: Jim Murphy
> To: Fairlie-Cuninghame, Robert
> Cc: 'Jonathan Rosenberg'; [email-masked]' '; [email-masked]'
> Sent: 27/07/01 11:22
> Subject: Re: [AVT] Re: RTP/RTCP Port Sharing (SSRC)
> 
> A bit off the thread, but I haven't heard anyone mention
> the problems this port sharing is going to present to the
> forwarding path in routers doing 5 tuple classification
> and policing and voice gateways trying to send RTP packets to DSPs and
> RTCP packets to some control level code. Not being able to
> rely on the 5 tuple is going to present some problems.
> 
> Thanks,
> 
> Jim

---

From: "Fairlie-Cuninghame, Robert" <[email-masked]>
Date: Mon, 30 Jul 2001 02:22:26 -0700

Jonathan,
> 
> It would be nice to have a mechanism which does not rely on 
> application
> specific capabilities. I don't know if thats possible. I'll 
> also note that
> if you can have these properties from the application layer, 
> I don't need
> ranges anymore either. In the case of forked early media, the 
> caller can
> tell each early media sender to use a specific SSRC. This 
> way, each sender
> is using a different SSRC. 
> 

I guess you could always kludge it with RTCP by inventing imaginary RTCP
receiver (fake an SSRC collision) but that is very nasty and has another
problem. The problem with doing any SSRC collision resolution entirely at
the transport/RTP level is that you lose the ability to correlate
media-flows with application sessions in a transport independent manner.

> >one sender but I think a small range is better). 
> 
> Right, this was my point. What is the value of the range?

For that example the PRACK had

which ranges from 34567800 to 345678FF. The size of the range can be any
thing the application chooses (based on the properties of the negotiation),
eg xxxxxxxx (anything) or 37843874 (no range - completely specified). 

You still always need a range for SIP - even with your early media draft
implemented. What about the multiple 200 Ok's case where local ringback is
used? [Multiple endpoints answering at the same time.] The SDP negotiation
in that situation does not have the property that the SDP offer is sent to
only one sender.

> Big assumption; the SIP messages typically will be visible at 
> some point in
> real systems. I think the best way to solve this spoofing 
> problem properly
> is through SRTP. 
> 

I definitely agree that SRTP is the way to go but I thought its still away's
off. I'm still not sure it will be the right solution for everyone's -
especially on DSP resource poor products.

By SIP messages I assume you mean both SIP & RTP (as SIP messages can be
encrypted in a variety of ways and have a much smaller bandwidth than the
media). I would say SSRC checks are a better RTP "sanity check" than any
sort of source address checking methods.

I perhaps should have emphasized the probabilistic protection from
systematic errors more. For instance, stuck ports, un-cooperative desktop
SIP clients, BYE's not being matched properly (or even not received) on one
side, NAT's playing havoc with ports, etc. There are all sorts of ways that
RTP media can be accidentally sent to the wrong port. These systematic
errors can also be thought of as blind attackers.

Robert.

---

From: "Fairlie-Cuninghame, Robert" <[email-masked]>
Date: Tue, 31 Jul 2001 07:21:44 -0700

> media-flows with application sessions in a transport 

Actually, I guess you could provide the CNAME in the ssrc (or "rtpssrc")
attribute which would thereby allow you to maintain the session-level
correlation even when an SSRC collision occurs (which should be resolvable
using standard RTCP methods). The "rtpssrc" attribute maintains the other
properties such as the session separation for RTP & RTCP packets and some
probabilistic protection from blind attacks and systematic errors (where
appropriate).

So here would be my new format suggestion:

rtpssrc-attribute = "x-rtpssrc:" rx-ssrc-mask SP tx-ssrc-info [SP
tx-ssrc-cname]
rx-ssrc-mask = *(HEXDIGIT) *("x")
	where rx-ssrc-mask is 1-8 characters in length
tx-ssrc-info = tx-ssrc-seed | "mixer" | "-"
tx-ssrc-seed = 1*(HEXDIGIT)
	where tx-ssrc-seed is 1-8 characters in length
tx-ssrc-cname = token | quoted-string
	[this is the CNAME value used in RTCP reports]

A tx-ssrc-info value of "mixer" indicates that multiple ssrc's will be sent
and that receiver must use the same rx-ssrc-mask (or simply "xxxxxxxx") when
receiving RTP & RTCP packets (and should specify the same rx-ssrc-mask value
in the reverse SDP if one is generated). A value of "-" indicates that the
forward SSRC information is not available.

The "mixer" value should be useful in Single Source Multicast sessions where
one server does all the RTP/RTCP mixing & distribution and all other
participants merely send back to the server (as described in that draft).
The server may request participants to use a certain SSRC port range (to
separate sessions on the same port pair) but all participants must not
select a different range in the reverse direction.

Robert.

---

From: Jonathan Rosenberg <[email-masked]>
Date: Tue, 7 Aug 2001 17:48:45 -0400

> Sent: Tuesday, July 31, 2001 3:22 PM
> To: 'Jonathan Rosenberg'

Hmm, I suspect you would not use SSRC ranges at all for the multicast group,
only for the recvonly streams towards the mixer. In that case, you don't
need to introduce this mixer flag. 

-Jonathan R.