haskell-tor-0.1.2: src/Tor/Options.hs
-- |Various options for running a Tor node
module Tor.Options(
-- * Options for running Tor
TorOptions(..), defaultTorOptions
, TorEntranceOptions(..), defaultTorEntranceOptions
, TorRelayOptions(..), defaultTorRelayOptions
, TorExitOptions(..), defaultTorExitOptions
, ExitRule(..), AddrSpec(..), PortSpec(..)
-- * Handy utilities
, makeLogger
)
where
import Data.Hourglass
import Data.Word
import System.Hourglass
import Tor.RouterDesc
-- |How the node should be set up during initialization. For each of these
-- items, 'Nothing' means that the node will not operate in that capacity, while
-- Just of the option type will initialize that system with those options.
--
-- Note that while we will do our best to make it work, it doesn't make a whole
-- lot of sense to be an Exit node and not be a Relay node.
data TorOptions = TorOptions {
torLog :: String -> IO ()
, torEntranceOptions :: Maybe TorEntranceOptions
, torRelayOptions :: Maybe TorRelayOptions
, torExitOptions :: Maybe TorExitOptions
}
-- |A reasonable default set of options for a Tor node. Sets the node up as an
-- entrance and relay node with their standard options, and logging output
-- printed to stdout.
defaultTorOptions :: TorOptions
defaultTorOptions = TorOptions {
torLog = makeLogger putStrLn
, torEntranceOptions = Just defaultTorEntranceOptions
, torRelayOptions = Just defaultTorRelayOptions
, torExitOptions = Nothing
}
-- |Options for allowing circuits that originated at this node.
data TorEntranceOptions = TorEntranceOptions {
-- |The number of intermediate hops to use between this node and
-- the exit node. To be clear, created circuits will have an entrance
-- node, this number of nodes, and then the exit node.
torInternalCircuitLength :: Int
-- |The target number of external connections to keep alive for
-- outgoing connections. Note that this is a target, rather than a hard
-- minimum or limit.
, torTargetLinks :: Int
}
-- |A reasonable set of entrance options. The internal circuit length is set to
-- 4, and a target number of links of 5.
defaultTorEntranceOptions :: TorEntranceOptions
defaultTorEntranceOptions = TorEntranceOptions {
torInternalCircuitLength = 4
, torTargetLinks = 5
}
-- |Options for allowing circuits that pass through this node.
data TorRelayOptions = TorRelayOptions {
-- |The port to listen on. By default, this is 9374, but there are
-- compelling reasons to have it be some other wel-known port, like
-- 80.
torOnionPort :: Word16
-- |The nickname for this node. This is completely optional, but can
-- be helpful in finding yourself in node lists.
, torNickname :: String
-- |A contact email address. If not provided, we will either provide
-- no email address or just include a junk address.
, torContact :: Maybe String
-- |If you're setting up a number of nodes within the same operating
-- environment, you might want to provide a "family" identifier. That way,
-- those building circuits can limit what percentage of their hops might
-- go through this group. A node can be a member of zero, one, or more
-- families, thus the list.
, torFamilies :: [NodeFamily]
-- |The maximum number of links from this node. Note that this should be
-- greater than or equal to torTargetLinks if this node is also to be used
-- as an entrance node.
, torMaximumLinks :: Int
}
-- |A reasonable set of relay options. The onion port is set to 9374, the
-- nickname is set to "", and no contact information is provided. These options
-- set the maximum number of links to 50.
defaultTorRelayOptions :: TorRelayOptions
defaultTorRelayOptions = TorRelayOptions {
torOnionPort = 9374
, torNickname = ""
, torContact = Nothing
, torFamilies = []
, torMaximumLinks = 50
}
-- |Options for allowing circuits that end at this node.
data TorExitOptions = TorExitOptions {
-- |The rules for allowing or rejecting traffic leaving this node.
torExitRules :: [ExitRule]
-- |The ports to disallow (Left) or allow (Right) when forwarding
-- IPv6 traffic.
, torIPv6Policy :: Either [PortSpec] [PortSpec]
-- |Set this flag if you want to allow single-hop exits. These are
-- usually not advisable, but according to the spec they may be
-- usefule for "specialized controllers desgined to support perspective
-- access and such."
, torAllowSingleHopExits :: Bool
}
-- |A reasonable default exit node options. This allows all outgoing
-- traffic to ports 22 (SSH), 80 (HTTP), 443 (HTTPS), 465 (SMTPS), and
-- 993 (IMAPS), and disallows single hop exits.
defaultTorExitOptions :: TorExitOptions
defaultTorExitOptions = TorExitOptions {
torExitRules = map (\ p -> ExitRuleAccept AddrSpecAll (PortSpecSingle p))
allowPorts
, torIPv6Policy = Right (map PortSpecSingle allowPorts)
, torAllowSingleHopExits = False
}
where allowPorts = [22, 80, 443, 465, 993]
-- -----------------------------------------------------------------------------
-- |If you like the output format of the default log function, but want to
-- send it to your own output stream, this is the function for you! This
-- function takes an outgoing logger and a string to log, and adds a nicely-
-- formatted and easily-sortable timestamp to the front of it.
--
-- NOTE: The default value for the logger is (makeLogger putStrLn).
makeLogger :: (String -> IO ()) -> String -> IO ()
makeLogger out msg =
do now <- dateCurrent
out (timePrint timeFormat now ++ msg)
where
timeFormat = [Format_Text '[', Format_Year4, Format_Text '-', Format_Month2,
Format_Text '-', Format_Day2, Format_Text ' ', Format_Hour,
Format_Text ':', Format_Minute, Format_Text ']',
Format_Text ' ']