haskell / network

Low-level networking interface
http://hackage.haskell.org/package/network
Other
325 stars 187 forks source link

Bug: ControlMessage Fd should be ControlMessage [Fd] (SCM_RIGHTS can contain > 1 Fd) #566

Open Dretch opened 1 year ago

Dretch commented 1 year ago

The docs for SCM_RIGHTS suggest that multiple file descriptors can be sent in one control message:

   SCM_RIGHTS
         Send or receive a set of open file descriptors from
         another process.  The data portion contains an integer
         array of the file descriptors.

However, we have ControlMessage Fd: so only a single file descriptor can be written-to / read-from a single control message. Currently, when reading a message with more than one file descriptor, only the first one is returned and the others are ignored.

Therefore, please entertain the idea of changing ControlMessage Fd to ControlMessage [Fd]. This would be a breaking change, though.

For now I am using this workaround to read messages with > 1 Fd. Writing is less of a problem because you can often send multiple control messages, each containing a single Fd:

decodeFdCmsg :: Cmsg -> Maybe [Fd]
decodeFdCmsg (Cmsg cmsid (PS fptr off len))
  | cmsid /= CmsgIdFd = Nothing
  | len < sizeOfFd = Nothing
  | otherwise =
    unsafeDupablePerformIO $ withForeignPtr fptr $ \p0 -> do
      let p = castPtr (p0 `plusPtr` off)
          numFds = len `div` sizeOfFd
      Just <$> peekArray numFds p
  where
    sizeOfFd = sizeOf (0 :: Fd)
kazu-yamamoto commented 1 year ago

Nice catch! We are working for the next major version. It would take time but a PR including breaking changes is now welcome!