mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			410 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * SRT - Secure, Reliable, Transport
 | |
|  * Copyright (c) 2018 Haivision Systems Inc.
 | |
|  * 
 | |
|  * This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
|  * 
 | |
|  */
 | |
| 
 | |
| /*****************************************************************************
 | |
| Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
 | |
| All rights reserved.
 | |
| 
 | |
| Redistribution and use in source and binary forms, with or without
 | |
| modification, are permitted provided that the following conditions are
 | |
| met:
 | |
| 
 | |
| * Redistributions of source code must retain the above
 | |
|   copyright notice, this list of conditions and the
 | |
|   following disclaimer.
 | |
| 
 | |
| * Redistributions in binary form must reproduce the
 | |
|   above copyright notice, this list of conditions
 | |
|   and the following disclaimer in the documentation
 | |
|   and/or other materials provided with the distribution.
 | |
| 
 | |
| * Neither the name of the University of Illinois
 | |
|   nor the names of its contributors may be used to
 | |
|   endorse or promote products derived from this
 | |
|   software without specific prior written permission.
 | |
| 
 | |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 | |
| IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | |
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
| PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | |
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | |
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | |
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | |
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | |
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | |
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| *****************************************************************************/
 | |
| 
 | |
| /*****************************************************************************
 | |
| written by
 | |
|    Haivision Systems Inc.
 | |
| *****************************************************************************/
 | |
| 
 | |
| #ifndef INC_SRT_SOCKETCONFIG_H
 | |
| #define INC_SRT_SOCKETCONFIG_H
 | |
| 
 | |
| #include "platform_sys.h"
 | |
| #ifdef SRT_ENABLE_BINDTODEVICE
 | |
| #include <linux/if.h>
 | |
| #endif
 | |
| #include <string>
 | |
| #include "haicrypt.h"
 | |
| #include "congctl.h"
 | |
| #include "packet.h"
 | |
| #include "handshake.h"
 | |
| #include "logger_defs.h"
 | |
| #include "packetfilter.h"
 | |
| 
 | |
| // SRT Version constants
 | |
| #define SRT_VERSION_UNK     0
 | |
| #define SRT_VERSION_MAJ1    0x010000            /* Version 1 major */
 | |
| #define SRT_VERSION_MAJ(v) (0xFF0000 & (v))     /* Major number ensuring backward compatibility */
 | |
| #define SRT_VERSION_MIN(v) (0x00FF00 & (v))
 | |
| #define SRT_VERSION_PCH(v) (0x0000FF & (v))
 | |
| 
 | |
| // NOTE: SRT_VERSION is primarily defined in the build file.
 | |
| extern const int32_t SRT_DEF_VERSION;
 | |
| 
 | |
| namespace srt
 | |
