]> gitweb @ CieloNegro.org - haskell-dns.git/commitdiff
The server started somewhat working...
authorPHO <pho@cielonegro.org>
Mon, 25 May 2009 08:08:04 +0000 (17:08 +0900)
committerPHO <pho@cielonegro.org>
Mon, 25 May 2009 08:08:04 +0000 (17:08 +0900)
ExampleDNSServer.hs
Network/DNS/Message.hs
Network/DNS/Named.hs
Network/DNS/Named/Responder.hs
Network/DNS/Named/Zone.hs

index e1aaa22e1cf56b86d9c9ce38700073a6bfbadcae..f590caab054b7d58240b9ae1c0e9d208682c42fc 100644 (file)
@@ -1,8 +1,10 @@
 import           Network.DNS.Message
 import           Network.DNS.Named
 import           Network.DNS.Named.Config
+import           Network.DNS.Named.Responder
 import           Network.DNS.Named.Zone
 import           Network.Socket
+import           System.IO.Unsafe
 
 main :: IO ()
 main = runNamed cnf zoneFor
@@ -13,4 +15,32 @@ main = runNamed cnf zoneFor
             }
 
       zoneFor :: DomainName -> Maybe Zone
-      zoneFor = const Nothing -- FIXME
\ No newline at end of file
+      zoneFor name
+          | name `isInZone` zone = Just zone
+          | otherwise            = Nothing
+
+      zone :: Zone
+      zone = Zone {
+               zoneName       = mkDN "cielonegro.org."
+             , zoneResponders = [ wrapResponder' $
+                                  do name <- getQueryName
+                                     if name == mkDN "ns.cielonegro.org." then
+                                         respond ResourceRecord {
+                                                       rrName  = name
+                                                     , rrType  = A
+                                                     , rrClass = IN
+                                                     , rrTTL   = 9600
+                                                     , rrData  = inetAddr "127.0.0.1"
+                                                     }
+                                       else
+                                         fail "FIXME: we want to throw NameError but we can't for now"
+                                ]
+             , zoneIsAuthoritative = True
+             }
+
+      wrapResponder' :: Responder A IN () -> SomeResponder
+      wrapResponder' = wrapResponder
+
+
+inetAddr :: String -> HostAddress
+inetAddr = unsafePerformIO . inet_addr
index fe595b4942e66686b17003eda1aa1ce4c9426577..9f2b144968c7f394e84068dae3a8cccd84b9b259 100644 (file)
@@ -50,6 +50,9 @@ module Network.DNS.Message
     , HS(..)
 
     , mkDomainName
+    , mkDN
+    , isZoneOf
+
     , wrapQuestion
     , wrapRecord
     )
@@ -70,6 +73,7 @@ import qualified Data.IntMap as IM
 import           Data.IntMap (IntMap)
 import qualified Data.IntSet as IS
 import           Data.IntSet (IntSet)
+import           Data.List
 import qualified Data.Map as M
 import           Data.Map (Map)
 import           Data.Word
@@ -224,6 +228,9 @@ unconsLabel :: DomainName -> (DomainLabel, DomainName)
 unconsLabel (DN (x:xs)) = (x, DN xs)
 unconsLabel x           = error ("Illegal use of unconsLabel: " ++ show x)
 
+isZoneOf :: DomainName -> DomainName -> Bool
+isZoneOf (DN a) (DN b) = a `isSuffixOf` b
+
 mkDomainName :: String -> DomainName
 mkDomainName = DN . mkLabels [] . notEmpty
     where
@@ -237,6 +244,9 @@ mkDomainName = DN . mkLabels [] . notEmpty
                                 -> mkLabels (C8.pack l : soFar) rest
                             _   -> error ("Illegal domain name: " ++ xs)
 
+mkDN :: String -> DomainName
+mkDN = mkDomainName
+
 
 class (Show rc, Eq rc, Typeable rc) => RecordClass rc where
     rcToInt :: rc -> Int
