diff --git a/NEWS.md b/NEWS.md
--- a/NEWS.md
+++ b/NEWS.md
@@ -3,14 +3,13 @@
 
 
 
-libravatar 0.4.0.1    2017-07-29
+libravatar 0.4.0.2    2017-12-20
 ================================
 
 General, build and documentation changes:
 
-* Replace mention of 'defOpts' with 'def' in doc comment
-* Build with GHC 8 and latest LTS
-* Update homepage and bug report URLs
+* The `dns` package has a new major release with breaking changes, we now
+  support that new version
 
 New APIs, features and enhancements:
 
diff --git a/libravatar.cabal b/libravatar.cabal
--- a/libravatar.cabal
+++ b/libravatar.cabal
@@ -1,12 +1,12 @@
 name: libravatar
-version: 0.4.0.1
+version: 0.4.0.2
 cabal-version: >=1.10
 build-type: Simple
 license: PublicDomain
 license-file: COPYING
 copyright: ♡ Copying is an act of love. Please copy, reuse and share.
 maintainer: fr33domlover@riseup.net
-homepage: https://rel4.seek-together.space/projects/libravatar/
+homepage: https://hub.darcs.net/fr33domlover/libravatar
 bug-reports: fr33domlover@riseup.net
 synopsis: Use Libravatar, the decentralized avatar delivery service
 description:
@@ -24,22 +24,22 @@
 
 source-repository head
     type: darcs
-    location: http://hub.darcs.net/fr33domlover/libravatar
+    location: https://hub.darcs.net/fr33domlover/libravatar
 
 library
     exposed-modules:
         Network.Libravatar
     build-depends:
         base >=4.7 && <5,
-        bytestring >=0.10.8.1,
-        cryptonite >=0.21,
-        data-default-class >=0.1.2.0,
-        dns >=2.0.10,
-        memory >=0.14.6,
-        random >=1.1,
-        text >=1.2.2.1,
-        uri-bytestring >=0.2.3.3,
-        url >=2.1.3
+        bytestring >=0.10.8.1 && <0.11,
+        cryptonite ==0.23.*,
+        data-default-class >=0.1.2.0 && <0.2,
+        dns >=2.0.13 && <2.1,
+        memory >=0.14.10 && <0.15,
+        random ==1.1.*,
+        text >=1.2.2.2 && <1.3,
+        uri-bytestring >=0.2.3.3 && <0.3,
+        url >=2.1.3 && <2.2
     default-language: Haskell2010
     hs-source-dirs: src
     ghc-options: -Wall
diff --git a/src/Network/Libravatar.hs b/src/Network/Libravatar.hs
--- a/src/Network/Libravatar.hs
+++ b/src/Network/Libravatar.hs
@@ -1,6 +1,6 @@
 {- This file is part of libravatar for Haskell.
  -
- - Written in 2015, 2016 by fr33domlover <fr33domlover@riseup.net>.
+ - Written in 2015, 2016, 2017 by fr33domlover <fr33domlover@riseup.net>.
  -
  - ♡ Copying is an act of love. Please copy, reuse and share.
  -
@@ -97,6 +97,9 @@
 import Data.Maybe (catMaybes, fromMaybe)
 import Data.Monoid ((<>))
 import Data.Text (Text)
+#if MIN_VERSION_dns(3,0,0)
+import Data.Word (Word16)
+#endif
 import Network.DNS.Lookup
 import Network.DNS.Resolver
 import Network.DNS.Types (DNSError, Domain)
@@ -193,7 +196,7 @@
     def = DefaultSize
 
 -- | Avatar details in addition to the user address itself. Define by starting
--- with 'def' and override fields using record syntax.
+-- with 'defOpts' and override fields using record syntax.
 data AvatarOptions = AvatarOptions
     { -- | Whether the avatar URL should be secure (use HTTPS).
       optSecure      :: Bool
@@ -300,7 +303,14 @@
 
 -- Get a random list item, with distribution based on weights. Weights must be
 -- non-negative. Any negative weights will just be treated as zero weights.
-weightedRandom :: (a -> Int) -> [a] -> IO a
+weightedRandom
+#if MIN_VERSION_dns(3,0,0)
+    :: (a -> Word16)
+#else
+    :: (a -> Int)
+#endif
+    -> [a]
+    -> IO a
 weightedRandom getw l =
     let wlist = map getw l
         wlist' = map (max 0) wlist
@@ -316,14 +326,27 @@
 
 -- Ensure we are getting a (mostly) valid hostname and port number from the DNS
 -- resolver
+#if MIN_VERSION_dns(3,0,0)
+targetSane :: Domain -> Word16 -> Bool
+#else
 targetSane :: Domain -> Int -> Bool
+#endif
 targetSane target port =
     not (BC.null target) &&
     BC.any NU.ok_host target &&
+#if MIN_VERSION_dns(3,0,0)
+    1 <= port
+#else
     1 <= port && port <= 65535
+#endif
 
 -- Get the right (target, port) pair from a list of SRV records
-srvHostname :: [(Int, Int, Int, Domain)] -> IO (Maybe (Domain, Int))
+srvHostname
+#if MIN_VERSION_dns(3,0,0)
+    :: [(Word16, Word16, Word16, Domain)] -> IO (Maybe (Domain, Word16))
+#else
+    :: [(Int, Int, Int, Domain)] -> IO (Maybe (Domain, Int))
+#endif
 srvHostname []                     = return Nothing
 srvHostname [(_, _, port, target)] = return $ Just (target, port)
 srvHostname records =
@@ -343,9 +366,14 @@
 
 -- Pick the right server and return its normalized hostname, i.e. only include
 -- the port number if it's necessary
-normalizedTarget :: [(Int, Int, Int, Domain)]
-                 -> Bool
-                 -> IO (Maybe NU.Host)
+normalizedTarget
+#if MIN_VERSION_dns(3,0,0)
+    :: [(Word16, Word16, Word16, Domain)]
+#else
+    :: [(Int, Int, Int, Domain)]
+#endif
+    -> Bool
+    -> IO (Maybe NU.Host)
 normalizedTarget records https = do
     tp <- srvHostname records
     let sane = maybe False (uncurry targetSane) tp
