diff --git a/api/stun1.txt b/api/stun1.txt index 8bd0929..bbd7aa7 100644 --- a/api/stun1.txt +++ b/api/stun1.txt @@ -175,7 +175,6 @@ pkg github.com/gortc/stun, method (AttrType) Required() bool pkg github.com/gortc/stun, method (AttrType) String() string pkg github.com/gortc/stun, method (AttrType) Value() uint16 pkg github.com/gortc/stun, method (Attributes) Get(AttrType) (RawAttribute, bool) -pkg github.com/gortc/stun, method (CRCMismatch) Error() string pkg github.com/gortc/stun, method (CloseErr) Error() string pkg github.com/gortc/stun, method (DecodeErr) Error() string pkg github.com/gortc/stun, method (DecodeErr) IsInvalidCookie() bool @@ -231,9 +230,6 @@ pkg github.com/gortc/stun, type AttrOverflowErr struct, Max int pkg github.com/gortc/stun, type AttrOverflowErr struct, Type AttrType pkg github.com/gortc/stun, type AttrType uint16 pkg github.com/gortc/stun, type Attributes []RawAttribute -pkg github.com/gortc/stun, type CRCMismatch struct -pkg github.com/gortc/stun, type CRCMismatch struct, Actual uint32 -pkg github.com/gortc/stun, type CRCMismatch struct, Expected uint32 pkg github.com/gortc/stun, type Checker interface { Check } pkg github.com/gortc/stun, type Checker interface, Check(*Message) error pkg github.com/gortc/stun, type Client struct @@ -318,6 +314,7 @@ pkg github.com/gortc/stun, var ErrClientClosed error pkg github.com/gortc/stun, var ErrClientNotInitialized error pkg github.com/gortc/stun, var ErrDecodeToNil error pkg github.com/gortc/stun, var ErrFingerprintBeforeIntegrity error +pkg github.com/gortc/stun, var ErrFingerprintMismatch error pkg github.com/gortc/stun, var ErrIntegrityMismatch error pkg github.com/gortc/stun, var ErrNoConnection error pkg github.com/gortc/stun, var ErrNoDefaultReason error diff --git a/checks.go b/checks.go index 10e604d..572de48 100644 --- a/checks.go +++ b/checks.go @@ -18,3 +18,10 @@ func checkHMAC(got, expected []byte) error { } return ErrIntegrityMismatch } + +func checkFingerprint(got, expected uint32) error { + if got == expected { + return nil + } + return ErrFingerprintMismatch +} diff --git a/checks_debug.go b/checks_debug.go index 4a1a73f..044a682 100644 --- a/checks_debug.go +++ b/checks_debug.go @@ -25,3 +25,13 @@ func checkHMAC(got, expected []byte) error { Actual: got, } } + +func checkFingerprint(got, expected uint32) error { + if got == expected { + return nil + } + return &CRCMismatch{ + Actual: got, + Expected: expected, + } +} diff --git a/fingerprint.go b/fingerprint.go index a8c5d16..9777bb2 100644 --- a/fingerprint.go +++ b/fingerprint.go @@ -1,7 +1,7 @@ package stun import ( - "fmt" + "errors" "hash/crc32" ) @@ -10,18 +10,8 @@ import ( // RFC 5389 Section 15.5 type FingerprintAttr struct{} -// CRCMismatch represents CRC check error. -type CRCMismatch struct { - Expected uint32 - Actual uint32 -} - -func (m CRCMismatch) Error() string { - return fmt.Sprintf("CRC mismatch: %x (expected) != %x (actual)", - m.Expected, - m.Actual, - ) -} +// ErrFingerprintMismatch means that computed fingerprint differs from expected. +var ErrFingerprintMismatch = errors.New("fingerprint check failed") // Fingerprint is shorthand for FingerprintAttr. // @@ -73,8 +63,5 @@ func (FingerprintAttr) Check(m *Message) error { val := bin.Uint32(b) attrStart := len(m.Raw) - (fingerprintSize + attributeHeaderSize) expected := FingerprintValue(m.Raw[:attrStart]) - if expected != val { - return &CRCMismatch{Expected: expected, Actual: val} - } - return nil + return checkFingerprint(val, expected) } diff --git a/fingerprint_debug.go b/fingerprint_debug.go new file mode 100644 index 0000000..6da074c --- /dev/null +++ b/fingerprint_debug.go @@ -0,0 +1,18 @@ +// +build debug + +package stun + +import "fmt" + +// CRCMismatch represents CRC check error. +type CRCMismatch struct { + Expected uint32 + Actual uint32 +} + +func (m CRCMismatch) Error() string { + return fmt.Sprintf("CRC mismatch: %x (expected) != %x (actual)", + m.Expected, + m.Actual, + ) +} diff --git a/fingerprint_test.go b/fingerprint_test.go index 52e291f..f2eb7b5 100644 --- a/fingerprint_test.go +++ b/fingerprint_test.go @@ -34,8 +34,8 @@ func TestFingerprint_Check(t *testing.T) { t.Error(err) } m.Raw[3] = m.Raw[3] + 1 - if err, ok := Fingerprint.Check(m).(*CRCMismatch); !ok { - t.Error(err, "should be *CRCMissmatch") + if err := Fingerprint.Check(m); err == nil { + t.Error("should error") } } diff --git a/message_test.go b/message_test.go index 7e16edc..5dfaf06 100644 --- a/message_test.go +++ b/message_test.go @@ -706,7 +706,11 @@ func ExampleMessage() { } fmt.Println("for corrupted message:") decoded.Raw[22] = 33 - fmt.Println("fingerprint:", Fingerprint.Check(decoded)) + if Fingerprint.Check(decoded) == nil { + fmt.Println("fingerprint: ok") + } else { + fmt.Println("fingerprint: failed") + } // Output: // binding request l=48 attrs=3 id=AQIDBAUGBwgJAAEA buff length: 68 @@ -717,7 +721,7 @@ func ExampleMessage() { // fingerprint is correct // integrity ok // for corrupted message: - // fingerprint: CRC mismatch: b36d2c38 (expected) != 8ef13141 (actual) + // fingerprint: failed } func TestAllocations(t *testing.T) {