summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nalias.hs70
-rw-r--r--nalias2.hs18
2 files changed, 88 insertions, 0 deletions
diff --git a/nalias.hs b/nalias.hs
new file mode 100644
index 00000000..fa1b6f71
--- /dev/null
+++ b/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 ()
diff --git a/nalias2.hs b/nalias2.hs
new file mode 100644
index 00000000..609f2ec6
--- /dev/null
+++ b/nalias2.hs
@@ -0,0 +1,18 @@
1import System.Environment
2import Control.Monad
3import qualified Data.Text as Text
4
5import DNSCache
6
7main = do
8 dns <- newDNSCache
9 args <- getArgs
10 forM args $ \arg -> do
11 putStrLn $ arg ++ ":"
12 let targ = Text.pack arg
13 addrs <- forwardResolve dns targ
14 putStrLn $ " forward: " ++ show addrs
15 forM addrs $ \addr -> do
16 names <- reverseResolve dns addr
17 putStrLn $ " reverse "++show addr++": "++show names
18 return ()