{-# LANGUAGE DeriveDataTypeable #-}
-- |
-- Module      : Network.Socks5.Types
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : unknown
module Network.Socks5.Types
    ( SocksVersion(..)
    , SocksCommand(..)
    , SocksMethod(..)
    , SocksHostAddress(..)
    , SocksAddress(..)
    , SocksReply(..)
    , SocksVersionNotSupported(..)
    , SocksError(..)
    ) where

import qualified Basement.String as UTF8
import           Basement.Compat.IsList
import Data.ByteString (ByteString)
import Data.Word
import Data.Data
import Network.Socket (HostAddress, HostAddress6, PortNumber)
import Control.Exception
import qualified Data.ByteString as B
import Numeric (showHex)
import Data.List (intersperse)

-- | Socks Version
data SocksVersion = SocksVer5
                  deriving (Int -> SocksVersion -> ShowS
[SocksVersion] -> ShowS
SocksVersion -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksVersion] -> ShowS
$cshowList :: [SocksVersion] -> ShowS
show :: SocksVersion -> String
$cshow :: SocksVersion -> String
showsPrec :: Int -> SocksVersion -> ShowS
$cshowsPrec :: Int -> SocksVersion -> ShowS
Show,SocksVersion -> SocksVersion -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksVersion -> SocksVersion -> Bool
$c/= :: SocksVersion -> SocksVersion -> Bool
== :: SocksVersion -> SocksVersion -> Bool
$c== :: SocksVersion -> SocksVersion -> Bool
Eq,Eq SocksVersion
SocksVersion -> SocksVersion -> Bool
SocksVersion -> SocksVersion -> Ordering
SocksVersion -> SocksVersion -> SocksVersion
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksVersion -> SocksVersion -> SocksVersion
$cmin :: SocksVersion -> SocksVersion -> SocksVersion
max :: SocksVersion -> SocksVersion -> SocksVersion
$cmax :: SocksVersion -> SocksVersion -> SocksVersion
>= :: SocksVersion -> SocksVersion -> Bool
$c>= :: SocksVersion -> SocksVersion -> Bool
> :: SocksVersion -> SocksVersion -> Bool
$c> :: SocksVersion -> SocksVersion -> Bool
<= :: SocksVersion -> SocksVersion -> Bool
$c<= :: SocksVersion -> SocksVersion -> Bool
< :: SocksVersion -> SocksVersion -> Bool
$c< :: SocksVersion -> SocksVersion -> Bool
compare :: SocksVersion -> SocksVersion -> Ordering
$ccompare :: SocksVersion -> SocksVersion -> Ordering
Ord)

-- | Command that can be send and receive on the SOCKS protocol
data SocksCommand =
      SocksCommandConnect
    | SocksCommandBind
    | SocksCommandUdpAssociate
    | SocksCommandOther !Word8
    deriving (Int -> SocksCommand -> ShowS
[SocksCommand] -> ShowS
SocksCommand -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksCommand] -> ShowS
$cshowList :: [SocksCommand] -> ShowS
show :: SocksCommand -> String
$cshow :: SocksCommand -> String
showsPrec :: Int -> SocksCommand -> ShowS
$cshowsPrec :: Int -> SocksCommand -> ShowS
Show,SocksCommand -> SocksCommand -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksCommand -> SocksCommand -> Bool
$c/= :: SocksCommand -> SocksCommand -> Bool
== :: SocksCommand -> SocksCommand -> Bool
$c== :: SocksCommand -> SocksCommand -> Bool
Eq,Eq SocksCommand
SocksCommand -> SocksCommand -> Bool
SocksCommand -> SocksCommand -> Ordering
SocksCommand -> SocksCommand -> SocksCommand
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksCommand -> SocksCommand -> SocksCommand
$cmin :: SocksCommand -> SocksCommand -> SocksCommand
max :: SocksCommand -> SocksCommand -> SocksCommand
$cmax :: SocksCommand -> SocksCommand -> SocksCommand
>= :: SocksCommand -> SocksCommand -> Bool
$c>= :: SocksCommand -> SocksCommand -> Bool
> :: SocksCommand -> SocksCommand -> Bool
$c> :: SocksCommand -> SocksCommand -> Bool
<= :: SocksCommand -> SocksCommand -> Bool
$c<= :: SocksCommand -> SocksCommand -> Bool
< :: SocksCommand -> SocksCommand -> Bool
$c< :: SocksCommand -> SocksCommand -> Bool
compare :: SocksCommand -> SocksCommand -> Ordering
$ccompare :: SocksCommand -> SocksCommand -> Ordering
Ord)

