From e81a4d23e790932d26494f6080407625c941fb63 Mon Sep 17 00:00:00 2001 From: Trolli Schmittlauch Date: Thu, 30 Apr 2020 23:32:16 +0200 Subject: [PATCH] make request and response distinguishable --- Hash2Pub/FediChord.asn1 | 5 +- Hash2Pub/src/Hash2Pub/ASN1Coding.hs | 71 +++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/Hash2Pub/FediChord.asn1 b/Hash2Pub/FediChord.asn1 index 7e32875..3d23fc6 100644 --- a/Hash2Pub/FediChord.asn1 +++ b/Hash2Pub/FediChord.asn1 @@ -7,11 +7,11 @@ Domain ::= VisibleString Action ::= ENUMERATED {queryID, join, leave, stabilise, ping} Request ::= SEQUENCE { + action Action, requestID INTEGER, senderID NodeID, parts INTEGER, -- number of message parts part INTEGER, -- part number of this message - action Action, actionPayload CHOICE { queryIDSendPayload QueryIDSendPayload, joinSendPayload JoinSendPayload, @@ -21,6 +21,9 @@ Request ::= SEQUENCE { } } +-- idea: different message layouts as a way of distinguishing between +-- request and response instead of explicit flag + Response ::= SEQUENCE { responseTo INTEGER, senderID NodeID, diff --git a/Hash2Pub/src/Hash2Pub/ASN1Coding.hs b/Hash2Pub/src/Hash2Pub/ASN1Coding.hs index 3c0c5fb..95acf01 100644 --- a/Hash2Pub/src/Hash2Pub/ASN1Coding.hs +++ b/Hash2Pub/src/Hash2Pub/ASN1Coding.hs @@ -114,14 +114,23 @@ encodeJoinReceivePayload succ' pred' ncache = encodeJoinSendPayload :: NodeState -> [ASN1] encodeJoinSendPayload = encodeNodeState +encodePingSendPayload :: [ASN1] +encodePingSendPayload = Null + +encodePingReceivePayload :: [NodeState] -> [ASN1] +encodePingReceivePayload nss = + Start Sequence + : concatMap encodeNodeState nss + ++ [End Sequence] + encodeRequest :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1] encodeRequest requestID senderID parts part action payload = [ Start Sequence + , Enumerated . fromIntegral . fromEnum $ action , IntVal requestID , IntVal . getNodeID $ senderID , IntVal parts - , IntVal part - , Enumerated . fromIntegral . fromEnum $ action] + , IntVal part ] ++ payload encodeResponse :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1] @@ -134,11 +143,55 @@ encodeResponse responseTo senderID parts part action payload = [ , Enumerated . fromIntegral . fromEnum $ action] ++ payload -encodePingSendPayload :: [ASN1] -encodePingSendPayload = Null +-- ===== parser combinators ===== -encodePingReceivePayload :: [NodeState] -> [ASN1] -encodePingReceivePayload nss = - Start Sequence - : concatMap encodeNodeState nss - ++ [End Sequence] +parseMessage :: ParseASN1 () -- todo: change type +parseMessage = do +-- request and response messages are distiguishable by their structure, +-- see ASN.1 schema + first <- getNext + case first of + Enumerated a -> parseRequest . toEnum $ a + IntVal i -> parseResponse i + +parseRequest :: Action -> ParseASN1 () -- todo: change type +parseRequest action = do + requestID <- parseInteger + senderID <- (fromInteger <$> parseInteger :: ParseASN1 NodeID) + parts <- parseInteger + part <- parseInteger + payload <- onNextContainer Sequence $ + case action of + QueryID -> parseQueryIDRequest + Join -> parseJoinRequest + Leave -> parseLeaveRequest + Stabilise -> parseStabiliseRequest + Ping -> parsePingRequest + + return () + +parseResponse :: Integer -> ParseASN1 () -- todo: change type +parseResponse responseTo = do + senderID <- (fromInteger <$> parseInteger :: ParseASN1 NodeID) + parts <- parseInteger + part <- parseInteger + action <- (parseEnum :: ParseASN1 Action) + payload <- onNextContainer Sequence $ + case action of + QueryID -> parseQueryIDResponse + Join -> parseJoinResponse + Leave -> parseLeaveResponse + Stabilise -> parseStabiliseResponse + Ping -> parsePingResponse + + return () + +parseInteger :: ParseASN1 Integer +parseInteger = do + IntVal parsed <- getNext + return parsed + +parseEnum :: Enum a => ParseASN1 a +parseEnum = do + Enumerated en <- getNext + return $ toEnum . fromIntegral $ en