{-# LINE 1 "Network/Socket/Options.hsc" #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE GADTs #-}
#include "HsNetDef.h"
module Network.Socket.Options (
SocketOption(SockOpt
,UnsupportedSocketOption
,AcceptConn,Debug,ReuseAddr,SoDomain,Type,SoProtocol,SoError
,DontRoute,Broadcast,SendBuffer,RecvBuffer,KeepAlive,OOBInline
,TimeToLive,MaxSegment,NoDelay,Cork,Linger,ReusePort
,RecvLowWater,SendLowWater,RecvTimeOut,SendTimeOut
,UseLoopBack,UserTimeout,IPv6Only
,RecvIPv4TTL,RecvIPv4TOS,RecvIPv4PktInfo
,RecvIPv6HopLimit,RecvIPv6TClass,RecvIPv6PktInfo
,CustomSockOpt)
, isSupportedSocketOption
, whenSupported
, getSocketType
, getSocketOption
, setSocketOption
, getSockOpt
, setSockOpt
, SockOptValue (..)
, setSockOptValue
, StructLinger (..)
, SocketTimeout (..)
) where
import qualified Text.Read as P
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Utils (with)
import Network.Socket.Imports
import Network.Socket.Internal
import Network.Socket.Types
import Network.Socket.ReadShow
data SocketOption = SockOpt
{-# LINE 56 "Network/Socket/Options.hsc" #-}
CInt
CInt
{-# LINE 62 "Network/Socket/Options.hsc" #-}
deriving (Eq)
socketOptionBijection :: Bijection SocketOption String
socketOptionBijection =
[ (UnsupportedSocketOption, "UnsupportedSocketOption")
, (Debug, "Debug")
, (ReuseAddr, "ReuseAddr")
, (SoDomain, "SoDomain")
, (Type, "Type")
, (SoProtocol, "SoProtocol")
, (SoError, "SoError")
, (DontRoute, "DontRoute")
, (Broadcast, "Broadcast")
, (SendBuffer, "SendBuffer")
, (RecvBuffer, "RecvBuffer")
, (KeepAlive, "KeepAlive")
, (OOBInline, "OOBInline")
, (Linger, "Linger")
, (ReusePort, "ReusePort")
, (RecvLowWater, "RecvLowWater")
, (SendLowWater, "SendLowWater")
, (RecvTimeOut, "RecvTimeOut")
, (SendTimeOut, "SendTimeOut")
, (UseLoopBack, "UseLoopBack")
, (MaxSegment, "MaxSegment")
, (NoDelay, "NoDelay")
, (UserTimeout, "UserTimeout")
, (Cork, "Cork")
, (TimeToLive, "TimeToLive")
, (RecvIPv4TTL, "RecvIPv4TTL")
, (RecvIPv4TOS, "RecvIPv4TOS")
, (RecvIPv4PktInfo, "RecvIPv4PktInfo")
, (IPv6Only, "IPv6Only")
, (RecvIPv6HopLimit, "RecvIPv6HopLimit")
, (RecvIPv6TClass, "RecvIPv6TClass")
, (RecvIPv6PktInfo, "RecvIPv6PktInfo")
]
instance Show SocketOption where
showsPrec = bijectiveShow socketOptionBijection def
where
defname = "SockOpt"
unwrap = \(CustomSockOpt nm) -> nm
def = defShow defname unwrap showIntInt
instance Read SocketOption where
readPrec = bijectiveRead socketOptionBijection def
where
defname = "SockOpt"
def = defRead defname CustomSockOpt readIntInt
pattern UnsupportedSocketOption :: SocketOption
pattern UnsupportedSocketOption = SockOpt (-1) (-1)
isSupportedSocketOption :: SocketOption -> Bool
isSupportedSocketOption opt = opt /= SockOpt (-1) (-1)
whenSupported :: SocketOption -> IO a -> IO ()
whenSupported s action
| isSupportedSocketOption s = action >> return ()
| otherwise = return ()
{-# LINE 135 "Network/Socket/Options.hsc" #-}
pattern AcceptConn :: SocketOption
{-# LINE 138 "Network/Socket/Options.hsc" #-}
pattern AcceptConn = SockOpt (1) (30)
{-# LINE 139 "Network/Socket/Options.hsc" #-}
{-# LINE 142 "Network/Socket/Options.hsc" #-}
pattern Debug :: SocketOption
{-# LINE 145 "Network/Socket/Options.hsc" #-}
pattern Debug = SockOpt (1) (1)
{-# LINE 146 "Network/Socket/Options.hsc" #-}
{-# LINE 149 "Network/Socket/Options.hsc" #-}
pattern ReuseAddr :: SocketOption
{-# LINE 152 "Network/Socket/Options.hsc" #-}
pattern ReuseAddr = SockOpt (1) (2)
{-# LINE 153 "Network/Socket/Options.hsc" #-}
{-# LINE 156 "Network/Socket/Options.hsc" #-}
pattern SoDomain :: SocketOption
{-# LINE 160 "Network/Socket/Options.hsc" #-}
pattern SoDomain = SockOpt (1) (39)
{-# LINE 161 "Network/Socket/Options.hsc" #-}
{-# LINE 164 "Network/Socket/Options.hsc" #-}
pattern Type :: SocketOption
{-# LINE 168 "Network/Socket/Options.hsc" #-}
pattern Type = SockOpt (1) (3)
{-# LINE 169 "Network/Socket/Options.hsc" #-}
{-# LINE 172 "Network/Socket/Options.hsc" #-}
pattern SoProtocol :: SocketOption
{-# LINE 176 "Network/Socket/Options.hsc" #-}
pattern SoProtocol = SockOpt (1) (38)
{-# LINE 177 "Network/Socket/Options.hsc" #-}
{-# LINE 180 "Network/Socket/Options.hsc" #-}
pattern SoError :: SocketOption
{-# LINE 184 "Network/Socket/Options.hsc" #-}
pattern SoError = SockOpt (1) (4)
{-# LINE 185 "Network/Socket/Options.hsc" #-}
{-# LINE 188 "Network/Socket/Options.hsc" #-}
pattern DontRoute :: SocketOption
{-# LINE 191 "Network/Socket/Options.hsc" #-}
pattern DontRoute = SockOpt (1) (5)
{-# LINE 192 "Network/Socket/Options.hsc" #-}
{-# LINE 195 "Network/Socket/Options.hsc" #-}
pattern Broadcast :: SocketOption
{-# LINE 198 "Network/Socket/Options.hsc" #-}
pattern Broadcast = SockOpt (1) (6)
{-# LINE 199 "Network/Socket/Options.hsc" #-}
{-# LINE 202 "Network/Socket/Options.hsc" #-}
pattern SendBuffer :: SocketOption
{-# LINE 205 "Network/Socket/Options.hsc" #-}
pattern SendBuffer = SockOpt (1) (7)
{-# LINE 206 "Network/Socket/Options.hsc" #-}
{-# LINE 209 "Network/Socket/Options.hsc" #-}
pattern RecvBuffer :: SocketOption
{-# LINE 212 "Network/Socket/Options.hsc" #-}
pattern RecvBuffer = SockOpt (1) (8)
{-# LINE 213 "Network/Socket/Options.hsc" #-}
{-# LINE 216 "Network/Socket/Options.hsc" #-}
pattern KeepAlive :: SocketOption
{-# LINE 219 "Network/Socket/Options.hsc" #-}
pattern KeepAlive = SockOpt (1) (9)
{-# LINE 220 "Network/Socket/Options.hsc" #-}
{-# LINE 223 "Network/Socket/Options.hsc" #-}
pattern OOBInline :: SocketOption
{-# LINE 226 "Network/Socket/Options.hsc" #-}
pattern OOBInline = SockOpt (1) (10)
{-# LINE 227 "Network/Socket/Options.hsc" #-}
{-# LINE 230 "Network/Socket/Options.hsc" #-}
pattern Linger :: SocketOption
{-# LINE 233 "Network/Socket/Options.hsc" #-}
pattern Linger = SockOpt (1) (13)
{-# LINE 234 "Network/Socket/Options.hsc" #-}
{-# LINE 237 "Network/Socket/Options.hsc" #-}
pattern ReusePort :: SocketOption
{-# LINE 240 "Network/Socket/Options.hsc" #-}
pattern ReusePort = SockOpt (1) (15)
{-# LINE 241 "Network/Socket/Options.hsc" #-}
{-# LINE 244 "Network/Socket/Options.hsc" #-}
pattern RecvLowWater :: SocketOption
{-# LINE 247 "Network/Socket/Options.hsc" #-}
pattern RecvLowWater = SockOpt (1) (18)
{-# LINE 248 "Network/Socket/Options.hsc" #-}
{-# LINE 251 "Network/Socket/Options.hsc" #-}
pattern SendLowWater :: SocketOption
{-# LINE 254 "Network/Socket/Options.hsc" #-}
pattern SendLowWater = SockOpt (1) (19)
{-# LINE 255 "Network/Socket/Options.hsc" #-}
{-# LINE 258 "Network/Socket/Options.hsc" #-}
pattern RecvTimeOut :: SocketOption
{-# LINE 262 "Network/Socket/Options.hsc" #-}
pattern RecvTimeOut = SockOpt (1) (20)
{-# LINE 263 "Network/Socket/Options.hsc" #-}
{-# LINE 266 "Network/Socket/Options.hsc" #-}
pattern SendTimeOut :: SocketOption
{-# LINE 270 "Network/Socket/Options.hsc" #-}
pattern SendTimeOut = SockOpt (1) (21)
{-# LINE 271 "Network/Socket/Options.hsc" #-}
{-# LINE 274 "Network/Socket/Options.hsc" #-}
pattern UseLoopBack :: SocketOption
{-# LINE 279 "Network/Socket/Options.hsc" #-}
pattern UseLoopBack = SockOpt (-1) (-1)
{-# LINE 281 "Network/Socket/Options.hsc" #-}
{-# LINE 282 "Network/Socket/Options.hsc" #-}
{-# LINE 284 "Network/Socket/Options.hsc" #-}
pattern MaxSegment :: SocketOption
{-# LINE 287 "Network/Socket/Options.hsc" #-}
pattern MaxSegment = SockOpt (6) (2)
{-# LINE 288 "Network/Socket/Options.hsc" #-}
{-# LINE 291 "Network/Socket/Options.hsc" #-}
pattern NoDelay :: SocketOption
{-# LINE 294 "Network/Socket/Options.hsc" #-}
pattern NoDelay = SockOpt (6) (1)
{-# LINE 295 "Network/Socket/Options.hsc" #-}
{-# LINE 298 "Network/Socket/Options.hsc" #-}
pattern UserTimeout :: SocketOption
{-# LINE 301 "Network/Socket/Options.hsc" #-}
pattern UserTimeout = SockOpt (6) (18)
{-# LINE 302 "Network/Socket/Options.hsc" #-}
{-# LINE 305 "Network/Socket/Options.hsc" #-}
pattern Cork :: SocketOption
{-# LINE 308 "Network/Socket/Options.hsc" #-}
pattern Cork = SockOpt (6) (3)
{-# LINE 309 "Network/Socket/Options.hsc" #-}
{-# LINE 312 "Network/Socket/Options.hsc" #-}
{-# LINE 313 "Network/Socket/Options.hsc" #-}
{-# LINE 315 "Network/Socket/Options.hsc" #-}
pattern TimeToLive :: SocketOption
{-# LINE 318 "Network/Socket/Options.hsc" #-}
pattern TimeToLive = SockOpt (0) (2)
{-# LINE 319 "Network/Socket/Options.hsc" #-}
{-# LINE 322 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4TTL :: SocketOption
{-# LINE 325 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4TTL = SockOpt (0) (12)
{-# LINE 326 "Network/Socket/Options.hsc" #-}
{-# LINE 329 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4TOS :: SocketOption
{-# LINE 332 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4TOS = SockOpt (0) (13)
{-# LINE 333 "Network/Socket/Options.hsc" #-}
{-# LINE 336 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4PktInfo :: SocketOption
{-# LINE 341 "Network/Socket/Options.hsc" #-}
pattern RecvIPv4PktInfo = SockOpt (0) (8)
{-# LINE 342 "Network/Socket/Options.hsc" #-}
{-# LINE 345 "Network/Socket/Options.hsc" #-}
{-# LINE 346 "Network/Socket/Options.hsc" #-}
{-# LINE 348 "Network/Socket/Options.hsc" #-}
pattern IPv6Only :: SocketOption
{-# LINE 351 "Network/Socket/Options.hsc" #-}
pattern IPv6Only = SockOpt (41) (26)
{-# LINE 352 "Network/Socket/Options.hsc" #-}
{-# LINE 355 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6HopLimit :: SocketOption
{-# LINE 358 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6HopLimit = SockOpt (41) (51)
{-# LINE 359 "Network/Socket/Options.hsc" #-}
{-# LINE 362 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6TClass :: SocketOption
{-# LINE 365 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6TClass = SockOpt (41) (66)
{-# LINE 366 "Network/Socket/Options.hsc" #-}
{-# LINE 369 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6PktInfo :: SocketOption
{-# LINE 372 "Network/Socket/Options.hsc" #-}
pattern RecvIPv6PktInfo = SockOpt (41) (49)
{-# LINE 373 "Network/Socket/Options.hsc" #-}
{-# LINE 378 "Network/Socket/Options.hsc" #-}
{-# LINE 379 "Network/Socket/Options.hsc" #-}
pattern CustomSockOpt :: (CInt, CInt) -> SocketOption
pattern CustomSockOpt xy <- ((\(SockOpt x y) -> (x, y)) -> xy)
where
CustomSockOpt (x, y) = SockOpt x y
setSocketOption :: Socket
-> SocketOption
-> Int
-> IO ()
{-# LINE 393 "Network/Socket/Options.hsc" #-}
setSocketOption s so@Linger v = do
let arg = if v == 0 then StructLinger 0 0 else StructLinger 1 (fromIntegral v)
setSockOpt s so arg
{-# LINE 397 "Network/Socket/Options.hsc" #-}
setSocketOption s so@RecvTimeOut v = setSockOpt s so $ SocketTimeout $ fromIntegral v
setSocketOption s so@SendTimeOut v = setSockOpt s so $ SocketTimeout $ fromIntegral v
setSocketOption s sa v = setSockOpt s sa (fromIntegral v :: CInt)
setSockOpt :: Storable a
=> Socket
-> SocketOption
-> a
-> IO ()
setSockOpt s (SockOpt level opt) v = do
with v $ \ptr -> void $ do
let sz = fromIntegral $ sizeOf v
withFdSocket s $ \fd ->
throwSocketErrorIfMinus1_ "Network.Socket.setSockOpt" $
c_setsockopt fd level opt ptr sz
setSockOptValue :: Socket
-> SocketOption
-> SockOptValue
-> IO ()
setSockOptValue s opt (SockOptValue v) = setSockOpt s opt v
getSocketOption :: Socket
-> SocketOption
-> IO Int
{-# LINE 437 "Network/Socket/Options.hsc" #-}
getSocketOption s so@Linger = do
StructLinger onoff linger <- getSockOpt s so
return $ fromIntegral $ if onoff == 0 then 0 else linger
{-# LINE 441 "Network/Socket/Options.hsc" #-}
getSocketOption s so@RecvTimeOut = do
SocketTimeout to <- getSockOpt s so
return $ fromIntegral to
getSocketOption s so@SendTimeOut = do
SocketTimeout to <- getSockOpt s so
return $ fromIntegral to
getSocketOption s so = do
n :: CInt <- getSockOpt s so
return $ fromIntegral n
getSockOpt :: forall a . Storable a
=> Socket
-> SocketOption
-> IO a
getSockOpt s (SockOpt level opt) = do
alloca $ \ptr -> do
let sz = fromIntegral $ sizeOf (undefined :: a)
withFdSocket s $ \fd -> with sz $ \ptr_sz -> do
throwSocketErrorIfMinus1Retry_ "Network.Socket.getSockOpt" $
c_getsockopt fd level opt ptr ptr_sz
peek ptr
getSocketType :: Socket -> IO SocketType
getSocketType s = unpackSocketType <$> getSockOpt s Type
{-# LINE 475 "Network/Socket/Options.hsc" #-}
{-# COMPLETE CustomSockOpt #-}
{-# LINE 477 "Network/Socket/Options.hsc" #-}
{-# LINE 478 "Network/Socket/Options.hsc" #-}
data StructLinger = StructLinger {
sl_onoff :: CInt,
sl_linger :: CInt
}
deriving (Eq, Ord, Show)
instance Storable StructLinger where
sizeOf ~_ = (8)
{-# LINE 491 "Network/Socket/Options.hsc" #-}
alignment ~_ = alignment (0 :: CInt)
peek p = do
onoff <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 495 "Network/Socket/Options.hsc" #-}
linger <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
{-# LINE 496 "Network/Socket/Options.hsc" #-}
return $ StructLinger onoff linger
poke p (StructLinger onoff linger) = do
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p onoff
{-# LINE 500 "Network/Socket/Options.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 4)) p linger
{-# LINE 501 "Network/Socket/Options.hsc" #-}
{-# LINE 502 "Network/Socket/Options.hsc" #-}
data SockOptValue where
SockOptValue :: Storable a => a -> SockOptValue
newtype SocketTimeout = SocketTimeout Word32 deriving (Eq, Ord, Show)
{-# LINE 526 "Network/Socket/Options.hsc" #-}
instance Storable SocketTimeout where
sizeOf ~_ = ((16))
{-# LINE 528 "Network/Socket/Options.hsc" #-}
alignment ~_ = (8)
{-# LINE 529 "Network/Socket/Options.hsc" #-}
peek ptr = do
sec <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 531 "Network/Socket/Options.hsc" #-}
usec <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr
{-# LINE 532 "Network/Socket/Options.hsc" #-}
return $ SocketTimeout (sec * 1000000 + usec)
poke ptr (SocketTimeout to) = do
let (sec, usec) = to `divMod` 1000000
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr sec
{-# LINE 536 "Network/Socket/Options.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 8)) ptr usec
{-# LINE 537 "Network/Socket/Options.hsc" #-}
{-# LINE 538 "Network/Socket/Options.hsc" #-}
foreign import CALLCONV unsafe "getsockopt"
c_getsockopt :: CInt -> CInt -> CInt -> Ptr a -> Ptr CInt -> IO CInt
foreign import CALLCONV unsafe "setsockopt"
c_setsockopt :: CInt -> CInt -> CInt -> Ptr a -> CInt -> IO CInt