-- |Structures and rules for describing routers. module Tor.RouterDesc( RouterDesc(..) , blankRouterDesc , NodeFamily(..) , ExitRule(..) , AddrSpec(..) , PortSpec(..) ) where import Crypto.PubKey.Curve25519 as Curve import Crypto.PubKey.RSA as RSA import Data.ByteString(ByteString, empty) import Data.Hourglass import Data.Word -- |The complete description of a router within the Tor network. data RouterDesc = RouterDesc { routerNickname :: String , routerIPv4Address :: String , routerORPort :: Word16 , routerDirPort :: Maybe Word16 , routerParseLog :: [String] , routerAvgBandwidth :: Int , routerBurstBandwidth :: Int , routerObservedBandwidth :: Int , routerPlatformName :: String , routerEntryPublished :: DateTime , routerFingerprint :: ByteString , routerHibernating :: Bool , routerUptime :: Maybe Integer , routerOnionKey :: RSA.PublicKey , routerNTorOnionKey :: Maybe Curve.PublicKey , routerSigningKey :: RSA.PublicKey , routerExitRules :: [ExitRule] , routerIPv6Policy :: Either [PortSpec] [PortSpec] , routerSignature :: ByteString , routerContact :: Maybe String , routerFamily :: [NodeFamily] , routerReadHistory :: Maybe (DateTime, Int, [Int]) , routerWriteHistory :: Maybe (DateTime, Int, [Int]) , routerCachesExtraInfo :: Bool , routerExtraInfoDigest :: Maybe ByteString , routerHiddenServiceDir :: Maybe Int , routerLinkProtocolVersions :: [Int] , routerCircuitProtocolVersions :: [Int] , routerAllowSingleHopExits :: Bool , routerAlternateORAddresses :: [(String, Word16)] , routerStatus :: [String] } deriving (Show) instance Eq RouterDesc where a == b = routerSigningKey a == routerSigningKey b -- |A blank router description, with most of the options initialized with -- standard "blank" values. blankRouterDesc :: RouterDesc blankRouterDesc = RouterDesc { routerNickname = "" , routerIPv4Address = "0.0.0.0" , routerORPort = 0 , routerDirPort = Nothing , routerParseLog = [] , routerAvgBandwidth = 0 , routerBurstBandwidth = 0 , routerObservedBandwidth = 0 , routerPlatformName = "Haskell" , routerEntryPublished = timeFromElapsed (Elapsed (Seconds 0)) , routerFingerprint = empty , routerHibernating = False , routerUptime = Nothing , routerOnionKey = error "No public onion key" , routerNTorOnionKey = Nothing , routerSigningKey = error "No signing key" , routerExitRules = [] , routerIPv6Policy = Left [] , routerSignature = empty , routerContact = Nothing , routerFamily = [] , routerReadHistory = Nothing , routerWriteHistory = Nothing , routerCachesExtraInfo = False , routerExtraInfoDigest = Nothing , routerHiddenServiceDir = Nothing , routerLinkProtocolVersions = [] , routerCircuitProtocolVersions = [] , routerAllowSingleHopExits = False , routerAlternateORAddresses = [] , routerStatus = [] } -- |A family descriptor for a node. Either a nickname, or a digest referencing -- the family, or both. data NodeFamily = NodeFamilyNickname String | NodeFamilyDigest ByteString | NodeFamilyBoth String ByteString deriving (Show) -- |A rule for accepting or rejecting traffic, usually specified by exit nodes. data ExitRule = ExitRuleAccept AddrSpec PortSpec -- ^Accept matching traffic. | ExitRuleReject AddrSpec PortSpec -- ^Reject matching traffic. deriving (Show) -- |A port specifier data PortSpec = PortSpecAll -- ^Accept any port | PortSpecRange Word16 Word16 -- ^Accept ports between the two -- values, inclusive. | PortSpecSingle Word16 -- ^Accept only the given port. deriving (Eq, Show) -- |An address or subnet specifier. data AddrSpec = AddrSpecAll -- ^Accept any address | AddrSpecIP4 String -- ^Accept this specific address. | AddrSpecIP4Mask String String -- ^Accept this IP address and -- subnet mask (255.255.255.0,etc.) | AddrSpecIP4Bits String Int -- ^Accept this IP address and CIDR -- mask (/24,etc.) | AddrSpecIP6 String -- ^Accept this specific IP6 address. | AddrSpecIP6Bits String Int -- ^Accept this subnet and CIDR -- mask. deriving (Eq, Show)