summaryrefslogtreecommitdiff
path: root/dht
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-10-18 00:29:32 -0400
committerJoe Crayne <joe@jerkface.net>2020-01-01 19:46:43 -0500
commitafe40dd42f257cb90a1de207867a1c399a26e38c (patch)
treebb552fd67e8162d82ac92c0f6f17c853bdc0defe /dht
parentbbe88b6faf37f3031312c7eaabaefd8d149f3e33 (diff)
Use O_NONBLOCK to interrupt blocking recvFrom.
Diffstat (limited to 'dht')
-rw-r--r--dht/src/Network/QueryResponse.hs21
1 files changed, 16 insertions, 5 deletions
diff --git a/dht/src/Network/QueryResponse.hs b/dht/src/Network/QueryResponse.hs
index c4ff50e3..f72763de 100644
--- a/dht/src/Network/QueryResponse.hs
+++ b/dht/src/Network/QueryResponse.hs
@@ -553,9 +553,14 @@ sockAddrFamily _ = AF_CAN -- SockAddrCan constructor depre
553-- | Packets with an empty payload may trigger EOF exception. 553-- | Packets with an empty payload may trigger EOF exception.
554-- 'udpTransport' uses this function to avoid throwing in that 554-- 'udpTransport' uses this function to avoid throwing in that
555-- case. 555-- case.
556ignoreEOF :: a -> IOError -> IO a 556ignoreEOF :: Socket -> MVar () -> a -> IOError -> IO (Maybe a)
557ignoreEOF def e | isEOFError e = pure def 557ignoreEOF sock isClosed def e = do
558 | otherwise = throwIO e 558 done <- tryReadMVar isClosed
559 case done of
560 Just () -> do close sock
561 pure Nothing
562 _ -> if isEOFError e then pure $ Just def
563 else throwIO e
559 564
560-- | Hard-coded maximum packet size for incoming UDP Packets received via 565-- | Hard-coded maximum packet size for incoming UDP Packets received via
561-- 'udpTransport'. 566-- 'udpTransport'.
@@ -589,9 +594,10 @@ udpTransport' bind_address = do
589 setSocketOption sock IPv6Only 0 594 setSocketOption sock IPv6Only 0
590 setSocketOption sock Broadcast 1 595 setSocketOption sock Broadcast 1
591 bind sock bind_address 596 bind sock bind_address
597 isClosed <- newEmptyMVar
592 let tr = Transport { 598 let tr = Transport {
593 awaitMessage = \kont -> do 599 awaitMessage = \kont -> do
594 r <- handle (ignoreEOF $ Just $ Right (B.empty, SockAddrInet 0 0)) $ do 600 r <- handle (ignoreEOF sock isClosed $ Right (B.empty, SockAddrInet 0 0)) $ do
595 Just . Right <$!> B.recvFrom sock udpBufferSize 601 Just . Right <$!> B.recvFrom sock udpBufferSize
596 kont $! r 602 kont $! r
597 , sendMessage = case family of 603 , sendMessage = case family of
@@ -609,7 +615,12 @@ udpTransport' bind_address = do
609 addr@(SockAddrInet6 {}) -> \bs -> dput XMisc ("Discarding packet to "++show addr) 615 addr@(SockAddrInet6 {}) -> \bs -> dput XMisc ("Discarding packet to "++show addr)
610 addr4 -> \bs -> saferSendTo sock bs addr4 616 addr4 -> \bs -> saferSendTo sock bs addr4
611 _ -> \addr bs -> saferSendTo sock bs addr 617 _ -> \addr bs -> saferSendTo sock bs addr
612 , closeTransport = close sock 618 , closeTransport = do
619 -- close sock
620 tryTakeMVar isClosed >> putMVar isClosed ()
621 -- set O_NONBLOCK using fcntl
622 setNonBlockIfNeeded (fdSocket sock) -- setSocketOption sock ??? 0
623
613 } 624 }
614 return (tr, sock) 625 return (tr, sock)
615 626