1{-# LANGUAGE CPP #-}
2module Network.Socket.SockAddr (
3      getPeerName
4    , getSocketName
5    , connect
6    , bind
7    , accept
8    , sendBufTo
9    , recvBufFrom
10    , sendBufMsg
11    , recvBufMsg
12    ) where
13
14import Control.Exception (try, throwIO, IOException)
15import System.Directory (removeFile)
16import System.IO.Error (isAlreadyInUseError, isDoesNotExistError)
17
18import qualified Network.Socket.Buffer as G
19import qualified Network.Socket.Name as G
20import qualified Network.Socket.Syscall as G
21import Network.Socket.Flag
22import Network.Socket.Imports
23#if !defined(mingw32_HOST_OS)
24import Network.Socket.Posix.Cmsg
25#else
26import Network.Socket.Win32.Cmsg
27#endif
28import Network.Socket.Types
29
30-- | Getting peer's 'SockAddr'.
31getPeerName :: Socket -> IO SockAddr
32getPeerName = G.getPeerName
33
34-- | Getting my 'SockAddr'.
35getSocketName :: Socket -> IO SockAddr
36getSocketName = G.getSocketName
37
38-- | Connect to a remote socket at address.
39connect :: Socket -> SockAddr -> IO ()
40connect = G.connect
41
42-- | Bind the socket to an address. The socket must not already be
43-- bound.  The 'Family' passed to @bind@ must be the
44-- same as that passed to 'socket'.  If the special port number
45-- 'defaultPort' is passed then the system assigns the next available
46-- use port.
47bind :: Socket -> SockAddr -> IO ()
48bind s a = case a of
49  SockAddrUnix p -> do
50    -- gracefully handle the fact that UNIX systems don't clean up closed UNIX
51    -- domain sockets, inspired by https://stackoverflow.com/a/13719866
52    res <- try (G.bind s a)
53    case res of
54      Right () -> return ()
55      Left e | not (isAlreadyInUseError e) -> throwIO (e :: IOException)
56      Left e | otherwise -> do
57        -- socket might be in use, try to connect
58        res2 <- try (G.connect s a)
59        case res2 of
60          Right () -> close s >> throwIO e
61          Left e2 | not (isDoesNotExistError e2) -> throwIO (e2 :: IOException)
62          _ -> do
63            -- socket not actually in use, remove it and retry bind
64            void (try $ removeFile p :: IO (Either IOError ()))
65            G.bind s a
66  _ -> G.bind s a
67
68-- | Accept a connection.  The socket must be bound to an address and
69-- listening for connections.  The return value is a pair @(conn,
70-- address)@ where @conn@ is a new socket object usable to send and
71-- receive data on the connection, and @address@ is the address bound
72-- to the socket on the other end of the connection.
73-- On Unix, FD_CLOEXEC is set to the new 'Socket'.
74accept :: Socket -> IO (Socket, SockAddr)
75accept = G.accept
76
77-- | Send data to the socket.  The recipient can be specified
78-- explicitly, so the socket need not be in a connected state.
79-- Returns the number of bytes sent.  Applications are responsible for
80-- ensuring that all data has been sent.
81sendBufTo :: Socket -> Ptr a -> Int -> SockAddr -> IO Int
82sendBufTo = G.sendBufTo
83
84-- | Receive data from the socket, writing it into buffer instead of
85-- creating a new string.  The socket need not be in a connected
86-- state. Returns @(nbytes, address)@ where @nbytes@ is the number of
87-- bytes received and @address@ is a 'SockAddr' representing the
88-- address of the sending socket.
89--
90-- If the first return value is zero, it means EOF.
91--
92-- For 'Stream' sockets, the second return value would be invalid.
93--
94-- NOTE: blocking on Windows unless you compile with -threaded (see
95-- GHC ticket #1129)
96recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr)
97recvBufFrom = G.recvBufFrom
98
99-- | Send data to the socket using sendmsg(2).
100sendBufMsg :: Socket            -- ^ Socket
101           -> SockAddr          -- ^ Destination address
102           -> [(Ptr Word8,Int)] -- ^ Data to be sent
103           -> [Cmsg]            -- ^ Control messages
104           -> MsgFlag           -- ^ Message flags
105           -> IO Int            -- ^ The length actually sent
106sendBufMsg = G.sendBufMsg
107
108-- | Receive data from the socket using recvmsg(2).
109recvBufMsg :: Socket            -- ^ Socket
110        -> [(Ptr Word8,Int)] -- ^ A list of a pair of buffer and its size.
111                             --   If the total length is not large enough,
112                             --   'MSG_TRUNC' is returned
113        -> Int               -- ^ The buffer size for control messages.
114                             --   If the length is not large enough,
115                             --   'MSG_CTRUNC' is returned
116        -> MsgFlag           -- ^ Message flags
117        -> IO (SockAddr,Int,[Cmsg],MsgFlag) -- ^ Source address, received data, control messages and message flags
118recvBufMsg = G.recvBufMsg
119