diff options
Diffstat (limited to 'src/Network')
-rw-r--r-- | src/Network/Address.hs | 4 | ||||
-rw-r--r-- | src/Network/QueryResponse.hs | 25 |
2 files changed, 24 insertions, 5 deletions
diff --git a/src/Network/Address.hs b/src/Network/Address.hs index cc06ac0d..9a601dcd 100644 --- a/src/Network/Address.hs +++ b/src/Network/Address.hs | |||
@@ -648,6 +648,10 @@ genBucketSample' gen self (q,m,b) | |||
648 | | otherwise = either error id . S.decode . build <$> gen (nodeIdSize - q + 1) | 648 | | otherwise = either error id . S.decode . build <$> gen (nodeIdSize - q + 1) |
649 | where | 649 | where |
650 | nodeIdSize = finiteBitSize (undefined :: nid) `div` 8 | 650 | nodeIdSize = finiteBitSize (undefined :: nid) `div` 8 |
651 | |||
652 | -- Prepends q bytes to modified input: | ||
653 | -- applies mask m | ||
654 | -- toggles bit b | ||
651 | build tl = BS.init hd <> BS.cons (h .|. t) (BS.tail tl) | 655 | build tl = BS.init hd <> BS.cons (h .|. t) (BS.tail tl) |
652 | where | 656 | where |
653 | hd = BS.take q $ S.encode self | 657 | hd = BS.take q $ S.encode self |
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs index 1346174f..41e25486 100644 --- a/src/Network/QueryResponse.hs +++ b/src/Network/QueryResponse.hs | |||
@@ -30,6 +30,7 @@ import Data.Maybe | |||
30 | import Data.Typeable | 30 | import Data.Typeable |
31 | import Network.Socket | 31 | import Network.Socket |
32 | import Network.Socket.ByteString as B | 32 | import Network.Socket.ByteString as B |
33 | import System.Endian | ||
33 | import System.IO | 34 | import System.IO |
34 | import System.IO.Error | 35 | import System.IO.Error |
35 | import System.Timeout | 36 | import System.Timeout |
@@ -120,15 +121,15 @@ onInbound f tr = addHandler (\addr x -> f addr x >> return (Just id)) tr | |||
120 | -- Example usage: | 121 | -- Example usage: |
121 | -- | 122 | -- |
122 | -- > -- Start client. | 123 | -- > -- Start client. |
123 | -- > quitServer <- forkListener (clientNet client) | 124 | -- > quitServer <- forkListener "listener" (clientNet client) |
124 | -- > -- Send a query q, recieve a response r. | 125 | -- > -- Send a query q, recieve a response r. |
125 | -- > r <- sendQuery client method q | 126 | -- > r <- sendQuery client method q |
126 | -- > -- Quit client. | 127 | -- > -- Quit client. |
127 | -- > quitServer | 128 | -- > quitServer |
128 | forkListener :: Transport err addr x -> IO (IO ()) | 129 | forkListener :: String -> Transport err addr x -> IO (IO ()) |
129 | forkListener client = do | 130 | forkListener name client = do |
130 | thread_id <- forkIO $ do | 131 | thread_id <- forkIO $ do |
131 | myThreadId >>= flip labelThread "listener" | 132 | myThreadId >>= flip labelThread ("listener."++name) |
132 | fix $ awaitMessage client . const | 133 | fix $ awaitMessage client . const |
133 | return $ do | 134 | return $ do |
134 | closeTransport client | 135 | closeTransport client |
@@ -470,9 +471,23 @@ udpTransport bind_address = do | |||
470 | r <- handle (ignoreEOF $ Just $ Right (B.empty, SockAddrInet 0 0)) $ do | 471 | r <- handle (ignoreEOF $ Just $ Right (B.empty, SockAddrInet 0 0)) $ do |
471 | Just . Right <$!> B.recvFrom sock udpBufferSize | 472 | Just . Right <$!> B.recvFrom sock udpBufferSize |
472 | kont $! r | 473 | kont $! r |
473 | , sendMessage = \addr bs -> void $ B.sendTo sock bs addr | 474 | , sendMessage = case family of |
474 | -- TODO: sendTo: does not exist (Network is unreachable) | 475 | -- TODO: sendTo: does not exist (Network is unreachable) |
475 | -- Occurs when IPv6 network is not available. | 476 | -- Occurs when IPv6 network is not available. |
476 | -- Currently, we require -threaded to prevent a forever-hang in this case. | 477 | -- Currently, we require -threaded to prevent a forever-hang in this case. |
478 | AF_INET6 -> \case | ||
479 | (SockAddrInet port addr) -> \bs -> | ||
480 | -- Change IPv4 to 4mapped6 address. | ||
481 | void $ B.sendTo sock bs $ SockAddrInet6 port 0 (0,0,0x0000ffff,fromBE32 addr) 0 | ||
482 | addr6 -> \bs -> void $ B.sendTo sock bs addr6 | ||
483 | AF_INET -> \case | ||
484 | (SockAddrInet6 port 0 (0,0,0x0000ffff,raw4) 0) -> \bs -> do | ||
485 | let host4 = toBE32 raw4 | ||
486 | -- Change 4mapped6 to ordinary IPv4. | ||
487 | -- hPutStrLn stderr $ "4mapped6 -> "++show (SockAddrInet port host4) | ||
488 | void $ B.sendTo sock bs (SockAddrInet port host4) | ||
489 | addr@(SockAddrInet6 {}) -> \bs -> hPutStrLn stderr ("Discarding packet to "++show addr) | ||
490 | addr4 -> \bs -> void $ B.sendTo sock bs addr4 | ||
491 | _ -> \addr bs -> void $ B.sendTo sock bs addr | ||
477 | , closeTransport = close sock | 492 | , closeTransport = close sock |
478 | } | 493 | } |