-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Safer socket #336
Safer socket #336
Conversation
s <- mkSocket fd | ||
unsetIPv6Only s `E.onException` close s | ||
return s | ||
where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the improvement in readability of moving the ifdef
s to where
.
c_socket (packFamily family) c_stype protocol | ||
setNonBlock fd `E.onException` c_close fd | ||
s <- mkSocket fd | ||
unsetIPv6Only s `E.onException` close s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be closing and throwing? Otherwise socket
will return a Socket
that has already been closed and file descriptor re-use by the OS could lead to us accidentally sending to an unknown socket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually reuse is not an issue here since close
changes it to -1
, but is above with using vanilla c_close
.
c_stype <- modifyFlag <$> packSocketTypeOrThrow "socket" stype | ||
fd <- throwSocketErrorIfMinus1Retry "Network.Socket.socket" $ | ||
c_socket (packFamily family) c_stype protocol | ||
setNonBlock fd `E.onException` c_close fd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this result in a Socket
with a closed file descriptor within its IORef
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops, ignore the issues above. onException
is fine here, since it isn't catching anything, but just a flavor of bracket
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm not sure. onException
is defined as:
onException :: IO a -> IO b -> IO a
onException io what = io `catch` \e -> do _ <- what
throwIO (e :: SomeException)
Is that sufficient to prevent async exceptions from causing file descriptors leaking? It seems we might want to utilize bracketOnError
to ensure masking and do something like:
bracketOnError create c_close $ \fd -> do
setNonBlock fd
s <- mkSocket fd
unsetIPv6Only s
return s
where
create =
c_stype <- modifyFlag <$> packSocketTypeOrThrow "socket" stype
throwSocketErrorIfMinus1Retry "Network.Socket.socket" $
c_socket (packFamily family) c_stype protocol
@eborden My code is safe only for synchronous exceptions while your code is safe even for asynchronous exceptions! Also, OK. I will adopt your code. Thank you for your suggestion! |
Rebased and merged. |
socket
closes the file descriptor on exception.This should fix #166 in
master
.