| {
 | |
| 
 | |
| struct CSrtMuxerConfig
 | |
| {
 | |
|     static const int DEF_UDP_BUFFER_SIZE = 65536;
 | |
| 
 | |
|     int  iIpTTL;
 | |
|     int  iIpToS;
 | |
|     int  iIpV6Only;  // IPV6_V6ONLY option (-1 if not set)
 | |
|     bool bReuseAddr; // reuse an exiting port or not, for UDP multiplexer
 | |
| 
 | |
| #ifdef SRT_ENABLE_BINDTODEVICE
 | |
|     std::string sBindToDevice;
 | |
| #endif
 | |
|     int iUDPSndBufSize; // UDP sending buffer size
 | |
|     int iUDPRcvBufSize; // UDP receiving buffer size
 | |
| 
 | |
|     // NOTE: this operator is not reversable. The syntax must use:
 | |
|     //  muxer_entry == socket_entry
 | |
|     bool isCompatWith(const CSrtMuxerConfig& other) const
 | |
|     {
 | |
| #define CEQUAL(field) (field == other.field)
 | |
|         return CEQUAL(iIpTTL)
 | |
|             && CEQUAL(iIpToS)
 | |
|             && CEQUAL(bReuseAddr)
 | |
| #ifdef SRT_ENABLE_BINDTODEVICE
 | |
|             && CEQUAL(sBindToDevice)
 | |
| #endif
 | |
|             && CEQUAL(iUDPSndBufSize)
 | |
|             && CEQUAL(iUDPRcvBufSize)
 | |
|             && (other.iIpV6Only == -1 || CEQUAL(iIpV6Only))
 | |
|             // NOTE: iIpV6Only is not regarded because
 | |
|             // this matches only in case of IPv6 with "any" address.
 | |
|             // And this aspect must be checked separately because here
 | |
|             // this procedure has no access to neither the address,
 | |
|             // nor the IP version (family).
 | |
| #undef CEQUAL
 | |
|             && true;
 | |
|     }
 | |
| 
 | |
|     CSrtMuxerConfig()
 | |
|         : iIpTTL(-1) /* IPv4 TTL or IPv6 HOPs [1..255] (-1:undefined) */
 | |
|         , iIpToS(-1) /* IPv4 Type of Service or IPv6 Traffic Class [0x00..0xff] (-1:undefined) */
 | |
|         , iIpV6Only(-1)
 | |
|         , bReuseAddr(true) // This is default in SRT
 | |
|         , iUDPSndBufSize(DEF_UDP_BUFFER_SIZE)
 | |
|         , iUDPRcvBufSize(DEF_UDP_BUFFER_SIZE)
 | |
|     {
 | |
|     }
 | |
| };
 | |
| 
 | |
| struct CSrtConfig;
 | |
| 
 | |
| template <size_t SIZE>
 | |
| class StringStorage
 | |
| {
 | |
|     char     stor[SIZE + 1];
 | |
|     uint16_t len;
 | |
| 
 | |
|     // NOTE: default copying allowed.
 | |
| 
 | |
| public:
 | |
|     StringStorage()
 | |
|         : len(0)
 | |
|     {
 | |
|         memset(stor, 0, sizeof stor);
 | |
|     }
 | |
| 
 | |
|     bool set(const char* s, size_t length)
 | |
|     {
 | |
|         if (length > SIZE)
 | |
|             return false;
 | |
| 
 | |
|         memcpy(stor, s, length);
 | |
|         stor[length] = 0;
 | |
|         len          = (int) length;
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     bool set(const std::string& s)
 | |
|     {
 | |
|         return set(s.c_str(), s.size());
 | |
|     }
 | |
| 
 | |
|     size_t copy(char* s, size_t length) const
 | |
|     {
 | |
|         if (!s)
 | |
|             return 0;
 | |
| 
 | |
|         size_t copy_len = std::min((size_t)len, length);
 | |
|         memcpy(s, stor, copy_len);
 | |
|         return copy_len;
 | |
|     }
 | |
| 
 | |
|     std::string str() const
 | |
|     {
 | |
|         return len == 0 ? std::string() : std::string(stor);
 | |
|     }
 | |
| 
 | |
|     const char* c_str() const
 | |
|     {
 | |
|         return stor;
 | |
|     }
 | |
| 
 | |
|     size_t size() const { return size_t(len); }
 | |
|     bool   empty() const { return len == 0; }
 | |
| };
 | |
| 
 | |
| struct CSrtConfig: CSrtMuxerConfig
 | |
| {
 | |
|     typedef srt::sync::steady_clock::time_point time_point;
 | |
|     typedef srt::sync::steady_clock::duration   duration;
 | |
| 
 | |
|     static const int
 | |
|         DEF_MSS = 1500,
 | |
|         DEF_FLIGHT_SIZE = 25600,
 | |
|         DEF_BUFFER_SIZE = 8192, //Rcv buffer MUST NOT be bigger than Flight Flag size
 | |
|         DEF_LINGER_S = 3*60,    // 3 minutes
 | |
|         DEF_CONNTIMEO_S = 3;    // 3 seconds
 | |
| 
 | |
|     enum
 | |
|     {
 | |
|         CIPHER_MODE_AUTO = 0,
 | |
|         CIPHER_MODE_AES_CTR = 1,
 | |
|         CIPHER_MODE_AES_GCM = 2
 | |
|     };
 | |
| 
 | |
|     static const int      COMM_RESPONSE_TIMEOUT_MS      = 5 * 1000; // 5 seconds
 | |
|     static const uint32_t COMM_DEF_MIN_STABILITY_TIMEOUT_MS = 60;   // 60 ms
 | |
| 
 | |
|     // Mimimum recv flight flag size is 32 packets
 | |
|     static const int    DEF_MIN_FLIGHT_PKT = 32;
 | |
|     static const size_t MAX_SID_LENGTH     = 512;
 | |
|     static const size_t MAX_PFILTER_LENGTH = 64;
 | |
|     static const size_t MAX_CONG_LENGTH    = 16;
 | |
| 
 | |
|     int    iMSS;            // Maximum Segment Size, in bytes
 | |
|     size_t zExpPayloadSize; // Expected average payload size (user option)
 | |
| 
 | |
|     // Options
 | |
|     bool   bSynSending;     // Sending synchronization mode
 | |
|     bool   bSynRecving;     // Receiving synchronization mode
 | |
|     int    iFlightFlagSize; // Maximum number of packets in flight from the peer side
 | |
|     int    iSndBufSize;     // Maximum UDT sender buffer size
 | |
|     int    iRcvBufSize;     // Maximum UDT receiver buffer size
 | |
|     linger Linger;          // Linger information on close
 | |
|     bool   bRendezvous;     // Rendezvous connection mode
 | |
| 
 | |
|     duration tdConnTimeOut; // connect timeout in milliseconds
 | |
|     bool     bDriftTracer;
 | |
|     int      iSndTimeOut; // sending timeout in milliseconds
 | |
|     int      iRcvTimeOut; // receiving timeout in milliseconds
 | |
|     int64_t  llMaxBW;     // maximum data transfer rate (threshold)
 | |
| #ifdef ENABLE_MAXREXMITBW
 | |
|     int64_t  llMaxRexmitBW; // maximum bandwidth limit for retransmissions (Bytes/s).
 | |
| #endif
 | |
| 
 | |
|     // These fields keep the options for encryption
 | |
|     // (SRTO_PASSPHRASE, SRTO_PBKEYLEN). Crypto object is
 | |
|     // created later and takes values from these.
 | |
|     HaiCrypt_Secret CryptoSecret;
 | |
|     int             iSndCryptoKeyLen;
 | |
| 
 | |
|     // XXX Consider removing. The bDataSender stays here
 | |
|     // in order to maintain the HS side selection in HSv4.
 | |
|     bool bDataSender;
 | |
| 
 | |
|     bool     bMessageAPI;
 | |
|     bool     bTSBPD;        // Whether AGENT will do TSBPD Rx (whether peer does, is not agent's problem)
 | |
|     int      iRcvLatency;   // Agent's Rx latency
 | |
|     int      iPeerLatency;  // Peer's Rx latency for the traffic made by Agent's Tx.
 | |
|     bool     bTLPktDrop;    // Whether Agent WILL DO TLPKTDROP on Rx.
 | |
|     int      iSndDropDelay; // Extra delay when deciding to snd-drop for TLPKTDROP, -1 to off
 | |
|     bool     bEnforcedEnc;  // Off by default. When on, any connection other than nopw-nopw & pw1-pw1 is rejected.
 | |
|     int      iGroupConnect;    // 1 - allow group connections
 | |
|     int      iPeerIdleTimeout_ms; // Timeout for hearing anything from the peer (ms).
 | |
|     uint32_t uMinStabilityTimeout_ms;
 | |
|     int      iRetransmitAlgo;
 | |
|     int      iCryptoMode; // SRTO_CRYPTOMODE
 | |
| 
 | |
|     int64_t llInputBW;         // Input stream rate (bytes/sec). 0: use internally estimated input bandwidth
 | |
|     int64_t llMinInputBW;      // Minimum input stream rate estimate (bytes/sec)
 | |
|     int  iOverheadBW;          // Percent above input stream rate (applies if llMaxBW == 0)
 | |
|     bool bRcvNakReport;        // Enable Receiver Periodic NAK Reports
 | |
|     int  iMaxReorderTolerance; //< Maximum allowed value for dynamic reorder tolerance
 | |
| 
 | |
|     // For the use of CCryptoControl
 | |
|     // HaiCrypt configuration
 | |
|     unsigned int uKmRefreshRatePkt;
 | |
|     unsigned int uKmPreAnnouncePkt;
 | |
| 
 | |
|     uint32_t uSrtVersion;
 | |
|     uint32_t uMinimumPeerSrtVersion;
 | |
| 
 | |
|     StringStorage<MAX_CONG_LENGTH>    sCongestion;
 | |
|     StringStorage<MAX_PFILTER_LENGTH> sPacketFilterConfig;
 | |
|     StringStorage<MAX_SID_LENGTH>     sStreamName;
 | |
| 
 | |
|     // Shortcuts and utilities
 | |
|     int32_t flightCapacity()
 | |
|     {
 | |
|         return std::min(iRcvBufSize, iFlightFlagSize);
 | |
|     }
 | |
| 
 | |
|     CSrtConfig()
 | |
|         : iMSS(DEF_MSS)
 | |
|         , zExpPayloadSize(SRT_LIVE_DEF_PLSIZE)
 | |
|         , bSynSending(true)
 | |
|         , bSynRecving(true)
 | |
|         , iFlightFlagSize(DEF_FLIGHT_SIZE)
 | |
|         , iSndBufSize(DEF_BUFFER_SIZE)
 | |
|         , iRcvBufSize(DEF_BUFFER_SIZE)
 | |
|         , bRendezvous(false)
 | |
|         , tdConnTimeOut(srt::sync::seconds_from(DEF_CONNTIMEO_S))
 | |
|         , bDriftTracer(true)
 | |
|         , iSndTimeOut(-1)
 | |
|         , iRcvTimeOut(-1)
 | |
|         , llMaxBW(-1)
 | |
| #ifdef ENABLE_MAXREXMITBW
 | |
|         , llMaxRexmitBW(-1)
 | |
| #endif
 | |
|         , bDataSender(false)
 | |
|         , bMessageAPI(true)
 | |
|         , bTSBPD(true)
 | |
|         , iRcvLatency(SRT_LIVE_DEF_LATENCY_MS)
 | |
|         , iPeerLatency(0)
 | |
|         , bTLPktDrop(true)
 | |
|         , iSndDropDelay(0)
 | |
|         , bEnforcedEnc(true)
 | |
|         , iGroupConnect(0)
 | |
|         , iPeerIdleTimeout_ms(COMM_RESPONSE_TIMEOUT_MS)
 | |
|         , uMinStabilityTimeout_ms(COMM_DEF_MIN_STABILITY_TIMEOUT_MS)
 | |
|         , iRetransmitAlgo(1)
 | |
|         , iCryptoMode(CIPHER_MODE_AUTO)
 | |
|         , llInputBW(0)
 | |
|         , llMinInputBW(0)
 | |
|         , iOverheadBW(25)
 | |
|         , bRcvNakReport(true)
 | |
|         , iMaxReorderTolerance(0) // Sensible optimal value is 10, 0 preserves old behavior
 | |
|         , uKmRefreshRatePkt(0)
 | |
|         , uKmPreAnnouncePkt(0)
 | |
|         , uSrtVersion(SRT_DEF_VERSION)
 | |
|         , uMinimumPeerSrtVersion(SRT_VERSION_MAJ1)
 | |
| 
 | |
|     {
 | |
|         // Default UDT configurations
 | |
|         iUDPRcvBufSize = iRcvBufSize * iMSS;
 | |
| 
 | |
|         // Linger: LIVE mode defaults, please refer to `SRTO_TRANSTYPE` option
 | |
|         // for other modes.
 | |
|         Linger.l_onoff   = 0;
 | |
|         Linger.l_linger  = 0;
 | |
|         CryptoSecret.len = 0;
 | |
|         iSndCryptoKeyLen = 0;
 | |
| 
 | |
|         // Default congestion is "live".
 | |
|         // Available builtin congestions: "file".
 | |
|         // Others can be registerred.
 | |
|         sCongestion.set("live", 4);
 | |
|     }
 | |
| 
 | |
|     ~CSrtConfig()
 | |
|     {
 | |
|         // Wipeout critical data
 | |
|         memset(&CryptoSecret, 0, sizeof(CryptoSecret));
 | |
|     }
 | |
| 
 | |
|     int set(SRT_SOCKOPT optName, const void* val, int size);
 | |
| };
 | |
| 
 | |
| template <typename T>
 | |
| inline T cast_optval(const void* optval)
 | |
| {
 | |
|     return *reinterpret_cast<const T*>(optval);
 | |
| }
 | |
| 
 | |
| template <typename T>
 | |
| inline T cast_optval(const void* optval, int optlen)
 | |
| {
 | |
|     if (optlen > 0 && optlen != sizeof(T))
 | |
|         throw CUDTException(MJ_NOTSUP, MN_INVAL, 0);
 | |
| 
 | |
|     return cast_optval<T>(optval);
 | |
| }
 | |
| 
 | |
| // This function is to make it possible for both C and C++
 | |
| // API to accept both bool and int types for boolean options.
 | |
| // (it's not that C couldn't use <stdbool.h>, it's that people
 | |
| // often forget to use correct type).
 | |
| template <>
 | |
| inline bool cast_optval(const void* optval, int optlen)
 | |
| {
 | |
|     if (optlen == sizeof(bool))
 | |
|     {
 | |
|         return *reinterpret_cast<const bool*>(optval);
 | |
|     }
 | |
| 
 | |
|     if (optlen == sizeof(int))
 | |
|     {
 | |
|         // 0!= is a windows warning-killer int-to-bool conversion
 | |
|         return 0 != *reinterpret_cast<const int*>(optval);
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| } // namespace srt
 | |
| 
 | |
| struct SRT_SocketOptionObject
 | |
| {
 | |
|     struct SingleOption
 | |
|     {
 | |
|         uint16_t      option;
 | |
|         uint16_t      length;
 | |
|         unsigned char storage[1]; // NOTE: Variable length object!
 | |
|     };
 | |
| 
 | |
|     std::vector<SingleOption*> options;
 | |
| 
 | |
|     SRT_SocketOptionObject() {}
 | |
| 
 | |
|     ~SRT_SocketOptionObject()
 | |
|     {
 | |
|         for (size_t i = 0; i < options.size(); ++i)
 | |
|         {
 | |
|             // Convert back
 | |
|             unsigned char* mem = reinterpret_cast<unsigned char*>(options[i]);
 | |
|             delete[] mem;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     bool add(SRT_SOCKOPT optname, const void* optval, size_t optlen);
 | |
| };
 | |
| 
 | |
| #endif
 |