-
Notifications
You must be signed in to change notification settings - Fork 198
Description
Context:
recvfrom()
stores the source address of a received package in the sockaddr
structure pointed to by the address
pointer and the length of the address is stored in the memory pointed to by the address_len
argument.
Problem description:
However, not all protocol provide source addresses, e.g. AF_UNIX does not.
In this case, the contents of the address
parameter is "unspecified" [1] and should not be inspected. I have not found it in the specification, but in practice I have observed that at least on Linux address_len
is set to 0
recvBufFrom
does not check address_len
at all and instead tries to parse the contents of address
directly [2]. This leads to an error because it interprets the zeroed memory as AF_UNSPEC
which is not supported. The error is ignored and getPeerName
is called, which also fails.
The solution is to peek ptr_len
and check if it is 0
, and if so to return an "unset" address. I'm not sure how best to represent such an address, perhaps SockAddrUnix []
would do the trick?
Compare also how Rust handles the situation [3]
I have included a minimal code example that reproduced the problem [4]
- [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
- [2]
network/Network/Socket/Buffer.hsc
Lines 114 to 126 in 26e9d3c
recvBufFrom :: SocketAddress sa => Socket -> Ptr a -> Int -> IO (Int, sa) recvBufFrom s ptr nbytes | nbytes <= 0 = ioError (mkInvalidRecvArgError "Network.Socket.recvBufFrom") | otherwise = withNewSocketAddress $ \ptr_sa sz -> alloca $ \ptr_len -> withFdSocket s $ \fd -> do poke ptr_len (fromIntegral sz) let cnbytes = fromIntegral nbytes flags = 0 len <- throwSocketErrorWaitRead s "Network.Socket.recvBufFrom" $ c_recvfrom fd ptr cnbytes flags ptr_sa ptr_len sockaddr <- peekSocketAddress ptr_sa `catchIOError` \_ -> getPeerName s return (fromIntegral len, sockaddr) - [3] https://doc.rust-lang.org/src/std/os/unix/net/addr.rs.html#109-113
- [4] https://gist.github.com/Philonous/7fd9d6620e631325f6bd2fffaba0cc2e