ccRTP 2.1.2: control.cpp Source File

ccRTP 2.1.2
control.cpp
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2015 Cherokees of Idaho.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
27 //
28 // This exception applies only to the code released under the name GNU
29 // ccRTP. If you copy code from other releases into a copy of GNU
30 // ccRTP, as the General Public License permits, the exception does
31 // not apply to the code that you add in this way. To avoid misleading
32 // anyone as to the status of such modified files, you must delete
33 // this exception notice from them.
34 //
35 // If you write modifications of your own for GNU ccRTP, it is your choice
36 // whether to permit this exception to apply to your modifications.
37 // If you do not wish that, delete this exception notice.
38 //
39 
46 #include "private.h"
47 #include <cstdlib>
48 #include <ccrtp/cqueue.h>
49 #include <cstdlib>
50 #include <climits>
51 
52 NAMESPACE_COMMONCPP
53 
54 const uint16 QueueRTCPManager::TIMEOUT_MULTIPLIER = 5;
55 const double QueueRTCPManager::RECONSIDERATION_COMPENSATION = 2.718281828 - 1.5;
56 const SDESItemType QueueRTCPManager::firstSchedulable = SDESItemTypeNAME;
57 const SDESItemType QueueRTCPManager::lastSchedulable = SDESItemTypePRIV;
59 const microtimeout_t QueueRTCPManager::defaultEnd2EndDelay = 0;
60 
61  QueueRTCPManager::QueueRTCPManager(uint32 size, RTPApplication& app):
62 RTPDataQueue(size), RTCPCompoundHandler(RTCPCompoundHandler::defaultPathMTU),
63 queueApplication(app), srtcpIndex(0)
64 {
65  controlServiceActive = false;
66  controlBwFract = 0.05f;
67  sendControlBwFract = 0.25;
68  recvControlBwFract = 1-sendControlBwFract;
69  ctrlSendCount = 0;
70 
71  lowerHeadersSize = networkHeaderSize() + transportHeaderSize();
72 
73  nextScheduledSDESItem = SDESItemTypeNAME;
74 
75  // initialize RTCP timing
76  reconsInfo.rtcpTp.tv_sec = reconsInfo.rtcpTc.tv_sec =
77  reconsInfo.rtcpTn.tv_sec = 0;
78  reconsInfo.rtcpTp.tv_usec = reconsInfo.rtcpTc.tv_usec =
79  reconsInfo.rtcpTn.tv_usec = 0;
80  reconsInfo.rtcpPMembers = 1;
81 
82  rtcpWeSent = false;
83  rtcpAvgSize = sizeof(RTCPFixedHeader) + sizeof(uint32) +
84  sizeof(SenderInfo);
85  rtcpInitial = true;
86  // force an initial check for incoming RTCP packets
87  SysTime::gettimeofday(&rtcpNextCheck,NULL);
88  // check for incoming RTCP packets every 1/4 seconds.
89  rtcpCheckInterval.tv_sec = 0;
90  rtcpCheckInterval.tv_usec = 250000;
91  timersub(&rtcpNextCheck,&rtcpCheckInterval,&rtcpLastCheck);
92 
93  lastSendPacketCount = 0;
94 
95  rtcpMinInterval = 5000000; // 5 seconds.
96 
97  leavingDelay = 1000000; // 1 second
98  end2EndDelay = getDefaultEnd2EndDelay();
99 
100  // Fill in fixed fields that will never change
101  RTCPPacket* pkt = reinterpret_cast<RTCPPacket*>(rtcpSendBuffer);
102  pkt->fh.version = CCRTP_VERSION;
103  // (SSRCCollision will have to take this into account)
104  pkt->info.SR.ssrc = getLocalSSRCNetwork();
105 
106  // allow to start RTCP service once everything is set up
107  controlServiceActive = true;
108 }
109 
110 // TODO Streamline this code (same as above, put into a separate method)
111  QueueRTCPManager::QueueRTCPManager(uint32 ssrc, uint32 size, RTPApplication& app):
112 RTPDataQueue(&ssrc, size),
113 RTCPCompoundHandler(RTCPCompoundHandler::defaultPathMTU),
114 queueApplication(app), srtcpIndex(0)
115 {
116  controlServiceActive = false;
117  controlBwFract = 0.05f;
118  sendControlBwFract = 0.25;
119  recvControlBwFract = 1-sendControlBwFract;
120  ctrlSendCount = 0;
121 
122  lowerHeadersSize = networkHeaderSize() + transportHeaderSize();
123 
124  nextScheduledSDESItem = SDESItemTypeNAME;
125 
126  // initialize RTCP timing
127  reconsInfo.rtcpTp.tv_sec = reconsInfo.rtcpTc.tv_sec =
128  reconsInfo.rtcpTn.tv_sec = 0;
129 
130  reconsInfo.rtcpTp.tv_usec = reconsInfo.rtcpTc.tv_usec =
131  reconsInfo.rtcpTn.tv_usec = 0;
132 
133  reconsInfo.rtcpPMembers = 1;
134 
135  rtcpWeSent = false;
136  rtcpAvgSize = sizeof(RTCPFixedHeader) + sizeof(uint32) + sizeof(SenderInfo);
137  rtcpInitial = true;
138  // force an initial check for incoming RTCP packets
139  SysTime::gettimeofday(&rtcpNextCheck,NULL);
140  // check for incoming RTCP packets every 1/4 seconds.
141  rtcpCheckInterval.tv_sec = 0;
142  rtcpCheckInterval.tv_usec = 250000;
143  timersub(&rtcpNextCheck,&rtcpCheckInterval,&rtcpLastCheck);
144 
145  lastSendPacketCount = 0;
146 
147  rtcpMinInterval = 5000000; // 5 seconds.
148 
149  leavingDelay = 1000000; // 1 second
150  end2EndDelay = getDefaultEnd2EndDelay();
151 
152  // Fill in fixed fields that will never change
153  RTCPPacket* pkt = reinterpret_cast<RTCPPacket*>(rtcpSendBuffer);
154  pkt->fh.version = CCRTP_VERSION;
155  // (SSRCCollision will have to take this into account)
156  pkt->info.SR.ssrc = getLocalSSRCNetwork();
157 
158  // allow to start RTCP service once everything is set up
159  controlServiceActive = true;
160 }
161 
162  QueueRTCPManager::~QueueRTCPManager()
163 {
164  endQueueRTCPManager();
165 }
166 
167  void QueueRTCPManager::endQueueRTCPManager()
168 {
169  controlServiceActive = false;
170  controlBwFract = sendControlBwFract = 0;
171  removeOutQueueCryptoContextCtrl(NULL); // remove the outgoing crypto context
172  removeInQueueCryptoContextCtrl(NULL); // Remove any incoming crypto contexts
173 
174 }
175 
176  bool QueueRTCPManager::checkSSRCInRTCPPkt(SyncSourceLink& sourceLink,
177 bool is_new, InetAddress& network_address, tpport_t transport_port)
178 {
179  bool result = true;
180 
181  // Test if the source is new and it is not the local one.
182  if ( is_new && sourceLink.getSource()->getID() != getLocalSSRC() )
183  return result;
184 
185  SyncSource *s = sourceLink.getSource();
186  if ( s->getControlTransportPort() != transport_port ||
187  s->getNetworkAddress() != network_address ) {
188  // SSRC collision or a loop has happened
189  if ( s->getID() != getLocalSSRC() ) {
190  // TODO: Optional error counter.
191 
192  // Note this differs from the default in the RFC.
193  // Discard packet only when the collision is
194  // repeating (to avoid flip-flopping)
195  if ( sourceLink.getPrevConflict() &&
196  (
197  (network_address ==
198  sourceLink.getPrevConflict()->networkAddress)
199  &&
200  (transport_port ==
201  sourceLink.getPrevConflict()->controlTransportPort)
202  ) ) {
203  // discard packet and do not flip-flop
204  result = false;
205  } else {
206  // Record who has collided so that in
207  // the future we can how if the
208  // collision repeats.
209  sourceLink.setPrevConflict(network_address,
210  0,transport_port);
211  // Change sync source transport address
212  setControlTransportPort(*s,transport_port);
213  setNetworkAddress(*s,network_address);
214  }
215 
216  } else {
217  // Collision or loop of own packets.
218  ConflictingTransportAddress* conflicting =
219  searchControlConflict(network_address,
220  transport_port);
221  if ( conflicting ) {
222  // Optional error counter.
223  updateConflict(*conflicting);
224  result = false;
225  } else {
226  // New collision
227  addConflict(s->getNetworkAddress(),
228  s->getDataTransportPort(),
229  s->getControlTransportPort());
230  dispatchBYE("SSRC collision detected when receiving RTCP packet");
231  renewLocalSSRC();
232  setNetworkAddress(*s,network_address);
233  setControlTransportPort(*s,transport_port);
234  setControlTransportPort(*s,0);
235  sourceLink.initStats();
236  }
237  }
238  }
239  return result;
240 }
241 
242  void QueueRTCPManager::controlReceptionService()
243 {
244  if ( !controlServiceActive )
245  return;
246 
247  // A) see if there are incoming RTCP packets
248  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
249  if ( timercmp(&(reconsInfo.rtcpTc),&rtcpNextCheck,>=) ) {
250  while ( isPendingControl(0) )
251  takeInControlPacket();
252  // If this do loops more than once, then we have not
253  // been in time. So it skips until the next future
254  // instant.
255  do {
256  timeval tmp = rtcpNextCheck;
257  timeradd(&rtcpLastCheck,&rtcpCheckInterval,
258  &rtcpNextCheck);
259  rtcpLastCheck = tmp;
260  } while ( timercmp(&(reconsInfo.rtcpTc), &(rtcpNextCheck), >=) );
261  }
262 }
263 
264  void QueueRTCPManager::controlTransmissionService()
265 {
266  if ( !controlServiceActive )
267  return;
268 
269  // B) send RTCP packets
270  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
271  if ( timercmp(&(reconsInfo.rtcpTc),&(reconsInfo.rtcpTn),>=) ) {
272  if ( timerReconsideration() ) {
273  // this would update to last received RTCP packets
274  //while ( isPendingControl(0) )
275  // takeInControlPacket();
276  rtcpLastCheck = reconsInfo.rtcpTc;
277  dispatchControlPacket();
278  if (rtcpInitial)
279  rtcpInitial = false;
280  expireSSRCs();
281  reconsInfo.rtcpTp = reconsInfo.rtcpTc;
282  // we have updated tp and sent a report, so we
283  // have to recalculate the sending interval
284  timeval T = computeRTCPInterval();
285  timeradd(&(reconsInfo.rtcpTc),&T,&(reconsInfo.rtcpTn));
286 
287  // record current number of members for the
288  // next check.
289  reconsInfo.rtcpPMembers = getMembersCount();
290  }
291  }
292 }
293 
294  bool QueueRTCPManager::timerReconsideration()
295 {
296  bool result = false;
297  // compute again the interval to confirm it under current
298  // circumstances
299  timeval T = computeRTCPInterval();
300  timeradd(&(reconsInfo.rtcpTp),&T,&(reconsInfo.rtcpTn));
301  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
302  if ( timercmp(&(reconsInfo.rtcpTc),&(reconsInfo.rtcpTn),>=) ) {
303  reconsInfo.rtcpTp = reconsInfo.rtcpTc;
304  result = true;
305  }
306  return result;
307 }
308 
309 void
310  QueueRTCPManager::expireSSRCs()
311 {}
312 
313 void
314  QueueRTCPManager::takeInControlPacket()
315 {
316  size_t len = 0;
317  InetHostAddress network_address;
318  tpport_t transport_port;
319  len = recvControl(rtcpRecvBuffer,getPathMTU(),network_address, transport_port);
320 
321  // get time of arrival
322  struct timeval recvtime;
323  SysTime::gettimeofday(&recvtime,NULL);
324 
325  // process a 'len' octets long RTCP compound packet
326 
327  RTCPPacket *pkt = reinterpret_cast<RTCPPacket *>(rtcpRecvBuffer);
328 
329  CryptoContextCtrl* pcc = getInQueueCryptoContextCtrl(pkt->getSSRC());
330  if (pcc == NULL) {
331  pcc = getInQueueCryptoContextCtrl(0);
332  if (pcc != NULL) {
333  pcc = pcc->newCryptoContextForSSRC(pkt->getSSRC());
334  if (pcc != NULL) {
335  pcc->deriveSrtcpKeys();
336  setInQueueCryptoContextCtrl(pcc);
337  }
338  }
339  }
340  // If no crypto context: then SRTP/SRTCP is off
341  // If crypto context is available then unprotect data here. If an error
342  // occurs report the error and discard the packet.
343  if (pcc != NULL) {
344  int32 ret;
345  if ((ret = unprotect(rtcpRecvBuffer, len, pcc)) < 0) {
346  // TODO: do more error handling?
347  return;
348  }
349  len = ret; // adjust length after unprotecting the packet
350  }
351  // Check validity of the header fields of the compound packet
352  if ( !RTCPCompoundHandler::checkCompoundRTCPHeader(len) )
353  return;
354 
355 
356  // TODO: for now, we do nothing with the padding bit
357  // in the header.
358 
359  bool source_created;
360  SyncSourceLink* sourceLink = getSourceBySSRC(pkt->getSSRC(),source_created);
361  SyncSource* s = sourceLink->getSource();
362 
363  if ( source_created ) {
364  // Set control transport address.
365  setControlTransportPort(*s,transport_port);
366  // Network address is assumed to be the same as the control one
367  setNetworkAddress(*s,network_address);
368  sourceLink->initStats();
369  sourceLink->setProbation(getMinValidPacketSequence());
370  if ( sourceLink->getHello() )
371  onNewSyncSource(*s);
372  } else if ( s->getControlTransportPort() == 0 ) {
373  // Test if RTP data packets had been received but this
374  // is the first control packet from this source.
375  setControlTransportPort(*s,transport_port);
376  }
377  // record reception time
378  sourceLink->lastRTCPPacketTime = recvtime;
379  sourceLink->lastRTCPSRTime = recvtime;
380 
381  size_t pointer = 0;
382  // Check the first packet is a report and do special
383  // processing for SR reports.
384  if ( RTCPPacket::tRR == pkt->fh.type ) {
385  // no special initialization is required for
386  // RR reports, all reports will be processed
387  // in the do-while down here.
388  } else if ( RTCPPacket::tSR == pkt->fh.type ){
389  if ( checkSSRCInRTCPPkt(*sourceLink,source_created,
390  network_address,
391  transport_port) )
392  sourceLink->lastRTCPSRTime = recvtime;
393  onGotSR(*s,pkt->info.SR,pkt->fh.block_count);
394  // Advance to the next packet in the compound.
395  pointer += pkt->getLength();
396  pkt = reinterpret_cast<RTCPPacket *>(rtcpRecvBuffer +pointer);
397  } else if ( RTCPPacket::tXR == pkt->fh.type ) {
398  // TODO: handle XR reports.
399  } else {
400  // Ignore RTCP types unknown.
401  }
402 
403  // Process all RR reports.
404  while ( (pointer < len) && (RTCPPacket::tRR == pkt->fh.type) ) {
405  sourceLink = getSourceBySSRC(pkt->getSSRC(),
406  source_created);
407  if ( checkSSRCInRTCPPkt(*sourceLink,source_created,
408  network_address,transport_port) )
409  onGotRR(*s,pkt->info.RR,pkt->fh.block_count);
410  // Advance to the next packet in the compound
411  pointer += pkt->getLength();
412  pkt = reinterpret_cast<RTCPPacket *>(rtcpRecvBuffer +pointer);
413  }
414 
415  // SDES, APP and BYE. process first everything but the
416  // BYE packets.
417  bool cname_found = false;
418  while ( (pointer < len ) &&
419  (pkt->fh.type == RTCPPacket::tSDES ||
420  pkt->fh.type == RTCPPacket::tAPP) ) {
421  I ( cname_found || !pkt->fh.padding );
422  sourceLink = getSourceBySSRC(pkt->getSSRC(),
423  source_created);
424  if ( checkSSRCInRTCPPkt(*sourceLink,source_created,
425  network_address,
426  transport_port) ) {
427  if ( pkt->fh.type == RTCPPacket::tSDES ) {
428  bool cname = onGotSDES(*s,*pkt);
429  cname_found = cname_found? cname_found : cname;
430  } else if ( pkt->fh.type == RTCPPacket::tAPP ) {
431  onGotAPP(*s,pkt->info.APP,pkt->getLength());
432  // pointer += pkt->getLength();
433  } else {
434  // error?
435  }
436  }
437  // Get the next packet in the compound.
438  pointer += pkt->getLength();
439  pkt = reinterpret_cast<RTCPPacket *>(rtcpRecvBuffer +pointer);
440  }
441 
442  // TODO: error? if !cname_found
443 
444  // process BYE packets
445  while ( pointer < len ) {
446  if ( pkt->fh.type == RTCPPacket::tBYE ) {
447  sourceLink = getSourceBySSRC(pkt->getSSRC(),
448  source_created);
449  if ( checkSSRCInRTCPPkt(*sourceLink,source_created,
450  network_address,
451  transport_port) )
452  getBYE(*pkt,pointer,len);
453  } else if ( pkt->fh.type != RTCPPacket::tBYE ) {
454  break; // TODO: check non-BYE out of place.
455  } else {
456  break;
457  }
458  }
459 
460  // Call plug-in in case there are profile extensions
461  // at the end of the SR/RR.
462  if ( pointer != len ) {
463  onGotRRSRExtension(rtcpRecvBuffer + pointer,
464  len - pointer);
465  }
466 
467  // Everything went right, update the RTCP average size
468  updateAvgRTCPSize(len);
469 }
470 
471  bool QueueRTCPManager::end2EndDelayed(IncomingRTPPktLink& pl)
472 {
473  bool result = false;
474 
475  if ( 0 != getEnd2EndDelay() ) {
476  SyncSourceLink* sl = pl.getSourceLink();
477  void* si = sl->getSenderInfo();
478  if ( NULL != si ) {
479  RTCPSenderInfo rsi(si);
480  uint32 tsInc = pl.getPacket()->getTimestamp() -
481  rsi.getRTPTimestamp();
482  // approx.
483  microtimeout_t Inc = tsInc * 1000 /
484  (getCurrentRTPClockRate() / 1000);
485  timeval timevalInc = microtimeout2Timeval(Inc);
486 
487  timeval tNTP = NTP2Timeval(rsi.getNTPTimestampInt(),
488  rsi.getNTPTimestampFrac());
489  timeval packetTime;
490  timeradd(&tNTP,&timevalInc,&packetTime);
491  timeval now, diff;
492  SysTime::gettimeofday(&now,NULL);
493  timersub(&now,&packetTime,&diff);
494 
495  if ( timeval2microtimeout(diff) > getEnd2EndDelay() )
496  result = true;
497  }
498  }
499  return result;
500 }
501 
502  void QueueRTCPManager::onGotSR(SyncSource& source, SendReport& SR, uint8)
503 {
504  // We ignore the receiver blocks and just get the sender info
505  // at the beginning of the SR.
506  getLink(source)->setSenderInfo(reinterpret_cast<unsigned char*>(&(SR.sinfo)));
507 }
508 
509  void QueueRTCPManager::onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks)
510 {
511  for ( uint8 i = 0; i < blocks; i++) {
512  // this generic RTCP manager ignores reports about
513  // other sources than the local one
514  if ( getLocalSSRCNetwork() == RR.ssrc ) {
515  getLink(source)->
516  setReceiverInfo
517  (reinterpret_cast<unsigned char*>(&(RR.blocks[i].rinfo)));
518  }
519  }
520 }
521 
522  void QueueRTCPManager::updateAvgRTCPSize(size_t len)
523 {
524  size_t newlen = len;
525  newlen += lowerHeadersSize;
526  rtcpAvgSize = (uint16)(( (15 * rtcpAvgSize) >> 4 ) + ( newlen >> 4));
527 }
528 
529  bool QueueRTCPManager::getBYE(RTCPPacket& pkt, size_t& pointer, size_t)
530 {
531  if ( 0 == pkt.fh.block_count )
532  return false;
533 
534  char *reason = NULL;
535 
536  if ( (sizeof(RTCPFixedHeader) + pkt.fh.block_count * sizeof(uint32))
537  < pkt.getLength() ) {
538  uint16 endpointer = (uint16)(pointer + sizeof(RTCPFixedHeader) +
539  pkt.fh.block_count * sizeof(uint32));
540  uint16 len = rtcpRecvBuffer[endpointer];
541  reason = new char[len + 1];
542  memcpy(reason,rtcpRecvBuffer + endpointer + 1,len);
543  reason[len] = '0円';
544  } else { // avoid dangerous conversion of NULL to a C++ string.
545  reason = new char[1];
546  reason[0] = '0円';
547  }
548 
549  int i = 0;
550  while ( i < pkt.fh.block_count ) {
551  bool created;
552  SyncSourceLink* srcLink =
553  getSourceBySSRC(pkt.getSSRC(),created);
554  i++;
555  if( srcLink->getGoodbye() )
556  onGotGoodbye(*(srcLink->getSource()),reason);
557  BYESource(pkt.getSSRC());
558  setState(*(srcLink->getSource()),SyncSource::stateLeaving);
559 
560  reverseReconsideration();
561  }
562 
563  delete [] reason;
564  pointer += pkt.getLength();
565  return true;
566 }
567 
568  void QueueRTCPManager::reverseReconsideration()
569 {
570  if ( getMembersCount() < reconsInfo.rtcpPMembers ) {
571  timeval inc;
572 
573  // reconsider reconsInfo.rtcpTn (time for next RTCP packet)
574  microtimeout_t t =
575  (reconsInfo.rtcpTn.tv_sec - reconsInfo.rtcpTc.tv_sec) *
576  1000000 +
577  (reconsInfo.rtcpTn.tv_usec - reconsInfo.rtcpTc.tv_usec);
578  t *= getMembersCount();
579  t /= reconsInfo.rtcpPMembers;
580  inc.tv_usec = t % 1000000;
581  inc.tv_sec = t / 1000000;
582  timeradd(&(reconsInfo.rtcpTc),&inc,&(reconsInfo.rtcpTn));
583 
584  // reconsider tp (time for previous RTCP packet)
585  t = (reconsInfo.rtcpTc.tv_sec - reconsInfo.rtcpTp.tv_sec) *
586  1000000 +
587  (reconsInfo.rtcpTc.tv_usec - reconsInfo.rtcpTp.tv_usec);
588  t *= getMembersCount();
589  t /= reconsInfo.rtcpPMembers;
590  inc.tv_usec = t % 1000000;
591  inc.tv_sec = t / 1000000;
592  timeradd(&(reconsInfo.rtcpTc),&inc,&(reconsInfo.rtcpTp));
593  }
594  reconsInfo.rtcpPMembers = getMembersCount();
595 }
596 
597  bool QueueRTCPManager::onGotSDES(SyncSource& source, RTCPPacket& pkt)
598 {
599  // Take into account that length fields in SDES items are
600  // 8-bit long, so no ntoh[s|l] is required
601  bool cname_found = false;
602 
603  std::ptrdiff_t pointer = reinterpret_cast<unsigned char*>(&pkt) - rtcpRecvBuffer;
604  uint16 i = 0;
605  do {
606  size_t len = pkt.getLength();
607  pointer += sizeof(RTCPFixedHeader);
608  SDESChunk* chunk = (SDESChunk*)(rtcpRecvBuffer + pointer);
609 
610  bool source_created = false;
611  // TODO: avoid searching again the source of the first chunk.
612  SyncSourceLink* sourceLink =
613  getSourceBySSRC(chunk->getSSRC(),
614  source_created);
615  // TODO: check that there are no two chunks with the
616  // same SSRC but different CNAME
617  SyncSource& src = *( sourceLink->getSource() );
618 
619  if ( onGotSDESChunk(source,*chunk,len) )
620  cname_found = true;
621  pointer +=len;
622  if( sourceLink->getHello() )
623  onNewSyncSource(src);
624  i++;
625  } while ( i < pkt.fh.block_count );
626  return cname_found;
627 }
628 
629  bool QueueRTCPManager::onGotSDESChunk(SyncSource& source, SDESChunk& chunk, size_t len)
630 {
631  bool cname_found = false;
632  bool end = false;
633 
634  SyncSourceLink* srcLink = getLink(source);
635  Participant* part = source.getParticipant();
636 
637  size_t pointer = sizeof(chunk.ssrc);
638 
639  // process chunk items
640  while ( (pointer < len) && !end ) {
641  SDESItem* item =
642  reinterpret_cast<SDESItem*>(size_t(&(chunk)) + pointer);
643  if ( item->type > SDESItemTypeEND && item->type <= SDESItemTypeLast) {
644  pointer += sizeof(item->type) + sizeof(item->len) +
645  item->len;
646  if ( NULL == part && SDESItemTypeCNAME == item->type ) {
647  const RTPApplication& app = getApplication();
648  std::string cname = std::string(item->data,item->len);
649  const Participant* p = app.getParticipant(cname);
650  if ( p ) {
651  part = const_cast<Participant*>(p);
652  setParticipant(*(srcLink->getSource()),*part);
653  } else {
654  part = new Participant("-");
655  addParticipant(const_cast<RTPApplication&>(getApplication()),*part);
656  }
657  setParticipant(*(srcLink->getSource()),*part);
658  }
659 
660  // support for CNAME updates
661  if ( part )
662  setSDESItem(part,(SDESItemType)item->type, item->data,item->len);
663 
664  if ( item->type == SDESItemTypeCNAME) {
665  cname_found = true;
666  // note that CNAME must be send in
667  // every RTCP compound, so we only
668  // trust sources that include it.
669  setState(*(srcLink->getSource()),
670  SyncSource::stateActive);
671  }
672  } else if ( item->type == SDESItemTypeEND) {
673  end = true;
674  pointer++;
675  pointer += (pointer & 0x03); // padding
676  } else if ( item->type == SDESItemTypePRIV ) {
677  std::ptrdiff_t prevpointer = pointer;
678  uint8 plength = *( &(item->len) + 1 );
679  pointer += sizeof(item->type) + sizeof(item->len) + 1;
680 
681  if ( part )
682  setSDESItem(part,SDESItemTypePRIV,
683  reinterpret_cast<char*>(item + pointer),plength);
684  pointer += plength;
685  setPRIVPrefix(part,
686  reinterpret_cast<char*>(item + pointer),
687  (item->len - 1 - plength));
688  pointer = prevpointer + item->len;
689  } else {
690  pointer++;
691  // TODO: error: SDES unknown
692  I( false );
693  }
694  }
695  return cname_found;
696 }
697 
698  timeval QueueRTCPManager::computeRTCPInterval()
699 {
700  float bwfract = controlBwFract * getSessionBandwidth();
701  uint32 participants = getMembersCount();
702  if ( getSendersCount() > 0 &&
703  ( getSendersCount() < (getMembersCount() * sendControlBwFract) )) {
704  // reserve "sendControlBwFract" fraction of the total
705  // RTCP bandwith for senders.
706  if (rtcpWeSent) {
707  // we take the side of active senders
708  bwfract *= sendControlBwFract;
709  participants = getSendersCount();
710  } else {
711  // we take the side of passive receivers
712  bwfract *= recvControlBwFract;
713  participants = getMembersCount() - getSendersCount();
714  }
715  }
716 
717  microtimeout_t min_interval = rtcpMinInterval;
718  // be a bit quicker at first
719  if ( rtcpInitial )
720  min_interval /= 2;
721  // this is the real computation:
722  microtimeout_t interval = 0;
723  if ( bwfract != 0 ) {
724  interval = static_cast<microtimeout_t >
725  ((participants * rtcpAvgSize / bwfract) * 1000000);
726 
727  if ( interval < rtcpMinInterval )
728  interval = rtcpMinInterval;
729  } else {
730  // 100 seconds instead of infinite
731  interval = 100000000;
732  }
733 
734  interval = static_cast<microtimeout_t >(interval * ( 0.5 +
735  (rand() / (RAND_MAX + 1.0))));
736 
737  timeval result;
738  result.tv_sec = interval / 1000000;
739  result.tv_usec = interval % 1000000;
740  return result;
741 }
742 
743  #define BYE_BUFFER_LENGTH 500
744 
745  size_t QueueRTCPManager::dispatchBYE(const std::string& reason)
746 {
747  // for this method, see section 6.3.7 in RFC 3550
748  // never send a BYE packet if never sent an RTP or RTCP packet
749  // before
750  if ( !(getSendPacketCount() || getSendRTCPPacketCount()) )
751  return 0;
752 
753  if ( getMembersCount() > 50) {
754  // Usurp the scheduler role and apply a back-off
755  // algorithm to avoid BYE floods.
756  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
757  reconsInfo.rtcpTp = reconsInfo.rtcpTc;
758  setMembersCount(1);
759  setPrevMembersNum(1);
760  rtcpInitial = true;
761  rtcpWeSent = false;
762  rtcpAvgSize = (uint16)(sizeof(RTCPFixedHeader) + sizeof(uint32) +
763  strlen(reason.c_str()) +
764  (4 - (strlen(reason.c_str()) & 0x03)));
765  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
766  timeval T = computeRTCPInterval();
767  timeradd(&(reconsInfo.rtcpTp),&T,&(reconsInfo.rtcpTn));
768  while ( timercmp(&(reconsInfo.rtcpTc),&(reconsInfo.rtcpTn),<) ) {
769  getOnlyBye();
770  if ( timerReconsideration() )
771  break;
772  SysTime::gettimeofday(&(reconsInfo.rtcpTc),NULL);
773  }
774  }
775 
776 
777  unsigned char buffer[BYE_BUFFER_LENGTH] = {0};
778  // Build an empty RR as first packet in the compound.
779  // TODO: provide more information if available. Not really
780  // important, since this is the last packet being sent.
781  RTCPPacket* pkt = reinterpret_cast<RTCPPacket*>(buffer);
782  pkt->fh.version = CCRTP_VERSION;
783  pkt->fh.padding = 0;
784  pkt->fh.block_count = 0;
785  pkt->fh.type = RTCPPacket::tRR;
786  pkt->info.RR.ssrc= getLocalSSRCNetwork();
787  uint16 len1 = sizeof(RTCPFixedHeader) + sizeof(uint32); // 1st pkt len.
788  pkt->fh.length = htons((len1 >> 2) - 1);
789  uint16 len = len1; // whole compound len.
790  // build a BYE packet
791  uint16 padlen = 0;
792  pkt = reinterpret_cast<RTCPPacket*>(buffer + len1);
793  pkt->fh.version = CCRTP_VERSION;
794  pkt->fh.block_count = 1;
795  pkt->fh.type = RTCPPacket::tBYE;
796  // add the SSRC identifier
797  pkt->info.BYE.ssrc = getLocalSSRCNetwork();
798  len += sizeof(RTCPFixedHeader) + sizeof(BYEPacket);
799  // add the optional reason
800  if ( reason.c_str() != NULL ){
801  pkt->info.BYE.length = (uint8)strlen(reason.c_str());
802  memcpy(buffer + len,reason.c_str(),pkt->info.BYE.length);
803  len += pkt->info.BYE.length;
804  padlen = 4 - ((len - len1) & 0x03);
805  if ( padlen ) {
806  memset(buffer + len,0,padlen);
807  len += padlen;
808  pkt->info.BYE.length += padlen;
809  }
810  }
811  pkt->fh.length = htons(((len - len1) >> 2) - 1);
812 
813  return sendControlToDestinations(buffer,len);
814 }
815 
816  void QueueRTCPManager::getOnlyBye()
817 {
818  // This method is kind of simplified recvControl
819  timeval wait;
820  timersub(&(reconsInfo.rtcpTn),&(reconsInfo.rtcpTc),&wait);
821  microtimeout_t timer = wait.tv_usec/1000 + wait.tv_sec * 1000;
822  // wait up to reconsInfo.rtcpTn
823  if ( !isPendingControl(timer) )
824  return;
825 
826  size_t len = 0;
827  InetHostAddress network_address;
828  tpport_t transport_port;
829  while ( (len = recvControl(rtcpRecvBuffer,getPathMTU(),
830  network_address,transport_port)) ) {
831  // Process a <code>len<code> octets long RTCP compound packet
832  // Check validity of the header fields of the compound packet
833  if ( !RTCPCompoundHandler::checkCompoundRTCPHeader(len) )
834  return;
835 
836  // TODO: For now, we do nothing with the padding bit
837  // in the header.
838  uint32 pointer = 0;
839  RTCPPacket* pkt;
840  while ( pointer < len) {
841  pkt = reinterpret_cast<RTCPPacket*>
842  (rtcpRecvBuffer + pointer);
843 
844  if (pkt->fh.type == RTCPPacket::tBYE ) {
845  bool created;
846  SyncSourceLink* srcLink =
847  getSourceBySSRC(pkt->getSSRC(),
848  created);
849  if( srcLink->getGoodbye() )
850  onGotGoodbye(*(srcLink->getSource()), "");
851  BYESource(pkt->getSSRC());
852  }
853  pointer += pkt->getLength();
854  }
855  }
856 }
857 
858  size_t QueueRTCPManager::dispatchControlPacket(void)
859 {
860  rtcpInitial = false;
861  // Keep in mind: always include a report (in SR or RR) and at
862  // least a SDES with the local CNAME. It is mandatory.
863 
864  // (A) SR or RR, depending on whether we sent.
865  // pkt will point to the packets of the compound
866 
867  RTCPPacket* pkt = reinterpret_cast<RTCPPacket*>(rtcpSendBuffer);
868  // Fixed header of the first report
869  pkt->fh.padding = 0;
870  pkt->fh.version = CCRTP_VERSION;
871  // length of the RTCP compound packet. It will increase till
872  // the end of this routine. Both sender and receiver report
873  // carry the general 32-bit long fixed header and a 32-bit
874  // long SSRC identifier.
875  uint16 len = sizeof(RTCPFixedHeader) + sizeof(uint32);
876 
877  // the fields block_count and length will be filled in later
878  // now decide whether to send a SR or a SR
879  if ( lastSendPacketCount != getSendPacketCount() ) {
880  // we have sent rtp packets since last RTCP -> send SR
881  lastSendPacketCount = getSendPacketCount();
882  pkt->fh.type = RTCPPacket::tSR;
883  pkt->info.SR.ssrc = getLocalSSRCNetwork();
884 
885  // Fill in sender info block. It would be more
886  // accurate if this were done as late as possible.
887  timeval now;
888  SysTime::gettimeofday(&now,NULL);
889  // NTP MSB and MSB: dependent on current payload type.
890  pkt->info.SR.sinfo.NTPMSW = htonl(now.tv_sec + NTP_EPOCH_OFFSET);
891  pkt->info.SR.sinfo.NTPLSW = htonl((uint32)(((double)(now.tv_usec)*(uint32)(~0))/1000000.0));
892  // RTP timestamp
893  int32 tstamp = now.tv_usec - getInitialTime().tv_usec;
894  tstamp *= (getCurrentRTPClockRate()/1000);
895  tstamp /= 1000;
896  tstamp += (now.tv_sec - getInitialTime().tv_sec) *
897  getCurrentRTPClockRate();
898  tstamp += getInitialTimestamp();
899  pkt->info.SR.sinfo.RTPTimestamp = htonl(tstamp);
900  // sender's packet and octet count
901  pkt->info.SR.sinfo.packetCount = htonl(getSendPacketCount());
902  pkt->info.SR.sinfo.octetCount = htonl(getSendOctetCount());
903  len += sizeof(SenderInfo);
904  } else {
905  // RR
906  pkt->fh.type = RTCPPacket::tRR;
907  pkt->info.RR.ssrc = getLocalSSRCNetwork();
908  }
909 
910  // (B) put report blocks
911  // After adding report blocks, we have to leave room for at
912  // least a CNAME SDES item
913  uint16 available = (uint16)(getPathMTU()
914  - lowerHeadersSize
915  - len
916  - (sizeof(RTCPFixedHeader) +
917  2*sizeof(uint8) +
918  getApplication().getSDESItem(SDESItemTypeCNAME).length())
919  - 100);
920 
921  // if we have to go to a new RR packet
922  bool another = false;
923  uint16 prevlen = 0;
924  RRBlock* reports;
925  if ( RTCPPacket::tRR == pkt->fh.type )
926  reports = pkt->info.RR.blocks;
927  else // ( RTCPPacket::tSR == pkt->fh.type )
928  reports = pkt->info.SR.blocks;
929  do {
930  uint8 blocks = 0;
931  pkt->fh.block_count = blocks = packReportBlocks(reports,len,available);
932  // the length field specifies 32-bit words
933  pkt->fh.length = htons( ((len - prevlen) >> 2) - 1);
934  prevlen = len;
935  if ( 31 == blocks ) {
936  // we would need room for a new RR packet and
937  // a CNAME SDES
938  if ( len < (available -
939  ( sizeof(RTCPFixedHeader) + sizeof(uint32) +
940  sizeof(RRBlock))) ) {
941  another = true;
942  // Header for this new packet in the compound
943  pkt = reinterpret_cast<RTCPPacket*>
944  (rtcpSendBuffer + len);
945  pkt->fh.version = CCRTP_VERSION;
946  pkt->fh.padding = 0;
947  pkt->fh.type = RTCPPacket::tRR;
948  pkt->info.RR.ssrc = getLocalSSRCNetwork();
949  // appended a new Header and a report block
950 
951  len += sizeof(RTCPFixedHeader)+ sizeof(uint32);
952  reports = pkt->info.RR.blocks;
953  } else {
954  another = false;
955  }
956  } else {
957  another = false;
958  }
959  } while ( (len < available) && another );
960 
961  // (C) SDES (CNAME)
962  // each SDES chunk must be 32-bit multiple long
963  // fill the padding with 0s
964  packSDES(len);
965 
966  // TODO: virtual for sending APP RTCP packets?
967 
968  // actually send the packet.
969  size_t count = sendControlToDestinations(rtcpSendBuffer,len);
970  ctrlSendCount++;
971  // Everything went right, update the RTCP average size
972  updateAvgRTCPSize(len);
973 
974  return count;
975 }
976 
977  void QueueRTCPManager::packSDES(uint16 &len)
978 {
979  uint16 prevlen = len;
980  RTCPPacket* pkt = reinterpret_cast<RTCPPacket*>(rtcpSendBuffer + len);
981  // Fill RTCP fixed header. Note fh.length is not set till the
982  // end of this routine.
983  pkt->fh.version = CCRTP_VERSION;
984  pkt->fh.padding = 0;
985  pkt->fh.block_count = 1;
986  pkt->fh.type = RTCPPacket::tSDES;
987  pkt->info.SDES.ssrc = getLocalSSRCNetwork();
988  pkt->info.SDES.item.type = SDESItemTypeCNAME;
989  // put CNAME
990  size_t cnameLen =
991  getApplication().getSDESItem(SDESItemTypeCNAME).length();
992  const char* cname =
993  getApplication().getSDESItem(SDESItemTypeCNAME).c_str();
994  pkt->info.SDES.item.len = (uint8)cnameLen;
995  len += sizeof(RTCPFixedHeader) + sizeof(pkt->info.SDES.ssrc) +
996  sizeof(pkt->info.SDES.item.type) +
997  sizeof(pkt->info.SDES.item.len);
998 
999  memcpy((rtcpSendBuffer + len),cname,cnameLen);
1000  len += (uint16)cnameLen;
1001  // pack items other than CNAME (following priorities
1002  // stablished inside scheduleSDESItem()).
1003  SDESItemType nexttype = scheduleSDESItem();
1004  if ( (nexttype > SDESItemTypeCNAME) &&
1005  (nexttype <= SDESItemTypeLast ) ) {
1006  SDESItem *item = reinterpret_cast<SDESItem *>(rtcpSendBuffer + len);
1007  item->type = nexttype;
1008  const char *content =
1009  getApplication().getSDESItem(nexttype).c_str();
1010  item->len = (uint8)strlen(content);
1011  len += 2;
1012  memcpy(reinterpret_cast<char *>(rtcpSendBuffer + len),
1013  content,item->len);
1014  len += item->len;
1015  }
1016 
1017  // pack END item (terminate list of items in this chunk)
1018  rtcpSendBuffer[len] = SDESItemTypeEND;
1019  len++;
1020 
1021  uint8 padding = len & 0x03;
1022  if ( padding ) {
1023  padding = 4 - padding;
1024  memset((rtcpSendBuffer + len),SDESItemTypeEND,padding);
1025  len += padding;
1026  }
1027  pkt->fh.length = htons((len - prevlen - 1) >>2);
1028 }
1029 
1030  uint8 QueueRTCPManager::packReportBlocks(RRBlock* blocks, uint16 &len, uint16& available)
1031 {
1032  uint8 j = 0;
1033  // pack as many report blocks as we can
1034  SyncSourceLink* i = getFirst();
1035  for ( ;
1036  ( ( i != NULL ) &&
1037  ( len < (available - sizeof(RTCPCompoundHandler::RRBlock)) ) &&
1038  ( j < 31 ) );
1039  i = i->getNext() ) {
1040  SyncSourceLink& srcLink = *i;
1041  // update stats.
1042  srcLink.computeStats();
1043  blocks[j].ssrc = htonl(srcLink.getSource()->getID());
1044  blocks[j].rinfo.fractionLost = srcLink.getFractionLost();
1045  blocks[j].rinfo.lostMSB =
1046  (srcLink.getCumulativePacketLost() & 0xFF0000) >> 16;
1047  blocks[j].rinfo.lostLSW =
1048  htons(srcLink.getCumulativePacketLost() & 0xFFFF);
1049  blocks[j].rinfo.highestSeqNum =
1050  htonl(srcLink.getExtendedMaxSeqNum());
1051  blocks[j].rinfo.jitter =
1052  htonl(static_cast<uint32>(srcLink.getJitter()));
1053  RTCPCompoundHandler::SenderInfo* si =
1054  reinterpret_cast<RTCPCompoundHandler::SenderInfo*>(srcLink.getSenderInfo());
1055  if ( NULL == si ) {
1056  blocks[j].rinfo.lsr = 0;
1057  blocks[j].rinfo.dlsr = 0;
1058  } else {
1059  blocks[j].rinfo.lsr =
1060  htonl( ((ntohl(si->NTPMSW) & 0x0FFFF) << 16 )+
1061  ((ntohl(si->NTPLSW) & 0xFFFF0000) >> 16)
1062  );
1063  timeval now, diff;
1064  SysTime::gettimeofday(&now,NULL);
1065  timeval last = srcLink.getLastRTCPSRTime();
1066  timersub(&now,&last,&diff);
1067  blocks[j].rinfo.dlsr =
1068  htonl(timevalIntervalTo65536(diff));
1069  }
1070  len += sizeof(RTCPCompoundHandler::RRBlock);
1071  j++;
1072  }
1073  return j;
1074 }
1075 
1076  void QueueRTCPManager::setSDESItem(Participant* part, SDESItemType type,
1077 const char* const value, size_t len)
1078 {
1079  char* buf = new char[len + 1];
1080  memcpy(buf,value,len);
1081  buf[len] = '0円';
1082  ParticipantHandler::setSDESItem(part,type,buf);
1083  delete [] buf;
1084 }
1085 
1086  void QueueRTCPManager::setPRIVPrefix(Participant* part, const char* const value, size_t len)
1087 {
1088  char *buf = new char[len + 1];
1089  memcpy(buf,value,len);
1090  buf[len] = '0円';
1091  ParticipantHandler::setPRIVPrefix(part,buf);
1092  delete [] buf;
1093 }
1094 
1095  SDESItemType QueueRTCPManager::scheduleSDESItem()
1096 {
1097  uint8 i = 0;
1098  // TODO: follow, at least, standard priorities
1099  SDESItemType type = nextScheduledSDESItem;
1100 
1101  while ( (queueApplication.getSDESItem(type).length() <= 0) &&
1102  i < (lastSchedulable - firstSchedulable) ) {
1103  i++;
1104  type = nextSDESType(type);
1105  }
1106  bool empty = true;
1107  if ( queueApplication.getSDESItem(type).length() > 0 )
1108  empty = false;
1109  nextScheduledSDESItem = nextSDESType(type);
1110  if ( empty )
1111  return SDESItemTypeEND;
1112  else
1113  return type;
1114 }
1115 
1116  SDESItemType QueueRTCPManager::nextSDESType(SDESItemType t)
1117 {
1118  t = static_cast<SDESItemType >( static_cast<int>(t) + 1 );
1119  if ( t > lastSchedulable )
1120  t = firstSchedulable;
1121  return t;
1122 }
1123 
1124  size_t QueueRTCPManager::sendControlToDestinations(unsigned char* buffer, size_t len)
1125 {
1126  size_t count = 0;
1127  lockDestinationList();
1128 
1129  // Cast to have easy access to ssrc et al
1130  RTCPPacket *pkt = reinterpret_cast<RTCPPacket *>(buffer);
1131 
1132  CryptoContextCtrl* pcc = getOutQueueCryptoContextCtrl(pkt->getSSRC());
1133  if (pcc == NULL) {
1134  pcc = getOutQueueCryptoContextCtrl(0);
1135  if (pcc != NULL) {
1136  pcc = pcc->newCryptoContextForSSRC(pkt->getSSRC());
1137  if (pcc != NULL) {
1138  pcc->deriveSrtcpKeys();
1139  setOutQueueCryptoContextCtrl(pcc);
1140  }
1141  }
1142  }
1143  // If no crypto context: then SRTP/SRTCP is off
1144  // If crypto context is available then unprotect data here. If an error
1145  // occurs report the error and discard the packet.
1146  if (pcc != NULL) {
1147  len = protect(buffer, len, pcc);
1148  }
1149 
1150  if ( isSingleDestination() ) {
1151  count = sendControl(buffer,len);
1152  } else {
1153  // when no destination has been added, NULL == dest.
1154  for (std::list<TransportAddress*>::iterator i =
1155  destList.begin(); destList.end() != i; i++) {
1156  TransportAddress* dest = *i;
1157  setControlPeer(dest->getNetworkAddress(),
1158  dest->getControlTransportPort());
1159  count += sendControl(buffer,len);
1160  }
1161  }
1162  unlockDestinationList();
1163 
1164  return count;
1165 }
1166 
1167 int32
1168  QueueRTCPManager::protect(uint8* pkt, size_t len, CryptoContextCtrl* pcc) {
1169  /* Encrypt the packet */
1170 
1171  uint32 ssrc = *(reinterpret_cast<uint32*>(pkt + 4)); // always SSRC of sender
1172  ssrc =ntohl(ssrc);
1173 
1174  pcc->srtcpEncrypt(pkt + 8, len - 8, srtcpIndex, ssrc);
1175 
1176  uint32 encIndex = srtcpIndex | 0x80000000; // set the E flag
1177 
1178  uint32* ip = reinterpret_cast<uint32*>(pkt+len);
1179  *ip = htonl(encIndex);
1180 
1181  // NO MKI support yet - here we assume MKI is zero. To build in MKI
1182  // take MKI length into account when storing the authentication tag.
1183 
1184  // Compute MAC and store in packet after the SRTCP index field
1185  pcc->srtcpAuthenticate(pkt, len, encIndex, pkt + len + sizeof(uint32));
1186 
1187  srtcpIndex++;
1188  srtcpIndex &= ~0x80000000; // clear possible overflow
1189 
1190  return len + pcc->getTagLength() + sizeof(uint32);
1191 }
1192 
1193 int32
1194  QueueRTCPManager::unprotect(uint8* pkt, size_t len, CryptoContextCtrl* pcc) {
1195  if (pcc == NULL) {
1196  return true;
1197  }
1198 
1199  // Compute the total length of the payload
1200  uint32 payloadLen = len - (pcc->getTagLength() + pcc->getMkiLength() + 4);
1201 
1202  // point to the SRTCP index field just after the real payload
1203  const uint32* index = reinterpret_cast<uint32*>(pkt + payloadLen);
1204  uint32 ssrc = *(reinterpret_cast<uint32*>(pkt + 4)); // always SSRC of sender
1205  ssrc =ntohl(ssrc);
1206 
1207  uint32 encIndex = ntohl(*index);
1208  uint32 remoteIndex = encIndex & ~0x80000000; // index without Encryption flag
1209 
1210  if (!pcc->checkReplay(remoteIndex)) {
1211  return -2;
1212  }
1213 
1214  uint8 mac[20];
1215 
1216  // Now get a pointer to the authentication tag field
1217  const uint8* tag = pkt + (len - pcc->getTagLength());
1218 
1219  // Authenticate includes the index, but not MKI and not (obviously) the tag itself
1220  pcc->srtcpAuthenticate(pkt, payloadLen, encIndex, mac);
1221  if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
1222  return -1;
1223  }
1224 
1225  // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)
1226  if (encIndex & 0x80000000)
1227  pcc->srtcpEncrypt(pkt + 8, payloadLen - 8, remoteIndex, ssrc);
1228 
1229  // Update the Crypto-context
1230  pcc->update(remoteIndex);
1231 
1232  return payloadLen;
1233 }
1234 
1235 
1236 void
1237  QueueRTCPManager::setOutQueueCryptoContextCtrl(CryptoContextCtrl* cc)
1238 {
1239  std::list<CryptoContextCtrl *>::iterator i;
1240 
1241  MutexLock lock(outCryptoMutex);
1242  // check if a CryptoContext for a SSRC already exists. If yes
1243  // remove it from list before inserting the new one.
1244  for( i = outCryptoContexts.begin(); i!= outCryptoContexts.end(); i++ ) {
1245  if( (*i)->getSsrc() == cc->getSsrc() ) {
1246  CryptoContextCtrl* tmp = *i;
1247  outCryptoContexts.erase(i);
1248  delete tmp;
1249  break;
1250  }
1251  }
1252  outCryptoContexts.push_back(cc);
1253 }
1254 
1255 void
1256  QueueRTCPManager::removeOutQueueCryptoContextCtrl(CryptoContextCtrl* cc)
1257 {
1258  std::list<CryptoContextCtrl *>::iterator i;
1259 
1260  MutexLock lock(outCryptoMutex);
1261  if (cc == NULL) { // Remove any incoming crypto contexts
1262  for (i = outCryptoContexts.begin(); i != outCryptoContexts.end(); ) {
1263  CryptoContextCtrl* tmp = *i;
1264  i = outCryptoContexts.erase(i);
1265  delete tmp;
1266  }
1267  }
1268  else {
1269  for( i = outCryptoContexts.begin(); i != outCryptoContexts.end(); i++ ) {
1270  if( (*i)->getSsrc() == cc->getSsrc() ) {
1271  CryptoContextCtrl* tmp = *i;
1272  outCryptoContexts.erase(i);
1273  delete tmp;
1274  return;
1275  }
1276  }
1277  }
1278 }
1279 
1280 CryptoContextCtrl*
1281  QueueRTCPManager::getOutQueueCryptoContextCtrl(uint32 ssrc)
1282 {
1283  std::list<CryptoContextCtrl *>::iterator i;
1284 
1285  MutexLock lock(outCryptoMutex);
1286  for( i = outCryptoContexts.begin(); i != outCryptoContexts.end(); i++ ){
1287  if( (*i)->getSsrc() == ssrc) {
1288  return (*i);
1289  }
1290  }
1291  return NULL;
1292 }
1293 
1294 void
1295  QueueRTCPManager::setInQueueCryptoContextCtrl(CryptoContextCtrl* cc)
1296 {
1297  std::list<CryptoContextCtrl *>::iterator i;
1298 
1299  MutexLock lock(inCryptoMutex);
1300  // check if a CryptoContext for a SSRC already exists. If yes
1301  // remove it from list before inserting the new one.
1302  for( i = inCryptoContexts.begin(); i!= inCryptoContexts.end(); i++ ) {
1303  if( (*i)->getSsrc() == cc->getSsrc() ) {
1304  CryptoContextCtrl* tmp = *i;
1305  inCryptoContexts.erase(i);
1306  delete tmp;
1307  break;
1308  }
1309  }
1310  inCryptoContexts.push_back(cc);
1311 }
1312 
1313 void
1314  QueueRTCPManager::removeInQueueCryptoContextCtrl(CryptoContextCtrl* cc)
1315 {
1316  std::list<CryptoContextCtrl *>::iterator i;
1317 
1318  MutexLock lock(inCryptoMutex);
1319  if (cc == NULL) { // Remove any incoming crypto contexts
1320  for (i = inCryptoContexts.begin(); i != inCryptoContexts.end(); ) {
1321  CryptoContextCtrl* tmp = *i;
1322  i = inCryptoContexts.erase(i);
1323  delete tmp;
1324  }
1325  }
1326  else {
1327  for( i = inCryptoContexts.begin(); i!= inCryptoContexts.end(); i++ ){
1328  if( (*i)->getSsrc() == cc->getSsrc() ) {
1329  CryptoContextCtrl* tmp = *i;
1330  inCryptoContexts.erase(i);
1331  delete tmp;
1332  return;
1333  }
1334  }
1335  }
1336 }
1337 
1338 CryptoContextCtrl*
1339  QueueRTCPManager::getInQueueCryptoContextCtrl(uint32 ssrc)
1340 {
1341  std::list<CryptoContextCtrl *>::iterator i;
1342 
1343  MutexLock lock(inCryptoMutex);
1344  for( i = inCryptoContexts.begin(); i!= inCryptoContexts.end(); i++ ){
1345  if( (*i)->getSsrc() == ssrc) {
1346  return (*i);
1347  }
1348  }
1349  return NULL;
1350 }
1351 
1352 END_NAMESPACE
1353 
OutgoingDataQueue::getSendPacketCount
uint32 getSendPacketCount() const
Get the total number of packets sent so far.
Definition: oqueue.h:391
RTCPCompoundHandler::RRBlock
Struct for a receiver info block in a SR (sender report) or an RR (receiver report) RTCP packet...
Definition: rtcppkt.h:125
RTCPCompoundHandler::ReceiverInfo::lsr
uint32 lsr
last sender report timestamp.
Definition: rtcppkt.h:115
RTCPSenderInfo::getNTPTimestampFrac
uint32 getNTPTimestampFrac() const
Get fractional part of the NTP timestamp of this packet.
Definition: rtcppkt.h:481
RTCPCompoundHandler::RTCPFixedHeader::block_count
unsigned char block_count
< For little endian boxes
Definition: rtcppkt.h:259
OutgoingDataQueue::getSendOctetCount
uint32 getSendOctetCount() const
Get the total number of octets (payload only) sent so far.
Definition: oqueue.h:400
CryptoContextCtrl::deriveSrtcpKeys
void deriveSrtcpKeys()
Perform key derivation according to SRTP specification.
Definition: CryptoContextCtrl.cpp:327
ApplicationHandler::addParticipant
void addParticipant(RTPApplication &app, Participant &part)
Definition: iqueue.h:209
RTCPSenderInfo::getNTPTimestampInt
uint32 getNTPTimestampInt() const
Get integer part of the NTP timestamp of this packet.
Definition: rtcppkt.h:473
QueueRTCPManager::getDefaultEnd2EndDelay
microtimeout_t getDefaultEnd2EndDelay() const
Definition: cqueue.h:136
QueueRTCPManager::protect
int32 protect(uint8 *pkt, size_t len, CryptoContextCtrl *cc)
Definition: control.cpp:1168
CryptoContextCtrl
The implementation for a SRTCP cryptographic context.
Definition: CryptoContextCtrl.h:61
CryptoContextCtrl::getTagLength
int32 getTagLength() const
Get the length of the SRTP authentication tag in bytes.
Definition: CryptoContextCtrl.h:240
QueueRTCPManager::nextSDESType
SDESItemType nextSDESType(SDESItemType t)
Definition: control.cpp:1116
QueueRTCPManager::getEnd2EndDelay
microtimeout_t getEnd2EndDelay() const
Definition: cqueue.h:140
SyncSource::getDataTransportPort
tpport_t getDataTransportPort() const
Definition: sources.h:271
QueueRTCPManager::isPendingControl
virtual bool isPendingControl(microtimeout_t timeout)=0
RTCPCompoundHandler::rtcpSendBuffer
unsigned char * rtcpSendBuffer
Definition: rtcppkt.h:352
RTCPCompoundHandler
low level structs and RTCP packet parsing and building methods.
Definition: rtcppkt.h:89
QueueRTCPManager::outCryptoContexts
std::list< CryptoContextCtrl * > outCryptoContexts
Definition: cqueue.h:693
SDESItemTypeLast
Last defined code.
Definition: rtcppkt.h:76
RTPApplication
An RTP application, holding identifying RTCP SDES item values.
Definition: sources.h:364
RTCPCompoundHandler::RTCPPacket::tBYE
End of participation.
Definition: rtcppkt.h:288
NTP_EPOCH_OFFSET
NAMESPACE_COMMONCPP const uint32 NTP_EPOCH_OFFSET
Definition: private.h:142
RTCPCompoundHandler::RRBlock::rinfo
ReceiverInfo rinfo
info about the source.
Definition: rtcppkt.h:128
SyncSource
Synchronization source in an RTP session.
Definition: sources.h:192
RTPDataQueue::renewLocalSSRC
void renewLocalSSRC()
Definition: ioqueue.h:281
QueueRTCPManager::firstSchedulable
static const SDESItemType firstSchedulable
Definition: cqueue.h:650
QueueRTCPManager::getBYE
bool getBYE(RTCPPacket &pkt, size_t &pointer, size_t len)
Process a BYE packet just received and identified.
Definition: control.cpp:529
RTCPCompoundHandler::ReceiverInfo::highestSeqNum
uint32 highestSeqNum
highest sequence number.
Definition: rtcppkt.h:113
ParticipantHandler::setPRIVPrefix
void setPRIVPrefix(Participant *part, const std::string val)
Definition: iqueue.h:188
QueueRTCPManager::controlServiceActive
volatile bool controlServiceActive
Definition: cqueue.h:640
RTCPCompoundHandler::BYEPacket::ssrc
uint32 ssrc
ssrc identifier of source leaving.
Definition: rtcppkt.h:203
CCRTP_VERSION
const uint8 CCRTP_VERSION
RTP protocol version supported.
Definition: base.h:64
RTCPCompoundHandler::ReceiverInfo::jitter
uint32 jitter
arrival jitter.
Definition: rtcppkt.h:114
MembershipBookkeeping::getMembersCount
uint32 getMembersCount()
Definition: iqueue.h:843
QueueRTCPManager::sendControl
virtual size_t sendControl(const unsigned char *const buffer, size_t len)=0
QueueRTCPManager::onGotSDESChunk
virtual bool onGotSDESChunk(SyncSource &source, SDESChunk &chunk, size_t len)
Plug-in for handling of SDES chunks.
Definition: control.cpp:629
QueueRTCPManager::updateAvgRTCPSize
void updateAvgRTCPSize(size_t len)
This must be called in order to update the average RTCP compound packet size estimation when: ...
Definition: control.cpp:522
RTCPCompoundHandler::SenderInfo::octetCount
uint32 octetCount
cumulative octet counter.
Definition: rtcppkt.h:155
RTCPCompoundHandler::checkCompoundRTCPHeader
bool checkCompoundRTCPHeader(size_t len)
Perform RTCP compound packet header validity check as specified in draft-ietv-avt-rtp-new.
Definition: rtcppkt.cpp:107
microtimeout_t
uint32 microtimeout_t
Time interval expressed in microseconds.
Definition: base.h:67
MembershipBookkeeping::getSendersCount
uint32 getSendersCount()
Definition: iqueue.h:851
QueueRTCPManager::~QueueRTCPManager
virtual ~QueueRTCPManager()
Definition: control.cpp:162
RTCPSenderInfo
Sender block information of SR RTCP reports.
Definition: rtcppkt.h:453
RTCPCompoundHandler::RTCPPacket::tAPP
APPlication specific.
Definition: rtcppkt.h:289
SDESItemTypeCNAME
Canonical end-point identifier.
Definition: rtcppkt.h:67
QueueRTCPManager::unprotect
int32 unprotect(uint8 *pkt, size_t len, CryptoContextCtrl *cc)
Definition: control.cpp:1194
RTPDataQueue::getSessionBandwidth
uint32 getSessionBandwidth() const
Definition: ioqueue.h:219
CryptoContextCtrl::srtcpEncrypt
void srtcpEncrypt(uint8 *rtp, size_t len, uint64 index, uint32 ssrc)
Perform SRTP encryption.
Definition: CryptoContextCtrl.cpp:193
QueueRTCPManager::scheduleSDESItem
virtual SDESItemType scheduleSDESItem()
Choose which should be the type of the next SDES item sent.
Definition: control.cpp:1095
SyncSourceHandler::setState
void setState(SyncSource &source, SyncSource::State ns)
Definition: iqueue.h:146
QueueRTCPManager::checkSSRCInRTCPPkt
bool checkSSRCInRTCPPkt(SyncSourceLink &sourceLink, bool is_new, InetAddress &na, tpport_t tp)
Appy collision and loop detection and correction algorithm when receiving RTCP packets.
Definition: control.cpp:176
QueueRTCPManager::end2EndDelay
microtimeout_t end2EndDelay
Definition: cqueue.h:684
RTCPCompoundHandler::RTCPFixedHeader::padding
unsigned char padding
Padding bit.
Definition: rtcppkt.h:260
QueueRTCPManager::lowerHeadersSize
uint16 lowerHeadersSize
Definition: cqueue.h:647
QueueRTCPManager::timerReconsideration
bool timerReconsideration()
Definition: control.cpp:294
QueueRTCPManager::endQueueRTCPManager
void endQueueRTCPManager()
Definition: control.cpp:167
QueueRTCPManager::reverseReconsideration
void reverseReconsideration()
Apply reverse reconsideration adjustment to timing parameters when receiving BYE packets and not wait...
Definition: control.cpp:568
RTCPCompoundHandler::RTCPPacket::getLength
uint32 getLength() const
Get the packet length specified in its header, in octets and in host order.
Definition: rtcppkt.h:299
timeval2microtimeout
microtimeout_t timeval2microtimeout(const timeval &t)
Convert a time interval, expressed as a timeval value into a microseconds counter.
Definition: base.h:90
DestinationListHandler::destList
std::list< TransportAddress * > destList
Definition: oqueue.h:68
QueueRTCPManager::rtcpCheckInterval
timeval rtcpCheckInterval
Definition: cqueue.h:667
QueueRTCPManager::getInQueueCryptoContextCtrl
CryptoContextCtrl * getInQueueCryptoContextCtrl(uint32 ssrc)
Get an input queue CryptoContext identified by SSRC.
Definition: control.cpp:1339
IncomingDataQueue::onNewSyncSource
virtual void onNewSyncSource(const SyncSource &)
Virtual called when a new synchronization source has joined the session.
Definition: iqueue.h:1185
QueueRTCPManager::ctrlSendCount
uint32 ctrlSendCount
Definition: cqueue.h:643
QueueRTCPManager::rtcpNextCheck
timeval rtcpNextCheck
Definition: cqueue.h:669
IncomingDataQueue::getMinValidPacketSequence
uint8 getMinValidPacketSequence() const
Get the minimun number of consecutive packets that must be received from a source before accepting it...
Definition: iqueue.h:1010
QueueRTCPManager::defaultEnd2EndDelay
static const microtimeout_t defaultEnd2EndDelay
maximum end to end delay: unlimited
Definition: cqueue.h:681
RTCPCompoundHandler::ReceiverInfo::dlsr
uint32 dlsr
delay since last sender report.
Definition: rtcppkt.h:116
RTCPCompoundHandler::RTCPFixedHeader
Fixed RTCP packet header.
Definition: rtcppkt.h:250
QueueRTCPManager::onGotSR
virtual void onGotSR(SyncSource &source, SendReport &SR, uint8 blocks)
Plug-in for processing (acquire information carried in) an incoming RTCP Sender Report.
Definition: control.cpp:502
QueueRTCPManager::removeInQueueCryptoContextCtrl
void removeInQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Remove input queue CryptoContext.
Definition: control.cpp:1314
RTPQueueBase::getInitialTime
timeval getInitialTime() const
Definition: queuebase.h:201
DestinationListHandler::lockDestinationList
void lockDestinationList() const
Definition: oqueue.h:85
private.h
Declaration of ccRTP internal stuff.
QueueRTCPManager::onGotAPP
virtual void onGotAPP(SyncSource &, RTCPCompoundHandler::APPPacket &, size_t)
Plug-in for handling of APP (application specific) RTCP packets.
Definition: cqueue.h:357
QueueRTCPManager::onGotRR
virtual void onGotRR(SyncSource &source, RecvReport &RR, uint8 blocks)
Plug-in for processing (acquire information carried in) an incoming RTCP Receiver Report...
Definition: control.cpp:509
QueueRTCPManager::packReportBlocks
uint8 packReportBlocks(RRBlock *blocks, uint16 &len, uint16 &available)
Definition: control.cpp:1030
RTCPCompoundHandler::ReceiverInfo::lostLSW
uint16 lostLSW
cumulative lost two LSB.
Definition: rtcppkt.h:112
QueueRTCPManager::setInQueueCryptoContextCtrl
void setInQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Set input queue CryptoContext.
Definition: control.cpp:1295
QueueRTCPManager::rtcpWeSent
bool rtcpWeSent
Definition: cqueue.h:661
QueueRTCPManager::onGotGoodbye
virtual void onGotGoodbye(const SyncSource &, const std::string &)
A plugin point for goodbye message.
Definition: cqueue.h:499
QueueRTCPManager::sendControlToDestinations
size_t sendControlToDestinations(unsigned char *buffer, size_t len)
Definition: control.cpp:1124
QueueRTCPManager::getOnlyBye
void getOnlyBye()
To be executed when whe are leaving the session.
Definition: control.cpp:816
QueueRTCPManager::getSendRTCPPacketCount
uint32 getSendRTCPPacketCount() const
Get the total number of RTCP packets sent until now.
Definition: cqueue.h:177
QueueRTCPManager::RECONSIDERATION_COMPENSATION
static const double RECONSIDERATION_COMPENSATION
Definition: cqueue.h:690
QueueRTCPManager::setSDESItem
void setSDESItem(Participant *part, SDESItemType type, const char *const value, size_t len)
Set item value from a string without null termination (as it is transported in RTCP packets)...
Definition: control.cpp:1076
RTCPCompoundHandler::BYEPacket
Struct for BYE (leaving session) RTCP packets.
Definition: rtcppkt.h:201
RTCPCompoundHandler::ReceiverInfo::lostMSB
uint8 lostMSB
cumulative lost MSB of 3 octets.
Definition: rtcppkt.h:111
RTCPCompoundHandler::SDESItem::len
uint8 len
item len in octets.
Definition: rtcppkt.h:178
RTCPCompoundHandler::RTCPFixedHeader::type
uint8 type
type of RTCP packet.
Definition: rtcppkt.h:263
OutgoingDataQueue::getInitialTimestamp
uint32 getInitialTimestamp()
Definition: oqueue.h:534
RTCPCompoundHandler::SDESChunk::ssrc
uint32 ssrc
SSRC identifer from sender.
Definition: rtcppkt.h:192
RTCPCompoundHandler::SenderInfo::NTPMSW
uint32 NTPMSW
NTP timestamp higher octets.
Definition: rtcppkt.h:151
Participant
A class of objects representing remote participants (RTP applications) in a multimedia session...
Definition: sources.h:124
RTPPacket::getTimestamp
uint32 getTimestamp() const
Definition: rtppkt.h:149
QueueRTCPManager::outCryptoMutex
Mutex outCryptoMutex
Definition: cqueue.h:692
RTCPCompoundHandler::SenderInfo
Struct for the sender info block in a SR (sender report) RTCP packet.
Definition: rtcppkt.h:149
RTCPCompoundHandler::SendReport
Struct for SR (sender report) RTCP packets.
Definition: rtcppkt.h:163
QueueRTCPManager::controlBwFract
float controlBwFract
Definition: cqueue.h:641
QueueRTCPManager::getOutQueueCryptoContextCtrl
CryptoContextCtrl * getOutQueueCryptoContextCtrl(uint32 ssrc)
Get an output queue CryptoContext identified by SSRC.
Definition: control.cpp:1281
RTCPCompoundHandler::BYEPacket::length
uint8 length
[optional] length of reason.
Definition: rtcppkt.h:204
RTCPCompoundHandler::SDESChunk::getSSRC
uint32 getSSRC() const
Definition: rtcppkt.h:189
QueueRTCPManager::QueueRTCPManager
QueueRTCPManager(uint32 size=RTPDataQueue::defaultMembersHashSize, RTPApplication &app=defaultApplication())
Definition: control.cpp:61
SyncSourceHandler::setNetworkAddress
void setNetworkAddress(SyncSource &source, InetAddress addr)
Definition: iqueue.h:162
MembershipBookkeeping::last
SyncSourceLink * last
Definition: iqueue.h:874
QueueRTCPManager::transportHeaderSize
virtual uint16 transportHeaderSize()
For certain control calculations in RTCP, the size of the underlying network and transport protocols ...
Definition: cqueue.h:618
QueueRTCPManager::rtcpMinInterval
microtimeout_t rtcpMinInterval
Definition: cqueue.h:678
RTCPCompoundHandler::RecvReport::blocks
RRBlock blocks[1]
receiver report blocks.
Definition: rtcppkt.h:140
RTCPCompoundHandler::SDESItem::type
uint8 type
item identifier.
Definition: rtcppkt.h:177
RTCPCompoundHandler::SendReport::sinfo
SenderInfo sinfo
actual sender info.
Definition: rtcppkt.h:166
QueueRTCPManager::expireSSRCs
void expireSSRCs()
Purge sources that do not seem active any more.
Definition: control.cpp:310
ParticipantHandler::setSDESItem
void setSDESItem(Participant *part, SDESItemType item, const std::string &val)
Definition: iqueue.h:183
RTCPCompoundHandler::SDESChunk::item
SDESItem item
SDES item from sender.
Definition: rtcppkt.h:193
RTCPCompoundHandler::SDESChunk
Struct for a chunk of items in a SDES RTCP packet.
Definition: rtcppkt.h:187
QueueRTCPManager::removeOutQueueCryptoContextCtrl
void removeOutQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Remove output queue CryptoContext.
Definition: control.cpp:1256
SyncSource::getParticipant
Participant * getParticipant() const
Get the participant this synchronization source is asociated to.
Definition: sources.h:268
SyncSourceHandler::setParticipant
void setParticipant(SyncSource &source, Participant &p)
Definition: iqueue.h:142
SDESItemTypeEND
END of SDES item list.
Definition: rtcppkt.h:66
RTCPCompoundHandler::SendReport::blocks
RRBlock blocks[1]
possibly several receiver info blocks.
Definition: rtcppkt.h:167
RTCPCompoundHandler::RTCPPacket
Struct representing general RTCP packet headers as they are sent through the network.
Definition: rtcppkt.h:277
MembershipBookkeeping::BYESource
bool BYESource(uint32 ssrc)
Mark the source identified by ssrc as having sent a BYE packet.
Definition: members.cpp:282
cqueue.h
Generic RTCP control queues.
SDESItemTypePRIV
Private extension.
Definition: rtcppkt.h:74
QueueRTCPManager::controlReceptionService
void controlReceptionService()
Process incoming RTCP packets pending in the control reception socket.
Definition: control.cpp:242
QueueRTCPManager::nextScheduledSDESItem
SDESItemType nextScheduledSDESItem
Definition: cqueue.h:649
OutgoingDataQueue::setControlPeer
virtual void setControlPeer(const InetAddress &host, tpport_t port)
Definition: oqueue.h:540
timevalIntervalTo65536
uint32 timevalIntervalTo65536(timeval &t)
Convert a time interval, expressed as a timeval, into a 32-bit time interval expressed in units of 1/...
Definition: rtcppkt.cpp:67
BYE_BUFFER_LENGTH
#define BYE_BUFFER_LENGTH
Definition: control.cpp:743
QueueRTCPManager::getApplication
const RTPApplication & getApplication()
Definition: cqueue.h:259
QueueRTCPManager::srtcpIndex
uint32 srtcpIndex
Definition: cqueue.h:694
CryptoContextCtrl::getSsrc
uint32 getSsrc() const
Get the SSRC of this SRTP Cryptograhic context.
Definition: CryptoContextCtrl.h:259
SyncSource::getNetworkAddress
const InetAddress & getNetworkAddress() const
Definition: sources.h:277
QueueRTCPManager::rtcpAvgSize
uint16 rtcpAvgSize
Definition: cqueue.h:662
QueueRTCPManager::takeInControlPacket
void takeInControlPacket()
For picking up incoming RTCP packets if they are waiting.
Definition: control.cpp:314
QueueRTCPManager::rtcpInitial
bool rtcpInitial
Definition: cqueue.h:663
SyncSource::getControlTransportPort
tpport_t getControlTransportPort() const
Definition: sources.h:274
SyncSource::stateActive
received, but source validity not yet guaranteed.
Definition: sources.h:230
I
#define I(e)
Definition: private.h:108
QueueRTCPManager::reconsInfo
struct QueueRTCPManager::@0 reconsInfo
CryptoContextCtrl::checkReplay
bool checkReplay(uint32 newSeqNumber)
Check for packet replay.
Definition: CryptoContextCtrl.cpp:372
CryptoContextCtrl::srtcpAuthenticate
void srtcpAuthenticate(uint8 *rtp, size_t len, uint32 roc, uint8 *tag)
Compute the authentication tag.
Definition: CryptoContextCtrl.cpp:265
RTCPCompoundHandler::SDESItem::data
char data[1]
item content.
Definition: rtcppkt.h:179
SDESItemTypeNAME
Personal NAME of the user.
Definition: rtcppkt.h:68
MembershipBookkeeping::getSourceBySSRC
SyncSourceLink * getSourceBySSRC(uint32 ssrc, bool &created)
Get the description of a source by its ssrc identifier.
Definition: members.cpp:226
QueueRTCPManager::rtcpLastCheck
timeval rtcpLastCheck
Definition: cqueue.h:665
RTPQueueBase::getLocalSSRCNetwork
uint32 getLocalSSRCNetwork() const
Definition: queuebase.h:214
QueueRTCPManager::lastSchedulable
static const SDESItemType lastSchedulable
Definition: cqueue.h:651
RTCPCompoundHandler::getPathMTU
uint16 getPathMTU()
Definition: rtcppkt.h:95
RTCPCompoundHandler::SenderInfo::RTPTimestamp
uint32 RTPTimestamp
RTP timestamp.
Definition: rtcppkt.h:153
QueueRTCPManager::networkHeaderSize
virtual uint16 networkHeaderSize()
For certain control calculations in RTCP, the size of the underlying network and transport protocols ...
Definition: cqueue.h:603
DestinationListHandler::TransportAddress::getControlTransportPort
tpport_t getControlTransportPort() const
Definition: oqueue.h:122
RTCPCompoundHandler::RecvReport
raw structure of the source and every receiver report in an SR or RR RTCP packet. ...
Definition: rtcppkt.h:137
DestinationListHandler::TransportAddress::getNetworkAddress
const InetAddress & getNetworkAddress() const
Definition: oqueue.h:116
RTCPCompoundHandler::rtcpRecvBuffer
unsigned char * rtcpRecvBuffer
Definition: rtcppkt.h:355
CryptoContextCtrl::getMkiLength
int32 getMkiLength() const
Get the length of the MKI in bytes.
Definition: CryptoContextCtrl.h:250
QueueRTCPManager::dispatchControlPacket
size_t dispatchControlPacket()
Posting of RTCP messages.
Definition: control.cpp:858
RTCPCompoundHandler::RecvReport::ssrc
uint32 ssrc
source identifier.
Definition: rtcppkt.h:139
RTCPCompoundHandler::RTCPPacket::getSSRC
uint32 getSSRC() const
Get the SSRC identifier specified in the packet header, in host order.
Definition: rtcppkt.h:306
QueueRTCPManager::TIMEOUT_MULTIPLIER
static const uint16 TIMEOUT_MULTIPLIER
Definition: cqueue.h:689
MembershipBookkeeping::setMembersCount
void setMembersCount(uint32 n)
Definition: iqueue.h:847
RTPQueueBase::getLocalSSRC
uint32 getLocalSSRC() const
Definition: queuebase.h:184
QueueRTCPManager::setPRIVPrefix
void setPRIVPrefix(Participant *part, const char *const value, size_t len)
Set PRIV item previx value from a string without null termination (as it is transported in RTCP packe...
Definition: control.cpp:1086
RTCPCompoundHandler::RTCPFixedHeader::length
uint16 length
number of 32-bit words in the packet (minus one).
Definition: rtcppkt.h:264
RTCPCompoundHandler::SDESItem
Struct for an item description of a SDES packet.
Definition: rtcppkt.h:175
CryptoContextCtrl::newCryptoContextForSSRC
CryptoContextCtrl * newCryptoContextForSSRC(uint32 ssrc)
Derive a new Crypto Context for use with a new SSRC.
Definition: CryptoContextCtrl.cpp:424
RTCPSenderInfo::getRTPTimestamp
uint32 getRTPTimestamp() const
Definition: rtcppkt.h:485
QueueRTCPManager::inCryptoMutex
Mutex inCryptoMutex
Definition: cqueue.h:696
QueueRTCPManager::end2EndDelayed
virtual bool end2EndDelayed(IncomingRTPPktLink &p)
Virtual reimplemented from RTPDataQueue.
Definition: control.cpp:471
RTCPCompoundHandler::ReceiverInfo::fractionLost
uint8 fractionLost
packet fraction lost.
Definition: rtcppkt.h:110
QueueRTCPManager::sendControlBwFract
float sendControlBwFract
Definition: cqueue.h:641
NTP2Timeval
timeval NTP2Timeval(uint32 msw, uint32 lsw)
Convert a NTP timestamp, expressed as two 32-bit long words, into a timeval value.
Definition: rtcppkt.cpp:58
QueueRTCPManager::leavingDelay
microtimeout_t leavingDelay
Definition: cqueue.h:680
MembershipBookkeeping::getFirst
SyncSourceLink * getFirst()
Definition: iqueue.h:836
QueueRTCPManager::inCryptoContexts
std::list< CryptoContextCtrl * > inCryptoContexts
Definition: cqueue.h:697
QueueRTCPManager::controlTransmissionService
void controlTransmissionService()
Build and send RTCP packets following timing rules (including the "timer reconsideration" algorithm)...
Definition: control.cpp:264
RTPQueueBase::getCurrentRTPClockRate
uint32 getCurrentRTPClockRate() const
Get the clock rate in RTP clock units (for instance, 8000 units per second for PCMU, or 90000 units per second for MP2T).
Definition: queuebase.h:195
QueueRTCPManager::onGotSDES
bool onGotSDES(SyncSource &source, RTCPPacket &pkt)
Definition: control.cpp:597
QueueRTCPManager::onGotRRSRExtension
virtual void onGotRRSRExtension(unsigned char *, size_t)
Plug-in for processing of SR/RR RTCP packet profile-specific extensions (third part of SR reports or ...
Definition: cqueue.h:486
RTCPCompoundHandler::RRBlock::ssrc
uint32 ssrc
source identifier.
Definition: rtcppkt.h:127
SyncSource::getID
uint32 getID() const
Definition: sources.h:257
ConflictHandler::addConflict
void addConflict(const InetAddress &na, tpport_t dtp, tpport_t ctp)
Definition: incqueue.cpp:75
QueueRTCPManager::packSDES
void packSDES(uint16 &len)
Builds an SDES RTCP packet.
Definition: control.cpp:977
RTPApplication::getSDESItem
const std::string & getSDESItem(SDESItemType item) const
Definition: sources.h:390
MembershipBookkeeping::getLink
SyncSourceLink * getLink(const SyncSource &source) const
Definition: iqueue.h:336
RTCPCompoundHandler::RTCPPacket::tSDES
Source DEScription.
Definition: rtcppkt.h:287
RTCPCompoundHandler::RTCPPacket::info
union RTCPCompoundHandler::RTCPPacket::@6 info
Union for SR, RR, SDES, BYE and APP.
RTCPCompoundHandler::RTCPFixedHeader::version
unsigned char version
Version, currently 2.
Definition: rtcppkt.h:261
RTCPCompoundHandler::RTCPPacket::fh
RTCPFixedHeader fh
Fixed RTCP header.
Definition: rtcppkt.h:310
DestinationListHandler::isSingleDestination
bool isSingleDestination() const
Get whether there is only a destination in the list.
Definition: oqueue.h:79
IncomingDataQueue::end
SyncSourcesIterator end()
Definition: iqueue.h:941
RTCPCompoundHandler::SenderInfo::packetCount
uint32 packetCount
cumulative packet counter.
Definition: rtcppkt.h:154
RTPApplication::getParticipant
const Participant * getParticipant(const std::string &cname) const
Definition: source.cpp:173
ConflictHandler::updateConflict
void updateConflict(ConflictingTransportAddress &ca)
Definition: iqueue.h:273
QueueRTCPManager::setOutQueueCryptoContextCtrl
void setOutQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Set ouput queue CryptoContext.
Definition: control.cpp:1237
QueueRTCPManager::setPrevMembersNum
void setPrevMembersNum(uint32 n)
Definition: cqueue.h:377
QueueRTCPManager::recvControl
virtual size_t recvControl(unsigned char *buffer, size_t len, InetHostAddress &na, tpport_t &tp)=0
RTCPCompoundHandler::SenderInfo::NTPLSW
uint32 NTPLSW
NTP timestamp lower octets.
Definition: rtcppkt.h:152
QueueRTCPManager::computeRTCPInterval
virtual timeval computeRTCPInterval()
Computes the interval for sending RTCP compound packets, based on the average size of RTCP packets se...
Definition: control.cpp:698
QueueRTCPManager::lastSendPacketCount
uint32 lastSendPacketCount
Definition: cqueue.h:673
microtimeout2Timeval
__EXPORT timeval microtimeout2Timeval(microtimeout_t to)
Convert a time interval, expressed as a microtimeout_t (number of microseconds), into a timeval value...
Definition: rtcppkt.cpp:76
CryptoContextCtrl::update
void update(uint32 newSeqNumber)
Update the SRTP packet index.
Definition: CryptoContextCtrl.cpp:406
SyncSource::stateLeaving
no packet from this source has been received lately.
Definition: sources.h:235
RTPDataQueue
A packet queue handler for building different kinds of RTP protocol systems.
Definition: ioqueue.h:74
ConflictHandler::searchControlConflict
ConflictingTransportAddress * searchControlConflict(InetAddress na, tpport_t ctp)
Definition: incqueue.cpp:64
SDESItemType
SDESItemType
SDES items that may be carried in a Source DEScription RTCP packet.
Definition: rtcppkt.h:64
QueueRTCPManager::queueApplication
RTPApplication & queueApplication
Definition: cqueue.h:686
QueueRTCPManager::dispatchBYE
size_t dispatchBYE(const std::string &reason)
This method is used to send an RTCP BYE packet.
Definition: control.cpp:745
DestinationListHandler::unlockDestinationList
void unlockDestinationList() const
Definition: oqueue.h:88
RTCPCompoundHandler::SendReport::ssrc
uint32 ssrc
source identifier.
Definition: rtcppkt.h:165
SyncSourceHandler::setControlTransportPort
void setControlTransportPort(SyncSource &source, tpport_t p)
Definition: iqueue.h:158
QueueRTCPManager::recvControlBwFract
float recvControlBwFract
Definition: cqueue.h:641

Generated on Dec 15, 2017 for ccrtp-2.1.2 (*.h and *.cpp) and libzrtpcpp-2.3.4 (*.h), by   doxygen 1.8.6

AltStyle によって変換されたページ (->オリジナル) /