Таблица 4.4.9.3.2. Типы SDES
Сокращенное название |
Имя |
Значение |
END | Конец списка SDES | 0 |
CNAME | Каноническое имя | 1 |
NAME | Имя пользователя | 2 |
Электронный адрес пользователя | 3 | |
PHONE | Телефонный номер пользователя | 4 |
OC | geographic user location | 5 |
TOOL | Имя приложения или программного средства | 6 |
NOTE | notice about the source | 7 |
PRIV | Частные расширения | 8 |
Типы пакетов RTCP. Могут быть определены и зарегистрированы IANA новые, специфические для определенных классов приложений типы пакетов RTCP.
Период отчетов RTCP. Профайл должен специфицировать, какие значения констант будут использоваться для вычисления периода посылки RTCP докладов. Это доля полосы пропускания выделенная для RTCP, минимальный период посылки отчетов.
Расширения SR/RR. Секция расширения может быть определена для RTCP SR и RR пакетов, если имеется дополнительная информация о получателе или отправителе, которая должна регулярно передаваться.
Проверка корректности заголовка RTCP
Пакеты RTCP подвергаются следующим проверкам.
Фрагмент приведенной ниже программы выполняет все рассмотренные проверки (текст взят из ссылки, приведенной в начале раздела). Тип пакета для последующих пакетов не проверяется, так как не известный тип пакета должен игнорироваться.
u_int32 len; /* Длина составного RTCP пакета в словах */
rtcp_t *r; /* заголовок RTCP */
rtcp_t *end; /* Конец составного RTCP пакета */
if ((*(u_int16 *)r & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
/* что-то не в порядке с форматом пакета */
}
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) {
/* что-то не в порядке с форматом пакета */
}
Генерирование пакетов SDES RTCP
Эта функция формирует фрагмент SDES, состоящий из элементов argc, взятых из массивов type, в буфере 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) {
/* неверная длина, возможно нужны другие действия */
len = RTP_MAX_SDES;
}
rsp->length = len;
memcpy(rsp->data, value[i], len);
rsp = (rtcp_sdes_item_t *)&rsp->data[len];
}
/* завершить конечным маркером и заполнителем на очередной 4-октетной границе */
len = ((char *) rsp) - b;
pad = 4 - (len & 0x3);
b = (char *) rsp;
while (pad--) *b++ = RTCP_SDES_END;
return b;
}
Разбор пакетов RTCP SDES
Эта функция осуществляет разбор пакета SDES, вызывая функции find_member() для поиска указателя на информацию для члена сессии с идентификатором SSRC и member_sdes() для запоминания новой информации SDES для этого участника. Этой функции необходим указатель на заголовок пакета RTCP.
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);
if (rspn >= end) {
rsp = rspn;
break;
}
member_sdes(s, rsp->type, rsp->data, rsp->length);
}
sd = (rtcp_sdes_t *)
((u_int32 *)sd + (((char *)rsp - (char *)sd) >> 2)+1);
}
if (count >= 0) {
/* некорректный формат пакета */
}
}
Вычисление периода рассылки RTCP
Следующая функция в качестве результата выдает время между посылками RTCP-пакетов, измеренное в секундах. Она должна вызываться после посылки одного составного RTCP-пакета для вычисления времени до посылки следующего пакета. Эта функция должна также вызываться для вычисления времени посылки первого RTCP-пакета при запуске. Это исключает любые кластеры RTCP-пакетов, если приложение запущено в нескольких узлах одновременно, например, в результате объявления об открытии сессии.
Параметры имеют следующий смысл:
rtcp_bw: Предельная полоса RTCP, т.е., полная пропускная способность, которая будет использоваться для RTCP-пакетов всеми участниками сессии, выраженная в октетах в секунду. Она должна быть порядка 5% от "полосы сессии", этот параметр задается при конфигурировании приложения.
senders: Число активных отправителей на момент посылки последнего отчета, известно из конструкции отчетов получателя.
members: Оценка числа членов сессии, включая нас самих. Инкрементируется, когда мы обнаруживаем новых членов сессии при получении RTP или RTCP-пакетов, и декрементируется, когда какой-либо участник покидает сессию (послав RTCP BYE) или он объявлен таковым по тайм-ауту (рекомендуемое время 30 минут). При первом вызове этот параметр должен иметь значение 1.
we_sent: Флаг, который равен true, если мы послали данные за время последних двух интервалов RTCP. Если флаг равен true, составной только что посланный пакет RTCP содержит SR пакет.
packet_size: Размер составного только что посланного пакета RTCP, в октетах, включая сетевую инкапсуляцию (напр., 28 октетов для UDP поверх IP).
avg_rtcp_size: Указатель оценщика размера составных пакетов RTCP; инициализируется и актуализуется для только что посланного пакета этой функцией, актуализуется также идентичной строкой программы приема пакетов RTCP для каждого пакета RTCP, полученного от другого участника сессии.
initial: Флаг, который равен true для первого вызова при инициализации с целью вычисления момента посылки первого отчета.
#include
double rtcp_interval(int members,
int senders,
double rtcp_bw,
int we_sent,
int packet_size,
int *avg_rtcp_size,
int initial)
{
/*
* Минимальное время между пакетами RTCP от данного узла (в секундах). Это время
* предотвращает группирование отчетов, когда в сессии участвует малое число
* участников. Это препятствует чрезмерному уменьшению интервалов межу отчетами.
*/
double const RTCP_MIN_TIME = 5.;
/*
* Доля полосы RTCP, которая должна быть поделена между активными участниками.
* (Эта доля была выбрана так, чтобы в типовой сессии с одним или двумя
* активными отправителями, вычисленный период посылки отчетов был примерно
* равен минимальному интервалу между отчетами. Доля получателя должна равняться
* 1 – доля отправителя.
*/
double const RTCP_SENDER_BW_FRACTION = 0.25;
double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION);
/*
* Коэффициент преобразования (сглаживающая константа) для полосового
* фильтра, который используется при оценке среднего размера RTCP пакетов.
*/
double const RTCP_SIZE_GAIN = (1./16.);
double t; /* интервал */
double rtcp_min_time = RTCP_MIN_TIME;
int n; /* число участников, используемое при вычислении */
/*
* Самый первый вызов приложения использует вдвое меньшую
* минимальную задержку для ускорения оповещения, в то же время оставляя
* некоторое время до отчета для рэндомизации и получения информации
* о других источниках. Таким образом, установление корректного периода
* отчетов произойдет быстрее. Средний размер RTCP пакета
* устанавливается в начальный момент равным 128 октетам
* (предполагается, что все остальные генерируют SR вместо RR:
* 20 IP + 8 UDP + 52 SR + 48 SDES CNAME октетов).
*/
if (initial) {
rtcp_min_time /= 2;
*avg_rtcp_size = 128;
}
/*
* Если имелись активные отправители, надо им дать
* по крайней мере минимальную долю полосы RTCP.
* В противном случае все участники будут делить полосу RTCP поровну
*/
n = members;
if (senders > 0 && senders < members * RTCP_SENDER_BW_FRACTION) {
if (we_sent) {
rtcp_bw *= RTCP_SENDER_BW_FRACTION;
n = senders;
} else {
rtcp_bw *= RTCP_RCVR_BW_FRACTION;
n -= senders;
}
}
/*
* Актуализация оценки среднего размера пакета отчета с учетом
* только что посланного пакета.
*/
*avg_rtcp_size += (packet_size - *avg_rtcp_size)*RTCP_SIZE_GAIN;
/*
* Эффективное число узлов, умножаем на средний размер пакета отчета
* и получаем полное число посланных октетов, если каждый из узлов
* посылает отчет. Деля это число на эффективную полосу,
* получаем средний временной интервал посылки пакетов-отчетов.
*/
t = (*avg_rtcp_size) * n / rtcp_bw;
if (t < rtcp_min_time) t = rtcp_min_time;
/*
* Для того чтобы избежать всплесков трафика из-за непреднамеренной
* синхронизации с другими узлами мы выбираем следующий интервал
* отчета равным случайному числу с равномерным распределением в
* диапазоне 0.5*t - 1.5*t.
*/
return t * (drand48() + 0.5);
}
Библиография
[1] | I. Busse, B. Deffner, and H. Schulzrinne, "Dynamic QoS control of multimedia applications based on RTP," Computer Communications , Jan. 1996. |
[2] | S. Floyd and V. Jacobson, "The synchronization of periodic routing messages," in SIGCOMM Symposium on Communications Architectures and Protocols (D. P. Sidhu, ed.), (San Francisco, California), pp. 33--44, ACM, Sept. 1993. also in [24] |
[3] | J. A. Cadzow, Foundations of digital signal processing and data analysis New York, New York: Macmillan, 1987 |
[4] | International Standards Organization, "ISO/IEC DIS 10646-1:1993 information technology -- universal multiple-octet coded character set (UCS) -- part I: Architecture and basic multilingual plane," 1993 |
[5] | The Unicode Consortium, The Unicode Standard New York, New York: Addison-Wesley, 1991 |
[6] | Mockapetris, P., "Domain Names - Concepts and Facilities", STD13, RFC 1034, USC/Information Sciences Institute, November 1987 |
[7] | Mockapetris, P., "Domain Names - Implementation and Specification", STD 13, RFC 1035, USC/Information Sciences Institute, November 1987 |
[8] | Braden, R., "Requirements for Internet Hosts - Application and Support", STD 3, RFC 1123, Internet Engineering Task Force, October 1989 |
[9] | Rekhter, Y., Moskowitz, R., Karrenberg, D., and G. de Groot, "Address Allocation for Private Internets", RFC 1597, T.J. Watson Research Center, IBM Corp., Chrysler Corp., RIPE NCC, March 1994 |
[10] | Lear, E., Fair, E., Crocker, D., and T. Kessler, "Network 10 Considered Harmful (Some Practices Shouldn't be Codified)", RFC1627, Silicon Graphics, Inc., Apple Computer, Inc., Silicon Graphics, Inc., July 1994 |
[11] | Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, UDEL, August 1982 |
[12] | W. Feller, An Introduction to Probability Theory and its Applications, Volume 1 , vol. 1. New York, New York: John Wiley and Sons, third ed., 1968 |