diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,23 +7,59 @@
 [![AUR](https://img.shields.io/aur/version/dprox.svg)](https://aur.archlinux.org/packages/dprox/)
 [![License](https://img.shields.io/github/license/bjin/dprox.svg)](https://github.com/bjin/dprox/blob/master/LICENSE)
 
-dprox is a lightweight DNS proxy server. It's written as a drop-in replacement
-of dnsmasq to work with [dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list),
+`dprox` is a lightweight DNS proxy server. It's created as a drop-in replacement
+of [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) to work with
+[dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list),
 while improving the overall lookup performance over large domain list.
 
 ### Installation
 
-Only Linux and macOS are supported. [stack](https://docs.haskellstack.org/en/stable/README/#how-to-install) is required to build `dprox`.
+`dprox` should build and work on all unix-like OS with [ghc](https://www.haskell.org/ghc/) support, but it's only
+been tested on Linux and macOS.
 
+While `dprox` can be built with [cabal](https://www.haskell.org/cabal/) like any other Hackage packages, for a
+reliable compilation with pinned dependencies, [stack](https://docs.haskellstack.org/en/stable/README/#how-to-install) is generally recommended.
+
 ```sh
+stack setup
 stack install
 ```
 
+For Arch Linux users, an [AUR package](https://aur.archlinux.org/packages/dprox/) is also provided.
+
 ### Usage
 
-Only a small subset of dnsmasq options are implemented at the moment, just barely enough to work with `dnsmasq-china-list`.
+Only a small subset of dnsmasq options are implemented at the moment, just barely enough to work with `dnsmasq-china-list` and [hosts-blocklists](https://github.com/notracking/hosts-blocklists).
 
-Use `dprox --help` to list those options. A [systemd unit file](https://github.com/bjin/dprox/blob/master/systemd/dprox.service) is also provided for Linux user.
+Here is the list of implemented dnsmasq options (with `server`, `local`, `address` and `bogus-nxdomain` options allowed in configuration file):
+
+```
+-u, --user=<username>
+-p, --port=<port>
+-a, --listen-address=<ipaddr>
+-C, --conf-file=<file>
+-h, --no-hosts
+-H, --addn-hosts=<file>
+-S, --local, --server=[/<domain>/]<ipaddr>[#<port>]
+-A, --address=[/<domain>/]<ipaddr>
+-B, --bogus-nxdomain=<ipaddr>
+```
+
+Use `dprox --help` or [dnsmasq manpage](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for further details about these options.
+But be aware that there might be minor differences on some options like `--server`.
+
+To use `dprox` with `dnsmasq-china-list`, with "8.8.4.4" as the remote DNS server
+(systemd user can also use [this unit file](https://github.com/bjin/dprox/blob/master/systemd/dprox.service)):
+
+```sh
+dprox -C /etc/dnsmasq.d/accelerated-domains.china.conf -C /etc/dnsmasq.d/bogus-nxdomain.china.conf -S 8.8.4.4
+```
+
+To use `dprox` with `hosts-blocklists` and the default remote DNS server ("8.8.8.8"), without loading system hosts file:
+
+```sh
+dprox -C /opt/hosts-blocklists/domains.txt -H /opt/hosts-blocklists/hostnames.txt -h
+```
 
 ### Known Issue
 
diff --git a/dprox.cabal b/dprox.cabal
--- a/dprox.cabal
+++ b/dprox.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: d262889761a247d0874e1aea677d066dce6b02883a49661fd85293dd83929b03
+-- hash: e6d3163f54b56ac9d5fc87fae25c5446de14a1af8a295aa09b2db319888e28d7
 
 name:           dprox
-version:        0.1.1
+version:        0.1.2
 synopsis:       a lightweight DNS proxy server
 description:    Please see the README on GitHub at <https://github.com/bjin/dprox#readme>
 category:       DNS
@@ -41,17 +41,17 @@
       src
   ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      attoparsec
-    , base >=4.7 && <5
-    , bytestring
-    , containers
+      attoparsec >=0.13
+    , base >=4.12 && <5
+    , bytestring >=0.10
+    , containers >=0.6
     , dns >=3.0.4
-    , iproute
-    , network
-    , optparse-applicative
-    , streaming-commons
-    , unix
-    , unordered-containers
+    , iproute >=1.7
+    , network >=2.8 && <3
+    , optparse-applicative >=0.14
+    , streaming-commons >=0.2
+    , unix >=2.7
+    , unordered-containers >=0.2
   if flag(static)
     ghc-options: -optl-static
   default-language: Haskell2010
@@ -66,16 +66,16 @@
       test
   ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      attoparsec
-    , base >=4.7 && <5
-    , bytestring
-    , containers
+      attoparsec >=0.13
+    , base >=4.12 && <5
+    , bytestring >=0.10
+    , containers >=0.6
     , dns >=3.0.4
     , hspec
-    , iproute
-    , network
-    , optparse-applicative
-    , streaming-commons
-    , unix
-    , unordered-containers
+    , iproute >=1.7
+    , network >=2.8 && <3
+    , optparse-applicative >=0.14
+    , streaming-commons >=0.2
+    , unix >=2.7
+    , unordered-containers >=0.2
   default-language: Haskell2010
diff --git a/src/Config.hs b/src/Config.hs
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -7,6 +7,7 @@
 , Config(..)
 , getConfig
 , IP(..)
+, invalidIPAddress
 , PortNumber
 ) where
 
@@ -18,7 +19,8 @@
 import qualified Data.ByteString                  as BS
 import qualified Data.ByteString.Char8            as BS8
 import           Data.IP                          (IP (..))
-import           Data.Maybe                       (catMaybes)
+import           Data.Maybe                       (catMaybes, fromMaybe,
+                                                   isNothing)
 import           Data.Streaming.Network           (HostPreference)
 import           Data.String                      (fromString)
 import qualified Network.DNS                      as DNS
@@ -47,7 +49,7 @@
   where
     opts = info ((,,,) <$> globalOption <*> configFileOption
                        <*> hostsFilesOption <*> plainOption <**> helper)
-      ( fullDesc <> progDesc "a simple DNS proxy server")
+      ( fullDesc <> progDesc "a lightweight DNS proxy server, supports a small subset of dnsmasq options")
 
     readConfigFromFile file = handle handler (parseConfigFile <$> BS.readFile file)
     readHostsFromFile file = handle handler (parseHostsFile <$> BS.readFile file)
@@ -64,6 +66,7 @@
 
     parseConfig =
         parsePair "server" serverValue <|>
+        parsePair "local" serverValue <|>
         parsePair "address" addressValue <|>
         parsePair "bogus-nxdomain" bogusNXValue
 
@@ -115,6 +118,9 @@
         Nothing     -> fail ("invalid IP address: " ++ ipstr)
         Just ipaddr -> return ipaddr
 
+invalidIPAddress :: IP
+invalidIPAddress = "::"
+
 port :: P.Parser PortNumber
 port = read . BS8.unpack <$> P.takeWhile1 P8.isDigit_w8 <?> "Port Number"
 
@@ -126,39 +132,39 @@
     userOption = optional $ strOption
         ( long "user"
        <> short 'u'
-       <> metavar "uid"
-       <> help "set user id")
+       <> metavar "<username>"
+       <> help "Specify the userid to which dprox will change after startup")
 
     portOption = optional $ option auto
         ( long "port"
        <> short 'p'
-       <> metavar "port"
-       <> help "listen on this port instead of 53")
+       <> metavar "<port>"
+       <> help "Listen on this port instead of 53")
 
     listenOption = optional $ fromString <$> strOption
         ( long "listen-address"
        <> short 'a'
-       <> metavar "ipaddr"
+       <> metavar "<ipaddr>"
        <> help "Listen on the given IP address")
 
 configFileOption :: Parser [FilePath]
 configFileOption = many $ strOption
     ( long "conf-file"
    <> short 'C'
-   <> metavar "path/to/dprox.conf"
-   <> help "configure file to read")
+   <> metavar "<file>"
+   <> help "Configure file to read")
 
 hostsFilesOption :: Parser [FilePath]
 hostsFilesOption = combine <$> noHostsOption <*> many newHostsOption
   where
     combine False newHosts = "/etc/hosts" : newHosts
-    combine True newHosts = newHosts
+    combine True newHosts  = newHosts
 
     newHostsOption = strOption
         ( long "addn-hosts"
        <> short 'H'
-       <> metavar "path/to/hosts"
-       <> help "additional hosts file to read (other than /etc/hosts)")
+       <> metavar "<file>"
+       <> help "Additional hosts file to read other than /etc/hosts")
 
     noHostsOption = switch
         ( long "no-hosts"
@@ -170,21 +176,29 @@
   where
     server = option (attoparsecReader serverValue)
         ( long "server"
+       <> long "local"
        <> short 'S'
-       <> metavar "[/domain/]ip[#port]"
-       <> help "remote dns server ip")
+       <> metavar "[/<domain>/]<ipaddr>[#<port>]"
+       <> help serverMsg)
 
+    serverMsg = "Specify remote DNS server to use. " ++
+                "If multiple servers are specified, only the last one will be used. " ++
+                "If no server is specified, 8.8.8.8 will be used. " ++
+                "If <domain> is specified, queries matching this domain or its subdomains will use use specified remote DNS server. " ++
+                "If <ipaddr> is empty, queries matching specified domains will be handled by local hosts file only. " ++
+                "<port> can be used to specify alternative port for DNS server."
+
     address = option (attoparsecReader addressValue)
         ( long "address"
        <> short 'A'
-       <> metavar "/domain/ip"
-       <> help "specifiy ip for target domain")
+       <> metavar "[/<domain>/]<ipaddr>"
+       <> help "For DNS queries matching <domain> or its subdomains, replies <ipaddr> directly")
 
     bogusnx = option (attoparsecReader bogusNXValue)
         ( long "bogus-nxdomain"
        <> short 'B'
        <> metavar "ip"
-       <> help "specify ip for no such domain blacklist")
+       <> help "Transform replies which contain the IP address given into \"No such domain\" replies")
 
 attoparsecReader :: P.Parser a -> ReadM a
 attoparsecReader p = eitherReader (P.parseOnly (p <* P.endOfInput) . BS8.pack)
@@ -192,9 +206,10 @@
 serverValue :: P.Parser Config
 serverValue = do
     parsedDomain <- P.option Nothing (Just <$> (P8.char '/' *> domain <* P8.char '/'))
-    parsedIP <- ip
+    parsedIP <- P.option Nothing (Just <$> ip)
+    when (isNothing parsedDomain && isNothing parsedIP) $ fail "at least one of <domain> and <ip> must be specified"
     parsedPort <- P.option Nothing (Just <$> (P8.char '#' *> port))
-    return (Server parsedDomain parsedIP parsedPort)
+    return (Server parsedDomain (fromMaybe invalidIPAddress parsedIP) parsedPort)
 
 addressValue :: P.Parser Config
 addressValue = Address <$> (P8.char '/' *> domain <* P8.char '/') <*> ip
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -7,10 +7,9 @@
 
 import           Control.Concurrent        (forkIO)
 import           Control.Exception         (SomeException, handle)
-import           Control.Monad             (forM, forever)
+import           Control.Monad             (forM, forever, join)
 import           Data.ByteString           (ByteString)
 import qualified Data.Foldable             as F
-import           Data.Map                  ((!))
 import qualified Data.Map                  as M
 import           Data.Maybe                (fromMaybe)
 import qualified Data.Set                  as S
@@ -67,10 +66,12 @@
         q <- DNS.decode bs
         if DNS.qOrR (DNS.flags (DNS.header q)) == DNS.QR_Query then return q else Left DNS.FormatError
 
-handleServer :: DomainRoute Resolver -> Resolver
-handleServer route qd = resolver qd
+handleServer :: DomainRoute (Maybe Resolver) -> Resolver
+handleServer route qd qt = case resolver of
+    Nothing        -> return (Left DNS.NameError)
+    Just resolver' -> resolver' qd qt
   where
-    resolver = fromMaybe (error "handleServer: internal error") (getDomainRouteByPrefix route qd)
+    resolver = join (getDomainRouteByPrefix route qd)
 
 handleAddressAndHosts :: DomainRoute [IP] -> DomainRoute [IP] -> Resolver -> Resolver
 handleAddressAndHosts address hosts resolver qd qt =
@@ -122,6 +123,7 @@
 
         resolvConfs = [ (addr, rc)
                       | addr@(host, port) <- S.toList serverAddressSet
+                      , host /= invalidIPAddress
                       , let rsinfo = if port == defaultPort
                                 then DNS.RCHostName (show host)
                                 else DNS.RCHostPort (show host) port
@@ -146,7 +148,7 @@
 
         createResolvers ((k,v):xs) m = DNS.withResolver v $ \rs ->
             createResolvers xs (M.insert k (DNS.lookup rs) m)
-        createResolvers [] m = let serverRoute' = fmap (m!) serverRoute
+        createResolvers [] m = let serverRoute' = fmap (`M.lookup`m) serverRoute
                                    resolver = handleBogusNX bogusnxSet $
                                               handleAddressAndHosts addressRoute hostsRoute $
                                               handleServer serverRoute'
