summaryrefslogtreecommitdiff
path: root/dht/examples/nalias.hs
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2019-09-28 13:43:29 -0400
committerJoe Crayne <joe@jerkface.net>2020-01-01 19:27:53 -0500
commit11987749fc6e6d3e53ea737d46d5ab13a16faeb8 (patch)
tree5716463275c2d3e902889db619908ded2a73971c /dht/examples/nalias.hs
parentadd2c76bced51fde5e9917e7449ef52be70faf87 (diff)
Factor out some new libraries
word64-map: Data.Word64Map network-addr: Network.Address tox-crypto: Crypto.Tox lifted-concurrent: Control.Concurrent.Lifted.Instrument Control.Concurrent.Async.Lifted.Instrument psq-wrap: Data.Wrapper.PSQInt Data.Wrapper.PSQ minmax-psq: Data.MinMaxPSQ tasks: Control.Concurrent.Tasks kad: Network.Kademlia Network.Kademlia.Bootstrap Network.Kademlia.Routing Network.Kademlia.CommonAPI Network.Kademlia.Persistence Network.Kademlia.Search
Diffstat (limited to 'dht/examples/nalias.hs')
-rw-r--r--dht/examples/nalias.hs70
1 files changed, 70 insertions, 0 deletions
diff --git a/dht/examples/nalias.hs b/dht/examples/nalias.hs
new file mode 100644
index 00000000..fa1b6f71
--- /dev/null
+++ b/dht/examples/nalias.hs
@@ -0,0 +1,70 @@
1import Network.Socket
2import qualified Network.BSD as BSD
3import ControlMaybe
4import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,ErrorCall(..))
5import System.IO.Error (isDoesNotExistError)
6import System.Endian
7import Data.List (nub)
8import qualified Data.Text as Text
9import GetHostByAddr (getHostByAddr)
10import Control.Concurrent
11import Control.Concurrent.STM
12import Control.Monad
13import System.Environment
14
15unmap6mapped4 addr@(SockAddrInet6 port _ (0,0,0xFFFF,a) _) =
16 SockAddrInet port (toBE32 a)
17unmap6mapped4 addr = addr
18
19make6mapped4 addr@(SockAddrInet6 {}) = addr
20make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0
21
22
23reverseResolve addr =
24 handleIO_ (return []) $ do
25 ent <- getHostByAddr (unmap6mapped4 addr) -- AF_UNSPEC addr
26 let names = BSD.hostName ent : BSD.hostAliases ent
27 return $ map Text.pack $ nub names
28
29forwardResolve addrtext = do
30 r <- atomically newEmptyTMVar
31 mvar <- atomically newEmptyTMVar
32 rt <- forkOS $ resolver r mvar
33 tt <- forkIO $ timer r rt
34 atomically $ putTMVar mvar tt
35 atomically $ readTMVar r
36 where
37 resolver r mvar = do
38 xs <- handle (\e -> let _ = isDoesNotExistError e in return [])
39 $ do fmap (map $ make6mapped4 . addrAddress) $
40 getAddrInfo (Just $ defaultHints { addrFlags = [ AI_CANONNAME, AI_V4MAPPED ]})
41 (Just $ Text.unpack $ strip_brackets addrtext)
42 (Just "5269")
43 did <- atomically $ tryPutTMVar r (nub xs)
44 when did $ do
45 tt <- atomically $ readTMVar mvar
46 throwTo tt (ErrorCall "Interrupted delay")
47 return ()
48 timer r rt = do
49 handle (\(ErrorCall _)-> return ()) $ do
50 threadDelay 2000000
51 did <- atomically $ tryPutTMVar r []
52 when did $ do
53 putStrLn $ "timeout resolving: "++show addrtext
54 killThread rt
55 strip_brackets s =
56 case Text.uncons s of
57 Just ('[',t) -> Text.takeWhile (/=']') t
58 _ -> s
59
60main = do
61 args <- getArgs
62 forM args $ \arg -> do
63 putStrLn $ arg ++ ":"
64 let targ = Text.pack arg
65 addrs <- forwardResolve targ
66 putStrLn $ " forward: " ++ show addrs
67 forM addrs $ \addr -> do
68 names <- reverseResolve addr
69 putStrLn $ " reverse "++show addr++": "++show names
70 return ()