RFC3550 - RTP: A Transport Protocol for Real-Time Applicatio(4)

时间:2005-02-17 来源: 作者: 点击:
identifies a source heard by the reporter, and that SSRC identifier is unrelated to the source transport address of the RTCP packet sent by the reporter.) If the SSRC or CSRC is not found, a new entr
  

identifies a source heard by the reporter, and that SSRC identifier
is unrelated to the source transport address of the RTCP packet sent
by the reporter.) If the SSRC or CSRC is not found, a new entry is
created. These table entries are removed when an RTCP BYE packet is
received with the corresponding SSRC identifier and validated by a
matching source transport address, or after no packets have arrived
for a relatively long time (see Section 6.2.1).

Note that if two sources on the same host are transmitting with the
same source identifier at the time a receiver begins operation, it
would be possible that the first RTP packet received came from one of
the sources while the first RTCP packet received came from the other.
This would cause the wrong RTCP information to be associated with the
RTP data, but this situation should be sufficiently rare and harmless
that it may be disregarded.

In order to track loops of the participant's own data packets, the
implementation MUST also keep a separate list of source transport
addresses (not identifiers) that have been found to be conflicting.
As in the source identifier table, two source transport addresses
MUST be kept to separately track conflicting RTP and RTCP packets.
Note that the conflicting address list should be short, usually
empty. Each element in this list stores the source addresses plus
the time when the most recent conflicting packet was received. An
element MAY be removed from the list when no conflicting packet has
arrived from that source for a time on the order of 10 RTCP report
intervals (see Section 6.2).

For the algorithm as shown, it is assumed that the participant's own
source identifier and state are included in the source identifier
table. The algorithm could be restructured to first make a separate
comparison against the participant's own source identifier.

if (SSRC or CSRC identifier is not found in the source
identifier table) {
create a new entry storing the data or control source
transport address, the SSRC or CSRC and other state;
}

/* Identifier is found in the table */

else if (table entry was created on receipt of a control packet
and this is the first data packet or vice versa) {
store the source transport address from this packet;
}
else if (source transport address from the packet does not match
the one saved in the table entry for this identifier) {

/* An identifier collision or a loop is indicated */

if (source identifier is not the participant's own) {
/* OPTIONAL error counter step */
if (source identifier is from an RTCP SDES chunk
containing a CNAME item that differs from the CNAME
in the table entry) {
count a third-party collision;
} else {
count a third-party loop;
}
abort processing of data packet or control element;
/* MAY choose a different policy to keep new source */
}

/* A collision or loop of the participant's own packets */

else if (source transport address is found in the list of
conflicting data or control source transport
addresses) {
/* OPTIONAL error counter step */
if (source identifier is not from an RTCP SDES chunk
containing a CNAME item or CNAME is the
participant's own) {
count occurrence of own traffic looped;
}
mark current time in conflicting address list entry;
abort processing of data packet or control element;
}

/* New collision, change SSRC identifier */

else {
log occurrence of a collision;
create a new entry in the conflicting data or control
source transport address list and mark current time;
send an RTCP BYE packet with the old SSRC identifier;
choose a new SSRC identifier;
create a new entry in the source identifier table with
the old SSRC plus the source transport address from
the data or control packet being processed;
}
}

In this algorithm, packets from a newly conflicting source address
will be ignored and packets from the original source address will be
kept. If no packets arrive from the original source for an extended
period, the table entry will be timed out and the new source will be

able to take over. This might occur if the original source detects
the collision and moves to a new source identifier, but in the usual
case an RTCP BYE packet will be received from the original source to
delete the state without having to wait for a timeout.

If the original source address was received through a mixer (i.e.,
learned as a CSRC) and later the same source is received directly,
the receiver may be well advised to switch to the new source address
unless other sources in the mix would be lost. Furthermore, for
applications such as telephony in which some sources such as mobile
entities may change addresses during the course of an RTP session,
the RTP implementation SHOULD modify the collision detection
algorithm to accept packets from the new source transport address.
To guard against flip-flopping between addresses if a genuine
collision does occur, the algorithm SHOULD include some means to
detect this case and avoid switching.

When a new SSRC identifier is chosen due to a collision, the
candidate identifier SHOULD first be looked up in the source
identifier table to see if it was already in use by some other
source. If so, another candidate MUST be generated and the process
repeated.

A loop of data packets to a multicast destination can cause severe
network flooding. All mixers and translators MUST implement a loop
detection algorithm like the one here so that they can break loops.
This should limit the excess traffic to no more than one duplicate
copy of the original traffic, which may allow the session to continue
so that the cause of the loop can be found and fixed. However, in
extreme cases where a mixer or translator does not properly break the
loop and high traffic levels result, it may be necessary for end
systems to cease transmitting data or control packets entirely. This
decision may depend upon the application. An error condition SHOULD
be indicated as appropriate. Transmission MAY be attempted again
periodically after a long, random time (on the order of minutes).

8.3 Use with Layered Encodings

