module Resolve.DNS.UDP where import qualified Resolve.DNS.Channel as C import Resolve.Types import Resolve.DNS.Types import Network.Socket hiding (send, sendTo, recv, recvFrom, socket) import Network.Socket.ByteString import qualified Data.ByteString as BS import Data.Typeable import Control.Exception import Control.Monad import System.Log.Logger nameM = "Resolve.DNS.UDP" data Config = Config { socket :: Socket , server :: SockAddr } data QueryTooLong = QueryTooLong deriving (Typeable, Show) instance Exception QueryTooLong where toException = dnsExceptionToException fromException = dnsExceptionFromException maxLength = 512 new :: Config -> IO (Resolver Message Message) new c = do chan <- C.new C.Config { C.send = \a -> do let nameF = nameM ++ ".send" if BS.length a > maxLength then throw QueryTooLong else do void $ sendTo (socket c) a (server c) , C.recv = let loop = do let nameF = nameM ++ ".recv" (bs, sa) <- (recvFrom (socket c) maxLength) if sa /= (server c) then loop else return bs in loop , C.nick = "UDP<" ++ (show $ socket $ c) ++ ">" ++ (show $ server $ c) } return $ Resolver { resolve = resolve chan , delete = delete chan }