Index: internet/interfaces.py
===================================================================
--- internet/interfaces.py	(revision 30842)
+++ internet/interfaces.py	(working copy)
@@ -56,12 +56,13 @@
 
 class IResolverSimple(Interface):
 
-    def getHostByName(name, timeout = (1, 3, 11, 45)):
+    def getHostByName(name, timeout = (1, 3, 11, 45), extended = False):
         """
         Resolve the domain name C{name} into an IP address.
 
         @type name: C{str}
         @type timeout: C{tuple}
+        @type extended: C{bool}
         @rtype: L{twisted.internet.defer.Deferred}
         @return: The callback of the Deferred that is returned will be
         passed a string that represents the IP address of the specified
@@ -69,7 +70,14 @@
         multiple types of address records are associated with the name,
         A6 records will be returned in preference to AAAA records, which
         will be returned in preference to A records.  If there are multiple
-        records of the type to be returned, one will be selected at random.
+        records of the type to be returned, one will be selected at random,
+        except when extended = True is specified, where the gethostbyname_ex
+        Python function's return value is returned, which is a tuple of
+        (hostname, aliaslist, ipaddrlist) where hostname is the primary host
+        name responding to the given ip_address, aliaslist is a (possibly
+        empty) list of alternative host names for the same address, and
+        ipaddrlist is a list of IPv4 addresses for the same interface on the
+        same host (often but not always a single address).
 
         @raise twisted.internet.defer.TimeoutError: Raised (asynchronously)
         if the name cannot be resolved within the specified timeout period.
Index: internet/base.py
===================================================================
--- internet/base.py	(revision 30842)
+++ internet/base.py	(working copy)
@@ -250,7 +250,7 @@
                 userDeferred.callback(result)
 
 
-    def getHostByName(self, name, timeout = (1, 3, 11, 45)):
+    def getHostByName(self, name, timeout = (1, 3, 11, 45), extended = False):
         """
         See L{twisted.internet.interfaces.IResolverSimple.getHostByName}.
 
@@ -258,6 +258,10 @@
         as a timeout for the lookup.  Any intermediate timeout or retry logic
         is left up to the platform via L{socket.gethostbyname}.
         """
+        if extended:
+            _gethostbyname = socket.gethostbyname_ex
+        else:
+            _gethostbyname = socket.gethostbyname
         if timeout:
             timeoutDelay = sum(timeout)
         else:
@@ -265,7 +269,7 @@
         userDeferred = defer.Deferred()
         lookupDeferred = threads.deferToThreadPool(
             self.reactor, self.reactor.getThreadPool(),
-            socket.gethostbyname, name)
+            _gethostbyname, name)
         cancelCall = self.reactor.callLater(
             timeoutDelay, self._cleanup, name, lookupDeferred)
         self._runningQueries[lookupDeferred] = (userDeferred, cancelCall)
@@ -277,9 +281,12 @@
 class BlockingResolver:
     implements(IResolverSimple)
 
-    def getHostByName(self, name, timeout = (1, 3, 11, 45)):
+    def getHostByName(self, name, timeout = (1, 3, 11, 45), extended = False):
         try:
-            address = socket.gethostbyname(name)
+            if extended:
+                address = socket.gethostbyname_ex(name)
+            else:
+                address = socket.gethostbyname(name)
         except socket.error:
             msg = "address %r not found" % (name,)
             err = error.DNSLookupError(msg)
@@ -548,7 +555,7 @@
             reflect.qual(self.__class__) + " did not implement getWriters")
 
 
-    def resolve(self, name, timeout = (1, 3, 11, 45)):
+    def resolve(self, name, timeout = (1, 3, 11, 45), extended = False):
         """Return a Deferred that will resolve a hostname.
         """
         if not name:
@@ -556,7 +563,7 @@
             return defer.succeed('0.0.0.0')
         if abstract.isIPAddress(name):
             return defer.succeed(name)
-        return self.resolver.getHostByName(name, timeout)
+        return self.resolver.getHostByName(name, timeout, extended)
 
     # Installation.
 