-- | Authentication methods available on the SOCKS protocol.
--
-- Only SocksMethodNone is effectively implemented, but
-- other value are enumerated for completeness.
data SocksMethod =
      SocksMethodNone
    | SocksMethodGSSAPI
    | SocksMethodUsernamePassword
    | SocksMethodOther !Word8
    | SocksMethodNotAcceptable
    deriving (Int -> SocksMethod -> ShowS
[SocksMethod] -> ShowS
SocksMethod -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksMethod] -> ShowS
$cshowList :: [SocksMethod] -> ShowS
show :: SocksMethod -> String
$cshow :: SocksMethod -> String
showsPrec :: Int -> SocksMethod -> ShowS
$cshowsPrec :: Int -> SocksMethod -> ShowS
Show,SocksMethod -> SocksMethod -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksMethod -> SocksMethod -> Bool
$c/= :: SocksMethod -> SocksMethod -> Bool
== :: SocksMethod -> SocksMethod -> Bool
$c== :: SocksMethod -> SocksMethod -> Bool
Eq,Eq SocksMethod
SocksMethod -> SocksMethod -> Bool
SocksMethod -> SocksMethod -> Ordering
SocksMethod -> SocksMethod -> SocksMethod
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksMethod -> SocksMethod -> SocksMethod
$cmin :: SocksMethod -> SocksMethod -> SocksMethod
max :: SocksMethod -> SocksMethod -> SocksMethod
$cmax :: SocksMethod -> SocksMethod -> SocksMethod
>= :: SocksMethod -> SocksMethod -> Bool
$c>= :: SocksMethod -> SocksMethod -> Bool
> :: SocksMethod -> SocksMethod -> Bool
$c> :: SocksMethod -> SocksMethod -> Bool
<= :: SocksMethod -> SocksMethod -> Bool
$c<= :: SocksMethod -> SocksMethod -> Bool
< :: SocksMethod -> SocksMethod -> Bool
$c< :: SocksMethod -> SocksMethod -> Bool
compare :: SocksMethod -> SocksMethod -> Ordering
$ccompare :: SocksMethod -> SocksMethod -> Ordering
Ord)

-- | A Host address on the SOCKS protocol.
data SocksHostAddress =
      SocksAddrIPV4 !HostAddress
    | SocksAddrDomainName !FQDN
    | SocksAddrIPV6 !HostAddress6
    deriving (SocksHostAddress -> SocksHostAddress -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksHostAddress -> SocksHostAddress -> Bool
$c/= :: SocksHostAddress -> SocksHostAddress -> Bool
== :: SocksHostAddress -> SocksHostAddress -> Bool
$c== :: SocksHostAddress -> SocksHostAddress -> Bool
Eq,Eq SocksHostAddress
SocksHostAddress -> SocksHostAddress -> Bool
SocksHostAddress -> SocksHostAddress -> Ordering
SocksHostAddress -> SocksHostAddress -> SocksHostAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksHostAddress -> SocksHostAddress -> SocksHostAddress
$cmin :: SocksHostAddress -> SocksHostAddress -> SocksHostAddress
max :: SocksHostAddress -> SocksHostAddress -> SocksHostAddress
$cmax :: SocksHostAddress -> SocksHostAddress -> SocksHostAddress
>= :: SocksHostAddress -> SocksHostAddress -> Bool
$c>= :: SocksHostAddress -> SocksHostAddress -> Bool
> :: SocksHostAddress -> SocksHostAddress -> Bool
$c> :: SocksHostAddress -> SocksHostAddress -> Bool
<= :: SocksHostAddress -> SocksHostAddress -> Bool
$c<= :: SocksHostAddress -> SocksHostAddress -> Bool
< :: SocksHostAddress -> SocksHostAddress -> Bool
$c< :: SocksHostAddress -> SocksHostAddress -> Bool
compare :: SocksHostAddress -> SocksHostAddress -> Ordering
$ccompare :: SocksHostAddress -> SocksHostAddress -> Ordering
Ord)

type FQDN = ByteString

instance Show SocksHostAddress where
    show :: SocksHostAddress -> String