For layered encodings transmitted on separate RTP sessions (see
Section 2.4), a single SSRC identifier space SHOULD be used across
the sessions of all layers and the core (base) layer SHOULD be used
for SSRC identifier allocation and collision resolution. When a
source discovers that it has collided, it transmits an RTCP BYE
packet on only the base layer but changes the SSRC identifier to the
new value in all layers.

9. Security

Lower layer protocols may eventually provide all the security
services that may be desired for applications of RTP, including
authentication, integrity, and confidentiality. These services have
been specified for IP in [27]. Since the initial audio and video
applications using RTP needed a confidentiality service before such
services were available for the IP layer, the confidentiality service
described in the next section was defined for use with RTP and RTCP.
That description is included here to codify existing practice. New
applications of RTP MAY implement this RTP-specific confidentiality
service for backward compatibility, and/or they MAY implement
alternative security services. The overhead on the RTP protocol for
this confidentiality service is low, so the penalty will be minimal
if this service is obsoleted by other services in the future.

Alternatively, other services, other implementations of services and
other algorithms may be defined for RTP in the future. In
particular, an RTP profile called Secure Real-time Transport Protocol
(SRTP) [28] is being developed to provide confidentiality of the RTP
payload while leaving the RTP header in the clear so that link-level
header compression algorithms can still operate. It is expected that
SRTP will be the correct choice for many applications. SRTP is based
on the Advanced Encryption Standard (AES) and provides stronger
security than the service described here. No claim is made that the
methods presented here are appropriate for a particular security
need. A profile may specify which services and algorithms should be
offered by applications, and may provide guidance as to their
appropriate use.

Key distribution and certificates are outside the scope of this
document.

9.1 Confidentiality

Confidentiality means that only the intended receiver(s) can decode
the received packets; for others, the packet contains no useful
information. Confidentiality of the content is achieved by
encryption.

When it is desired to encrypt RTP or RTCP according to the method
specified in this section, all the octets that will be encapsulated
for transmission in a single lower-layer packet are encrypted as a
unit. For RTCP, a 32-bit random number redrawn for each unit MUST be
prepended to the unit before encryption. For RTP, no prefix is
prepended; instead, the sequence number and timestamp fields are
initialized with random offsets. This is considered to be a weak

initialization vector (IV) because of poor randomness properties. In
addition, if the subsequent field, the SSRC, can be manipulated by an
enemy, there is further weakness of the encryption method.

For RTCP, an implementation MAY segregate the individual RTCP packets
in a compound RTCP packet into two separate compound RTCP packets,
one to be encrypted and one to be sent in the clear. For example,
SDES information might be encrypted while reception reports were sent
in the clear to accommodate third-party monitors that are not privy
to the encryption key. In this example, depicted in Fig. 4, the SDES
information MUST be appended to an RR packet with no reports (and the
random number) to satisfy the requirement that all compound RTCP
packets begin with an SR or RR packet. The SDES CNAME item is
required in either the encrypted or unencrypted packet, but not both.
The same SDES information SHOULD NOT be carried in both packets as
this may compromise the encryption.

