, PdnsRequest(..)
, pdnsParse
, pdnsReport
- , pdnsOut
+ , pdnsOutQ
, pdnsOutXfr
) where
import Data.Text.Lazy (splitOn, pack)
+import Data.Map.Lazy (foldrWithKey)
import NmcDom
let
getInt s = case reads s :: [(Int, String)] of
[(x, _)] -> x
- _ -> -1
+ _ -> (-1)
getLIp ver xs
| ver >= 2 = case xs of
x:_ -> Just x
pdnsReport err = "LOG\tError: " ++ err ++ "\nFAIL\n"
-- | Produce answer to the Q request
-pdnsOut :: Int -> Int -> String -> RRType -> Either String NmcDom -> String
-pdnsOut ver id name rrtype edom =
+pdnsOutQ :: Int -> Int -> String -> RRType -> Either String NmcDom -> String
+pdnsOutQ ver id name rrt edom =
let
- rrl = case rrtype of
- RRTypeANY -> [RRTypeSRV, RRTypeA, RRTypeAAAA, RRTypeCNAME
+ rrl = case rrt of
+ RRTypeANY -> [ RRTypeSRV, RRTypeA, RRTypeAAAA, RRTypeCNAME
, RRTypeDNAME, RRTypeRP, RRTypeLOC, RRTypeNS
- , RRTypeDS, RRTypeMX]
- rrt -> [rrt]
+ , RRTypeDS, RRTypeMX -- SOA not included
+ ]
+ x -> [x]
in
- (formatDom ver id name rrl edom) ++ "END\n"
+ case edom of
+ Left err ->
+ pdnsReport $ err ++ " in the " ++ (show rrt) ++ " query for " ++ name
+ Right dom ->
+ formatDom ver id rrl name dom "END\n"
-- | Produce answer to the AXFR request
pdnsOutXfr :: Int -> Int -> String -> Either String NmcDom -> String
-pdnsOutXfr ver id name edom = "" -- FIXME
-
-formatDom ver id name rrl edom = case edom of
- Left err ->
- pdnsReport $ err ++ " in the " ++ (show rrl) ++ " query for " ++ name
- Right dom ->
- foldr (\x a -> (formatRR ver id name dom x) ++ a) "" rrl
+pdnsOutXfr ver id name edom =
+ let
+ allrrs = [ RRTypeSRV, RRTypeA, RRTypeAAAA, RRTypeCNAME
+ , RRTypeDNAME, RRTypeRP, RRTypeLOC, RRTypeNS
+ , RRTypeDS, RRTypeMX, RRTypeSOA
+ ]
+ walkDom f acc name dom =
+ f name dom $ case domMap dom of
+ Nothing -> acc
+ Just dm ->
+ foldrWithKey (\n d a -> walkDom f a (n ++ "." ++ name) d) acc dm
+ in
+ case edom of
+ Left err ->
+ pdnsReport $ err ++ " in the AXFR request for " ++ name
+ Right dom ->
+ walkDom (formatDom ver id allrrs) "END\n" name dom
+
+formatDom ver id rrl name dom acc =
+ foldr (\x a -> (formatRR ver id name dom x) ++ a) acc rrl
formatRR ver id name dom rrtype =
foldr (\x a -> "DATA\t" ++ v3ext ++ name ++ "\tIN\t" ++ (show rrtype)
case parseJsonRpc (responseBody rsp) :: Either JsonRpcError NmcRes of
Left jerr ->
case (jrpcErrCode jerr) of
- -4 -> Right "{}" -- this is how non-existent entry is returned
- _ -> Left $ "JsonRpc error response: " ++ (show jerr)
+ (-4) -> Right "{}" -- this is how non-existent entry is returned
+ _ -> Left $ "JsonRpc error response: " ++ (show jerr)
Right jrsp -> Right $ resValue jrsp
-- NMC interface
case preq of
PdnsRequestQ qname qtype id _ _ _ -> do
io $ queryDom (queryOpNmc cfg mgr id) qname
- >>= putStr . (pdnsOut ver count qname qtype)
+ >>= putStr . (pdnsOutQ ver count qname qtype)
-- debug
io $ putStrLn $ "LOG\tRequest number " ++ (show count)
++ " id: " ++ (show id)
runStateT mainloop (0, empty) >> return ()
+-- helper for command-line tools
+
+pdnsOut key qt dom =
+ case qt of
+ "AXFR" -> pdnsOutXfr 1 (-1) key dom
+ _ -> pdnsOutQ 1 (-1) key (rrType qt) dom
+
-- query by key from Namecoin
mainOne key qt = do
mgr <- newManager def
dom <- queryDom (queryOpNmc cfg mgr (-1)) key
putStrLn $ ppShow dom
- putStr $ pdnsOut 1 (-1) key qt dom
+ putStr $ pdnsOut key qt dom
-- using file backend for testing json domain data
mainFile key qt = do
dom <- queryDom queryOpFile key
putStrLn $ ppShow dom
- putStr $ pdnsOut 1 (-1) key qt dom
+ putStr $ pdnsOut key qt dom
-- Entry point
args <- getArgs
case args of
[] -> mainPdnsNmc
- [key, qtype] -> mainOne key (rrType qtype)
- ["-f" ,key, qtype] -> mainFile key (rrType qtype)
- _ -> error $ "usage: empty args, or \"[-f] <fqdn> <QTYPE>\" (type in caps)"
+ [key, qtype] -> mainOne key qtype
+ ["-f" ,key, qtype] -> mainFile key qtype
+ _ -> error $ "usage: empty args, or \"[-f] <fqdn> {<TYPE>|ANY|AXFR}\" (type in caps)"