show (SocksAddrIPV4 Word32
ha)       = String
"SocksAddrIPV4(" forall a. [a] -> [a] -> [a]
++ Word32 -> String
showHostAddress Word32
ha forall a. [a] -> [a] -> [a]
++ String
")"
    show (SocksAddrIPV6 HostAddress6
ha6)      = String
"SocksAddrIPV6(" forall a. [a] -> [a] -> [a]
++ HostAddress6 -> String
showHostAddress6 HostAddress6
ha6 forall a. [a] -> [a] -> [a]
++ String
")"
    show (SocksAddrDomainName FQDN
dn) = String
"SocksAddrDomainName(" forall a. [a] -> [a] -> [a]
++ FQDN -> String
showFQDN FQDN
dn forall a. [a] -> [a] -> [a]
++ String
")"

-- | Converts a FQDN to a String
showFQDN :: FQDN -> String
showFQDN :: FQDN -> String
showFQDN FQDN
bs = forall l. IsList l => l -> [Item l]
toList forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ UArray Word8 -> (String, UArray Word8)
UTF8.fromBytesLenient forall a b. (a -> b) -> a -> b
$ forall l. IsList l => [Item l] -> l
fromList forall a b. (a -> b) -> a -> b
$ FQDN -> [Word8]
B.unpack FQDN
bs

-- | Converts a HostAddress to a String in dot-decimal notation
showHostAddress :: HostAddress -> String
showHostAddress :: Word32 -> String
showHostAddress Word32
num = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [forall a. Show a => a -> String
show Word32
q1, String
".", forall a. Show a => a -> String
show Word32
q2, String
".", forall a. Show a => a -> String
show Word32
q3, String
".", forall a. Show a => a -> String
show Word32
q4]
  where (Word32
num',Word32
q1)   = Word32
num forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
        (Word32
num'',Word32
q2)  = Word32
num' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
        (Word32
num''',Word32
q3) = Word32
num'' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256
        (Word32
_,Word32
q4)      = Word32
num''' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
256

-- | Converts a IPv6 HostAddress6 to standard hex notation
showHostAddress6 :: HostAddress6 -> String
showHostAddress6 :: HostAddress6 -> String
showHostAddress6 (Word32
a,Word32
b,Word32
c,Word32
d) =
    (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse String
":" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Integral a, Show a) => a -> ShowS
showHex String
""))
        [Word32
p1,Word32
p2,Word32
p3,Word32
p4,Word32
p5,Word32
p6,Word32
p7,Word32
p8]
    where (Word32
a',Word32
p2) = Word32
a forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
_,Word32
p1)  = Word32
a' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
b',Word32
p4) = Word32
b forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
_,Word32
p3)  = Word32
b' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
c',Word32
p6) = Word32
c forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
_,Word32
p5)  = Word32
c' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
d',Word32
p8) = Word32
d forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536
          (Word32
_,Word32
p7)  = Word32
d' forall a. Integral a => a -> a -> (a, a)
`quotRem` Word32
65536

-- | Describe a Socket address on the SOCKS protocol
data SocksAddress = SocksAddress !SocksHostAddress !PortNumber
    deriving (Int -> SocksAddress -> ShowS
[SocksAddress] -> ShowS
SocksAddress -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksAddress] -> ShowS
$cshowList :: [SocksAddress] -> ShowS
show :: SocksAddress -> String
$cshow :: SocksAddress -> String
showsPrec :: Int -> SocksAddress -> ShowS
$cshowsPrec :: Int -> SocksAddress -> ShowS
Show,SocksAddress -> SocksAddress -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksAddress -> SocksAddress -> Bool
$c/= :: SocksAddress -> SocksAddress -> Bool
== :: SocksAddress -> SocksAddress -> Bool
$c== :: SocksAddress -> SocksAddress -> Bool
Eq,Eq SocksAddress
SocksAddress -> SocksAddress -> Bool
SocksAddress -> SocksAddress -> Ordering
SocksAddress -> SocksAddress -> SocksAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksAddress -> SocksAddress -> SocksAddress
$cmin :: SocksAddress -> SocksAddress -> SocksAddress
max :: SocksAddress -> SocksAddress -> SocksAddress
$cmax :: SocksAddress -> SocksAddress -> SocksAddress
>= :: SocksAddress -> SocksAddress -> Bool
$c>= :: SocksAddress -> SocksAddress -> Bool
> :: SocksAddress -> SocksAddress -> Bool
$c> :: SocksAddress -> SocksAddress -> Bool
<= :: SocksAddress -> SocksAddress -> Bool
$c<= :: SocksAddress -> SocksAddress -> Bool
< :: SocksAddress -> SocksAddress -> Bool
$c< :: SocksAddress -> SocksAddress -> Bool
compare :: SocksAddress -> SocksAddress -> Ordering
$ccompare :: SocksAddress -> SocksAddress -> Ordering
Ord)