UDP packet UDP packet
----------------------------- ------------------------------
[random][RR][SDES #CNAME ...] [SR #senderinfo #site1 #site2]
----------------------------- ------------------------------
encrypted not encrypted

#: SSRC identifier

Figure 4: Encrypted and non-encrypted RTCP packets

The presence of encryption and the use of the correct key are
confirmed by the receiver through header or payload validity checks.
Examples of such validity checks for RTP and RTCP headers are given
in Appendices A.1 and A.2.

To be consistent with existing implementations of the initial
specification of RTP in RFC1889, the default encryption algorithm is
the Data Encryption Standard (DES) algorithm in cipher block chaining
(CBC) mode, as described in Section 1.1 of RFC1423 [29], except that
padding to a multiple of 8 octets is indicated as described for the P
bit in Section 5.1. The initialization vector is zero because random
values are supplied in the RTP header or by the random prefix for
compound RTCP packets. For details on the use of CBC initialization
vectors, see [30].

Implementations that support the encryption method specified here
SHOULD always support the DES algorithm in CBC mode as the default
cipher for this method to maximize interoperability. This method was
chosen because it has been demonstrated to be easy and practical to
use in experimental audio and video tools in operation on the
Internet. However, DES has since been found to be too easily broken.

It is RECOMMENDED that stronger encryption algorithms such as
Triple-DES be used in place of the default algorithm. Furthermore,
secure CBC mode requires that the first block of each packet be XORed
with a random, independent IV of the same size as the cipher's block
size. For RTCP, this is (partially) achieved by prepending each
packet with a 32-bit random number, independently chosen for each
packet. For RTP, the timestamp and sequence number start from random
values, but consecutive packets will not be independently randomized.
It should be noted that the randomness in both cases (RTP and RTCP)
is limited. High-security applications SHOULD consider other, more
conventional, protection means. Other encryption algorithms MAY be
specified dynamically for a session by non-RTP means. In particular,
the SRTP profile [28] based on AES is being developed to take into
account known plaintext and CBC plaintext manipulation concerns, and
will be the correct choice in the future.

As an alternative to encryption at the IP level or at the RTP level
as described above, profiles MAY define additional payload types for
encrypted encodings. Those encodings MUST specify how padding and
other aspects of the encryption are to be handled. This method
allows encrypting only the data while leaving the headers in the
clear for applications where that is desired. It may be particularly
useful for hardware devices that will handle both decryption and
decoding. It is also valuable for applications where link-level
compression of RTP and lower-layer headers is desired and
confidentiality of the payload (but not addresses) is sufficient
since encryption of the headers precludes compression.

9.2 Authentication and Message Integrity

Authentication and message integrity services are not defined at the
RTP level since these services would not be directly feasible without
a key management infrastructure. It is expected that authentication
and integrity services will be provided by lower layer protocols.

10. Congestion Control

All transport protocols used on the Internet need to address
congestion control in some way [31]. RTP is not an exception, but
because the data transported over RTP is often inelastic (generated
at a fixed or controlled rate), the means to control congestion in
RTP may be quite different from those for other transport protocols
such as TCP. In one sense, inelasticity reduces the risk of
congestion because the RTP stream will not expand to consume all
available bandwidth as a TCP stream can. However, inelasticity also
means that the RTP stream cannot arbitrarily reduce its load on the
network to eliminate congestion when it occurs.

Since RTP may be used for a wide variety of applications in many
different contexts, there is no single congestion control mechanism
that will work for all. Therefore, congestion control SHOULD be
defined in each RTP profile as appropriate. For some profiles, it
may be sufficient to include an applicability statement restricting
the use of that profile to environments where congestion is avoided
by engineering. For other profiles, specific methods such as data
rate adaptation based on RTCP feedback may be required.

11. RTP over Network and Transport Protocols

This section describes issues specific to carrying RTP packets within
particular network and transport protocols. The following rules
apply unless superseded by protocol-specific definitions outside this
specification.

RTP relies on the underlying protocol(s) to provide demultiplexing of
RTP data and RTCP control streams. For UDP and similar protocols,
RTP SHOULD use an even destination port number and the corresponding
RTCP stream SHOULD use the next higher (odd) destination port number.
For applications that take a single port number as a parameter and
derive the RTP and RTCP port pair from that number, if an odd number
is supplied then the application SHOULD replace that number with the
next lower (even) number to use as the base of the port pair. For
applications in which the RTP and RTCP destination port numbers are
specified via explicit, separate parameters (using a signaling
protocol or other means), the application MAY disregard the
restrictions that the port numbers be even/odd and consecutive
although the use of an even/odd port pair is still encouraged. The
RTP and RTCP port numbers MUST NOT be the same since RTP relies on
the port numbers to demultiplex the RTP data and RTCP control
streams.

In a unicast session, both participants need to identify a port pair
for receiving RTP and RTCP packets. Both participants MAY use the
same port pair. A participant MUST NOT assume that the source port
of the incoming RTP or RTCP packet can be used as the destination
port for outgoing RTP or RTCP packets. When RTP data packets are
being sent in both directions, each participant's RTCP SR packets
MUST be sent to the port that the other participant has specified for
reception of RTCP. The RTCP SR packets combine sender information
for the outgoing data plus reception report information for the
incoming data. If a side is not actively sending data (see Section
6.4), an RTCP RR packet is sent instead.

It is RECOMMENDED that layered encoding applications (see Section
2.4) use a set of contiguous port numbers. The port numbers MUST be
distinct because of a widespread deficiency in existing operating

systems that prevents use of the same port with multiple multicast
addresses, and for unicast, there is only one permissible address.
Thus for layer n, the data port is P + 2n, and the control port is P
+ 2n + 1. When IP multicast is used, the addresses MUST also be
distinct because multicast routing and group membership are managed
on an address granularity. However, allocation of contiguous IP
multicast addresses cannot be assumed because some groups may require
different scopes and may therefore be allocated from different
address ranges.

The previous paragraph conflicts with the SDP specification, RFC2327
[15], which says that it is illegal for both multiple addresses and
multiple ports to be specified in the same session description
because the association of addresses with ports could be ambiguous.
It is intended that this restriction will be relaxed in a revision of
RFC2327 to allow an equal number of addresses and ports to be
specified with a one-to-one mapping implied.

RTP data packets contain no length field or other delineation,
therefore RTP relies on the underlying protocol(s) to provide a
length indication. The maximum length of RTP packets is limited only
by the underlying protocols.

If RTP packets are to be carried in an underlying protocol that
provides the abstraction of a continuous octet stream rather than
messages (packets), an encapsulation of the RTP packets MUST be
defined to provide a framing mechanism. Framing is also needed if
the underlying protocol may contain padding so that the extent of the
RTP payload cannot be determined. The framing mechanism is not
defined here.

A profile MAY specify a framing method to be used even when RTP is
carried in protocols that do provide framing in order to allow
carrying several RTP packets in one lower-layer protocol data unit,
such as a UDP packet. Carrying several RTP packets in one network or
transport packet reduces header overhead and may simplify
synchronization between different streams.

12. Summary of Protocol Constants

This section contains a summary listing of the constants defined in
this specification.

The RTP payload type (PT) constants are defined in profiles rather
than this document. However, the octet of the RTP header which
contains the marker bit(s) and payload type MUST avoid the reserved
values 200 and 201 (decimal) to distinguish RTP packets from the RTCP
SR and RR packet types for the header validation procedure described

in Appendix A.1. For the standard definition of one marker bit and a
7-bit payload type field as shown in this specification, this
restriction means that payload types 72 and 73 are reserved.

12.1 RTCP Packet Types

abbrev. name value
SR sender report 200
RR receiver report 201
SDES source description 202
BYE goodbye 203
APP application-defined 204

These type values were chosen in the range 200-204 for improved
header validity checking of RTCP packets compared to RTP packets or
other unrelated packets. When the RTCP packet type field is compared
to the corresponding octet of the RTP header, this range corresponds
to the marker bit being 1 (which it usually is not in data packets)
and to the high bit of the standard payload type field being 1 (since
the static payload types are typically defined in the low half).
This range was also chosen to be some distance numerically from 0 and
255 since all-zeros and all-ones are common data patterns.

Since all compound RTCP packets MUST begin with SR or RR, these codes
were chosen as an even/odd pair to allow the RTCP validity check to
test the maximum number of bits with mask and value.

Additional RTCP packet types may be registered through IANA (see
Section 15).

12.2 SDES Types

abbrev. name value
END end of SDES list 0
CNAME canonical name 1
NAME user name 2
EMAIL user's electronic mail address 3
PHONE user's phone number 4
LOC geographic user location 5
TOOL name of application or tool 6
NOTE notice about the source 7
PRIV private extensions 8

Additional SDES types may be registered through IANA (see Section
15).

13. RTP Profiles and Payload Format Specifications

A complete specification of RTP for a particular application will
require one or more companion documents of two types described here:
profiles, and payload format specifications.

RTP may be used for a variety of applications with somewhat differing
requirements. The flexibility to adapt to those requirements is
provided by allowing multiple choices in the main protocol
specification, then selecting the appropriate choices or defining
extensions for a particular environment and class of applications in
a separate profile document. Typically an application will operate
under only one profile in a particular RTP session, so there is no
explicit indication within the RTP protocol itself as to which
profile is in use. A profile for audio and video applications may be
found in the companion RFC3551. Profiles are typically titled "RTP
Profile for ...".

The second type of companion document is a payload format
specification, which defines how a particular kind of payload data,
such as H.261 encoded video, should be carried in RTP. These
documents are typically titled "RTP Payload Format for XYZ
Audio/Video Encoding". Payload formats may be useful under multiple
profiles and may therefore be defined independently of any particular
profile. The profile documents are then responsible for assigning a
default mapping of that format to a payload type value if needed.

Within this specification, the following items have been identified
for possible definition within a profile, but this list is not meant
to be exhaustive:

RTP data header: The octet in the RTP data header that contains
the marker bit and payload type field MAY be redefined by a
profile to suit different requirements, for example with more or
fewer marker bits (Section 5.3, p. 18).

Payload types: Assuming that a payload type field is included,
the profile will usually define a set of payload formats (e.g.,
media encodings) and a default static mapping of those formats to
payload type values. Some of the payload formats may be defined
by reference to separate payload format specifications. For each
payload type defined, the profile MUST specify the RTP timestamp
clock rate to be used (Section 5.1, p. 14).

RTP data header additions: Additional fields MAY be appended to
the fixed RTP data header if some additional functionality is
required across the profile's class of applications independent of
payload type (Section 5.3, p. 18).

RTP data header extensions: The contents of the first 16 bits of
the RTP data header extension structure MUST be defined if use of
that mechanism is to be allowed under the profile for
implementation-specific extensions (Section 5.3.1, p. 18).

RTCP packet types: New application-class-specific RTCP packet
types MAY be defined and registered with IANA.

RTCP report interval: A profile SHOULD specify that the values
suggested in Section 6.2 for the constants employed in the
calculation of the RTCP report interval will be used. Those are
the RTCP fraction of session bandwidth, the minimum report
interval, and the bandwidth split between senders and receivers.
A profile MAY specify alternate values if they have been
demonstrated to work in a scalable manner.

SR/RR extension: An extension section MAY be defined for the
RTCP SR and RR packets if there is additional information that
should be reported regularly about the sender or receivers
(Section 6.4.3, p. 42 and 43).

SDES use: The profile MAY specify the relative priorities for
RTCP SDES items to be transmitted or excluded entirely (Section
6.3.9); an alternate syntax or semantics for the CNAME item
(Section 6.5.1); the format of the LOC item (Section 6.5.5); the
semantics and use of the NOTE item (Section 6.5.7); or new SDES
item types to be registered with IANA.

Security: A profile MAY specify which security services and
algorithms should be offered by applications, and MAY provide
guidance as to their appropriate use (Section 9, p. 65).

String-to-key mapping: A profile MAY specify how a user-provided
password or pass phrase is mapped into an encryption key.

Congestion: A profile SHOULD specify the congestion control
behavior appropriate for that profile.

Underlying protocol: Use of a particular underlying network or
transport layer protocol to carry RTP packets MAY be required.

Transport mapping: A mapping of RTP and RTCP to transport-level
addresses, e.g., UDP ports, other than the standard mapping
defined in Section 11, p. 68 may be specified.

Encapsulation: An encapsulation of RTP packets may be defined to
allow multiple RTP data packets to be carried in one lower-layer
packet or to provide framing over underlying protocols that do not
already do so (Section 11, p. 69).

It is not expected that a new profile will be required for every
application. Within one application class, it would be better to
extend an existing profile rather than make a new one in order to
facilitate interoperation among the applications since each will
typically run under only one profile. Simple extensions such as the
definition of additional payload type values or RTCP packet types may
be accomplished by registering them through IANA and publishing their
descriptions in an addendum to the profile or in a payload format
specification.

14. Security Considerations

RTP suffers from the same security liabilities as the underlying
protocols. For example, an impostor can fake source or destination
network addresses, or change the header or payload. Within RTCP, the
CNAME and NAME information may be used to impersonate another
participant. In addition, RTP may be sent via IP multicast, which
provides no direct means for a sender to know all the receivers of
the data sent and therefore no measure of privacy. Rightly or not,
users may be more sensitive to privacy concerns with audio and video
communication than they have been with more traditional forms of
network communication [33]. Therefore, the use of security
mechanisms with RTP is important. These mechanisms are discussed in
Section 9.

RTP-level translators or mixers may be used to allow RTP traffic to
reach hosts behind firewalls. Appropriate firewall security
principles and practices, which are beyond the scope of this
document, should be followed in the design and installation of these
devices and in the admission of RTP applications for use behind the
firewall.

15. IANA Considerations

Additional RTCP packet types and SDES item types may be registered
through the Internet Assigned Numbers Authority (IANA). Since these
number spaces are small, allowing unconstrained registration of new
values would not be prudent. To facilitate review of requests and to
promote shared use of new types among multiple applications, requests
for registration of new values must be documented in an RFCor other
permanent and readily available reference such as the product of
another cooperative standards body (e.g., ITU-T). Other requests may
also be accepted, under the advice of a "designated expert."

(Contact the IANA for the contact information of the current expert.)

RTP profile specifications SHOULD register with IANA a name for the
profile in the form "RTP/xxx", where xxx is a short abbreviation of
the profile title. These names are for use by higher-level control
protocols, such as the Session Description Protocol (SDP), RFC2327
[15], to refer to transport methods.

16. Intellectual Property Rights Statement

The IETF takes no position regarding the validity or scope of any
intellectual property or other rights that might be claimed to
pertain to the implementation or use of the technology described in
this document or the extent to which any license under such rights
might or might not be available; neither does it represent that it
has made any effort to identify any such rights. Information on the
IETF's procedures with respect to rights in standards-track and
standards-related documentation can be found in BCP-11. Copies of
claims of rights made available for publication and any assurances of
licenses to be made available, or the result of an attempt made to
obtain a general license or permission for the use of such
proprietary rights by implementors or users of this specification can
be obtained from the IETF Secretariat.

The IETF invites any interested party to bring to its attention any
copyrights, patents or patent applications, or other proprietary
rights which may cover technology that may be required to practice
this standard. Please address the information to the IETF Executive
Director.

17. Acknowledgments

This memorandum is based on discussions within the IETF Audio/Video
Transport working group chaired by Stephen Casner and Colin Perkins.
The current protocol has its origins in the Network Voice Protocol
and the Packet Video Protocol (Danny Cohen and Randy Cole) and the
protocol implemented by the vat application (Van Jacobson and Steve
McCanne). Christian Huitema provided ideas for the random identifier
generator. Extensive analysis and simulation of the timer
reconsideration algorithm was done by Jonathan Rosenberg. The
additions for layered encodings were specified by Michael Speer and
Steve McCanne.

Appendix A - Algorithms

We provide examples of C code for aspects of RTP sender and receiver
algorithms. There may be other implementation methods that are
faster in particular operating environments or have other advantages.
These implementation notes are for informational purposes only and
are meant to clarify the RTP specification.

The following definitions are used for all examples; for clarity and
brevity, the structure definitions are only valid for 32-bit big-
endian (most significant octet first) architectures. Bit fields are
assumed to be packed tightly in big-endian bit order, with no
additional padding. Modifications would be required to construct a
portable implementation.

/*
* rtp.h -- RTP header file
*/
#include <sys/types.h>

/*
* The type definitions below are valid for 32-bit architectures and
* may have to be adjusted for 16- or 64-bit architectures.
*/
typedef unsigned char u_int8;
typedef unsigned short u_int16;
typedef unsigned int u_int32;
typedef short int16;

/*
* Current protocol version.
*/
#define RTP_VERSION 2

#define RTP_SEQ_MOD (1<<16)
#define RTP_MAX_SDES 255 /* maximum text length for SDES */

typedef enum {
RTCP_SR = 200,
RTCP_RR = 201,
RTCP_SDES = 202,
RTCP_BYE = 203,
RTCP_APP = 204
} rtcp_type_t;

typedef enum {
RTCP_SDES_END = 0,
RTCP_SDES_CNAME = 1,

RTCP_SDES_NAME = 2,
RTCP_SDES_EMAIL = 3,
RTCP_SDES_PHONE = 4,
RTCP_SDES_LOC = 5,
RTCP_SDES_TOOL = 6,
RTCP_SDES_NOTE = 7,
RTCP_SDES_PRIV = 8
} rtcp_sdes_type_t;

/*
* RTP data header
*/
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int x:1; /* header extension flag */
unsigned int cc:4; /* CSRC count */
unsigned int m:1; /* marker bit */
unsigned int pt:7; /* payload type */
unsigned int seq:16; /* sequence number */
u_int32 ts; /* timestamp */
u_int32 ssrc; /* synchronization source */
u_int32 csrc[1]; /* optional CSRC list */
} rtp_hdr_t;

