module Network.Stun.Error where
import Control.Applicative
import Control.Monad
import Data.Bits
import Data.Serialize
import Data.Text (Text)
import qualified Data.Text.Encoding as Text
import Network.Stun.Base
data ErrorAttribute = ErrorAttribute { code :: !Int
, reason :: !Text
} deriving (Show, Eq)
instance IsAttribute ErrorAttribute where
attributeTypeValue _ = 0x0009
putErrorAttribute :: ErrorAttribute -> PutM ()
putErrorAttribute ErrorAttribute{..} = do
putWord16be 0
putWord8 (fromIntegral $ code `div` 100)
putWord8 (fromIntegral $ code `mod` 100)
putByteString $ Text.encodeUtf8 reason
getErrorAttribute :: Get ErrorAttribute
getErrorAttribute = do
skip 2
hundreds <- (fromIntegral . (0x7 .&.)) <$> getWord8
guard (hundreds >= 3 && hundreds <= 6 )
rest <- fromIntegral <$> getWord8
guard $ rest <= 99
let code = 100 * hundreds + rest
reason <- Text.decodeUtf8 <$> ensure 0
return ErrorAttribute{..}
instance Serialize ErrorAttribute where
put = putErrorAttribute
get = getErrorAttribute
errTryAlternate :: ErrorAttribute
errTryAlternate = ErrorAttribute { code = 300
, reason = "Try Alternate: The client should contact an alternate server for this request."
}
errBadRequest :: ErrorAttribute
errBadRequest = ErrorAttribute { code = 400
, reason = "Bad Request: The request was malformed."
}
errUnauthorized :: ErrorAttribute
errUnauthorized = ErrorAttribute { code = 401
, reason = "Unauthorized: The request did not contain the correct credentials to proceed."
}
errUnknownAttribute :: ErrorAttribute
errUnknownAttribute = ErrorAttribute {code = 420
, reason = "Unknown Attribute: The server received a STUN packet containing a comprehension-required attribute that it did not understand."
}
errStaleNonce :: ErrorAttribute
errStaleNonce = ErrorAttribute {code = 438
, reason = "Stale Nonce: The NONCE used by the client was no longer valid."
}
errServerError :: ErrorAttribute
errServerError = ErrorAttribute { code = 500
, reason = "Server Error: The server has suffered a temporary error."
}