-- | Type of reply on the SOCKS protocol
data SocksReply =
      SocksReplySuccess
    | SocksReplyError SocksError
    deriving (Int -> SocksReply -> ShowS
[SocksReply] -> ShowS
SocksReply -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksReply] -> ShowS
$cshowList :: [SocksReply] -> ShowS
show :: SocksReply -> String
$cshow :: SocksReply -> String
showsPrec :: Int -> SocksReply -> ShowS
$cshowsPrec :: Int -> SocksReply -> ShowS
Show,SocksReply -> SocksReply -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksReply -> SocksReply -> Bool
$c/= :: SocksReply -> SocksReply -> Bool
== :: SocksReply -> SocksReply -> Bool
$c== :: SocksReply -> SocksReply -> Bool
Eq,Eq SocksReply
SocksReply -> SocksReply -> Bool
SocksReply -> SocksReply -> Ordering
SocksReply -> SocksReply -> SocksReply
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksReply -> SocksReply -> SocksReply
$cmin :: SocksReply -> SocksReply -> SocksReply
max :: SocksReply -> SocksReply -> SocksReply
$cmax :: SocksReply -> SocksReply -> SocksReply
>= :: SocksReply -> SocksReply -> Bool
$c>= :: SocksReply -> SocksReply -> Bool
> :: SocksReply -> SocksReply -> Bool
$c> :: SocksReply -> SocksReply -> Bool
<= :: SocksReply -> SocksReply -> Bool
$c<= :: SocksReply -> SocksReply -> Bool
< :: SocksReply -> SocksReply -> Bool
$c< :: SocksReply -> SocksReply -> Bool
compare :: SocksReply -> SocksReply -> Ordering
$ccompare :: SocksReply -> SocksReply -> Ordering
Ord,Typeable SocksReply
SocksReply -> DataType
SocksReply -> Constr
(forall b. Data b => b -> b) -> SocksReply -> SocksReply
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SocksReply -> u
forall u. (forall d. Data d => d -> u) -> SocksReply -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksReply
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksReply -> c SocksReply
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksReply)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksReply)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksReply -> m SocksReply
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SocksReply -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SocksReply -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SocksReply -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SocksReply -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksReply -> r
gmapT :: (forall b. Data b => b -> b) -> SocksReply -> SocksReply
$cgmapT :: (forall b. Data b => b -> b) -> SocksReply -> SocksReply
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksReply)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksReply)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksReply)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksReply)
dataTypeOf :: SocksReply -> DataType
$cdataTypeOf :: SocksReply -> DataType
toConstr :: SocksReply -> Constr
$ctoConstr :: SocksReply -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksReply
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksReply
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksReply -> c SocksReply
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksReply -> c SocksReply
Data,Typeable)