/*
* RTCP common header word
*/
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int count:5; /* varies by packet type */
unsigned int pt:8; /* RTCP packet type */
u_int16 length; /* pkt len in words, w/o this word */
} rtcp_common_t;

/*
* Big-endian mask for version, padding bit and packet type pair
*/
#define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe)
#define RTCP_VALID_VALUE ((RTP_VERSION << 14) | RTCP_SR)

/*
* Reception report block
*/
typedef struct {
u_int32 ssrc; /* data source being reported */
unsigned int fraction:8; /* fraction lost since last SR/RR */

int lost:24; /* cumul. no. pkts lost (signed!) */
u_int32 last_seq; /* extended last seq. no. received */
u_int32 jitter; /* interarrival jitter */
u_int32 lsr; /* last SR packet from this source */
u_int32 dlsr; /* delay since last SR packet */
} rtcp_rr_t;

/*
* SDES item
*/
typedef struct {
u_int8 type; /* type of item (rtcp_sdes_type_t) */
u_int8 length; /* length of item (in octets) */
char data[1]; /* text, not null-terminated */
} rtcp_sdes_item_t;

/*
* One RTCP packet
*/
typedef struct {
rtcp_common_t common; /* common header */
union {
/* sender report (SR) */
struct {
u_int32 ssrc; /* sender generating this report */
u_int32 ntp_sec; /* NTP timestamp */
u_int32 ntp_frac;
u_int32 rtp_ts; /* RTP timestamp */
u_int32 psent; /* packets sent */
u_int32 osent; /* octets sent */
rtcp_rr_t rr[1]; /* variable-length list */
} sr;

/* reception report (RR) */
struct {
u_int32 ssrc; /* receiver generating this report */
rtcp_rr_t rr[1]; /* variable-length list */
} rr;

/* source description (SDES) */
struct rtcp_sdes {
u_int32 src; /* first SSRC/CSRC */
rtcp_sdes_item_t item[1]; /* list of SDES items */
} sdes;

/* BYE */
struct {
u_int32 src[1]; /* list of sources */

/* can't express trailing text for reason */
} bye;
} r;
} rtcp_t;

