diff options
-rw-r--r-- | nalias.hs | 70 | ||||
-rw-r--r-- | nalias2.hs | 18 |
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 @@ | |||
1 | import Network.Socket | ||
2 | import qualified Network.BSD as BSD | ||
3 | import ControlMaybe | ||
4 | import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,ErrorCall(..)) | ||
5 | import System.IO.Error (isDoesNotExistError) | ||
6 | import System.Endian | ||
7 | import Data.List (nub) | ||
8 | import qualified Data.Text as Text | ||
9 | import GetHostByAddr (getHostByAddr) | ||
10 | import Control.Concurrent | ||
11 | import Control.Concurrent.STM | ||
12 | import Control.Monad | ||
13 | import System.Environment | ||
14 | |||
15 | unmap6mapped4 addr@(SockAddrInet6 port _ (0,0,0xFFFF,a) _) = | ||
16 | SockAddrInet port (toBE32 a) | ||
17 | unmap6mapped4 addr = addr | ||
18 | |||
19 | make6mapped4 addr@(SockAddrInet6 {}) = addr | ||
20 | make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0 | ||
21 | |||
22 | |||
23 | reverseResolve 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 | |||
29 | forwardResolve 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 | |||
60 | main = 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 @@ | |||
1 | import System.Environment | ||
2 | import Control.Monad | ||
3 | import qualified Data.Text as Text | ||
4 | |||
5 | import DNSCache | ||
6 | |||
7 | main = 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 () | ||