-- | SOCKS error that can be received or sent
data SocksError =
      SocksErrorGeneralServerFailure
    | SocksErrorConnectionNotAllowedByRule
    | SocksErrorNetworkUnreachable
    | SocksErrorHostUnreachable
    | SocksErrorConnectionRefused
    | SocksErrorTTLExpired
    | SocksErrorCommandNotSupported
    | SocksErrorAddrTypeNotSupported
    | SocksErrorOther Word8
    deriving (Int -> SocksError -> ShowS
[SocksError] -> ShowS
SocksError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksError] -> ShowS
$cshowList :: [SocksError] -> ShowS
show :: SocksError -> String
$cshow :: SocksError -> String
showsPrec :: Int -> SocksError -> ShowS
$cshowsPrec :: Int -> SocksError -> ShowS
Show,SocksError -> SocksError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocksError -> SocksError -> Bool
$c/= :: SocksError -> SocksError -> Bool
== :: SocksError -> SocksError -> Bool
$c== :: SocksError -> SocksError -> Bool
Eq,Eq SocksError
SocksError -> SocksError -> Bool
SocksError -> SocksError -> Ordering
SocksError -> SocksError -> SocksError
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocksError -> SocksError -> SocksError
$cmin :: SocksError -> SocksError -> SocksError
max :: SocksError -> SocksError -> SocksError
$cmax :: SocksError -> SocksError -> SocksError
>= :: SocksError -> SocksError -> Bool
$c>= :: SocksError -> SocksError -> Bool
> :: SocksError -> SocksError -> Bool
$c> :: SocksError -> SocksError -> Bool
<= :: SocksError -> SocksError -> Bool
$c<= :: SocksError -> SocksError -> Bool
< :: SocksError -> SocksError -> Bool
$c< :: SocksError -> SocksError -> Bool
compare :: SocksError -> SocksError -> Ordering
$ccompare :: SocksError -> SocksError -> Ordering
Ord,Typeable SocksError
SocksError -> DataType
SocksError -> Constr
(forall b. Data b => b -> b) -> SocksError -> SocksError
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SocksError -> u
forall u. (forall d. Data d => d -> u) -> SocksError -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksError
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksError -> c SocksError
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksError)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksError)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SocksError -> m SocksError
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SocksError -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SocksError -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SocksError -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SocksError -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SocksError -> r
gmapT :: (forall b. Data b => b -> b) -> SocksError -> SocksError
$cgmapT :: (forall b. Data b => b -> b) -> SocksError -> SocksError
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksError)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SocksError)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksError)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksError)
dataTypeOf :: SocksError -> DataType
$cdataTypeOf :: SocksError -> DataType
toConstr :: SocksError -> Constr
$ctoConstr :: SocksError -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksError
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksError
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksError -> c SocksError
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SocksError -> c SocksError
Data,Typeable)

-- | Exception returned when using a SOCKS version that is not supported.
--
-- This package only implement version 5.
data SocksVersionNotSupported = SocksVersionNotSupported
    deriving (Int -> SocksVersionNotSupported -> ShowS
[SocksVersionNotSupported] -> ShowS
SocksVersionNotSupported -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocksVersionNotSupported] -> ShowS
$cshowList :: [SocksVersionNotSupported] -> ShowS
show :: SocksVersionNotSupported -> String
$cshow :: SocksVersionNotSupported -> String
showsPrec :: Int -> SocksVersionNotSupported -> ShowS
$cshowsPrec :: Int -> SocksVersionNotSupported -> ShowS
Show,Typeable SocksVersionNotSupported
SocksVersionNotSupported -> DataType
SocksVersionNotSupported -> Constr
(forall b. Data b => b -> b)
-> SocksVersionNotSupported -> SocksVersionNotSupported
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int
-> (forall d. Data d => d -> u) -> SocksVersionNotSupported -> u
forall u.
(forall d. Data d => d -> u) -> SocksVersionNotSupported -> [u]
forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksVersionNotSupported
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SocksVersionNotSupported
-> c SocksVersionNotSupported
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksVersionNotSupported)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SocksVersionNotSupported)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SocksVersionNotSupported -> m SocksVersionNotSupported
gmapQi :: forall u.
Int
-> (forall d. Data d => d -> u) -> SocksVersionNotSupported -> u
$cgmapQi :: forall u.
Int
-> (forall d. Data d => d -> u) -> SocksVersionNotSupported -> u
gmapQ :: forall u.
(forall d. Data d => d -> u) -> SocksVersionNotSupported -> [u]
$cgmapQ :: forall u.
(forall d. Data d => d -> u) -> SocksVersionNotSupported -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> SocksVersionNotSupported
-> r
gmapT :: (forall b. Data b => b -> b)
-> SocksVersionNotSupported -> SocksVersionNotSupported
$cgmapT :: (forall b. Data b => b -> b)
-> SocksVersionNotSupported -> SocksVersionNotSupported
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SocksVersionNotSupported)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SocksVersionNotSupported)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksVersionNotSupported)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SocksVersionNotSupported)
dataTypeOf :: SocksVersionNotSupported -> DataType
$cdataTypeOf :: SocksVersionNotSupported -> DataType
toConstr :: SocksVersionNotSupported -> Constr
$ctoConstr :: SocksVersionNotSupported -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksVersionNotSupported
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SocksVersionNotSupported
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SocksVersionNotSupported
-> c SocksVersionNotSupported
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> SocksVersionNotSupported
-> c SocksVersionNotSupported
Data,Typeable)