typedef struct rtcp_sdes rtcp_sdes_t;

/*
* Per-source state information
*/
typedef struct {
u_int16 max_seq; /* highest seq. number seen */
u_int32 cycles; /* shifted count of seq. number cycles */
u_int32 base_seq; /* base seq number */
u_int32 bad_seq; /* last 'bad' seq number + 1 */
u_int32 probation; /* sequ. packets till source is valid */
u_int32 received; /* packets received */
u_int32 expected_prior; /* packet expected at last interval */
u_int32 received_prior; /* packet received at last interval */
u_int32 transit; /* relative trans time for prev pkt */
u_int32 jitter; /* estimated jitter */
/* ... */
} source;

A.1 RTP Data Header Validity Checks

An RTP receiver should check the validity of the RTP header on
incoming packets since they might be encrypted or might be from a
different application that happens to be misaddressed. Similarly, if
encryption according to the method described in Section 9 is enabled,
the header validity check is needed to verify that incoming packets
have been correctly decrypted, although a failure of the header
validity check (e.g., unknown payload type) may not necessarily
indicate decryption failure.

Only weak validity checks are possible on an RTP data packet from a
source that has not been heard before:

o RTP version field must equal 2.

o The payload type must be known, and in particular it must not be
equal to SR or RR.

o If the P bit is set, then the last octet of the packet must
contain a valid octet count, in particular, less than the total
packet length minus the header size.

