ccRTP
|
00001 // Copyright (C) 2001-2015 Federico Montesino Pouzols <fedemp@altern.org>. 00002 // 00003 // This program is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU Lesser General Public License 00014 // along with GNU ccRTP. If not, see <http://www.gnu.org/licenses/>. 00015 // 00016 // As a special exception, you may use this file as part of a free software 00017 // library without restriction. Specifically, if other files instantiate 00018 // templates or use macros or inline functions from this file, or you compile 00019 // this file and link it with other files to produce an executable, this 00020 // file does not by itself cause the resulting executable to be covered by 00021 // the GNU General Public License. This exception does not however 00022 // invalidate any other reasons why the executable file might be covered by 00023 // the GNU General Public License. 00024 // 00025 // This exception applies only to the code released under the name GNU 00026 // ccRTP. If you copy code from other releases into a copy of GNU 00027 // ccRTP, as the General Public License permits, the exception does 00028 // not apply to the code that you add in this way. To avoid misleading 00029 // anyone as to the status of such modified files, you must delete 00030 // this exception notice from them. 00031 // 00032 // If you write modifications of your own for GNU ccRTP, it is your choice 00033 // whether to permit this exception to apply to your modifications. 00034 // If you do not wish that, delete this exception notice. 00035 // 00036 00043 #ifndef CCXX_RTP_OQUEUE_H_ 00044 #define CCXX_RTP_OQUEUE_H_ 00045 00046 #include <ccrtp/queuebase.h> 00047 #include <ccrtp/CryptoContext.h> 00048 #include <list> 00049 00050 NAMESPACE_COMMONCPP 00051 00065 class __EXPORT DestinationListHandler 00066 { 00067 protected: 00068 struct TransportAddress; 00069 std::list<TransportAddress*> destList; 00070 00071 public: 00072 DestinationListHandler(); 00073 00074 ~DestinationListHandler(); 00075 00079 inline bool isSingleDestination() const 00080 { return (1 == destList.size()); } 00081 00082 inline TransportAddress* getFirstDestination() const 00083 { return destList.front(); } 00084 00085 inline void lockDestinationList() const 00086 { destinationLock.readLock(); } 00087 00088 inline void unlockDestinationList() const 00089 { destinationLock.unlock(); } 00090 00091 protected: 00092 inline void writeLockDestinationList() const 00093 { destinationLock.writeLock(); } 00094 00098 bool 00099 addDestinationToList(const InetAddress& ia, tpport_t data, 00100 tpport_t control); 00101 00105 bool removeDestinationFromList(const InetAddress& ia, 00106 tpport_t dataPort, 00107 tpport_t controlPort); 00108 00109 struct TransportAddress 00110 { 00111 TransportAddress(InetAddress na, tpport_t dtp, tpport_t ctp) : 00112 networkAddress(na), dataTransportPort(dtp), 00113 controlTransportPort(ctp) 00114 { } 00115 00116 inline const InetAddress& getNetworkAddress() const 00117 { return networkAddress; } 00118 00119 inline tpport_t getDataTransportPort() const 00120 { return dataTransportPort; } 00121 00122 inline tpport_t getControlTransportPort() const 00123 { return controlTransportPort; } 00124 00125 InetAddress networkAddress; 00126 tpport_t dataTransportPort, controlTransportPort; 00127 }; 00128 00129 private: 00130 mutable ThreadLock destinationLock; 00131 }; 00132 00133 #ifdef CCXX_IPV6 00134 00142 class __EXPORT DestinationListHandlerIPV6 00143 { 00144 protected: 00145 struct TransportAddressIPV6; 00146 std::list<TransportAddressIPV6*> destListIPV6; 00147 00148 public: 00149 DestinationListHandlerIPV6(); 00150 00151 ~DestinationListHandlerIPV6(); 00152 00156 inline bool isSingleDestinationIPV6() const 00157 { return (1 == destListIPV6.size()); } 00158 00159 inline TransportAddressIPV6* getFirstDestinationIPV6() const 00160 { return destListIPV6.front(); } 00161 00162 inline void lockDestinationListIPV6() const 00163 { destinationLock.readLock(); } 00164 00165 inline void unlockDestinationListIPV6() const 00166 { destinationLock.unlock(); } 00167 00168 protected: 00169 inline void writeLockDestinationListIPV6() const 00170 { destinationLock.writeLock(); } 00171 00175 bool 00176 addDestinationToListIPV6(const IPV6Address& ia, tpport_t data, 00177 tpport_t control); 00178 00182 bool removeDestinationFromListIPV6(const IPV6Address& ia, 00183 tpport_t dataPort, 00184 tpport_t controlPort); 00185 00186 struct TransportAddressIPV6 00187 { 00188 TransportAddressIPV6(IPV6Address na, tpport_t dtp, tpport_t ctp) : 00189 networkAddress(na), dataTransportPort(dtp), 00190 controlTransportPort(ctp) 00191 { } 00192 00193 inline const IPV6Address& getNetworkAddress() const 00194 { return networkAddress; } 00195 00196 inline tpport_t getDataTransportPort() const 00197 { return dataTransportPort; } 00198 00199 inline tpport_t getControlTransportPort() const 00200 { return controlTransportPort; } 00201 00202 IPV6Address networkAddress; 00203 tpport_t dataTransportPort, controlTransportPort; 00204 }; 00205 00206 private: 00207 mutable ThreadLock destinationLock; 00208 }; 00209 00210 #endif 00211 00219 class __EXPORT OutgoingDataQueue: 00220 public OutgoingDataQueueBase, 00221 #ifdef CCXX_IPV6 00222 protected DestinationListHandlerIPV6, 00223 #endif 00224 protected DestinationListHandler 00225 { 00226 public: 00227 #ifdef CCXX_IPV6 00228 bool 00229 addDestination(const IPV6Address& ia, 00230 tpport_t dataPort = DefaultRTPDataPort, 00231 tpport_t controlPort = 0); 00232 00233 bool 00234 forgetDestination(const IPV6Address& ia, 00235 tpport_t dataPort = DefaultRTPDataPort, 00236 tpport_t controlPort = 0); 00237 00238 #endif 00239 00240 bool 00241 addDestination(const InetHostAddress& ia, 00242 tpport_t dataPort = DefaultRTPDataPort, 00243 tpport_t controlPort = 0); 00244 00245 bool 00246 addDestination(const InetMcastAddress& ia, 00247 tpport_t dataPort = DefaultRTPDataPort, 00248 tpport_t controlPort = 0); 00249 00250 bool 00251 forgetDestination(const InetHostAddress& ia, 00252 tpport_t dataPort = DefaultRTPDataPort, 00253 tpport_t controlPort = 0); 00254 00255 bool 00256 forgetDestination(const InetMcastAddress& ia, 00257 tpport_t dataPort = DefaultRTPDataPort, 00258 tpport_t controlPort = 0); 00259 00265 void 00266 addContributor(uint32 csrc); 00267 00271 bool 00272 removeContributor(uint32 csrc); 00273 00279 bool 00280 isSending() const; 00281 00282 00295 void 00296 putData(uint32 stamp, const unsigned char* data = NULL, size_t len = 0); 00297 00310 void 00311 sendImmediate(uint32 stamp, const unsigned char* data = NULL, size_t len = 0); 00312 00313 00320 void setPadding(uint8 paddinglen) 00321 { sendInfo.paddinglen = paddinglen; } 00322 00331 void setMark(bool mark) 00332 { sendInfo.marked = mark; } 00333 00337 inline bool getMark() const 00338 { return sendInfo.marked; } 00339 00350 size_t 00351 setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max); 00352 00353 inline microtimeout_t 00354 getDefaultSchedulingTimeout() const 00355 { return defaultSchedulingTimeout; } 00356 00363 inline void 00364 setSchedulingTimeout(microtimeout_t to) 00365 { schedulingTimeout = to; } 00366 00367 inline microtimeout_t 00368 getDefaultExpireTimeout() const 00369 { return defaultExpireTimeout; } 00370 00378 inline void 00379 setExpireTimeout(microtimeout_t to) 00380 { expireTimeout = to; } 00381 00382 inline microtimeout_t getExpireTimeout() const 00383 { return expireTimeout; } 00384 00390 inline uint32 00391 getSendPacketCount() const 00392 { return sendInfo.packetCount; } 00393 00399 inline uint32 00400 getSendOctetCount() const 00401 { return sendInfo.octetCount; } 00402 00408 inline uint16 00409 getSequenceNumber() const 00410 { return sendInfo.sendSeq; } 00411 00420 void 00421 setOutQueueCryptoContext(CryptoContext* cc); 00422 00431 void 00432 removeOutQueueCryptoContext(CryptoContext* cc); 00433 00441 CryptoContext* 00442 getOutQueueCryptoContext(uint32 ssrc); 00443 00444 00445 protected: 00446 OutgoingDataQueue(); 00447 00448 virtual ~OutgoingDataQueue() 00449 { } 00450 00451 struct OutgoingRTPPktLink 00452 { 00453 OutgoingRTPPktLink(OutgoingRTPPkt* pkt, 00454 OutgoingRTPPktLink* p, 00455 OutgoingRTPPktLink* n) : 00456 packet(pkt), prev(p), next(n) { } 00457 00458 ~OutgoingRTPPktLink() { delete packet; } 00459 00460 inline OutgoingRTPPkt* getPacket() { return packet; } 00461 00462 inline void setPacket(OutgoingRTPPkt* pkt) { packet = pkt; } 00463 00464 inline OutgoingRTPPktLink* getPrev() { return prev; } 00465 00466 inline void setPrev(OutgoingRTPPktLink* p) { prev = p; } 00467 00468 inline OutgoingRTPPktLink* getNext() { return next; } 00469 00470 inline void setNext(OutgoingRTPPktLink* n) { next = n; } 00471 00472 // the packet this link refers to. 00473 OutgoingRTPPkt* packet; 00474 // global outgoing packets queue. 00475 OutgoingRTPPktLink * prev, * next; 00476 }; 00477 00485 void 00486 dispatchImmediate(OutgoingRTPPkt *packet); 00487 00497 microtimeout_t 00498 getSchedulingTimeout(); 00499 00506 size_t 00507 dispatchDataPacket(); 00508 00517 inline void 00518 setNextSeqNum(uint32 seqNum) 00519 { sendInfo.sendSeq = seqNum; } 00520 00521 inline uint32 00522 getCurrentSeqNum(void) 00523 { return sendInfo.sendSeq; } 00524 00527 inline void 00528 setInitialTimestamp(uint32 ts) 00529 { initialTimestamp = ts; } 00530 00533 inline uint32 00534 getInitialTimestamp() 00535 { return initialTimestamp; } 00536 00537 void purgeOutgoingQueue(); 00538 00539 virtual void 00540 setControlPeer(const InetAddress &host, tpport_t port) {} 00541 00542 #ifdef CCXX_IPV6 00543 virtual void 00544 setControlPeerIPV6(const IPV6Address &host, tpport_t port) {} 00545 #endif 00546 00547 // The crypto contexts for outgoing SRTP sessions. 00548 mutable Mutex cryptoMutex; 00549 std::list<CryptoContext *> cryptoContexts; 00550 00551 private: 00557 inline virtual void onExpireSend(OutgoingRTPPkt&) 00558 { } 00559 00560 virtual void 00561 setDataPeer(const InetAddress &host, tpport_t port) {} 00562 00563 #ifdef CCXX_IPV6 00564 virtual void 00565 setDataPeerIPV6(const IPV6Address &host, tpport_t port) {} 00566 #endif 00567 00577 virtual size_t 00578 sendData(const unsigned char* const buffer, size_t len) {return 0;} 00579 00580 #ifdef CCXX_IPV6 00581 virtual size_t 00582 sendDataIPV6(const unsigned char* const buffer, size_t len) {return 0;} 00583 #endif 00584 00585 static const microtimeout_t defaultSchedulingTimeout; 00586 static const microtimeout_t defaultExpireTimeout; 00587 mutable ThreadLock sendLock; 00588 // outgoing data packets queue 00589 OutgoingRTPPktLink* sendFirst, * sendLast; 00590 uint32 initialTimestamp; 00591 // transmission scheduling timeout for the service thread 00592 microtimeout_t schedulingTimeout; 00593 // how old a packet can reach in the sending queue before deletetion 00594 microtimeout_t expireTimeout; 00595 00596 00597 struct { 00598 // number of packets sent from the beginning 00599 uint32 packetCount; 00600 // number of payload octets sent from the beginning 00601 uint32 octetCount; 00602 // the sequence number of the next packet to sent 00603 uint16 sendSeq; 00604 // contributing sources 00605 uint32 sendSources[16]; 00606 // how many CSRCs to send. 00607 uint16 sendCC; 00608 // pad packets to a paddinglen multiple 00609 uint8 paddinglen; 00610 // This flags tells whether to set the bit M in the 00611 // RTP fixed header of the packet in which the next 00612 // provided data will be sent. 00613 bool marked; 00614 // whether there was not loss. 00615 bool complete; 00616 // ramdonly generated offset for the timestamp of sent packets 00617 uint32 initialTimestamp; 00618 // elapsed time accumulated through successive overflows of 00619 // the local timestamp field 00620 timeval overflowTime; 00621 } sendInfo; 00622 }; 00623 // oqueue 00625 00626 END_NAMESPACE 00627 00628 #endif //CCXX_RTP_OQUEUE_H_ 00629