mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			260 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
	
		
			6.5 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.
 | |
| *****************************************************************************/
 | |
| 
 | |
| #include <cstring>
 | |
| #include <string>
 | |
| #include <sstream>
 | |
| #include <iterator>
 | |
| #include <algorithm>
 | |
| 
 | |
| #include "udt.h"
 | |
| #include "core.h"
 | |
| #include "handshake.h"
 | |
| #include "utilities.h"
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| 
 | |
| CHandShake::CHandShake():
 | |
| m_iVersion(0),
 | |
| m_iType(0), // Universal: UDT_UNDEFINED or no flags
 | |
| m_iISN(0),
 | |
| m_iMSS(0),
 | |
| m_iFlightFlagSize(0),
 | |
| m_iReqType(URQ_WAVEAHAND),
 | |
| m_iID(0),
 | |
| m_iCookie(0),
 | |
| m_extension(false)
 | |
| {
 | |
|    for (int i = 0; i < 4; ++ i)
 | |
|       m_piPeerIP[i] = 0;
 | |
| }
 | |
| 
 | |
| int CHandShake::store_to(char* buf, ref_t<size_t> r_size)
 | |
| {
 | |
|    size_t& size = *r_size;
 | |
|    if (size < m_iContentSize)
 | |
|       return -1;
 | |
| 
 | |
|    int32_t* p = reinterpret_cast<int32_t*>(buf);
 | |
|    *p++ = m_iVersion;
 | |
|    *p++ = m_iType;
 | |
|    *p++ = m_iISN;
 | |
|    *p++ = m_iMSS;
 | |
|    *p++ = m_iFlightFlagSize;
 | |
|    *p++ = int32_t(m_iReqType);
 | |
|    *p++ = m_iID;
 | |
|    *p++ = m_iCookie;
 | |
|    for (int i = 0; i < 4; ++ i)
 | |
|       *p++ = m_piPeerIP[i];
 | |
| 
 | |
|    size = m_iContentSize;
 | |
| 
 | |
|    return 0;
 | |
| }
 | |
| 
 | |
| int CHandShake::load_from(const char* buf, size_t size)
 | |
| {
 | |
|    if (size < m_iContentSize)
 | |
|       return -1;
 | |
| 
 | |
|    const int32_t* p = reinterpret_cast<const int32_t*>(buf);
 | |
| 
 | |
|    m_iVersion = *p++;
 | |
|    m_iType = *p++;
 | |
|    m_iISN = *p++;
 | |
|    m_iMSS = *p++;
 | |
|    m_iFlightFlagSize = *p++;
 | |
|    m_iReqType = UDTRequestType(*p++);
 | |
|    m_iID = *p++;
 | |
|    m_iCookie = *p++;
 | |
|    for (int i = 0; i < 4; ++ i)
 | |
|       m_piPeerIP[i] = *p++;
 | |
| 
 | |
|    return 0;
 | |
| }
 | |
| 
 | |
| #ifdef ENABLE_LOGGING
 | |
| 
 | |
| const char* srt_rejectreason_name [] = {
 | |
|     "UNKNOWN",
 | |
|     "SYSTEM",
 | |
|     "PEER",
 | |
|     "RESOURCE",
 | |
|     "ROGUE",
 | |
|     "BACKLOG",
 | |
|     "IPE",
 | |
|     "CLOSE",
 | |
|     "VERSION",
 | |
|     "RDVCOOKIE",
 | |
|     "BADSECRET",
 | |
|     "UNSECURE",
 | |
|     "MESSAGEAPI",
 | |
|     "CONGESTION",
 | |
|     "FILTER",
 | |
| };
 | |
| 
 | |
| std::string RequestTypeStr(UDTRequestType rq)
 | |
| {
 | |
|     if (rq >= URQ_FAILURE_TYPES)
 | |
|     {
 | |
|         SRT_REJECT_REASON rej = RejectReasonForURQ(rq);
 | |
|         int id = rej;
 | |
|         return std::string("ERROR:") + srt_rejectreason_name[id];
 | |
|     }
 | |
| 
 | |
|     switch ( rq )
 | |
|     {
 | |
|     case URQ_INDUCTION: return "induction";
 | |
|     case URQ_WAVEAHAND: return "waveahand";
 | |
|     case URQ_CONCLUSION: return "conclusion";
 | |
|     case URQ_AGREEMENT: return "agreement";
 | |
| 
 | |
|     default: return "INVALID";
 | |
|     }
 | |
| }
 | |