o The X bit must be zero if the profile does not specify that the
header extension mechanism may be used. Otherwise, the extension
length field must be less than the total packet size minus the
fixed header length and padding.

o The length of the packet must be consistent with CC and payload
type (if payloads have a known length).

The last three checks are somewhat complex and not always possible,
leaving only the first two which total just a few bits. If the SSRC
identifier in the packet is one that has been received before, then
the packet is probably valid and checking if the sequence number is
in the expected range provides further validation. If the SSRC
identifier has not been seen before, then data packets carrying that
identifier may be considered invalid until a small number of them
arrive with consecutive sequence numbers. Those invalid packets MAY
be discarded or they MAY be stored and delivered once validation has
been achieved if the resulting delay is acceptable.

The routine update_seq shown below ensures that a source is declared
valid only after MIN_SEQUENTIAL packets have been received in
sequence. It also validates the sequence number seq of a newly
received packet and updates the sequence state for the packet's
source in the structure to which s points.

When a new source is heard for the first time, that is, its SSRC
identifier is not in the table (see Section 8.2), and the per-source
state is allocated for it, s->probation is set to the number of
sequential packets required before declaring a source valid
(parameter MIN_SEQUENTIAL) and other variables are initialized:

init_seq(s, seq);
s->max_seq = seq - 1;
s->probation = MIN_SEQUENTIAL;

