remote: separate (Client|Server)Handshake(Input|Output) types

This commit is contained in:
sorki 2023-12-07 07:08:54 +01:00
parent bdce1a3035
commit aa94d3c3da
3 changed files with 79 additions and 50 deletions

View File

@ -30,7 +30,7 @@ import System.Nix.Store.Remote.Logger (processOutput)
import System.Nix.Store.Remote.MonadStore import System.Nix.Store.Remote.MonadStore
import System.Nix.Store.Remote.Socket (sockPutS, sockGetS) import System.Nix.Store.Remote.Socket (sockPutS, sockGetS)
import System.Nix.Store.Remote.Serializer (bool, enum, int, mapErrorS, protoVersion, storeRequest, text, trustedFlag, workerMagic) import System.Nix.Store.Remote.Serializer (bool, enum, int, mapErrorS, protoVersion, storeRequest, text, trustedFlag, workerMagic)
import System.Nix.Store.Remote.Types.Handshake (Handshake(..)) import System.Nix.Store.Remote.Types.Handshake (ClientHandshakeInput(..), ClientHandshakeOutput(..))
import System.Nix.Store.Remote.Types.Logger (Logger) import System.Nix.Store.Remote.Types.Logger (Logger)
import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion(..), ourProtoVersion) import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion(..), ourProtoVersion)
import System.Nix.Store.Remote.Types.StoreConfig (PreStoreConfig, StoreConfig, preStoreConfigToStoreConfig) import System.Nix.Store.Remote.Types.StoreConfig (PreStoreConfig, StoreConfig, preStoreConfigToStoreConfig)
@ -177,16 +177,23 @@ runStoreSocket
-> Run m a -> Run m a
runStoreSocket preStoreConfig code = runStoreSocket preStoreConfig code =
runRemoteStoreT preStoreConfig $ do runRemoteStoreT preStoreConfig $ do
Handshake{..} <- greet ClientHandshakeOutput{..}
<- greet
ClientHandshakeInput
{ clientHandshakeInputOurVersion = ourProtoVersion
}
mapStoreConfig mapStoreConfig
(preStoreConfigToStoreConfig handshakeProtoVersion) (preStoreConfigToStoreConfig
clientHandshakeOutputLeastCommonVerison)
code code
where where
greet greet
:: MonadIO m :: MonadIO m
=> RemoteStoreT PreStoreConfig m Handshake => ClientHandshakeInput
greet = do -> RemoteStoreT PreStoreConfig m ClientHandshakeOutput
greet ClientHandshakeInput{..} = do
sockPutS sockPutS
(mapErrorS (mapErrorS
@ -210,19 +217,19 @@ runStoreSocket preStoreConfig code =
when (daemonVersion < ProtoVersion 1 10) when (daemonVersion < ProtoVersion 1 10)
$ throwError RemoteStoreError_ClientVersionTooOld $ throwError RemoteStoreError_ClientVersionTooOld
sockPutS protoVersion ourProtoVersion sockPutS protoVersion clientHandshakeInputOurVersion
let minimumCommonVersion = min daemonVersion ourProtoVersion let leastCommonVersion = min daemonVersion ourProtoVersion
when (minimumCommonVersion >= ProtoVersion 1 14) when (leastCommonVersion >= ProtoVersion 1 14)
$ sockPutS int (0 :: Int) -- affinity, obsolete $ sockPutS int (0 :: Int) -- affinity, obsolete
when (minimumCommonVersion >= ProtoVersion 1 11) $ do when (leastCommonVersion >= ProtoVersion 1 11) $ do
sockPutS sockPutS
(mapErrorS RemoteStoreError_SerializerPut bool) (mapErrorS RemoteStoreError_SerializerPut bool)
False -- reserveSpace, obsolete False -- reserveSpace, obsolete
daemonNixVersion <- if minimumCommonVersion >= ProtoVersion 1 33 daemonNixVersion <- if leastCommonVersion >= ProtoVersion 1 33
then do then do
-- If we were buffering I/O, we would flush the output here. -- If we were buffering I/O, we would flush the output here.
txtVer <- txtVer <-
@ -233,19 +240,19 @@ runStoreSocket preStoreConfig code =
pure $ Just txtVer pure $ Just txtVer
else pure Nothing else pure Nothing
remoteTrustsUs <- if minimumCommonVersion >= ProtoVersion 1 35 remoteTrustsUs <- if leastCommonVersion >= ProtoVersion 1 35
then do then do
sockGetS sockGetS
$ mapErrorS RemoteStoreError_SerializerHandshake trustedFlag $ mapErrorS RemoteStoreError_SerializerHandshake trustedFlag
else pure Nothing else pure Nothing
mapStoreConfig mapStoreConfig
(preStoreConfigToStoreConfig minimumCommonVersion) (preStoreConfigToStoreConfig leastCommonVersion)
processOutput processOutput
pure Handshake pure ClientHandshakeOutput
{ handshakeNixVersion = daemonNixVersion { clientHandshakeOutputNixVersion = daemonNixVersion
, handshakeTrust = remoteTrustsUs , clientHandshakeOutputTrust = remoteTrustsUs
, handshakeProtoVersion = minimumCommonVersion , clientHandshakeOutputLeastCommonVerison = leastCommonVersion
, handshakeRemoteProtoVersion = daemonVersion , clientHandshakeOutputServerVersion = daemonVersion
} }

View File

@ -27,7 +27,7 @@ import System.Nix.Store.Remote.Types.ProtoVersion (HasProtoVersion(..), ProtoVer
import System.Nix.Store.Remote.Types.Logger (BasicError(..), ErrorInfo, Logger(..)) import System.Nix.Store.Remote.Types.Logger (BasicError(..), ErrorInfo, Logger(..))
import System.Nix.Store.Remote.MonadStore (WorkerError(..), WorkerException(..), RemoteStoreError(..), RemoteStoreT, runRemoteStoreT, mapStoreConfig) import System.Nix.Store.Remote.MonadStore (WorkerError(..), WorkerException(..), RemoteStoreError(..), RemoteStoreT, runRemoteStoreT, mapStoreConfig)
import System.Nix.Store.Remote.Types.Handshake (Handshake(..)) import System.Nix.Store.Remote.Types.Handshake (ServerHandshakeInput(..), ServerHandshakeOutput(..))
import System.Nix.Store.Remote.Types.ProtoVersion (ourProtoVersion) import System.Nix.Store.Remote.Types.ProtoVersion (ourProtoVersion)
import System.Nix.Store.Remote.Types.WorkerMagic (WorkerMagic(..)) import System.Nix.Store.Remote.Types.WorkerMagic (WorkerMagic(..))
@ -79,28 +79,26 @@ processConnection
-> PreStoreConfig -> PreStoreConfig
-> m () -> m ()
processConnection workerHelper preStoreConfig = do processConnection workerHelper preStoreConfig = do
let handshake = Handshake
{ handshakeNixVersion = Just "nixVersion (hnix-store-remote)"
, handshakeTrust = Nothing
-- TODO: doesn't make sense for server
, handshakeProtoVersion = ourProtoVersion
-- TODO: doesn't make sense for server
, handshakeRemoteProtoVersion = ourProtoVersion
}
~() <- void $ runRemoteStoreT preStoreConfig $ do ~() <- void $ runRemoteStoreT preStoreConfig $ do
minimumCommonVersion <- greet handshake ServerHandshakeOutput{..}
<- greet
ServerHandshakeInput
{ serverHandshakeInputNixVersion = "nixVersion (hnix-store-remote)"
, serverHandshakeInputOurVersion= ourProtoVersion
, serverHandshakeInputTrust = Nothing
}
mapStoreConfig mapStoreConfig
(preStoreConfigToStoreConfig minimumCommonVersion) (preStoreConfigToStoreConfig
serverHandshakeOutputLeastCommonVersion)
$ do $ do
tunnelLogger <- liftIO $ newTunnelLogger tunnelLogger <- liftIO $ newTunnelLogger
-- Send startup error messages to the client. -- Send startup error messages to the client.
startWork tunnelLogger startWork tunnelLogger
-- TODO: do we need auth at all? probably? -- TODO: do we need auth at all? probably?
-- If we can't accept clientVersion, then throw an error *here* (not above). -- If we can't accept clientVersion, then throw an error *here* (not above).
--authHook(*store); --authHook(*store);
stopWork tunnelLogger stopWork tunnelLogger
@ -124,9 +122,9 @@ processConnection workerHelper preStoreConfig = do
-- Exchange the greeting. -- Exchange the greeting.
greet greet
:: MonadIO m :: MonadIO m
=> Handshake => ServerHandshakeInput
-> RemoteStoreT PreStoreConfig m ProtoVersion -> RemoteStoreT PreStoreConfig m ServerHandshakeOutput
greet Handshake{..} = do greet ServerHandshakeInput{..} = do
magic <- magic <-
sockGetS sockGetS
$ mapErrorS $ mapErrorS
@ -135,7 +133,9 @@ processConnection workerHelper preStoreConfig = do
liftIO $ print ("magic" :: Text, magic) liftIO $ print ("magic" :: Text, magic)
when (magic /= WorkerMagic_One) when (magic /= WorkerMagic_One)
$ throwError $ RemoteStoreError_WorkerException WorkerException_ProtocolMismatch $ throwError
$ RemoteStoreError_WorkerException
WorkerException_ProtocolMismatch
sockPutS sockPutS
(mapErrorS (mapErrorS
@ -144,13 +144,13 @@ processConnection workerHelper preStoreConfig = do
) )
WorkerMagic_Two WorkerMagic_Two
sockPutS protoVersion ourProtoVersion sockPutS protoVersion serverHandshakeInputOurVersion
clientVersion <- sockGetS protoVersion clientVersion <- sockGetS protoVersion
let minimumCommonVersion = min clientVersion ourProtoVersion let leastCommonVersion = min clientVersion ourProtoVersion
liftIO $ print ("Versions client, min" :: Text, clientVersion, minimumCommonVersion) liftIO $ print ("Versions client, min" :: Text, clientVersion, leastCommonVersion)
when (clientVersion < ProtoVersion 1 10) when (clientVersion < ProtoVersion 1 10)
$ throwError $ throwError
@ -174,8 +174,7 @@ processConnection workerHelper preStoreConfig = do
RemoteStoreError_SerializerPut RemoteStoreError_SerializerPut
text text
) )
-- TODO serverHandshakeInputNixVersion
(maybe undefined id handshakeNixVersion)
when (clientVersion >= ProtoVersion 1 35) $ do when (clientVersion >= ProtoVersion 1 35) $ do
sockPutS sockPutS
@ -183,9 +182,12 @@ processConnection workerHelper preStoreConfig = do
RemoteStoreError_SerializerHandshake RemoteStoreError_SerializerHandshake
trustedFlag trustedFlag
) )
handshakeTrust serverHandshakeInputTrust
pure minimumCommonVersion pure ServerHandshakeOutput
{ serverHandshakeOutputLeastCommonVersion = leastCommonVersion
, serverHandshakeOutputClientVersion = clientVersion
}
simpleOp simpleOp
:: ( MonadIO m :: ( MonadIO m

View File

@ -1,5 +1,8 @@
module System.Nix.Store.Remote.Types.Handshake module System.Nix.Store.Remote.Types.Handshake
( Handshake(..) ( ClientHandshakeInput(..)
, ClientHandshakeOutput(..)
, ServerHandshakeInput(..)
, ServerHandshakeOutput(..)
) where ) where
import Data.Text (Text) import Data.Text (Text)
@ -7,11 +10,28 @@ import GHC.Generics (Generic)
import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion) import System.Nix.Store.Remote.Types.ProtoVersion (ProtoVersion)
import System.Nix.Store.Remote.Types.TrustedFlag (TrustedFlag) import System.Nix.Store.Remote.Types.TrustedFlag (TrustedFlag)
-- | Data for initial protocol handshake -- | Data sent by the client during initial protocol handshake
data Handshake = Handshake data ClientHandshakeInput = ClientHandshakeInput
{ handshakeNixVersion :: Maybe Text -- ^ Textual version, since 1.33 { clientHandshakeInputOurVersion :: ProtoVersion -- ^ Our protocol version (that we advertise to the server)
, handshakeTrust :: Maybe TrustedFlag -- ^ Whether remote side trusts us } deriving (Eq, Generic, Ord, Show)
, handshakeProtoVersion :: ProtoVersion -- ^ Minimum protocol supported by both sides
, handshakeRemoteProtoVersion :: ProtoVersion -- ^ Protocol supported by remote side -- | Data received by the client via initial protocol handshake
} data ClientHandshakeOutput = ClientHandshakeOutput
deriving (Eq, Generic, Ord, Show) { clientHandshakeOutputNixVersion :: Maybe Text -- ^ Textual version, since 1.33
, clientHandshakeOutputTrust :: Maybe TrustedFlag -- ^ Whether remote side trusts us
, clientHandshakeOutputLeastCommonVerison :: ProtoVersion -- ^ Minimum protocol version supported by both sides
, clientHandshakeOutputServerVersion :: ProtoVersion -- ^ Protocol version supported by the server
} deriving (Eq, Generic, Ord, Show)
-- | Data sent by the server during initial protocol handshake
data ServerHandshakeInput = ServerHandshakeInput
{ serverHandshakeInputNixVersion :: Text -- ^ Textual version, since 1.33
, serverHandshakeInputOurVersion :: ProtoVersion -- ^ Our protocol version (that we advertise to the client)
, serverHandshakeInputTrust :: Maybe TrustedFlag -- ^ Whether client should trusts us
} deriving (Eq, Generic, Ord, Show)
-- | Data received by the server during initial protocol handshake
data ServerHandshakeOutput = ServerHandshakeOutput
{ serverHandshakeOutputLeastCommonVersion :: ProtoVersion -- ^ Minimum protocol version supported by both sides
, serverHandshakeOutputClientVersion :: ProtoVersion -- ^ Protocol version supported by the client
} deriving (Eq, Generic, Ord, Show)