| 
 | |
| string CHandShake::RdvStateStr(CHandShake::RendezvousState s)
 | |
| {
 | |
|     switch (s)
 | |
|     {
 | |
|     case RDV_WAVING: return "waving";
 | |
|     case RDV_ATTENTION: return "attention";
 | |
|     case RDV_FINE: return "fine";
 | |
|     case RDV_INITIATED: return "initiated";
 | |
|     case RDV_CONNECTED: return "connected";
 | |
|     default: ;
 | |
|     }
 | |
| 
 | |
|     return "invalid";
 | |
| }
 | |
| #endif
 | |
| 
 | |
| string CHandShake::show()
 | |
| {
 | |
|     ostringstream so;
 | |
| 
 | |
|     so << "version=" << m_iVersion << " type=" << hex << m_iType << dec
 | |
|         << " ISN=" << m_iISN << " MSS=" << m_iMSS << " FLW=" << m_iFlightFlagSize
 | |
|         << " reqtype=" << RequestTypeStr(m_iReqType) << " srcID=" << m_iID
 | |
|         << " cookie=" << hex << m_iCookie << dec
 | |
|         << " srcIP=";
 | |
| 
 | |
|     const unsigned char* p  = (const unsigned char*)m_piPeerIP;
 | |
|     const unsigned char* pe = p + 4 * (sizeof(uint32_t));
 | |
| 
 | |
|     copy(p, pe, ostream_iterator<unsigned>(so, "."));
 | |
| 
 | |
|     // XXX HS version symbols should be probably declared inside
 | |
|     // CHandShake, not CUDT.
 | |
|     if ( m_iVersion > CUDT::HS_VERSION_UDT4 )
 | |
|     {
 | |
|         so << "EXT: ";
 | |
|         if (m_iType == 0) // no flags at all
 | |
|             so << "none";
 | |
|         else
 | |
|             so << ExtensionFlagStr(m_iType);
 | |
|     }
 | |
| 
 | |
|     return so.str();
 | |
| }
 | |
| 
 | |
| string CHandShake::ExtensionFlagStr(int32_t fl)
 | |
| {
 | |
|     std::ostringstream out;
 | |
|     if ( fl & HS_EXT_HSREQ )
 | |
|         out << " hsx";
 | |
|     if ( fl & HS_EXT_KMREQ )
 | |
|         out << " kmx";
 | |
|     if ( fl & HS_EXT_CONFIG )
 | |
|         out << " config";
 | |
| 
 | |
|     int kl = SrtHSRequest::SRT_HSTYPE_ENCFLAGS::unwrap(fl) << 6;
 | |
|     if (kl != 0)
 | |
|     {
 | |
|         out << " AES-" << kl;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         out << " no-pbklen";
 | |
|     }
 | |
| 
 | |
|     return out.str();
 | |
| }
 | |
| 
 | |
| 
 | |
| // XXX This code isn't currently used. Left here because it can
 | |
| // be used in future, should any refactoring for the "manual word placement"
 | |
| // code be done.
 | |
| bool SrtHSRequest::serialize(char* buf, size_t size) const
 | |
| {
 | |
|     if (size < SRT_HS_SIZE)
 | |
|         return false;
 | |
| 
 | |
|     int32_t* p = reinterpret_cast<int32_t*>(buf);
 | |
| 
 | |
|     *p++ = m_iSrtVersion;
 | |
|     *p++ = m_iSrtFlags;
 | |
|     *p++ = m_iSrtTsbpd;
 | |
|     *p++ = 0; // SURPRISE! Seriously, use (something) if this "reserved" is going to be used for something.
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| 
 | |
| bool SrtHSRequest::deserialize(const char* buf, size_t size)
 | |
| {
 | |
|     m_iSrtVersion = 0; // just to let users recognize if it succeeded or not.
 | |
| 
 | |
|     if (size < SRT_HS_SIZE)
 | |
|         return false;
 | |
| 
 | |
|    const int32_t* p = reinterpret_cast<const int32_t*>(buf);
 | |
| 
 | |
|     m_iSrtVersion = (*p++);
 | |
|     m_iSrtFlags = (*p++);
 | |
|     m_iSrtTsbpd = (*p++);
 | |
|     m_iSrtReserved = (*p++);
 | |
|     return true;
 | |
| }
 |