A non-zero s->probation marks the source as not yet valid so the
state may be discarded after a short timeout rather than a long one,
as discussed in Section 6.2.1.

After a source is considered valid, the sequence number is considered
valid if it is no more than MAX_DROPOUT ahead of s->max_seq nor more
than MAX_MISORDER behind. If the new sequence number is ahead of
max_seq modulo the RTP sequence number range (16 bits), but is
smaller than max_seq, it has wrapped around and the (shifted) count
of sequence number cycles is incremented. A value of one is returned
to indicate a valid sequence number.

Otherwise, the value zero is returned to indicate that the validation
failed, and the bad sequence number plus 1 is stored. If the next
packet received carries the next higher sequence number, it is
considered the valid start of a new packet sequence presumably caused
by an extended dropout or a source restart. Since multiple complete
sequence number cycles may have been missed, the packet loss
statistics are reset.

Typical values for the parameters are shown, based on a maximum
misordering time of 2 seconds at 50 packets/second and a maximum
dropout of 1 minute. The dropout parameter MAX_DROPOUT should be a
small fraction of the 16-bit sequence number space to give a
reasonable probability that new sequence numbers after a restart will
not fall in the acceptable range for sequence numbers from before the
restart.

void init_seq(source *s, u_int16 seq)
{
s->base_seq = seq;
s->max_seq = seq;
s->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
s->cycles = 0;
s->received = 0;
s->received_prior = 0;
s->expected_prior = 0;
/* other initialization */
}

int update_seq(source *s, u_int16 seq)
{
u_int16 udelta = seq - s->max_seq;
const int MAX_DROPOUT = 3000;
const int MAX_MISORDER = 100;
const int MIN_SEQUENTIAL = 2;

/*
* Source is not valid until MIN_SEQUENTIAL packets with
* sequential sequence numbers have been received.
*/
if (s->probation) {
/* packet is in sequence */
if (seq == s->max_seq + 1) {
s->probation--;
s->max_seq = seq;
if (s->probation == 0) {
init_seq(s, seq);
s->received++;
return 1;

}
} else {
s->probation = MIN_SEQUENTIAL - 1;
s->max_seq = seq;
}
return 0;
} else if (udelta < MAX_DROPOUT) {
/* in order, with permissible gap */
if (seq < s->max_seq) {
/*
* Sequence number wrapped - count another 64K cycle.
*/
s->cycles += RTP_SEQ_MOD;
}
s->max_seq = seq;
} else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
/* the sequence number made a very large jump */
if (seq == s->bad_seq) {
/*
* Two sequential packets -- assume that the other side
* restarted without telling us so just re-sync
* (i.e., pretend this was the first packet).
*/
init_seq(s, seq);
}
else {
s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
return 0;
}
} else {
/* duplicate or reordered packet */
}
s->received++;
return 1;
}

The validity check can be made stronger requiring more than two
packets in sequence. The disadvantages are that a larger number of
initial packets will be discarded (or delayed in a queue) and that
high packet loss rates could prevent validation. However, because
the RTCP header validation is relatively strong, if an RTCP packet is
received from a source before the data packets, the count could be
adjusted so that only two packets are required in sequence. If
initial data loss for a few seconds can be tolerated, an application
MAY choose to discard all data packets from a source until a valid
RTCP packet has been received from that source.

Depending on the application and encoding, algorithms may exploit
additional knowledge about the payload format for further validation.
For payload types where the timestamp increment is the same for all
packets, the timestamp values can be predicted from the previous
packet received from the same source using the sequence number
difference (assuming no change in payload type).

