packages feed

moesocks-0.1.2.0: src/Network/MoeSocks/Type.hs

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}

module Network.MoeSocks.Type where

import Control.Lens
import Control.Monad.Except
import Control.Monad.Reader
import Control.Concurrent.Async
import Data.Aeson
import Data.ByteString (ByteString)
import Data.Text (Text)
import Data.IP
import Data.Word
import Data.Monoid
import GHC.Generics
import System.Log.Logger
import qualified Data.Strict as S

data ClientGreeting = ClientGreeting
  {
    _authenticationMethods :: [Word8]
  }
  deriving (Show)

makeLenses ''ClientGreeting

data ConnectionType =
    TCP_IP_StreamConnection
  | TCP_IP_PortBinding
  | UDP_Port
  deriving (Show, Eq)

data AddressType = 
    IPv4_Address (Word8, Word8, Word8, Word8)
  | DomainName Text
  | IPv6_Address [Word16]
  deriving (Show, Eq)

type Port = Int

data ClientRequest = ClientRequest
  {
    _connectionType :: ConnectionType
  , _addressType :: AddressType
  , _portNumber :: Port
  }
  deriving (Show, Eq)

makeLenses ''ClientRequest


data Config = Config
  {
    _remoteAddress :: Text
  , _remotePort :: Int
  , _localAddress :: Text
  , _localPort :: Int
  , _password :: Text
  , _method :: Text
  , _timeout :: Int
  , _tcpBufferSize :: Int -- in packets
  , _throttle :: Bool
  , _throttleSpeed :: Double
  , _obfuscationFlushBound :: Int -- should be greater then MTU
  , _fastOpen :: Bool
  , _socketOption_TCP_NOTSENT_LOWAT :: Bool
  }
  deriving (Show, Eq, Generic)

instance FromJSON Config
instance ToJSON Config

makeLenses ''Config

data RunningMode = RemoteMode | LocalMode | DebugMode
      deriving (Show, Eq)

data Verbosity = Normal | Verbose
      deriving (Show, Eq)

data Forward = Forward
  {
    _forwardLocalPort :: Port
  , _forwardRemoteHost :: Text
  , _forwardRemotePort :: Port
  }
  deriving (Show, Eq)


makeLenses ''Forward

{-data Profile =    Mac-}
                {-| Linux-}
  {-deriving (Show, Eq, Read)-}

{-makePrisms ''Profile-}

data Options = Options
  {
    _runningMode :: RunningMode
  , _configFile :: Maybe Text
  , _verbosity :: Priority
  , _forward_TCPs :: [Forward]
  , _forward_UDPs :: [Forward]
  , _disable_SOCKS5 :: Bool
  , _obfuscation :: Bool
  , _forbidden_IPs :: [IPRange]
  , _listMethods :: Bool
  , _params :: [(Text, Value)]
  }
  deriving (Show, Eq)

makeLenses ''Options

type Cipher = S.Maybe ByteString -> IO ByteString 
type IV = ByteString
type CipherBuilder = IV -> IO Cipher

data CipherBox = CipherBox
  {
    _ivLength :: Int
  , _generate_IV :: IO IV
  , _encryptBuilder :: CipherBuilder
  , _decryptBuilder ::  CipherBuilder
  }

makeLenses ''CipherBox

data LocalRelayType =
      Local_TCP_Relay Forward
    | Local_UDP_Relay Forward
    | Local_SOCKS_Relay Int
    deriving (Show, Eq)

makePrisms ''LocalRelayType

data LocalRelay = LocalRelay
  {
    _localRelayType :: LocalRelayType
  , _localRelayAddress :: Text
  , _localRelayRemoteAddress :: Text
  , _localRelayRemotePort :: Int
  }
  deriving (Show, Eq)

makeLenses ''LocalRelay

data RemoteRelayType =
      Remote_TCP_Relay
    | Remote_UDP_Relay
    deriving (Show, Eq)

makePrisms ''RemoteRelayType

newtype Relay_ID = Relay_ID { _unRelay_ID :: Async () }
  deriving (Eq, Ord)

makeLenses ''Relay_ID

instance Show Relay_ID where
  show _ = "Relay ID"

data RemoteRelay = RemoteRelay
  {
    _remoteRelayType :: RemoteRelayType
  , _remoteRelayAddress :: Text
  , _remoteRelayPort :: Int
  , _relay_ID :: Maybe Relay_ID
  }
  deriving (Show, Eq)

makeLenses ''RemoteRelay

data Runtime = Runtime
  {
    _localRelays :: [LocalRelay]
  , _remoteRelays :: [RemoteRelay]
  }
  deriving (Show, Eq)

makeLenses ''Runtime

instance Monoid Runtime where
  mempty = Runtime [] []
  Runtime x y `mappend` Runtime x' y' = Runtime (x <> x') (y <> y')
          

data Env = Env
  {
    _options :: Options
  , _config :: Config
  , _cipherBox :: CipherBox
  }

makeLenses ''Env


type MoeMonadT = ReaderT Options (ExceptT String IO)