diff --git a/Hash2Pub/src/Hash2Pub/ASN1Coding.hs b/Hash2Pub/src/Hash2Pub/ASN1Coding.hs index b5f1019..cbe45c9 100644 --- a/Hash2Pub/src/Hash2Pub/ASN1Coding.hs +++ b/Hash2Pub/src/Hash2Pub/ASN1Coding.hs @@ -20,6 +20,8 @@ import Hash2Pub.FediChord import Hash2Pub.Utils import Hash2Pub.DHTProtocol (QueryResponse (..)) +import Debug.Trace (trace) + data Action = QueryID | Join @@ -270,6 +272,7 @@ encodeMessage IntVal parts , IntVal part ] ++ encodePayload requestPayload + ++ [End Sequence] encodeMessage (Response responseTo senderID parts part action responsePayload) = [ Start Sequence @@ -279,6 +282,7 @@ encodeMessage , IntVal part , Enumerated . fromIntegral . fromEnum $ action] ++ encodePayload responsePayload + ++ [End Sequence] -- ===== parser combinators ===== @@ -290,11 +294,19 @@ parseMessage = do x -> throwParseError $ "unexpected ASN.1 element " ++ show x -- request and response messages are distiguishable by their structure, -- see ASN.1 schema - first <- getNext - case first of + firstElem <- getNext + message <- case firstElem of Enumerated a -> parseRequest . toEnum . fromIntegral $ a IntVal i -> parseResponse i other -> throwParseError $ "unexpected first ASN1 element: " ++ show other + -- consume sequence end + end <- getNext + case end of + End Sequence -> return () + x -> throwParseError $ "unexpected ASN.1 element " ++ show x + return message + + parseRequest :: Action -> ParseASN1 FediChordMessage parseRequest action = do @@ -309,11 +321,6 @@ parseRequest action = do Leave -> parseLeaveRequest Stabilise -> parseStabiliseRequest Ping -> parsePingRequest - -- consume sequence end - end <- getNext - case end of - End Sequence -> return () - x -> throwParseError $ "unexpected ASN.1 element " ++ show x return $ Request requestID sender parts part action payload @@ -374,7 +381,7 @@ parseNull = do x -> throwParseError $ "Expected Null but got " ++ show x parseNodeState :: ParseASN1 NodeState -parseNodeState = do +parseNodeState = onNextContainer Sequence $ do nid' <- fromInteger <$> parseInteger domain' <- parseString ip' <- bsAsIpAddr <$> parseOctets @@ -387,17 +394,19 @@ parseNodeState = do , dhtPort = dhtPort' , apPort = if apPort' == 0 then Nothing else Just apPort' , vServerID = vServer' + , ipAddr = ip' + , internals = Nothing } parseCacheEntry :: ParseASN1 CacheEntry -parseCacheEntry = do +parseCacheEntry = onNextContainer Sequence $ do node <- parseNodeState timestamp <- toEnum . fromIntegral <$> parseInteger return $ NodeEntry False node timestamp parseNodeCache :: ParseASN1 [CacheEntry] -parseNodeCache = getMany parseCacheEntry +parseNodeCache = onNextContainer Sequence $ getMany parseCacheEntry parseJoinRequest :: ParseASN1 ActionPayload parseJoinRequest = do @@ -430,6 +439,7 @@ parseQueryIDResponse = do result <- case resultType of 0 -> FOUND <$> parseNodeState 1 -> FORWARD . Set.fromList <$> parseNodeCache + _ -> throwParseError "invalid QueryIDResponse type" return $ QueryIDResponsePayload { queryResult = result }