A strong "fast-path" check is possible since with high probability
the first four octets in the header of a newly received RTP data
packet will be just the same as that of the previous packet from the
same SSRC except that the sequence number will have increased by one.
Similarly, a single-entry cache may be used for faster SSRC lookups
in applications where data is typically received from one source at a
time.

A.2 RTCP Header Validity Checks

The following checks should be applied to RTCP packets.

o RTP version field must equal 2.

o The payload type field of the first RTCP packet in a compound
packet must be equal to SR or RR.

o The padding bit (P) should be zero for the first packet of a
compound RTCP packet because padding should only be applied, if it
is needed, to the last packet.

o The length fields of the individual RTCP packets must add up to
the overall length of the compound RTCP packet as received. This
is a fairly strong check.

The code fragment below performs all of these checks. The packet
type is not checked for subsequent packets since unknown packet types
may be present and should be ignored.

u_int32 len; /* length of compound RTCP packet in words */
rtcp_t *r; /* RTCP header */
rtcp_t *end; /* end of compound RTCP packet */

if ((*(u_int16 *)r & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
/* something wrong with packet format */
}
end = (rtcp_t *)((u_int32 *)r + len);

do r = (rtcp_t *)((u_int32 *)r + r->common.length + 1);
while (r < end && r->common.version == 2);

if (r != end) {
/* something wrong with packet format */
}

A.3 Determining Number of Packets Expected and Lost

In order to compute packet loss rates, the number of RTP packets
expected and actually received from each source needs to be known,
using per-source state information defined in struct source
referenced via pointer s in the code below. The number of packets
received is simply the count of packets as they arrive, including any
late or duplicate packets. The number of packets expected can be
computed by the receiver as the difference between the highest
sequence number received (s->max_seq) and the first sequence number
received (s->base_seq). Since the sequence number is only 16 bits
and will wrap around, it is necessary to extend the highest sequence
number with the (shifted) count of sequence number wraparounds
(s->cycles). Both the received packet count and the count of cycles
are maintained the RTP header validity check routine in Appendix A.1.

extended_max = s->cycles + s->max_seq;
expected = extended_max - s->base_seq + 1;

The number of packets lost is defined to be the number of packets
expected less the number of packets actually received:

lost = expected - s->received;

Since this signed number is carried in 24 bits, it should be clamped
at 0x7fffff for positive loss or 0x800000 for negative loss rather
than wrapping around.

The fraction of packets lost during the last reporting interval
(since the previous SR or RR packet was sent) is calculated from
differences in the expected and received packet counts across the
interval, where expected_prior and received_prior are the values
saved when the previous reception report was generated:

expected_interval = expected - s->expected_prior;
s->expected_prior = expected;
received_interval = s->received - s->received_prior;
s->received_prior = s->received;
lost_interval = expected_interval - received_interval;
if (expected_interval == 0 || lost_interval <= 0) fraction = 0;
else fraction = (lost_interval << 8) / expected_interval;

The resulting fraction is an 8-bit fixed point number with the binary
point at the left edge.

A.4 Generating RTCP SDES Packets

This function builds one SDES chunk into buffer b composed of argc
items supplied in arrays type, value and length. It returns a
pointer to the next available location within b.

char *rtp_write_sdes(char *b, u_int32 src, int argc,
rtcp_sdes_type_t type[], char *value[],
int length[])
{
rtcp_sdes_t *s = (rtcp_sdes_t *)b;
rtcp_sdes_item_t *rsp;
int i;
int len;
int pad;

/* SSRC header */
s->src = src;
rsp = &s->item[0];

/* SDES items */
for (i = 0; i < argc; i++) {
rsp->type = type[i];
len = length[i];
if (len > RTP_MAX_SDES) {
/* invalid length, may want to take other action */
len = RTP_MAX_SDES;
}
rsp->length = len;
memcpy(rsp->data, value[i], len);
rsp = (rtcp_sdes_item_t *)&rsp->data[len];
}

/* terminate with end marker and pad to next 4-octet boundary */
len = ((char *) rsp) - b;
pad = 4 - (len & 0x3);
b = (char *) rsp;
while (pad--) *b++ = RTCP_SDES_END;

return b;
}

A.5 Parsing RTCP SDES Packets

This function parses an SDES packet, calling functions find_member()
to find a pointer to the information for a session member given the
SSRC identifier and member_sdes() to store the new SDES information
for that member. This function expects a pointer to the header of
the RTCP packet.

void rtp_read_sdes(rtcp_t *r)
{
int count = r->common.count;
rtcp_sdes_t *sd = &r->r.sdes;
rtcp_sdes_item_t *rsp, *rspn;
rtcp_sdes_item_t *end = (rtcp_sdes_item_t *)
((u_int32 *)r + r->common.length + 1);
source *s;

while (--count >= 0) {
rsp = &sd->item[0];
if (rsp >= end) break;
s = find_member(sd->src);

for (; rsp->type; rsp = rspn ) {
rspn = (rtcp_sdes_item_t *)((char*)rsp+rsp->length+2);
------分隔线----------------------------
顶一下
(0)
0%
踩一下
(3)
100%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容