mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			67 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package stun
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"hash/crc32"
 | 
						|
)
 | 
						|
 | 
						|
// FingerprintAttr represents FINGERPRINT attribute.
 | 
						|
//
 | 
						|
// RFC 5389 Section 15.5
 | 
						|
type FingerprintAttr struct{}
 | 
						|
 | 
						|
// ErrFingerprintMismatch means that computed fingerprint differs from expected.
 | 
						|
var ErrFingerprintMismatch = errors.New("fingerprint check failed")
 | 
						|
 | 
						|
// Fingerprint is shorthand for FingerprintAttr.
 | 
						|
//
 | 
						|
// Example:
 | 
						|
//
 | 
						|
//  m := New()
 | 
						|
//  Fingerprint.AddTo(m)
 | 
						|
var Fingerprint FingerprintAttr
 | 
						|
 | 
						|
const (
 | 
						|
	fingerprintXORValue uint32 = 0x5354554e //nolint:staticcheck
 | 
						|
	fingerprintSize            = 4          // 32 bit
 | 
						|
)
 | 
						|
 | 
						|
// FingerprintValue returns CRC-32 of b XOR-ed by 0x5354554e.
 | 
						|
//
 | 
						|
// The value of the attribute is computed as the CRC-32 of the STUN message
 | 
						|
// up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
 | 
						|
// the 32-bit value 0x5354554e (the XOR helps in cases where an
 | 
						|
// application packet is also using CRC-32 in it).
 | 
						|
func FingerprintValue(b []byte) uint32 {
 | 
						|
	return crc32.ChecksumIEEE(b) ^ fingerprintXORValue // XOR
 | 
						|
}
 | 
						|
 | 
						|
// AddTo adds fingerprint to message.
 | 
						|
func (FingerprintAttr) AddTo(m *Message) error {
 | 
						|
	l := m.Length
 | 
						|
	// length in header should include size of fingerprint attribute
 | 
						|
	m.Length += fingerprintSize + attributeHeaderSize // increasing length
 | 
						|
	m.WriteLength()                                   // writing Length to Raw
 | 
						|
	b := make([]byte, fingerprintSize)
 | 
						|
	val := FingerprintValue(m.Raw)
 | 
						|
	bin.PutUint32(b, val)
 | 
						|
	m.Length = l
 | 
						|
	m.Add(AttrFingerprint, b)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Check reads fingerprint value from m and checks it, returning error if any.
 | 
						|
// Can return *AttrLengthErr, ErrAttributeNotFound, and *CRCMismatch.
 | 
						|
func (FingerprintAttr) Check(m *Message) error {
 | 
						|
	b, err := m.Get(AttrFingerprint)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if err = CheckSize(AttrFingerprint, len(b), fingerprintSize); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	val := bin.Uint32(b)
 | 
						|
	attrStart := len(m.Raw) - (fingerprintSize + attributeHeaderSize)
 | 
						|
	expected := FingerprintValue(m.Raw[:attrStart])
 | 
						|
	return checkFingerprint(val, expected)
 | 
						|
}
 |