packet.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * SRT - Secure Reliable Transport
  3. * Copyright (c) 2018 Haivision Systems Inc.
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. *
  9. */
  10. /*****************************************************************************
  11. Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
  12. All rights reserved.
  13. Redistribution and use in source and binary forms, with or without
  14. modification, are permitted provided that the following conditions are
  15. met:
  16. * Redistributions of source code must retain the above
  17. copyright notice, this list of conditions and the
  18. following disclaimer.
  19. * Redistributions in binary form must reproduce the
  20. above copyright notice, this list of conditions
  21. and the following disclaimer in the documentation
  22. and/or other materials provided with the distribution.
  23. * Neither the name of the University of Illinois
  24. nor the names of its contributors may be used to
  25. endorse or promote products derived from this
  26. software without specific prior written permission.
  27. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *****************************************************************************/
  39. /*****************************************************************************
  40. written by
  41. Yunhong Gu, last updated 01/02/2011
  42. modified by
  43. Haivision Systems Inc.
  44. *****************************************************************************/
  45. #ifndef INC_SRT_PACKET_H
  46. #define INC_SRT_PACKET_H
  47. #include "udt.h"
  48. #include "common.h"
  49. #include "utilities.h"
  50. #include "netinet_any.h"
  51. #include "packetfilter_api.h"
  52. namespace srt
  53. {
  54. //////////////////////////////////////////////////////////////////////////////
  55. // The purpose of the IOVector class is to proide a platform-independet interface
  56. // to the WSABUF on Windows and iovec on Linux, that can be easilly converted
  57. // to the native structure for use in WSARecvFrom() and recvmsg(...) functions
  58. class IOVector
  59. #ifdef _WIN32
  60. : public WSABUF
  61. #else
  62. : public iovec
  63. #endif
  64. {
  65. public:
  66. inline void set(void* buffer, size_t length)
  67. {
  68. #ifdef _WIN32
  69. len = (ULONG)length;
  70. buf = (CHAR*)buffer;
  71. #else
  72. iov_base = (void*)buffer;
  73. iov_len = length;
  74. #endif
  75. }
  76. inline char*& dataRef()
  77. {
  78. #ifdef _WIN32
  79. return buf;
  80. #else
  81. return (char*&)iov_base;
  82. #endif
  83. }
  84. inline char* data()
  85. {
  86. #ifdef _WIN32
  87. return buf;
  88. #else
  89. return (char*)iov_base;
  90. #endif
  91. }
  92. inline size_t size() const
  93. {
  94. #ifdef _WIN32
  95. return (size_t)len;
  96. #else
  97. return iov_len;
  98. #endif
  99. }
  100. inline void setLength(size_t length)
  101. {
  102. #ifdef _WIN32
  103. len = (ULONG)length;
  104. #else
  105. iov_len = length;
  106. #endif
  107. }
  108. };
  109. /// To define packets in order in the buffer. This is public due to being used in buffer.
  110. enum PacketBoundary
  111. {
  112. PB_SUBSEQUENT = 0, // 00: a packet in the middle of a message, neither the first, not the last.
  113. PB_LAST = 1, // 01: last packet of a message
  114. PB_FIRST = 2, // 10: first packet of a message
  115. PB_SOLO = 3, // 11: solo message packet
  116. };
  117. // Breakdown of the PM_SEQNO field in the header:
  118. // C| X X ... X, where:
  119. typedef Bits<31> SEQNO_CONTROL;
  120. // 1|T T T T T T T T T T T T T T T|E E...E
  121. typedef Bits<30, 16> SEQNO_MSGTYPE;
  122. typedef Bits<15, 0> SEQNO_EXTTYPE;
  123. // 0|S S ... S
  124. typedef Bits<30, 0> SEQNO_VALUE;
  125. // This bit cannot be used by SEQNO anyway, so it's additionally used
  126. // in LOSSREPORT data specification to define that this value is the
  127. // BEGIN value for a SEQNO range (to distinguish it from a SOLO loss SEQNO value).
  128. const int32_t LOSSDATA_SEQNO_RANGE_FIRST = SEQNO_CONTROL::mask;
  129. // Just cosmetics for readability.
  130. const int32_t LOSSDATA_SEQNO_RANGE_LAST = 0, LOSSDATA_SEQNO_SOLO = 0;
  131. inline int32_t CreateControlSeqNo(UDTMessageType type)
  132. {
  133. return SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(uint32_t(type));
  134. }
  135. inline int32_t CreateControlExtSeqNo(int exttype)
  136. {
  137. return SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(size_t(UMSG_EXT)) | SEQNO_EXTTYPE::wrap(exttype);
  138. }
  139. // MSGNO breakdown: B B|O|K K|R|M M M M M M M M M M...M
  140. typedef Bits<31, 30> MSGNO_PACKET_BOUNDARY;
  141. typedef Bits<29> MSGNO_PACKET_INORDER;
  142. typedef Bits<28, 27> MSGNO_ENCKEYSPEC;
  143. #if 1 // can block rexmit flag
  144. // New bit breakdown - rexmit flag supported.
  145. typedef Bits<26> MSGNO_REXMIT;
  146. typedef Bits<25, 0> MSGNO_SEQ;
  147. // Old bit breakdown - no rexmit flag
  148. typedef Bits<26, 0> MSGNO_SEQ_OLD;
  149. // This symbol is for older SRT version, where the peer does not support the MSGNO_REXMIT flag.
  150. // The message should be extracted as PMASK_MSGNO_SEQ, if REXMIT is supported, and PMASK_MSGNO_SEQ_OLD otherwise.
  151. const uint32_t PACKET_SND_NORMAL = 0, PACKET_SND_REXMIT = MSGNO_REXMIT::mask;
  152. const int MSGNO_SEQ_MAX = MSGNO_SEQ::mask;
  153. #else
  154. // Old bit breakdown - no rexmit flag
  155. typedef Bits<26, 0> MSGNO_SEQ;
  156. #endif
  157. typedef RollNumber<MSGNO_SEQ::size - 1, 1> MsgNo;
  158. // constexpr in C++11 !
  159. inline int32_t PacketBoundaryBits(PacketBoundary o)
  160. {
  161. return MSGNO_PACKET_BOUNDARY::wrap(int32_t(o));
  162. }
  163. enum EncryptionKeySpec
  164. {
  165. EK_NOENC = 0,
  166. EK_EVEN = 1,
  167. EK_ODD = 2
  168. };
  169. enum EncryptionStatus
  170. {
  171. ENCS_CLEAR = 0,
  172. ENCS_FAILED = -1,
  173. ENCS_NOTSUP = -2
  174. };
  175. const int32_t PMASK_MSGNO_ENCKEYSPEC = MSGNO_ENCKEYSPEC::mask;
  176. inline int32_t EncryptionKeyBits(EncryptionKeySpec f)
  177. {
  178. return MSGNO_ENCKEYSPEC::wrap(int32_t(f));
  179. }
  180. inline EncryptionKeySpec GetEncryptionKeySpec(int32_t msgno)
  181. {
  182. return EncryptionKeySpec(MSGNO_ENCKEYSPEC::unwrap(msgno));
  183. }
  184. const int32_t PUMASK_SEQNO_PROBE = 0xF;
  185. std::string PacketMessageFlagStr(uint32_t msgno_field);
  186. class CPacket
  187. {
  188. friend class CChannel;
  189. friend class CSndQueue;
  190. friend class CRcvQueue;
  191. public:
  192. CPacket();
  193. ~CPacket();
  194. void allocate(size_t size);
  195. void deallocate();
  196. /// Get the payload or the control information field length.
  197. /// @return the payload or the control information field length.
  198. size_t getLength() const;
  199. /// Set the payload or the control information field length.
  200. /// @param len [in] the payload or the control information field length.
  201. void setLength(size_t len);
  202. /// Set the payload or the control information field length.
  203. /// @param len [in] the payload or the control information field length.
  204. /// @param cap [in] capacity (if known).
  205. void setLength(size_t len, size_t cap);
  206. /// Pack a Control packet.
  207. /// @param pkttype [in] packet type filed.
  208. /// @param lparam [in] pointer to the first data structure, explained by the packet type.
  209. /// @param rparam [in] pointer to the second data structure, explained by the packet type.
  210. /// @param size [in] size of rparam, in number of bytes;
  211. void pack(UDTMessageType pkttype, const int32_t* lparam = NULL, void* rparam = NULL, size_t size = 0);
  212. /// Read the packet vector.
  213. /// @return Pointer to the packet vector.
  214. IOVector* getPacketVector();
  215. uint32_t* getHeader() { return m_nHeader; }
  216. /// Read the packet type.
  217. /// @return packet type filed (000 ~ 111).
  218. UDTMessageType getType() const;
  219. bool isControl(UDTMessageType type) const { return isControl() && type == getType(); }
  220. bool isControl() const { return 0 != SEQNO_CONTROL::unwrap(m_nHeader[SRT_PH_SEQNO]); }
  221. void setControl(UDTMessageType type) { m_nHeader[SRT_PH_SEQNO] = SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(type); }
  222. /// Read the extended packet type.
  223. /// @return extended packet type filed (0x000 ~ 0xFFF).
  224. int getExtendedType() const;
  225. /// Read the ACK-2 seq. no.
  226. /// @return packet header field (bit 16~31).
  227. int32_t getAckSeqNo() const;
  228. uint16_t getControlFlags() const;
  229. // Note: this will return a "singular" value, if the packet
  230. // contains the control message
  231. int32_t getSeqNo() const { return m_nHeader[SRT_PH_SEQNO]; }
  232. /// Read the message boundary flag bit.
  233. /// @return packet header field [1] (bit 0~1).
  234. PacketBoundary getMsgBoundary() const;
  235. /// Read the message inorder delivery flag bit.
  236. /// @return packet header field [1] (bit 2).
  237. bool getMsgOrderFlag() const;
  238. /// Read the rexmit flag (true if the packet was sent due to retransmission).
  239. /// If the peer does not support retransmission flag, the current agent cannot use it as well
  240. /// (because the peer will understand this bit as a part of MSGNO field).
  241. bool getRexmitFlag() const;
  242. void setRexmitFlag(bool bRexmit);
  243. /// Read the message sequence number.
  244. /// @return packet header field [1]
  245. int32_t getMsgSeq(bool has_rexmit = true) const;
  246. /// Read the message crypto key bits.
  247. /// @return packet header field [1] (bit 3~4).
  248. EncryptionKeySpec getMsgCryptoFlags() const;
  249. void setMsgCryptoFlags(EncryptionKeySpec spec);
  250. /// Read the message time stamp.
  251. /// @return packet header field [2] (bit 0~31, bit 0-26 if SRT_DEBUG_TSBPD_WRAP).
  252. uint32_t getMsgTimeStamp() const;
  253. sockaddr_any udpDestAddr() const { return m_DestAddr; }
  254. #ifdef SRT_DEBUG_TSBPD_WRAP // Receiver
  255. static const uint32_t MAX_TIMESTAMP = 0x07FFFFFF; // 27 bit fast wraparound for tests (~2m15s)
  256. #else
  257. static const uint32_t MAX_TIMESTAMP = 0xFFFFFFFF; // Full 32 bit (01h11m35s)
  258. #endif
  259. protected:
  260. static const uint32_t TIMESTAMP_MASK = MAX_TIMESTAMP; // this value to be also used as a mask
  261. public:
  262. /// Clone this packet.
  263. /// @return Pointer to the new packet.
  264. CPacket* clone() const;
  265. enum PacketVectorFields
  266. {
  267. PV_HEADER = 0,
  268. PV_DATA = 1,
  269. PV_SIZE = 2
  270. };
  271. public:
  272. void toNL();
  273. void toHL();
  274. protected:
  275. // DynamicStruct is the same as array of given type and size, just it
  276. // enforces that you index it using a symbol from symbolic enum type, not by a bare integer.
  277. typedef DynamicStruct<uint32_t, SRT_PH_E_SIZE, SrtPktHeaderFields> HEADER_TYPE;
  278. HEADER_TYPE m_nHeader; //< The 128-bit header field
  279. IOVector m_PacketVector[PV_SIZE]; //< The two-dimensional vector of an SRT packet [header, data]
  280. int32_t m_extra_pad;
  281. bool m_data_owned;
  282. sockaddr_any m_DestAddr;
  283. size_t m_zCapacity;
  284. protected:
  285. CPacket& operator=(const CPacket&);
  286. CPacket(const CPacket&);
  287. public:
  288. int32_t& m_iSeqNo; // alias: sequence number
  289. int32_t& m_iMsgNo; // alias: message number
  290. int32_t& m_iTimeStamp; // alias: timestamp
  291. int32_t& m_iID; // alias: destination SRT socket ID
  292. char*& m_pcData; // alias: payload (data packet) / control information fields (control packet)
  293. // Experimental: sometimes these references don't work!
  294. char* getData();
  295. char* release();
  296. static const size_t HDR_SIZE = sizeof(HEADER_TYPE); // packet header size = SRT_PH_E_SIZE * sizeof(uint32_t)
  297. // Can also be calculated as: sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct udphdr).
  298. static const size_t UDP_HDR_SIZE = 28; // 20 bytes IPv4 + 8 bytes of UDP { u16 sport, dport, len, csum }.
  299. static const size_t SRT_DATA_HDR_SIZE = UDP_HDR_SIZE + HDR_SIZE;
  300. // Maximum transmission unit size. 1500 in case of Ethernet II (RFC 1191).
  301. static const size_t ETH_MAX_MTU_SIZE = 1500;
  302. // Maximum payload size of an SRT packet.
  303. static const size_t SRT_MAX_PAYLOAD_SIZE = ETH_MAX_MTU_SIZE - SRT_DATA_HDR_SIZE;
  304. // Packet interface
  305. char* data() { return m_pcData; }
  306. const char* data() const { return m_pcData; }
  307. size_t size() const { return getLength(); }
  308. size_t capacity() const { return m_zCapacity; }
  309. void setCapacity(size_t cap) { m_zCapacity = cap; }
  310. uint32_t header(SrtPktHeaderFields field) const { return m_nHeader[field]; }
  311. #if ENABLE_LOGGING
  312. std::string MessageFlagStr() { return PacketMessageFlagStr(m_nHeader[SRT_PH_MSGNO]); }
  313. std::string Info();
  314. #else
  315. std::string MessageFlagStr() { return std::string(); }
  316. std::string Info() { return std::string(); }
  317. #endif
  318. };
  319. } // namespace srt
  320. #endif