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.Socket (sockPutS, sockGetS)
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.ProtoVersion (ProtoVersion(..), ourProtoVersion)
import System.Nix.Store.Remote.Types.StoreConfig (PreStoreConfig, StoreConfig, preStoreConfigToStoreConfig)
@ -177,16 +177,23 @@ runStoreSocket
-> Run m a
runStoreSocket preStoreConfig code =
runRemoteStoreT preStoreConfig $ do
Handshake{..} <- greet
ClientHandshakeOutput{..}
<- greet
ClientHandshakeInput
{ clientHandshakeInputOurVersion = ourProtoVersion
}
mapStoreConfig
(preStoreConfigToStoreConfig handshakeProtoVersion)
(preStoreConfigToStoreConfig
clientHandshakeOutputLeastCommonVerison)
code
where
greet
:: MonadIO m
=> RemoteStoreT PreStoreConfig m Handshake
greet = do
=> ClientHandshakeInput
-> RemoteStoreT PreStoreConfig m ClientHandshakeOutput
greet ClientHandshakeInput{..} = do
sockPutS
(mapErrorS
@ -210,19 +217,19 @@ runStoreSocket preStoreConfig code =
when (daemonVersion < ProtoVersion 1 10)
$ 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
when (minimumCommonVersion >= ProtoVersion 1 11) $ do
when (leastCommonVersion >= ProtoVersion 1 11) $ do
sockPutS
(mapErrorS RemoteStoreError_SerializerPut bool)
False -- reserveSpace, obsolete
daemonNixVersion <- if minimumCommonVersion >= ProtoVersion 1 33
daemonNixVersion <- if leastCommonVersion >= ProtoVersion 1 33
then do
-- If we were buffering I/O, we would flush the output here.
txtVer <-
@ -233,19 +240,19 @@ runStoreSocket preStoreConfig code =
pure $ Just txtVer
else pure Nothing
remoteTrustsUs <- if minimumCommonVersion >= ProtoVersion 1 35
remoteTrustsUs <- if leastCommonVersion >= ProtoVersion 1 35
then do
sockGetS
$ mapErrorS RemoteStoreError_SerializerHandshake trustedFlag
else pure Nothing
mapStoreConfig
(preStoreConfigToStoreConfig minimumCommonVersion)
(preStoreConfigToStoreConfig leastCommonVersion)
processOutput
pure Handshake
{ handshakeNixVersion = daemonNixVersion
, handshakeTrust = remoteTrustsUs
, handshakeProtoVersion = minimumCommonVersion
, handshakeRemoteProtoVersion = daemonVersion
pure ClientHandshakeOutput
{ clientHandshakeOutputNixVersion = daemonNixVersion
, clientHandshakeOutputTrust = remoteTrustsUs
, clientHandshakeOutputLeastCommonVerison = leastCommonVersion
, 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.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.WorkerMagic (WorkerMagic(..))
@ -79,28 +79,26 @@ processConnection
-> PreStoreConfig
-> m ()
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
minimumCommonVersion <- greet handshake
ServerHandshakeOutput{..}
<- greet
ServerHandshakeInput
{ serverHandshakeInputNixVersion = "nixVersion (hnix-store-remote)"
, serverHandshakeInputOurVersion= ourProtoVersion
, serverHandshakeInputTrust = Nothing
}
mapStoreConfig
(preStoreConfigToStoreConfig minimumCommonVersion)
(preStoreConfigToStoreConfig
serverHandshakeOutputLeastCommonVersion)
$ do
tunnelLogger <- liftIO $ newTunnelLogger
-- Send startup error messages to the client.
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).
--authHook(*store);
stopWork tunnelLogger
@ -124,9 +122,9 @@ processConnection workerHelper preStoreConfig = do
-- Exchange the greeting.
greet
:: MonadIO m
=> Handshake
-> RemoteStoreT PreStoreConfig m ProtoVersion
greet Handshake{..} = do
=> ServerHandshakeInput
-> RemoteStoreT PreStoreConfig m ServerHandshakeOutput
greet ServerHandshakeInput{..} = do
magic <-
sockGetS
$ mapErrorS
@ -135,7 +133,9 @@ processConnection workerHelper preStoreConfig = do
liftIO $ print ("magic" :: Text, magic)
when (magic /= WorkerMagic_One)
$ throwError $ RemoteStoreError_WorkerException WorkerException_ProtocolMismatch
$ throwError
$ RemoteStoreError_WorkerException
WorkerException_ProtocolMismatch
sockPutS
(mapErrorS
@ -144,13 +144,13 @@ processConnection workerHelper preStoreConfig = do
)
WorkerMagic_Two
sockPutS protoVersion ourProtoVersion
sockPutS protoVersion serverHandshakeInputOurVersion
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)
$ throwError
@ -174,8 +174,7 @@ processConnection workerHelper preStoreConfig = do
RemoteStoreError_SerializerPut
text
)
-- TODO
(maybe undefined id handshakeNixVersion)
serverHandshakeInputNixVersion
when (clientVersion >= ProtoVersion 1 35) $ do
sockPutS
@ -183,9 +182,12 @@ processConnection workerHelper preStoreConfig = do
RemoteStoreError_SerializerHandshake
trustedFlag
)
handshakeTrust
serverHandshakeInputTrust
pure minimumCommonVersion
pure ServerHandshakeOutput
{ serverHandshakeOutputLeastCommonVersion = leastCommonVersion
, serverHandshakeOutputClientVersion = clientVersion
}
simpleOp
:: ( MonadIO m

View File

@ -1,5 +1,8 @@
module System.Nix.Store.Remote.Types.Handshake
( Handshake(..)
( ClientHandshakeInput(..)
, ClientHandshakeOutput(..)
, ServerHandshakeInput(..)
, ServerHandshakeOutput(..)
) where
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.TrustedFlag (TrustedFlag)
-- | Data for initial protocol handshake
data Handshake = Handshake
{ handshakeNixVersion :: Maybe Text -- ^ Textual version, since 1.33
, handshakeTrust :: Maybe TrustedFlag -- ^ Whether remote side trusts us
, handshakeProtoVersion :: ProtoVersion -- ^ Minimum protocol supported by both sides
, handshakeRemoteProtoVersion :: ProtoVersion -- ^ Protocol supported by remote side
}
deriving (Eq, Generic, Ord, Show)
-- | Data sent by the client during initial protocol handshake
data ClientHandshakeInput = ClientHandshakeInput
{ clientHandshakeInputOurVersion :: ProtoVersion -- ^ Our protocol version (that we advertise to the server)
} deriving (Eq, Generic, Ord, Show)
-- | Data received by the client via initial protocol handshake
data ClientHandshakeOutput = ClientHandshakeOutput
{ 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)