errorcode.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package stun
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. )
  7. // ErrorCodeAttribute represents ERROR-CODE attribute.
  8. //
  9. // RFC 5389 Section 15.6
  10. type ErrorCodeAttribute struct {
  11. Code ErrorCode
  12. Reason []byte
  13. }
  14. func (c ErrorCodeAttribute) String() string {
  15. return fmt.Sprintf("%d: %s", c.Code, c.Reason)
  16. }
  17. // constants for ERROR-CODE encoding.
  18. const (
  19. errorCodeReasonStart = 4
  20. errorCodeClassByte = 2
  21. errorCodeNumberByte = 3
  22. errorCodeReasonMaxB = 763
  23. errorCodeModulo = 100
  24. )
  25. // AddTo adds ERROR-CODE to m.
  26. func (c ErrorCodeAttribute) AddTo(m *Message) error {
  27. value := make([]byte, 0, errorCodeReasonStart+errorCodeReasonMaxB)
  28. if err := CheckOverflow(AttrErrorCode,
  29. len(c.Reason)+errorCodeReasonStart,
  30. errorCodeReasonMaxB+errorCodeReasonStart,
  31. ); err != nil {
  32. return err
  33. }
  34. value = value[:errorCodeReasonStart+len(c.Reason)]
  35. number := byte(c.Code % errorCodeModulo) // error code modulo 100
  36. class := byte(c.Code / errorCodeModulo) // hundred digit
  37. value[errorCodeClassByte] = class
  38. value[errorCodeNumberByte] = number
  39. copy(value[errorCodeReasonStart:], c.Reason)
  40. m.Add(AttrErrorCode, value)
  41. return nil
  42. }
  43. // GetFrom decodes ERROR-CODE from m. Reason is valid until m.Raw is valid.
  44. func (c *ErrorCodeAttribute) GetFrom(m *Message) error {
  45. v, err := m.Get(AttrErrorCode)
  46. if err != nil {
  47. return err
  48. }
  49. if len(v) < errorCodeReasonStart {
  50. return io.ErrUnexpectedEOF
  51. }
  52. var (
  53. class = uint16(v[errorCodeClassByte])
  54. number = uint16(v[errorCodeNumberByte])
  55. code = int(class*errorCodeModulo + number)
  56. )
  57. c.Code = ErrorCode(code)
  58. c.Reason = v[errorCodeReasonStart:]
  59. return nil
  60. }
  61. // ErrorCode is code for ERROR-CODE attribute.
  62. type ErrorCode int
  63. // ErrNoDefaultReason means that default reason for provided error code
  64. // is not defined in RFC.
  65. var ErrNoDefaultReason = errors.New("no default reason for ErrorCode")
  66. // AddTo adds ERROR-CODE with default reason to m. If there
  67. // is no default reason, returns ErrNoDefaultReason.
  68. func (c ErrorCode) AddTo(m *Message) error {
  69. reason := errorReasons[c]
  70. if reason == nil {
  71. return ErrNoDefaultReason
  72. }
  73. a := &ErrorCodeAttribute{
  74. Code: c,
  75. Reason: reason,
  76. }
  77. return a.AddTo(m)
  78. }
  79. // Possible error codes.
  80. const (
  81. CodeTryAlternate ErrorCode = 300
  82. CodeBadRequest ErrorCode = 400
  83. CodeUnauthorized ErrorCode = 401
  84. CodeUnknownAttribute ErrorCode = 420
  85. CodeStaleNonce ErrorCode = 438
  86. CodeRoleConflict ErrorCode = 487
  87. CodeServerError ErrorCode = 500
  88. )
  89. // DEPRECATED constants.
  90. const (
  91. // DEPRECATED, use CodeUnauthorized.
  92. CodeUnauthorised = CodeUnauthorized
  93. )
  94. // Error codes from RFC 5766.
  95. //
  96. // RFC 5766 Section 15
  97. const (
  98. CodeForbidden ErrorCode = 403 // Forbidden
  99. CodeAllocMismatch ErrorCode = 437 // Allocation Mismatch
  100. CodeWrongCredentials ErrorCode = 441 // Wrong Credentials
  101. CodeUnsupportedTransProto ErrorCode = 442 // Unsupported Transport Protocol
  102. CodeAllocQuotaReached ErrorCode = 486 // Allocation Quota Reached
  103. CodeInsufficientCapacity ErrorCode = 508 // Insufficient Capacity
  104. )
  105. // Error codes from RFC 6062.
  106. //
  107. // RFC 6062 Section 6.3
  108. const (
  109. CodeConnAlreadyExists ErrorCode = 446
  110. CodeConnTimeoutOrFailure ErrorCode = 447
  111. )
  112. // Error codes from RFC 6156.
  113. //
  114. // RFC 6156 Section 10.2
  115. const (
  116. CodeAddrFamilyNotSupported ErrorCode = 440 // Address Family not Supported
  117. CodePeerAddrFamilyMismatch ErrorCode = 443 // Peer Address Family Mismatch
  118. )
  119. var errorReasons = map[ErrorCode][]byte{
  120. CodeTryAlternate: []byte("Try Alternate"),
  121. CodeBadRequest: []byte("Bad Request"),
  122. CodeUnauthorized: []byte("Unauthorized"),
  123. CodeUnknownAttribute: []byte("Unknown Attribute"),
  124. CodeStaleNonce: []byte("Stale Nonce"),
  125. CodeServerError: []byte("Server Error"),
  126. CodeRoleConflict: []byte("Role Conflict"),
  127. // RFC 5766.
  128. CodeForbidden: []byte("Forbidden"),
  129. CodeAllocMismatch: []byte("Allocation Mismatch"),
  130. CodeWrongCredentials: []byte("Wrong Credentials"),
  131. CodeUnsupportedTransProto: []byte("Unsupported Transport Protocol"),
  132. CodeAllocQuotaReached: []byte("Allocation Quota Reached"),
  133. CodeInsufficientCapacity: []byte("Insufficient Capacity"),
  134. // RFC 6062.
  135. CodeConnAlreadyExists: []byte("Connection Already Exists"),
  136. CodeConnTimeoutOrFailure: []byte("Connection Timeout or Failure"),
  137. // RFC 6156.
  138. CodeAddrFamilyNotSupported: []byte("Address Family not Supported"),
  139. CodePeerAddrFamilyMismatch: []byte("Peer Address Family Mismatch"),
  140. }