Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Network/Socket.hs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ module Network.Socket (
RecvIPv4TTL,
RecvIPv4TOS,
RecvIPv4PktInfo,
DontFragment,
RecvIPv6HopLimit,
RecvIPv6TClass,
RecvIPv6PktInfo
Expand Down
12 changes: 11 additions & 1 deletion Network/Socket/Options.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module Network.Socket.Options (
,OOBInline,TimeToLive,MaxSegment,NoDelay,Cork,Linger,ReusePort
,RecvLowWater,SendLowWater,RecvTimeOut,SendTimeOut
,UseLoopBack,UserTimeout,IPv6Only
,RecvIPv4TTL,RecvIPv4TOS,RecvIPv4PktInfo
,RecvIPv4TTL,RecvIPv4TOS,RecvIPv4PktInfo,DontFragment
,RecvIPv6HopLimit,RecvIPv6TClass,RecvIPv6PktInfo
,CustomSockOpt)
, isSupportedSocketOption
Expand Down Expand Up @@ -94,6 +94,7 @@ socketOptionBijection =
, (RecvIPv4TTL, "RecvIPv4TTL")
, (RecvIPv4TOS, "RecvIPv4TOS")
, (RecvIPv4PktInfo, "RecvIPv4PktInfo")
, (DontFragment, "DontFragment")
, (IPv6Only, "IPv6Only")
, (RecvIPv6HopLimit, "RecvIPv6HopLimit")
, (RecvIPv6TClass, "RecvIPv6TClass")
Expand Down Expand Up @@ -352,6 +353,15 @@ pattern RecvIPv4PktInfo = SockOpt (#const IPPROTO_IP) (#const IP_PKTINFO)
#else
pattern RecvIPv4PktInfo = SockOpt (-1) (-1)
#endif
-- | IP_DONTFRAG
pattern DontFragment :: SocketOption
#if HAVE_DECL_IP_DONTFRAG
pattern DontFragment = SockOpt (#const IPPROTO_IP) (#const IP_DONTFRAG)
#elif HAVE_DECL_IP_MTU_DISCOVER
pattern DontFragment = SockOpt (#const IPPROTO_IP) (#const IP_MTU_DISCOVER)
#else
pattern DontFragment = SockOpt (-1) (-1)
#endif
#endif // HAVE_DECL_IPPROTO_IP

#if HAVE_DECL_IPPROTO_IPV6
Expand Down
10 changes: 10 additions & 0 deletions Network/Socket/Syscall.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ socket family stype protocol = E.bracketOnError create c_close $ \fd -> do
-- This socket is not managed by the IO manager yet.
-- So, we don't have to call "close" which uses "closeFdWith".
unsetIPv6Only s
setDontFragment s
return s
where
create = do
Expand Down Expand Up @@ -120,6 +121,15 @@ socket family stype protocol = E.bracketOnError create c_close $ \fd -> do
unsetIPv6Only _ = return ()
#endif

setDontFragment s = when (family == AF_INET) $
#if HAVE_DECL_IP_DONTFRAG || HAVE_DECL_IP_MTU_DISCOVER
setSocketOption s DontFragment 1
#else
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These four lines (#else clause) are not necessary

Copy link
Contributor Author

@thehajime thehajime Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there are OSs/kernels which don't have those sockoption, I guess the compilation fails like below.

Network/Socket/Syscall.hs:138:1: error: [GHC-58481]
    parse error (possibly incorrect indentation or mismatched brackets)
    |
138 | bind :: SocketAddress sa => Socket -> sa -> IO ()
    | ^

I followed the way ipv6only option does in the #else clause to work around this situation.
do you still think it's unnecessary ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind.
I misunderstand that you are using setDontFragment here but you are defining it here.

-- do nothing
return ()
#endif


-----------------------------------------------------------------------------
-- Binding a socket

Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ AC_CHECK_DECLS([AI_ADDRCONFIG, AI_ALL, AI_NUMERICSERV, AI_V4MAPPED])
AC_CHECK_DECLS([IPV6_V6ONLY])
AC_CHECK_DECLS([IPPROTO_IP, IPPROTO_TCP, IPPROTO_IPV6])
AC_CHECK_DECLS([SO_PEERCRED])
AC_CHECK_DECLS([IP_DONTFRAG])
AC_CHECK_DECLS([IP_MTU_DISCOVER])

AC_CHECK_MEMBERS([struct msghdr.msg_control, struct msghdr.msg_accrights])
AC_CHECK_MEMBERS([struct sockaddr.sa_len])
Expand Down
2 changes: 1 addition & 1 deletion tests/Network/SocketSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ sockoptPatterns = nub
,TimeToLive,MaxSegment,NoDelay,Cork,Linger,ReusePort
,RecvLowWater,SendLowWater,RecvTimeOut,SendTimeOut
,UseLoopBack,UserTimeout,IPv6Only
,RecvIPv4TTL,RecvIPv4TOS,RecvIPv4PktInfo
,RecvIPv4TTL,RecvIPv4TOS,RecvIPv4PktInfo,DontFragment
,RecvIPv6HopLimit,RecvIPv6TClass,RecvIPv6PktInfo]

cmsgidPatterns :: [CmsgId]
Expand Down