    module Network.TLS.Handshake (
        handshake_,
        handshakeWith,
        handshakeClientWith,
        handshakeServerWith,
        handshakeClient,
        handshakeServer,
    ) where

    import Network.TLS.Context.Internal
    import Network.TLS.Struct

    import Network.TLS.Handshake.Client
    import Network.TLS.Handshake.Common
    import Network.TLS.Handshake.Server

    import Control.Monad.State.Strict

    handshake_ :: MonadIO m => Context -> m ()
    handshake_ :: forall (m :: * -> *). MonadIO m => Context -> m ()
    handshake_ Context
    ctx =
        IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $
            Context -> IO () -> IO ()
    forall a. Context -> IO a -> IO a
    withRWLock Context
    ctx (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                Context -> IO () -> IO ()
    handleException Context
    ctx (RoleParams -> Context -> IO ()
    doHandshake_ (Context -> RoleParams
    ctxRoleParams Context
    ctx) Context
    ctx)

    -- Handshake when requested by the remote end
    -- This is called automatically by 'recvData', in a context where the read lock
    -- is already taken.  So contrary to 'handshake' above, here we only need to
    -- call withWriteLock.
    handshakeWith :: MonadIO m => Context -> Handshake -> m ()
    handshakeWith :: forall (m :: * -> *). MonadIO m => Context -> Handshake -> m ()
    handshakeWith Context
    ctx Handshake
    hs =
        IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $
            Context -> IO () -> IO ()
    forall a. Context -> IO a -> IO a
    withWriteLock Context
    ctx (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                Context -> IO () -> IO ()
    handleException Context
    ctx (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
                    RoleParams -> Context -> Handshake -> IO ()
    doHandshakeWith_ (Context -> RoleParams
    ctxRoleParams Context
    ctx) Context
    ctx Handshake
    hs