instance Exception SocksError
instance Exception SocksVersionNotSupported

instance Enum SocksCommand where
    toEnum :: Int -> SocksCommand
toEnum Int
1 = SocksCommand
SocksCommandConnect
    toEnum Int
2 = SocksCommand
SocksCommandBind
    toEnum Int
3 = SocksCommand
SocksCommandUdpAssociate
    toEnum Int
w
        | Int
w forall a. Ord a => a -> a -> Bool
< Int
256   = Word8 -> SocksCommand
SocksCommandOther forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w
        | Bool
otherwise = forall a. HasCallStack => String -> a
error String
"socks command is only 8 bits"
    fromEnum :: SocksCommand -> Int
fromEnum SocksCommand
SocksCommandConnect      = Int
1
    fromEnum SocksCommand
SocksCommandBind         = Int
2
    fromEnum SocksCommand
SocksCommandUdpAssociate = Int
3
    fromEnum (SocksCommandOther Word8
w)    = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w

instance Enum SocksMethod where
    toEnum :: Int -> SocksMethod
toEnum Int
0    = SocksMethod
SocksMethodNone
    toEnum Int
1    = SocksMethod
SocksMethodGSSAPI
    toEnum Int
2    = SocksMethod
SocksMethodUsernamePassword
    toEnum Int
0xff = SocksMethod
SocksMethodNotAcceptable
    toEnum Int
w
        | Int
w forall a. Ord a => a -> a -> Bool
< Int
256   = Word8 -> SocksMethod
SocksMethodOther forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w
        | Bool
otherwise = forall a. HasCallStack => String -> a
error String
"socks method is only 8 bits"
    fromEnum :: SocksMethod -> Int
fromEnum SocksMethod
SocksMethodNone             = Int
0
    fromEnum SocksMethod
SocksMethodGSSAPI           = Int
1
    fromEnum SocksMethod
SocksMethodUsernamePassword = Int
2
    fromEnum (SocksMethodOther Word8
w)        = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w
    fromEnum SocksMethod
SocksMethodNotAcceptable    = Int
0xff

instance Enum SocksError where
    fromEnum :: SocksError -> Int
fromEnum SocksError
SocksErrorGeneralServerFailure       = Int
1
    fromEnum SocksError
SocksErrorConnectionNotAllowedByRule = Int
2
    fromEnum SocksError
SocksErrorNetworkUnreachable         = Int
3
    fromEnum SocksError
SocksErrorHostUnreachable            = Int
4
    fromEnum SocksError
SocksErrorConnectionRefused          = Int
5
    fromEnum SocksError
SocksErrorTTLExpired                 = Int
6
    fromEnum SocksError
SocksErrorCommandNotSupported        = Int
7
    fromEnum SocksError
SocksErrorAddrTypeNotSupported       = Int
8
    fromEnum (SocksErrorOther Word8
w)                  = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w
    toEnum :: Int -> SocksError
toEnum Int
1 = SocksError
SocksErrorGeneralServerFailure
    toEnum Int
2 = SocksError
SocksErrorConnectionNotAllowedByRule
    toEnum Int
3 = SocksError
SocksErrorNetworkUnreachable
    toEnum Int
4 = SocksError
SocksErrorHostUnreachable
    toEnum Int
5 = SocksError
SocksErrorConnectionRefused
    toEnum Int
6 = SocksError
SocksErrorTTLExpired
    toEnum Int
7 = SocksError
SocksErrorCommandNotSupported
    toEnum Int
8 = SocksError
SocksErrorAddrTypeNotSupported
    toEnum Int
w = Word8 -> SocksError
SocksErrorOther forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
w

instance Enum SocksReply where
    fromEnum :: SocksReply -> Int
fromEnum SocksReply
SocksReplySuccess                    = Int
0
    fromEnum (SocksReplyError SocksError
e)                  = forall a. Enum a => a -> Int
fromEnum SocksError
e
    toEnum :: Int -> SocksReply
toEnum Int
0 = SocksReply
SocksReplySuccess
    toEnum Int
n = SocksError -> SocksReply
SocksReplyError (forall a. Enum a => Int -> a
toEnum Int
n)