module Network.TLS.Record.Writing
( encodeRecord
, encodeRecord13
, sendBytes
) where
import Network.TLS.Cap
import Network.TLS.Cipher
import Network.TLS.Context.Internal
import Network.TLS.Hooks
import Network.TLS.Imports
import Network.TLS.Packet
import Network.TLS.Parameters
import Network.TLS.Record
import Network.TLS.State
import Network.TLS.Struct
import Control.Concurrent.MVar
import Control.Monad.State.Strict
import qualified Data.ByteString as B
encodeRecord :: Context -> Record Plaintext -> IO (Either TLSError ByteString)
encodeRecord ctx = prepareRecord ctx . encodeRecordM
prepareRecord :: Context -> RecordM a -> IO (Either TLSError a)
prepareRecord ctx f = do
ver <- usingState_ ctx (getVersionWithDefault $ maximum $ supportedVersions $ ctxSupported ctx)
txState <- readMVar $ ctxTxState ctx
let sz = case stCipher txState of
Nothing -> 0
Just cipher -> if hasRecordIV $ bulkF $ cipherBulk cipher
then bulkIVSize $ cipherBulk cipher
else 0
if hasExplicitBlockIV ver && sz > 0
then do newIV <- getStateRNG ctx sz
runTxState ctx (modify (setRecordIV newIV) >> f)
else runTxState ctx f
encodeRecordM :: Record Plaintext -> RecordM ByteString
encodeRecordM record = do
erecord <- engageRecord record
let (hdr, content) = recordToRaw erecord
return $ B.concat [ encodeHeader hdr, content ]
encodeRecord13 :: Context -> Record Plaintext -> IO (Either TLSError ByteString)
encodeRecord13 ctx = prepareRecord13 ctx . encodeRecordM
prepareRecord13 :: Context -> RecordM a -> IO (Either TLSError a)
prepareRecord13 = runTxState
sendBytes :: Context -> ByteString -> IO ()
sendBytes ctx dataToSend = do
withLog ctx $ \logging -> loggingIOSent logging dataToSend
contextSend ctx dataToSend