index 57d9ea4b78b6a765bce5a044444503211c1a8b21..dbe8e71c2865f135ac93d41d2439e3f4bf16d0e5 100644 (file)
@@ -72,7 +72,9 @@ runNamed cnf zf
                -- FIXME: this is merely a bogus implementation.
                -- It considers no additional or authoritative sections.
                results <- mapM (runResponder' q) (zoneResponders zone)
-               return $ mapM_ addAnswer $ concat results
+               return $ do mapM_ addAnswer $ concat results
+                           unless (zoneIsAuthoritative zone) $
+                                  unauthorise
 
 
 validateQuery :: Message -> ResponseCode
index 5148f2ba74361e2885edb0158660f6f1efc59a0e..b94b7ca43a48a5c3841d026fa58bcbf2aabbda26 100644 (file)
@@ -19,7 +19,7 @@ import Network.DNS.Message
 import Network.DNS.Named.Sanity
 
 
-data ResponderState qt qc
+data (QueryType qt, QueryClass qc) => ResponderState qt qc
     = ResponderState {
         rsQuestion :: !(Question qt qc)
       , rsAnswers  :: ![SomeRR]
@@ -31,13 +31,13 @@ newtype (QueryType qt, QueryClass qc) => Responder qt qc a
       }
     deriving Typeable
 
-instance (RecordType qt dt, RecordClass qc) => Monad (Responder qt qc) where
+instance (QueryType qt, QueryClass qc) => Monad (Responder qt qc) where
     return a = Responder $ \ s -> return (a, s)
     m >>= k  = Responder $ \ s -> do (a, s') <- unR m s
                                      unR (k a) s'
     fail err = Responder $ \ _ -> fail err
 
-instance (RecordType qt dt, RecordClass qc) => MonadIO (Responder qt qc) where
+instance (QueryType qt, QueryClass qc) => MonadIO (Responder qt qc) where
     liftIO m = Responder $ \ s -> do a <- m
                                      return (a, s)
 
@@ -66,16 +66,16 @@ runResponder' q (SomeResponder r)
         Just m
             -> runResponder q m
 
-getQuestion :: (RecordType qt dt, RecordClass qc) => Responder qt qc (Question qt qc)
+getQuestion :: (QueryType qt, QueryClass qc) => Responder qt qc (Question qt qc)
 getQuestion = Responder $ \ s ->
               return (rsQuestion s, s)
 
-getQueryName :: (RecordType qt dt, RecordClass qc) => Responder qt qc DomainName
+getQueryName :: (QueryType qt, QueryClass qc) => Responder qt qc DomainName
 getQueryName = liftM qName getQuestion
 
 respond :: ( SaneAnswerType qt at, SaneAnswerClass qc ac
            , QueryType qt, RecordType at dt
-           , RecordClass qc, RecordClass ac
+           , QueryClass qc, RecordClass ac
            ) =>
            ResourceRecord at ac dt
         -> Responder qt qc ()
@@ -89,7 +89,7 @@ respond rr
 data SomeResponder
     = forall qt qc. (Typeable qt, Typeable qc) => SomeResponder (Responder qt qc ())
 
-wrapResponder :: (RecordType qt dt, RecordClass qc) =>
+wrapResponder :: (QueryType qt, QueryClass qc) =>
                  Responder qt qc a
               -> SomeResponder
 wrapResponder m
index 8311376661bf5b506d951f802234448aab79e677..6cde400e8f5ce6fdbe49e6575d03468e456f0776 100644 (file)
@@ -2,6 +2,8 @@ module Network.DNS.Named.Zone
     ( Zone(..)
     , ZoneFinder(..)
 
+    , isInZone
+
     , defaultRootZone
     )
     where
@@ -13,8 +15,9 @@ import Network.DNS.Named.Responder
 
 data Zone
     = Zone {
-        zoneName       :: !DomainName
-      , zoneResponders :: ![SomeResponder]
+        zoneName            :: !DomainName
+      , zoneResponders      :: ![SomeResponder]
+      , zoneIsAuthoritative :: !Bool
       }
 
 class ZoneFinder a where
@@ -33,9 +36,14 @@ instance ZoneFinder (DomainName -> IO (Maybe Zone)) where
     findZone = (fmap (fromMaybe defaultRootZone) .)
 
 
+isInZone :: DomainName -> Zone -> Bool
+isInZone name zone = zoneName zone `isZoneOf` name
+
+
 defaultRootZone :: Zone
 defaultRootZone
     = Zone {
-        zoneName       = mkDomainName "."
-      , zoneResponders = [] -- FIXME
+        zoneName            = mkDomainName "."
+      , zoneResponders      = [] -- FIXME
+      , zoneIsAuthoritative = False
       }