@@ -20,6 +20,7 @@ import Control.Monad (unless)
2020
2121import Data.Aeson
2222import Data.Aeson.Types
23+ import Data.ByteString (ByteString )
2324import Data.ByteString.Char8 qualified as BSC
2425import Data.IP qualified as IP
2526import Data.Text qualified as Text
@@ -59,18 +60,22 @@ instance NFData RelayAccessPoint where
5960 IP. IPv4 ipv4 -> rnf (IP. fromIPv4w ipv4)
6061 IP. IPv6 ipv6 -> rnf (IP. fromIPv6w ipv6)
6162
63+ -- This instance is used to parse `RelayAccessPoint`s in topology files.
6264instance FromJSON RelayAccessPoint where
6365 parseJSON = withObject " RelayAccessPoint" $ \ o -> do
6466 addr <- encodeUtf8 <$> o .: " address"
6567 let res = flip parseMaybe o $ const do
6668 port <- o .: " port"
67- return ( toRelayAccessPoint addr port)
69+ return $ toRelayAccessPoint addr port
6870 case res of
6971 Nothing -> return $ RelayAccessSRVDomain (fullyQualified addr)
72+ Just rap@ (RelayAccessAddress addr' _) -> do
73+ unless (isValidDestinationIPAddr addr') $
74+ fail (show addr' ++ " is not a valid destination address" )
75+ return rap
7076 Just rap -> return rap
71-
7277 where
73- toRelayAccessPoint :: DNS. Domain -> Int -> RelayAccessPoint
78+ toRelayAccessPoint :: ByteString -> Int -> RelayAccessPoint
7479 toRelayAccessPoint address port =
7580 case readMaybe (BSC. unpack address) of
7681 Nothing -> RelayAccessDomain (fullyQualified address) (fromIntegral port)
@@ -79,6 +84,10 @@ instance FromJSON RelayAccessPoint where
7984 domain | Just (_, ' .' ) <- BSC. unsnoc domain -> domain
8085 | otherwise -> domain `BSC.snoc` ' .'
8186
87+ isValidDestinationIPAddr :: IP. IP -> Bool
88+ isValidDestinationIPAddr (IP. IPv4 ipv4) = IP. fromIPv4w ipv4 /= 0
89+ isValidDestinationIPAddr (IP. IPv6 ipv6) = IP. fromIPv6w ipv6 /= (0 ,0 ,0 ,0 )
90+
8291instance ToJSON RelayAccessPoint where
8392 toJSON (RelayAccessDomain addr port) =
8493 object
@@ -190,11 +199,12 @@ instance FromJSON LedgerRelayAccessPoint where
190199 Just rap -> return rap
191200
192201 where
193- toRelayAccessPoint :: DNS. Domain -> Int -> LedgerRelayAccessPoint
202+ toRelayAccessPoint :: ByteString -> Int -> LedgerRelayAccessPoint
194203 toRelayAccessPoint address port =
195204 case readMaybe (BSC. unpack address) of
196205 Nothing -> LedgerRelayAccessDomain (fullyQualified address) (fromIntegral port)
197206 Just addr -> LedgerRelayAccessAddress addr (fromIntegral port)
207+
198208 fullyQualified = \ case
199209 domain | Just (_, ' .' ) <- BSC. unsnoc domain -> domain
200210 | otherwise -> domain `BSC.snoc` ' .'
0 commit comments