patternMinor
A program to proxy MDNS requests to the DNS server
Viewed 0 times
mdnsproxytheprogramdnsrequestsserver
Problem
I wrote a program to proxy MDNS requests in a local network to the DNS server. This is useful because in some private networks, host names ending in ".local" are configured in the DNS server. But ".local" is actually reversed for MDNS. Some systems have problems resolving these host names because they only try to resolve names through MDNS while those names are configured in the DNS server.
I started to use Haskell because XMonad. This is my first "practical" program written in Haskell. It would be very helpful if anyone could kindly give me some suggestions to improve my code.
The repository is here: https://github.com/abaw/mdns2dns
Here's the code for the main program:
```
{-# LANGUAGE DoAndIfThenElse #-}
import Control.Monad (forever,forM,guard,void)
import Control.Concurrent (forkIO)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8 as C
import Data.Binary.Get (getWord32host,runGet)
import Data.Char (isAscii)
import Data.Functor (())
import Data.Maybe (catMaybes)
import Debug.Trace (traceShow)
import Network.DNS
import Network.Multicast (addMembership)
import Network.Socket hiding (recv,sendTo)
import Network.Socket.ByteString(recv,sendTo)
import System.Environment (getArgs)
import System.Exit (exitFailure)
-- | The port used for MDNS requests/respones
mdnsPort :: PortNumber
mdnsPort = 5353
-- | The multicast IP address used for MDNS responses
mdnsIp :: HostAddress
mdnsIp = runGet getWord32host $ BL.pack [224,0,0,251]
-- | The SockAddr used for MDNS response
mdnsAddr :: SockAddr
mdnsAddr = SockAddrInet mdnsPort mdnsIp
-- | The maximum size of UDP DNS message defined in RFC-1035
maxDNSMsgSize :: Int
maxDNSMsgSize = 512
-- | Convert a String with only ascii characters to Domain
toDomain :: String -> Domain
toDomain = C.pack
-- | Convert strict ByteString to lazy ByteString
bsFromStrict :: B.ByteString -> BL.ByteString
bsFromStrict = BL.pack . B.unpack
-- | Convert lazy ByteString to
I started to use Haskell because XMonad. This is my first "practical" program written in Haskell. It would be very helpful if anyone could kindly give me some suggestions to improve my code.
The repository is here: https://github.com/abaw/mdns2dns
Here's the code for the main program:
```
{-# LANGUAGE DoAndIfThenElse #-}
import Control.Monad (forever,forM,guard,void)
import Control.Concurrent (forkIO)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8 as C
import Data.Binary.Get (getWord32host,runGet)
import Data.Char (isAscii)
import Data.Functor (())
import Data.Maybe (catMaybes)
import Debug.Trace (traceShow)
import Network.DNS
import Network.Multicast (addMembership)
import Network.Socket hiding (recv,sendTo)
import Network.Socket.ByteString(recv,sendTo)
import System.Environment (getArgs)
import System.Exit (exitFailure)
-- | The port used for MDNS requests/respones
mdnsPort :: PortNumber
mdnsPort = 5353
-- | The multicast IP address used for MDNS responses
mdnsIp :: HostAddress
mdnsIp = runGet getWord32host $ BL.pack [224,0,0,251]
-- | The SockAddr used for MDNS response
mdnsAddr :: SockAddr
mdnsAddr = SockAddrInet mdnsPort mdnsIp
-- | The maximum size of UDP DNS message defined in RFC-1035
maxDNSMsgSize :: Int
maxDNSMsgSize = 512
-- | Convert a String with only ascii characters to Domain
toDomain :: String -> Domain
toDomain = C.pack
-- | Convert strict ByteString to lazy ByteString
bsFromStrict :: B.ByteString -> BL.ByteString
bsFromStrict = BL.pack . B.unpack
-- | Convert lazy ByteString to
Solution
Overall this code reads well. Nice job.
I do not know a better way to write
I have two concerns:
I do not know a better way to write
mdnsIp.I have two concerns:
- Logging. A proper daemon should have logging to let people know what is happening.
- Infinite loops. There are several places in the code where the service could just spin for an indeterminate amount of time. The usual solution to this is a timeout of some sort.
Context
StackExchange Code Review Q#29361, answer score: 2
Revisions (0)
No revisions yet.