Ticket #3014: ipv6.2.patch

File ipv6.2.patch, 56.1 KB (added by dripton, 6 years ago)

Version 3 of the ipv6 patch

  • twisted/internet/abstract.py

    diff --git a/twisted/internet/abstract.py b/twisted/internet/abstract.py
    index 4419d61..eea676a 100644
    a b  
    11# -*- test-case-name: twisted.test.test_abstract -*- 
    2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. 
     2# Copyright (c) 2001-2008 Twisted Matrix Laboratories. 
    33# See LICENSE for details. 
    44 
    55 
    API Stability: stable 
    1010Maintainer: U{Itamar Shtull-Trauring<mailto:twisted@itamarst.org>} 
    1111""" 
    1212 
     13import socket 
     14 
    1315from zope.interface import implements 
    1416 
    1517# Twisted Imports 
    def isIPAddress(addr): 
    366368    return False 
    367369 
    368370 
     371def isIPv6Address(ip): 
     372    """ 
     373    Return True iff ip is a valid bare IPv6 address. 
     374 
     375    Return False for 'enhanced' IPv6 addresses like '::1%lo' and '::1/128' 
     376    """ 
     377    try: 
     378        socket.inet_pton(socket.AF_INET6, ip) 
     379    except (ValueError, socket.error): 
     380        return False 
     381    return True 
     382 
     383 
    369384__all__ = ["FileDescriptor"] 
  • twisted/internet/address.py

    diff --git a/twisted/internet/address.py b/twisted/internet/address.py
    index b349080..3f25770 100644
    a b class IPv4Address(object): 
    2121    # _bwHack is given to old users who think we are a tuple. They expected 
    2222    # addr[0] to define the socket type rather than the address family, so 
    2323    # the value comes from a different namespace than the new .type value: 
    24      
     24 
    2525    #  type = map[_bwHack] 
    2626    # map = { 'SSL': 'TCP', 'INET': 'TCP', 'INET_UDP': 'UDP' } 
    2727 
    2828    implements(IAddress) 
    29      
     29 
    3030    def __init__(self, type, host, port, _bwHack = None): 
    31         assert type in ('TCP', 'UDP') 
     31        if type not in ('TCP', 'UDP'): 
     32            raise ValueError, "illegal transport type" 
    3233        self.type = type 
    3334        self.host = host 
    3435        self.port = port 
    class IPv4Address(object): 
    5657    def __str__(self): 
    5758        return 'IPv4Address(%s, %r, %d)' % (self.type, self.host, self.port) 
    5859 
     60class IPv6Address(object): 
     61    """ 
     62    Object representing an IPv6 socket endpoint. 
     63 
     64    @ivar type: A string describing the type of transport, either 'TCP' or 'UDP'. 
     65    @ivar host: A string containing the coloned-oct IP address. 
     66    @ivar port: An integer representing the port number. 
     67    @ivar flowinfo: An integer representing the sockaddr-in6 flowinfo 
     68    @ivar scopeid: An integer representing the sockaddr-in6 scopeid 
     69    """ 
     70 
     71    implements(IAddress) 
     72 
     73    def __init__(self, type, host, port, flowinfo=0, scopeid=0): 
     74        if type not in ('TCP', 'UDP'): 
     75            raise ValueError, "illegal transport type" 
     76        self.type = type 
     77        self.host = host 
     78        self.port = port 
     79        self.flowinfo = flowinfo 
     80        self.scopeid = scopeid 
     81 
     82    def __eq__(self, other): 
     83        if isinstance(other, tuple): 
     84            return tuple(self) == other 
     85        elif isinstance(other, IPv6Address): 
     86            a = (self.type, self.host, self.port, self.flowinfo, self.scopeid) 
     87            b = (other.type, other.host, other.port, other.flowinfo, other.scopeid) 
     88            return a == b 
     89        return False 
     90 
     91    def __str__(self): 
     92        return 'IPv6Address(%s, %r, %d, %s, %s, %s)' % (self.type, self.host, 
     93          self.port, self.flowinfo, self.scopeid) 
    5994 
    6095class UNIXAddress(object): 
    6196    """ 
    class UNIXAddress(object): 
    66101    """ 
    67102 
    68103    implements(IAddress) 
    69      
     104 
    70105    def __init__(self, name, _bwHack='UNIX'): 
    71106        self.name = name 
    72107        self._bwHack = _bwHack 
    73      
     108 
    74109    def __getitem__(self, index): 
    75110        warnings.warn("UNIXAddress.__getitem__ is deprecated.  Use attributes instead.", 
    76111                      category=DeprecationWarning, stacklevel=2) 
    class UNIXAddress(object): 
    100135 
    101136class _ServerFactoryIPv4Address(IPv4Address): 
    102137    """Backwards compatability hack. Just like IPv4Address in practice.""" 
    103      
     138 
    104139    def __eq__(self, other): 
    105140        if isinstance(other, tuple): 
    106141            warnings.warn("IPv4Address.__getitem__ is deprecated.  Use attributes instead.", 
  • twisted/internet/base.py

    diff --git a/twisted/internet/base.py b/twisted/internet/base.py
    index 3337fca..8f7e16c 100644
    a b class DelayedCall(styles.Ephemeral): 
    194194        return "".join(L) 
    195195 
    196196 
     197def getHostByName(name): 
     198    """ 
     199    Call socket.getaddrinfo, using the args and return value type of 
     200    socket.gethostbyname 
     201    """ 
     202    lst = socket.getaddrinfo(name, None) 
     203    res = lst[0] 
     204    (family, socktype, proto, canonname, sockaddr) = res 
     205    address = sockaddr[0] 
     206    return address 
     207 
     208 
    197209class ThreadedResolver: 
    198210    implements(IResolverSimple) 
    199211 
    class ThreadedResolver: 
    224236            else: 
    225237                userDeferred.callback(result) 
    226238 
     239 
     240 
    227241    def getHostByName(self, name, timeout = (1, 3, 11, 45)): 
    228242        if timeout: 
    229243            timeoutDelay = reduce(operator.add, timeout) 
    230244        else: 
    231245            timeoutDelay = 60 
    232246        userDeferred = defer.Deferred() 
    233         lookupDeferred = threads.deferToThread(socket.gethostbyname, name) 
     247        lookupDeferred = threads.deferToThread(getHostByName, name) 
    234248        cancelCall = self.reactor.callLater( 
    235249            timeoutDelay, self._cleanup, name, lookupDeferred) 
    236250        self._runningQueries[lookupDeferred] = (userDeferred, cancelCall) 
    class BlockingResolver: 
    242256 
    243257    def getHostByName(self, name, timeout = (1, 3, 11, 45)): 
    244258        try: 
    245             address = socket.gethostbyname(name) 
     259            address = getHostByName(name) 
    246260        except socket.error: 
    247261            msg = "address %r not found" % (name,) 
    248262            err = error.DNSLookupError(msg) 
  • twisted/internet/interfaces.py

    diff --git a/twisted/internet/interfaces.py b/twisted/internet/interfaces.py
    index d9c2744..3d1b45a 100644
    a b class IReactorTCP(Interface): 
    209209                 docs for details. 
    210210        """ 
    211211 
     212class IReactorTCP6(Interface): 
     213 
     214    def listenTCP6(port, factory, backlog=50, interface=''): 
     215        """ 
     216        Connects a given protocol factory to the given numeric TCP/IPv6 port. 
     217 
     218        @param port: a port number on which to listen 
     219 
     220        @param factory: a L{twisted.internet.protocol.ServerFactory} instance 
     221 
     222        @param backlog: size of the listen queue 
     223 
     224        @param interface: the hostname to bind to, defaults to '' (all) 
     225 
     226        @return: an object that provides L{IListeningPort}. 
     227 
     228        @raise CannotListenError: as defined here 
     229                                  L{twisted.internet.error.CannotListenError}, 
     230                                  if it cannot listen on this port (e.g., it 
     231                                  cannot bind to the required port number) 
     232        """ 
     233 
     234    def connectTCP6(host, port, factory, timeout=30, bindAddress=None): 
     235        """ 
     236        Connect a TCPv6 client. 
     237 
     238        @param host: a host name 
     239 
     240        @param port: a port number 
     241 
     242        @param factory: a L{twisted.internet.protocol.ClientFactory} instance 
     243 
     244        @param timeout: number of seconds to wait before assuming the 
     245                        connection has failed. 
     246 
     247        @param bindAddress: a (host, port) tuple of local address to bind 
     248                            to, or None. 
     249 
     250        @return: An object which provides L{IConnector}. This connector will 
     251                 call various callbacks on the factory when a connection is 
     252                 made, failed, or lost - see 
     253                 L{ClientFactory<twisted.internet.protocol.ClientFactory>} 
     254                 docs for details. 
     255        """ 
     256 
    212257class IReactorSSL(Interface): 
    213258 
    214259    def connectSSL(host, port, factory, contextFactory, timeout=30, bindAddress=None): 
  • twisted/internet/posixbase.py

    diff --git a/twisted/internet/posixbase.py b/twisted/internet/posixbase.py
    index ab2d9b5..691f265 100644
    a b  
    11# -*- test-case-name: twisted.test.test_internet -*- 
    22# 
    3 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. 
     3# Copyright (c) 2001-2008 Twisted Matrix Laboratories. 
    44# See LICENSE for details. 
    55 
    66 
    from zope.interface import implements, classImplements 
    2222 
    2323from twisted.internet.interfaces import IReactorUNIX, IReactorUNIXDatagram 
    2424from twisted.internet.interfaces import IReactorTCP, IReactorUDP, IReactorSSL, IReactorArbitrary 
     25from twisted.internet.interfaces import IReactorTCP6 
    2526from twisted.internet.interfaces import IReactorProcess, IReactorMulticast 
    2627from twisted.internet.interfaces import IHalfCloseableDescriptor 
    2728from twisted.internet import error 
    class PosixReactorBase(ReactorBase): 
    167168    """ 
    168169    A basis for reactors that use file descriptors. 
    169170    """ 
    170     implements(IReactorArbitrary, IReactorTCP, IReactorUDP, IReactorMulticast) 
     171    implements(IReactorArbitrary, IReactorTCP, IReactorTCP6, IReactorUDP, 
     172               IReactorMulticast) 
    171173 
    172174    def __init__(self): 
    173175        ReactorBase.__init__(self) 
    class PosixReactorBase(ReactorBase): 
    481483        c.connect() 
    482484        return c 
    483485 
     486    # IReactorTCP6 
     487 
     488    def listenTCP6(self, port, factory, backlog=50, interface=''): 
     489        """ 
     490        @see: twisted.internet.interfaces.IReactorTCP.listenTCP6 
     491        """ 
     492        p = tcp.Port6(port, factory, backlog, interface, self) 
     493        p.startListening() 
     494        return p 
     495 
     496    def connectTCP6(self, host, port, factory, timeout=30, bindAddress=None, 
     497                    flowinfo=0, scopeid=0): 
     498        """ 
     499        @see: twisted.internet.interfaces.IReactorTCP.connectTCP6 
     500        """ 
     501        c = tcp.Connector6(host, port, factory, timeout, bindAddress, self, 
     502                           flowinfo, scopeid) 
     503        c.connect() 
     504        return c 
     505 
    484506    # IReactorSSL (sometimes, not implemented) 
    485507 
    486508    def connectSSL(self, host, port, factory, contextFactory, timeout=30, bindAddress=None): 
  • twisted/internet/protocol.py

    diff --git a/twisted/internet/protocol.py b/twisted/internet/protocol.py
    index 15e344c..5909d09 100644
    a b  
    11# -*- test-case-name: twisted.test.test_factories -*- 
    22# 
    3 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. 
     3# Copyright (c) 2001-2008 Twisted Matrix Laboratories. 
    44# See LICENSE for details. 
    55 
    66 
    class _InstanceFactory(ClientFactory): 
    137137    """Factory used by ClientCreator.""" 
    138138 
    139139    noisy = False 
    140      
     140 
    141141    def __init__(self, reactor, instance, deferred): 
    142142        self.reactor = reactor 
    143143        self.instance = instance 
    class _InstanceFactory(ClientFactory): 
    145145 
    146146    def __repr__(self): 
    147147        return "<ClientCreator factory: %r>" % (self.instance, ) 
    148      
     148 
    149149    def buildProtocol(self, addr): 
    150150        self.reactor.callLater(0, self.deferred.callback, self.instance) 
    151151        del self.deferred 
    class ClientCreator: 
    162162    The various connect* methods create a protocol instance using the given 
    163163    protocol class and arguments, and connect it, returning a Deferred of the 
    164164    resulting protocol instance. 
    165      
     165 
    166166    Useful for cases when we don't really need a factory.  Mainly this 
    167167    is when there is no shared state between protocol instances, and no need 
    168168    to reconnect. 
    class ClientCreator: 
    181181        self.reactor.connectTCP(host, port, f, timeout=timeout, bindAddress=bindAddress) 
    182182        return d 
    183183 
     184    def connectTCP6(self, host, port, timeout=30, bindAddress=None): 
     185        """ 
     186        Connect to remote host, return Deferred of resulting protocol instance. 
     187        @see twisted.internet.interfaces.IReactorTCP6.connectTCP6 
     188        """ 
     189        d = defer.Deferred() 
     190        f = _InstanceFactory(self.reactor, self.protocolClass(*self.args,  
     191                                                    **self.kwargs), d) 
     192        self.reactor.connectTCP6(host, port, f, timeout=timeout,  
     193                                 bindAddress=bindAddress) 
     194        return d 
     195 
    184196    def connectUNIX(self, address, timeout = 30, checkPID=0): 
    185197        """Connect to Unix socket, return Deferred of resulting protocol instance.""" 
    186198        d = defer.Deferred() 
    187199        f = _InstanceFactory(self.reactor, self.protocolClass(*self.args, **self.kwargs), d) 
    188200        self.reactor.connectUNIX(address, f, timeout = timeout, checkPID=checkPID) 
    189201        return d 
    190      
     202 
    191203    def connectSSL(self, host, port, contextFactory, timeout=30, bindAddress=None): 
    192204        """Connect to SSL server, return Deferred of resulting protocol instance.""" 
    193205        d = defer.Deferred() 
    class FileWrapper: 
    630642    def pauseProducing(self): 
    631643        # Never sends data anyways 
    632644        pass 
    633      
     645 
    634646    def stopProducing(self): 
    635647        self.loseConnection() 
    636          
    637648 
    638 __all__ = ["Factory", "ClientFactory", "ReconnectingClientFactory", "connectionDone",  
     649 
     650__all__ = ["Factory", "ClientFactory", "ReconnectingClientFactory", "connectionDone", 
    639651           "Protocol", "ProcessProtocol", "FileWrapper", "ServerFactory", 
    640652           "AbstractDatagramProtocol", "DatagramProtocol", "ConnectedDatagramProtocol", 
    641653           "ClientCreator"] 
  • twisted/internet/tcp.py

    diff --git a/twisted/internet/tcp.py b/twisted/internet/tcp.py
    index bbb7029..2a567eb 100644
    a b if platformType == 'win32': 
    5252    ENOMEM = object() 
    5353    EAGAIN = EWOULDBLOCK 
    5454    from errno import WSAECONNRESET as ECONNABORTED 
    55      
    56     from twisted.python.win32 import formatError as strerror     
     55 
     56    from twisted.python.win32 import formatError as strerror 
    5757else: 
    5858    from errno import EPERM 
    5959    from errno import EINVAL 
    else: 
    7070    from errno import ENOMEM 
    7171    from errno import EAGAIN 
    7272    from errno import ECONNABORTED 
    73      
     73 
    7474    from os import strerror 
    7575 
    7676from errno import errorcode 
    class Connector(base.BaseConnector): 
    892892 
    893893    def getDestination(self): 
    894894        return address.IPv4Address('TCP', self.host, self.port, 'INET') 
     895 
     896 
     897class Client6(Client): 
     898    """ 
     899    A TCP6 client. 
     900    """ 
     901    addressFamily = socket.AF_INET6 
     902 
     903    def __init__(self, host, port, bindAddress, connector, reactor=None, 
     904                 flowinfo=0, scopeid=0): 
     905        Client.__init__(self, host, port, bindAddress, connector, reactor) 
     906        self.addr = (host, port, flowinfo, scopeid) 
     907 
     908    def resolveAddress(self): 
     909        """ 
     910        Lookup the IPv6 address for self.addr[0] if necessary, then set 
     911        self.realAddress to that IPv6 address. 
     912        """ 
     913        if abstract.isIPv6Address(self.addr[0]): 
     914            self._setRealAddress(self.addr[0]) 
     915        else: 
     916            d = self.reactor.resolve(self.addr[0]) 
     917            d.addCallbacks(self._setRealAddress, self.failIfNotConnected) 
     918 
     919    def _setRealAddress(self, address): 
     920        """ 
     921        Set self.realAddress[0] to address.  Set the remaining parts of  
     922        self.realAddress to the corresponding parts of self.addr. 
     923        """ 
     924        self.realAddress = (address, self.addr[1], self.addr[2], self.addr[3]) 
     925        self.doConnect() 
     926 
     927    def getHost(self): 
     928        """ 
     929        Returns an IPv6Address. 
     930 
     931        This indicates the address from which I am connecting. 
     932        """ 
     933        return address.IPv6Address('TCP', *(self.socket.getsockname())) 
     934 
     935    def getPeer(self): 
     936        """ 
     937        Returns an IPv6Address. 
     938 
     939        This indicates the address that I am connected to. 
     940        """ 
     941        return address.IPv6Address('TCP', *(self.addr)) 
     942 
     943    def __repr__(self): 
     944        s = '<%s to %s at %x>' % (self.__class__, self.addr, unsignedID(self)) 
     945        return s 
     946 
     947 
     948class Server6(Server): 
     949    """ 
     950    IPv6 serverside socket-stream connection class. 
     951 
     952    This is a serverside network connection transport; a socket which came from 
     953    an accept() on a server. 
     954    """ 
     955    def getHost(self): 
     956        """ 
     957        Returns an IPv6Address. 
     958 
     959        This indicates the server's address. 
     960        """ 
     961        return address.IPv6Address('TCP', *(self.socket.getsockname())) 
     962 
     963    def getPeer(self): 
     964        """ 
     965        Returns an IPv6Address. 
     966 
     967        This indicates the client's address. 
     968        """ 
     969        return address.IPv6Address('TCP', *(self.client)) 
     970 
     971 
     972class Connector6(base.BaseConnector): 
     973    """ 
     974    IPv6 implementation of connector 
     975 
     976    @ivar flowinfo An integer representing the sockaddr-in6 flowinfo 
     977    @ivar scopeid An integer representing the sockaddr-in6 scopeid 
     978    """ 
     979 
     980    def __init__(self, host, port, factory, timeout, bindAddress, 
     981                 reactor=None, flowinfo=0, scopeid=0): 
     982        self.host = host 
     983        if isinstance(port, types.StringTypes): 
     984            try: 
     985                port = socket.getservbyname(port, 'tcp') 
     986            except socket.error, e: 
     987                raise error.ServiceNameUnknownError(string="%s (%r)" % (e, port)) 
     988        self.port = port 
     989        self.bindAddress = bindAddress 
     990        self.flowinfo = flowinfo 
     991        self.scopeid = scopeid 
     992        base.BaseConnector.__init__(self, factory, timeout, reactor) 
     993 
     994    def _makeTransport(self): 
     995        """ 
     996        Build and return a TCP6 client for the connector's transport. 
     997        """ 
     998        return Client6(self.host, self.port, self.bindAddress, self, 
     999                      self.reactor, self.flowinfo, self.scopeid) 
     1000 
     1001    def getDestination(self): 
     1002        """ 
     1003        @see twisted.internet.interfaces.IConnector.getDestination 
     1004        """ 
     1005        return address.IPv6Address('TCP', self.host, self.port, self.flowinfo, 
     1006                                   self.scopeid) 
     1007 
     1008 
     1009class Port6(Port): 
     1010    """ 
     1011    I am a TCP server port, listening for connections. 
     1012 
     1013    When a connection is accepted, I will call my factory's buildProtocol with 
     1014    the incoming connection as an argument, according to the specification 
     1015    described in twisted.internet.interfaces.IProtocolFactory. 
     1016 
     1017    If you wish to change the sort of transport that will be used, my 
     1018    `transport' attribute will be called with the signature expected for 
     1019    Server.__init__, so it can be replaced. 
     1020    """ 
     1021    addressFamily = socket.AF_INET6 
     1022    transport = Server6 
     1023 
     1024    def _buildAddr(self, (host, port, flowinfo, scopeid)): 
     1025        """ 
     1026        Build and return an IPv6Address from the passed sockaddr-in6 tuple. 
     1027        """ 
     1028        return address.IPv6Address('TCP', host, port, flowinfo, scopeid) 
     1029 
     1030    def getHost(self): 
     1031        """ 
     1032        Returns an IPv6Address. 
     1033 
     1034        This indicates the server's address. 
     1035        """ 
     1036        return address.IPv6Address('TCP', *(self.socket.getsockname())) 
  • twisted/test/test_abstract.py

    diff --git a/twisted/test/test_abstract.py b/twisted/test/test_abstract.py
    index 44b4646..294a69e 100644
    a b  
    1 # Copyright (c) 2007 Twisted Matrix Laboratories. 
     1# Copyright (c) 2007-2008 Twisted Matrix Laboratories. 
    22# See LICENSE for details. 
    33 
    44""" 
    Tests for generic file descriptor based reactor support code. 
    88from twisted.trial.unittest import TestCase 
    99 
    1010from twisted.internet.abstract import isIPAddress 
     11from twisted.internet.abstract import isIPv6Address 
    1112 
    1213 
    1314class AddressTests(TestCase): 
    class AddressTests(TestCase): 
    8182        self.assertFalse(isIPAddress('0.0.256.0')) 
    8283        self.assertFalse(isIPAddress('0.0.0.256')) 
    8384        self.assertFalse(isIPAddress('256.256.256.256')) 
     85 
     86 
     87class IPv6AddressTests(TestCase): 
     88    """ 
     89    Tests for IPv6 addresses. 
     90    """ 
     91    def test_hexadecimalColoned(self): 
     92        """ 
     93        L{isIPv6Address} should return C{True} for any valid colon-separated 
     94        hexadecimal representation of an IPv6 address. 
     95        """ 
     96        self.assertTrue(isIPv6Address('::1')) 
     97        self.assertTrue(isIPv6Address('fe80::215:cbfe:feac:8888')) 
     98        self.assertTrue(isIPv6Address('fe80::215:cbfe:feac:8888')) 
     99        self.assertTrue(isIPv6Address('fe80:5:5:5:215:cbfe:feac:8888')) 
     100 
     101    def test_illegalHexadecimalColoned(self): 
     102        """ 
     103        L{isIPv6Address} should return C{False} for any invalid colon-separated 
     104        hexadecimal representation of an IPv6 address. 
     105        """ 
     106        self.assertFalse(isIPv6Address(':1::2')) 
     107        self.assertFalse(isIPv6Address('fe80:5:5:5:215:cbfe:feac:8888:5')) 
     108        self.assertFalse(isIPv6Address('g::h')) 
  • twisted/test/test_tcp.py

    diff --git a/twisted/test/test_tcp.py b/twisted/test/test_tcp.py
    index ac7b8b9..d3cf433 100644
    a b from twisted.trial import unittest 
    1414from twisted.python.log import msg 
    1515from twisted.internet import protocol, reactor, defer, interfaces 
    1616from twisted.internet import error 
    17 from twisted.internet.address import IPv4Address 
     17from twisted.internet.address import IPv4Address, IPv6Address 
    1818from twisted.internet.interfaces import IHalfCloseableProtocol, IPullProducer 
    1919from twisted.protocols import policies 
    2020 
    class PortCleanerUpper(unittest.TestCase): 
    179179 
    180180 
    181181class ListeningTestCase(PortCleanerUpper): 
     182    """ 
     183    Tests for listening on a port. 
     184 
     185    @ivar listenMethod Method used to listen 
     186    @ivar connectMethod Method used to connect 
     187    @ivar loopback Loopback interface to use for testing 
     188    """ 
     189 
     190    listenMethod = reactor.listenTCP 
     191    connectMethod = reactor.connectTCP 
     192    loopback = "127.0.0.1" 
    182193 
    183194    def testListen(self): 
    184195        f = MyServerFactory() 
    185         p1 = reactor.listenTCP(0, f, interface="127.0.0.1") 
     196        p1 = self.listenMethod(0, f, interface=self.loopback) 
    186197        self.failUnless(interfaces.IListeningPort.providedBy(p1)) 
    187198        return p1.stopListening() 
    188199 
    189200    def testStopListening(self): 
    190201        f = MyServerFactory() 
    191         port = reactor.listenTCP(0, f, interface="127.0.0.1") 
     202        port = self.listenMethod(0, f, interface=self.loopback) 
    192203        n = port.getHost().port 
    193204        self.ports.append(port) 
    194205 
    195206        def cbStopListening(ignored): 
    196207            # Make sure we can rebind the port right away 
    197             port = reactor.listenTCP(n, f, interface="127.0.0.1") 
     208            port = self.listenMethod(n, f, interface=self.loopback) 
    198209            self.ports.append(port) 
    199210 
    200211        d = defer.maybeDeferred(port.stopListening) 
    class ListeningTestCase(PortCleanerUpper): 
    204215    def testNumberedInterface(self): 
    205216        f = MyServerFactory() 
    206217        # listen only on the loopback interface 
    207         p1 = reactor.listenTCP(0, f, interface='127.0.0.1') 
     218        p1 = self.listenMethod(0, f, interface=self.loopback) 
    208219        return p1.stopListening() 
    209220 
    210221    def testPortRepr(self): 
    211222        f = MyServerFactory() 
    212         p = reactor.listenTCP(0, f) 
     223        p = self.listenMethod(0, f) 
    213224        portNo = str(p.getHost().port) 
    214225        self.failIf(repr(p).find(portNo) == -1) 
    215226        def stoppedListening(ign): 
    class ListeningTestCase(PortCleanerUpper): 
    225236        """ 
    226237        server = MyServerFactory() 
    227238        serverConnMade = server.protocolConnectionMade = defer.Deferred() 
    228         port = reactor.listenTCP(0, server) 
     239        port = self.listenMethod(0, server) 
    229240        self.addCleanup(port.stopListening) 
    230241 
    231242        client = MyClientFactory() 
    232243        clientConnMade = client.protocolConnectionMade = defer.Deferred() 
    233         connector = reactor.connectTCP("127.0.0.1", 
    234                                        port.getHost().port, client) 
     244        connector = self.connectMethod(self.loopback, port.getHost().port, 
     245                                       client) 
    235246        self.addCleanup(connector.disconnect) 
    236247        def check((serverProto, clientProto)): 
    237248            portNumber = port.getHost().port 
    class ListeningTestCase(PortCleanerUpper): 
    242253        return defer.gatherResults([serverConnMade, clientConnMade] 
    243254            ).addCallback(check) 
    244255 
     256class ListeningIPv6TestCase(ListeningTestCase): 
     257    """ 
     258    Tests for listening on a port using IPv6. 
     259 
     260    @ivar listenMethod Method used to listen 
     261    @ivar connectMethod Method used to connect 
     262    @ivar loopback Loopback interface to use for testing 
     263    """ 
     264    listenMethod = reactor.listenTCP6 
     265    connectMethod = reactor.connectTCP6 
     266    loopback = "::1" 
    245267 
    246268 
    247269def callWithSpew(f): 
    def callWithSpew(f): 
    254276        sys.settrace(None) 
    255277 
    256278class LoopbackTestCase(PortCleanerUpper): 
    257     """Test loopback connections.""" 
     279    """ 
     280    Test loopback connections. 
    258281 
    259     n = 10081 
     282    @ivar listenMethod Method used to listen 
     283    @ivar connectMethod Method used to connect 
     284    @ivar loopback Loopback interface to use for testing 
     285    @ivar addressFamily Socket address family to use 
     286    """ 
    260287 
     288    listenMethod = reactor.listenTCP 
     289    connectMethod = reactor.connectTCP 
     290    creatorConnectMethod = protocol.ClientCreator.connectTCP 
     291    loopback = "127.0.0.1" 
     292    addressFamily = socket.AF_INET 
     293    n = 10081 
    261294 
    262295    def testClosePortInProtocolFactory(self): 
    263296        f = ClosingFactory() 
    264         port = reactor.listenTCP(0, f, interface="127.0.0.1") 
     297        port = self.listenMethod(0, f, interface=self.loopback) 
    265298        self.n = port.getHost().port 
    266299        self.ports.append(port) 
    267300        f.port = port 
    268301        clientF = MyClientFactory() 
    269         reactor.connectTCP("127.0.0.1", self.n, clientF) 
     302        self.connectMethod(self.loopback, self.n, clientF) 
    270303        def check(x): 
    271304            self.assert_(clientF.protocol.made) 
    272305            self.assert_(port.disconnected) 
    class LoopbackTestCase(PortCleanerUpper): 
    278311 
    279312    def testTcpNoDelay(self): 
    280313        f = MyServerFactory() 
    281         port = reactor.listenTCP(0, f, interface="127.0.0.1") 
     314        port = self.listenMethod(0, f, interface=self.loopback) 
    282315 
    283316        self.n = port.getHost().port 
    284317        self.ports.append(port) 
    285318        clientF = MyClientFactory() 
    286         reactor.connectTCP("127.0.0.1", self.n, clientF) 
     319        self.connectMethod(self.loopback, self.n, clientF) 
    287320 
    288321        d = loopUntil(lambda: (f.called > 0 and 
    289322                               getattr(clientF, 'protocol', None) is not None)) 
    class LoopbackTestCase(PortCleanerUpper): 
    301334 
    302335    def testTcpKeepAlive(self): 
    303336        f = MyServerFactory() 
    304         port = reactor.listenTCP(0, f, interface="127.0.0.1") 
     337        port = self.listenMethod(0, f, interface=self.loopback) 
    305338        self.n = port.getHost().port 
    306339        self.ports.append(port) 
    307340        clientF = MyClientFactory() 
    308         reactor.connectTCP("127.0.0.1", self.n, clientF) 
     341        self.connectMethod(self.loopback, self.n, clientF) 
    309342 
    310343        d = loopUntil(lambda :(f.called > 0 and 
    311344                               getattr(clientF, 'protocol', None) is not None)) 
    class LoopbackTestCase(PortCleanerUpper): 
    324357    def testFailing(self): 
    325358        clientF = MyClientFactory() 
    326359        # XXX we assume no one is listening on TCP port 69 
    327         reactor.connectTCP("127.0.0.1", 69, clientF, timeout=5) 
     360        self.connectMethod(self.loopback, 69, clientF, timeout=5) 
    328361        def check(ignored): 
    329362            clientF.reason.trap(error.ConnectionRefusedError) 
    330363        return clientF.failDeferred.addCallback(check) 
    class LoopbackTestCase(PortCleanerUpper): 
    357390 
    358391        serverSockets = [] 
    359392        for i in xrange(10): 
    360             serverSocket = socket.socket() 
    361             serverSocket.bind(('127.0.0.1', 0)) 
     393            serverSocket = socket.socket(self.addressFamily) 
     394            serverSocket.bind((self.loopback, 0)) 
    362395            serverSocket.listen(1) 
    363396            serverSockets.append(serverSocket) 
    364397        random.shuffle(serverSockets) 
    class LoopbackTestCase(PortCleanerUpper): 
    376409                self.fail("Could not fail to connect - could not test errno for that case.") 
    377410 
    378411            serverSocket = serverSockets.pop() 
    379             serverHost, serverPort = serverSocket.getsockname() 
     412            serverHost, serverPort = serverSocket.getsockname()[:2] 
    380413            serverSocket.close() 
    381414 
    382             connectDeferred = clientCreator.connectTCP(serverHost, serverPort) 
     415            connectDeferred = self.creatorConnectMethod(clientCreator,  
     416                                                        serverHost, serverPort) 
    383417            connectDeferred.addCallback(connected) 
    384418            return connectDeferred 
    385419 
    class LoopbackTestCase(PortCleanerUpper): 
    398432 
    399433    def testConnectByServiceFail(self): 
    400434        try: 
    401             reactor.connectTCP("127.0.0.1", "thisbetternotexist", 
     435            self.connectMethod(self.loopback, "thisbetternotexist", 
    402436                               MyClientFactory()) 
    403437        except error.ServiceNameUnknownError: 
    404438            return 
    class LoopbackTestCase(PortCleanerUpper): 
    409443        d = defer.succeed(None) 
    410444        try: 
    411445            s = MyServerFactory() 
    412             port = reactor.listenTCP(0, s, interface="127.0.0.1") 
     446            port = self.listenMethod(0, s, interface=self.loopback) 
    413447            self.n = port.getHost().port 
    414448            socket.getservbyname = (lambda s, p,n=self.n: 
    415449                                    s == 'http' and p == 'tcp' and n or 10) 
    416450            self.ports.append(port) 
    417451            cf = MyClientFactory() 
    418452            try: 
    419                 c = reactor.connectTCP('127.0.0.1', 'http', cf) 
     453                c = self.connectMethod(self.loopback, 'http', cf) 
    420454            except: 
    421455                socket.getservbyname = serv 
    422456                raise 
    class LoopbackTestCase(PortCleanerUpper): 
    432466                                              '%s was not called' % (s,))) 
    433467        return d 
    434468 
     469class LoopbackIPv6TestCase(LoopbackTestCase): 
     470    """ 
     471    Test IPv6 loopback connections. 
     472    """ 
     473    listenMethod = reactor.listenTCP6 
     474    connectMethod = reactor.connectTCP6 
     475    creatorConnectMethod = protocol.ClientCreator.connectTCP6 
     476    loopback = "::1" 
     477    addressFamily = socket.AF_INET6 
     478 
    435479 
    436480class StartStopFactory(protocol.Factory): 
    437481 
    class ClientStartStopFactory(MyClientFactory): 
    466510 
    467511 
    468512class FactoryTestCase(PortCleanerUpper): 
    469     """Tests for factories.""" 
     513    """ 
     514    Tests for factories. 
     515 
     516    @ivar listenMethod Method used to listen 
     517    @ivar loopback Loopback interface to use for testing 
     518    """ 
     519    listenMethod = reactor.listenTCP 
     520    loopback = "127.0.0.1" 
    470521 
    471522    def testServerStartStop(self): 
    472523        f = StartStopFactory() 
    473524 
    474525        # listen on port 
    475         p1 = reactor.listenTCP(0, f, interface='127.0.0.1') 
     526        p1 = self.listenMethod(0, f, interface=self.loopback) 
    476527        self.n1 = p1.getHost().port 
    477528        self.ports.append(p1) 
    478529 
    class FactoryTestCase(PortCleanerUpper): 
    482533    def _testServerStartStop(self, ignored, f, p1): 
    483534        self.assertEquals((f.started, f.stopped), (1,0)) 
    484535        # listen on two more ports 
    485         p2 = reactor.listenTCP(0, f, interface='127.0.0.1') 
     536        p2 = self.listenMethod(0, f, interface=self.loopback) 
    486537        self.n2 = p2.getHost().port 
    487538        self.ports.append(p2) 
    488         p3 = reactor.listenTCP(0, f, interface='127.0.0.1') 
     539        p3 = self.listenMethod(0, f, interface=self.loopback) 
    489540        self.n3 = p3.getHost().port 
    490541        self.ports.append(p3) 
    491542        d = loopUntil(lambda :(p2.connected == 1 and p3.connected == 1)) 
    class FactoryTestCase(PortCleanerUpper): 
    513564 
    514565    def testClientStartStop(self): 
    515566        f = ClosingFactory() 
    516         p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     567        p = self.listenMethod(0, f, interface=self.loopback) 
    517568        self.n = p.getHost().port 
    518569        self.ports.append(p) 
    519570        f.port = p 
    class FactoryTestCase(PortCleanerUpper): 
    521572        d = loopUntil(lambda :p.connected) 
    522573        def check(ignored): 
    523574            factory = ClientStartStopFactory() 
    524             reactor.connectTCP("127.0.0.1", self.n, factory) 
     575            self.connectMethod(self.loopback, self.n, factory) 
    525576            self.assert_(factory.started) 
    526577            return loopUntil(lambda :factory.stopped) 
    527578        d.addCallback(check) 
    528579        d.addBoth(lambda _: self.cleanPorts(*self.ports)) 
    529580        return d 
    530581 
     582class FactoryIPv6TestCase(FactoryTestCase): 
     583    """ 
     584    IPv6 Tests for factories. 
     585 
     586    @ivar listenMethod Method used to listen 
     587    @ivar loopback Loopback interface to use for testing 
     588    """ 
     589    listenMethod = reactor.listenTCP6 
     590    loopback = "::1" 
     591 
    531592 
    532593class ConnectorTestCase(PortCleanerUpper): 
     594    """ 
     595    Tests for connectors. 
     596 
     597    @ivar listenMethod Method used to listen 
     598    @ivar connectMethod Method used to connect 
     599    @ivar loopback Loopback interface to use for testing 
     600    """ 
     601    listenMethod = reactor.listenTCP 
     602    connectMethod = reactor.connectTCP 
     603    loopback = "127.0.0.1" 
    533604 
    534605    def testConnectorIdentity(self): 
    535606        f = ClosingFactory() 
    536         p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     607        p = self.listenMethod(0, f, interface=self.loopback) 
    537608        n = p.getHost().port 
    538609        self.ports.append(p) 
    539610        f.port = p 
    class ConnectorTestCase(PortCleanerUpper): 
    547618            factory.clientConnectionLost = lambda c, r: (l.append(c), 
    548619                                                         m.append(r)) 
    549620            factory.startedConnecting = lambda c: l.append(c) 
    550             connector = reactor.connectTCP("127.0.0.1", n, factory) 
     621            connector = self.connectMethod(self.loopback, n, factory) 
    551622            self.failUnless(interfaces.IConnector.providedBy(connector)) 
    552623            dest = connector.getDestination() 
    553624            self.assertEquals(dest.type, "TCP") 
    554             self.assertEquals(dest.host, "127.0.0.1") 
     625            self.assertEquals(dest.host, self.loopback) 
    555626            self.assertEquals(dest.port, n) 
    556627 
    557628            d = loopUntil(lambda :factory.stopped) 
    class ConnectorTestCase(PortCleanerUpper): 
    564635 
    565636    def testUserFail(self): 
    566637        f = MyServerFactory() 
    567         p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     638        p = self.listenMethod(0, f, interface=self.loopback) 
    568639        n = p.getHost().port 
    569640        self.ports.append(p) 
    570641 
    class ConnectorTestCase(PortCleanerUpper): 
    573644 
    574645        factory = ClientStartStopFactory() 
    575646        factory.startedConnecting = startedConnecting 
    576         reactor.connectTCP("127.0.0.1", n, factory) 
     647        self.connectMethod(self.loopback, n, factory) 
    577648 
    578649        d = loopUntil(lambda :factory.stopped) 
    579650        def check(ignored): 
    class ConnectorTestCase(PortCleanerUpper): 
    585656 
    586657    def testReconnect(self): 
    587658        f = ClosingFactory() 
    588         p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     659        p = self.listenMethod(0, f, interface=self.loopback) 
    589660        n = p.getHost().port 
    590661        self.ports.append(p) 
    591662        f.port = p 
    class ConnectorTestCase(PortCleanerUpper): 
    596667            def clientConnectionLost(c, reason): 
    597668                c.connect() 
    598669            factory.clientConnectionLost = clientConnectionLost 
    599             reactor.connectTCP("127.0.0.1", n, factory) 
     670            self.connectMethod(self.loopback, n, factory) 
    600671            return loopUntil(lambda :factory.failed) 
    601672 
    602673        def step2(ignored): 
    class ConnectorTestCase(PortCleanerUpper): 
    609680        return d.addCallback(step1).addCallback(step2) 
    610681 
    611682 
     683class ConnectorIPv6TestCase(ConnectorTestCase): 
     684    """ 
     685    Tests for IPv6 connectors. 
     686    """ 
     687    listenMethod = reactor.listenTCP6 
     688    connectMethod = reactor.connectTCP6 
     689    loopback = "::1" 
     690 
     691 
    612692class CannotBindTestCase(PortCleanerUpper): 
    613     """Tests for correct behavior when a reactor cannot bind to the required 
    614     TCP port.""" 
     693    """ 
     694    Tests for correct behavior when a reactor cannot bind to the required 
     695    TCP port. 
     696 
     697    @ivar listenMethod Method used to listen 
     698    @ivar connectMethod Method used to connect 
     699    @ivar loopback Loopback interface to use for testing 
     700    """ 
     701 
     702    listenMethod = reactor.listenTCP 
     703    connectMethod = reactor.connectTCP 
     704    loopback = "127.0.0.1" 
    615705 
    616706    def testCannotBind(self): 
    617707        f = MyServerFactory() 
    618708 
    619         p1 = reactor.listenTCP(0, f, interface='127.0.0.1') 
     709        p1 = self.listenMethod(0, f, interface=self.loopback) 
    620710        n = p1.getHost().port 
    621711        self.ports.append(p1) 
    622712        dest = p1.getHost() 
    623713        self.assertEquals(dest.type, "TCP") 
    624         self.assertEquals(dest.host, "127.0.0.1") 
     714        self.assertEquals(dest.host, self.loopback) 
    625715        self.assertEquals(dest.port, n) 
    626716 
    627717        # make sure new listen raises error 
    628718        self.assertRaises(error.CannotListenError, 
    629                           reactor.listenTCP, n, f, interface='127.0.0.1') 
     719                          reactor.listenTCP, n, f, interface=self.loopback) 
    630720 
    631721        return self.cleanPorts(*self.ports) 
    632722 
    class CannotBindTestCase(PortCleanerUpper): 
    644734        theDeferred = defer.Deferred() 
    645735        sf = MyServerFactory() 
    646736        sf.startFactory = self._fireWhenDoneFunc(theDeferred, sf.startFactory) 
    647         p = reactor.listenTCP(0, sf, interface="127.0.0.1") 
     737        p = self.listenMethod(0, sf, interface=self.loopback) 
    648738        self.ports.append(p) 
    649739 
    650740        def _connect1(results): 
    651741            d = defer.Deferred() 
    652742            cf1 = MyClientFactory() 
    653743            cf1.buildProtocol = self._fireWhenDoneFunc(d, cf1.buildProtocol) 
    654             reactor.connectTCP("127.0.0.1", p.getHost().port, cf1, 
    655                                bindAddress=("127.0.0.1", 0)) 
     744            self.connectMethod(self.loopback, p.getHost().port, cf1, 
     745                               bindAddress=(self.loopback, 0)) 
    656746            d.addCallback(_conmade, cf1) 
    657747            return d 
    658748 
    class CannotBindTestCase(PortCleanerUpper): 
    673763            cf2.clientConnectionFailed = self._fireWhenDoneFunc( 
    674764                d1, cf2.clientConnectionFailed) 
    675765            cf2.stopFactory = self._fireWhenDoneFunc(d2, cf2.stopFactory) 
    676             reactor.connectTCP("127.0.0.1", p.getHost().port, cf2, 
    677                                bindAddress=("127.0.0.1", port)) 
     766            self.connectMethod(self.loopback, p.getHost().port, cf2, 
     767                               bindAddress=(self.loopback, port)) 
    678768            d1.addCallback(_check2failed, cf1, cf2) 
    679769            d2.addCallback(_check2stopped, cf1, cf2) 
    680770            dl = defer.DeferredList([d1, d2]) 
    class CannotBindTestCase(PortCleanerUpper): 
    705795        theDeferred.addCallback(_connect1) 
    706796        return theDeferred 
    707797 
     798 
     799class CannotBindIPv6TestCase(CannotBindTestCase): 
     800    """ 
     801    Tests for correct behavior when a reactor cannot bind to the required 
     802    TCPv6 port. 
     803    """ 
     804    listenMethod = reactor.listenTCP6 
     805    connectMethod = reactor.connectTCP6 
     806    loopback = "::1" 
     807 
     808 
    708809class MyOtherClientFactory(protocol.ClientFactory): 
    709810    def buildProtocol(self, address): 
    710811        self.address = address 
    class MyOtherClientFactory(protocol.ClientFactory): 
    714815 
    715816 
    716817class LocalRemoteAddressTestCase(PortCleanerUpper): 
    717     """Tests for correct getHost/getPeer values and that the correct address 
     818    """ 
     819    Tests for correct getHost/getPeer values and that the correct address 
    718820    is passed to buildProtocol. 
     821 
     822    @ivar listenMethod Method used to listen 
     823    @ivar connectMethod Method used to connect 
     824    @ivar loopback Loopback interface to use for testing 
    719825    """ 
     826 
     827    listenMethod = reactor.listenTCP 
     828    connectMethod = reactor.connectTCP 
     829    loopback = "127.0.0.1" 
     830 
    720831    def testHostAddress(self): 
    721832        f1 = MyServerFactory() 
    722         p1 = reactor.listenTCP(0, f1, interface='127.0.0.1') 
     833        p1 = self.listenMethod(0, f1, interface=self.loopback) 
    723834        n = p1.getHost().port 
    724835        self.ports.append(p1) 
    725836 
    726837        f2 = MyOtherClientFactory() 
    727         p2 = reactor.connectTCP('127.0.0.1', n, f2) 
     838        p2 = self.connectMethod(self.loopback, n, f2) 
    728839 
    729840        d = loopUntil(lambda :p2.state == "connected") 
    730841        def check(ignored): 
    class LocalRemoteAddressTestCase(PortCleanerUpper): 
    737848        return d.addCallback(check).addCallback(cleanup) 
    738849 
    739850 
     851class LocalRemoteAddressIPv6TestCase(LocalRemoteAddressTestCase): 
     852    """ 
     853    IPv6 tests for correct getHost/getPeer values and that the correct address 
     854    is passed to buildProtocol. 
     855    """ 
     856    listenMethod = reactor.listenTCP6 
     857    connectMethod = reactor.connectTCP6 
     858    loopback = "::1" 
     859 
     860 
    740861class WriterProtocol(protocol.Protocol): 
    741862    def connectionMade(self): 
    742863        # use everything ITransport claims to provide. If something here 
    class WriterClientFactory(protocol.ClientFactory): 
    778899class WriteDataTestCase(PortCleanerUpper): 
    779900    """Test that connected TCP sockets can actually write data. Try to 
    780901    exercise the entire ITransport interface. 
     902 
     903    @ivar listenMethod Method used to listen 
     904    @ivar connectMethod Method used to connect 
     905    @ivar loopback Loopback interface to use for testing 
    781906    """ 
     907    listenMethod = reactor.listenTCP 
     908    connectMethod = reactor.connectTCP 
     909    loopback = "127.0.0.1" 
    782910 
    783911    def testWriter(self): 
    784912        f = protocol.Factory() 
    class WriteDataTestCase(PortCleanerUpper): 
    786914        f.done = 0 
    787915        f.problem = 0 
    788916        wrappedF = WiredFactory(f) 
    789         p = reactor.listenTCP(0, wrappedF, interface="127.0.0.1") 
     917        p = self.listenMethod(0, wrappedF, interface=self.loopback) 
    790918        n = p.getHost().port 
    791919        self.ports.append(p) 
    792920        clientF = WriterClientFactory() 
    793921        wrappedClientF = WiredFactory(clientF) 
    794         reactor.connectTCP("127.0.0.1", n, wrappedClientF) 
     922        self.connectMethod(self.loopback, n, wrappedClientF) 
    795923 
    796924        def check(ignored): 
    797925            self.failUnless(f.done, "writer didn't finish, it probably died") 
    class WriteDataTestCase(PortCleanerUpper): 
    820948        # Gtk reactor cannot pass this test, though, because it fails to 
    821949        # implement IReactorTCP entirely correctly.  Gtk is quite old at 
    822950        # this point, so it's more likely that gtkreactor will be deprecated 
    823         # and removed rather than fixed to handle this case correctly.  
     951        # and removed rather than fixed to handle this case correctly. 
    824952        # Since this is a pre-existing (and very long-standing) issue with 
    825953        # the Gtk reactor, there's no reason for it to prevent this test 
    826954        # being added to exercise the other reactors, for which the behavior 
    class WriteDataTestCase(PortCleanerUpper): 
    8721000        # Create the server port to which a connection will be made. 
    8731001        server = protocol.ServerFactory() 
    8741002        server.protocol = Disconnecter 
    875         port = reactor.listenTCP(0, server, interface='127.0.0.1') 
     1003        port = self.listenMethod(0, server, interface=self.loopback) 
    8761004        self.addCleanup(port.stopListening) 
    8771005        addr = port.getHost() 
    8781006 
    class WriteDataTestCase(PortCleanerUpper): 
    9421070            return client.lostReason 
    9431071        clientConnectionLost.addCallback(cbClientLost) 
    9441072        msg('Connecting to %s:%s' % (addr.host, addr.port)) 
    945         connector = reactor.connectTCP(addr.host, addr.port, client) 
     1073        connector = self.connectMethod(addr.host, addr.port, client) 
    9461074 
    9471075        # By the end of the test, the client should have received notification 
    9481076        # of unclean disconnection. 
    9491077        msg('Returning Deferred') 
    9501078        return self.assertFailure(clientConnectionLost, error.ConnectionLost) 
    9511079 
     1080class WriteDataIPv6TestCase(WriteDataTestCase): 
     1081    """ 
     1082    Test that connected TCPv6 sockets can actually write data. Try to 
     1083    exercise the entire ITransport interface. 
     1084    """ 
     1085    listenMethod = reactor.listenTCP6 
     1086    connectMethod = reactor.connectTCP6 
     1087    loopback = "::1" 
     1088 
    9521089 
    9531090 
    9541091class ConnectionLosingProtocol(protocol.Protocol): 
    class ProperlyCloseFilesMixin: 
    10531190        serverFactory = protocol.ServerFactory() 
    10541191        serverFactory.protocol = lambda: ConnectionLostNotifyingProtocol( 
    10551192            onServerConnectionLost) 
    1056         serverPort = self.createServer('127.0.0.1', 0, serverFactory) 
     1193        serverPort = self.createServer(self.loopback, 0, serverFactory) 
    10571194 
    10581195        onClientConnectionLost = defer.Deferred() 
    10591196        serverAddr = serverPort.getHost() 
    class ProperlyCloseFilesMixin: 
    10981235 
    10991236 
    11001237class ProperlyCloseFilesTestCase(unittest.TestCase, ProperlyCloseFilesMixin): 
    1101     def createServer(self, address, portNumber, factory): 
    1102         return reactor.listenTCP(portNumber, factory, interface=address) 
     1238    """ 
     1239    Test that we properly close files. 
    11031240 
     1241    @ivar listenMethod Method used to listen 
     1242    @ivar connectMethod Method used to connect 
     1243    @ivar loopback Loopback interface to use for testing 
     1244    """ 
    11041245 
    1105     def connectClient(self, address, portNumber, clientCreator): 
    1106         return clientCreator.connectTCP(address, portNumber) 
     1246    listenMethod = reactor.listenTCP 
     1247    creatorConnectMethod = protocol.ClientCreator.connectTCP 
     1248    loopback = "127.0.0.1" 
    11071249 
     1250    def createServer(self, address, portNumber, factory): 
     1251        return self.listenMethod(portNumber, factory, interface=address) 
     1252 
     1253    def connectClient(self, address, portNumber, clientCreator): 
     1254        return self.creatorConnectMethod(clientCreator, address, portNumber) 
    11081255 
    11091256    def getHandleExceptionType(self): 
    11101257        return socket.error 
    11111258 
     1259class ProperlyCloseFilesIPv6TestCase(ProperlyCloseFilesTestCase): 
     1260    """ 
     1261    Test that we properly close files using IPv6 
     1262    """ 
     1263    listenMethod = reactor.listenTCP6 
     1264    creatorConnectMethod = protocol.ClientCreator.connectTCP6 
     1265    loopback = "::1" 
    11121266 
    11131267 
    11141268class WiredForDeferreds(policies.ProtocolWrapper): 
    class WiredFactory(policies.WrappingFactory): 
    11381292class AddressTestCase(unittest.TestCase): 
    11391293    """ 
    11401294    Tests for address-related interactions with client and server protocols. 
     1295 
     1296    @ivar listenMethod Method used to listen 
     1297    @ivar connectMethod Method used to connect 
     1298    @ivar loopback Loopback interface to use for testing 
     1299    @ivar addrType Type of address we expect to see 
    11411300    """ 
     1301 
     1302    listenMethod = reactor.listenTCP 
     1303    connectMethod = reactor.connectTCP 
     1304    loopback = "127.0.0.1" 
     1305    addrtype = IPv4Address 
     1306 
    11421307    def setUp(self): 
    11431308        """ 
    11441309        Create a port and connected client/server pair which can be used 
    class AddressTestCase(unittest.TestCase): 
    11891354        self.clientConnLost = self.client.protocolConnectionLost = defer.Deferred() 
    11901355        self.clientWrapper = RememberingWrapper(self.client) 
    11911356 
    1192         self.port = reactor.listenTCP(0, self.serverWrapper, interface='127.0.0.1') 
    1193         self.connector = reactor.connectTCP( 
     1357        self.port = self.listenMethod(0, self.serverWrapper, interface=self.loopback) 
     1358        self.connector = self.connectMethod( 
    11941359            self.port.getHost().host, self.port.getHost().port, self.clientWrapper) 
    11951360 
    11961361        return defer.gatherResults([self.serverConnMade, self.clientConnMade]) 
    class AddressTestCase(unittest.TestCase): 
    12201385 
    12211386        self.assertEqual( 
    12221387            self.clientWrapper.addresses, 
    1223             [IPv4Address('TCP', serverHost.host, serverHost.port)]) 
     1388            [self.addrtype('TCP', serverHost.host, serverHost.port)]) 
    12241389        self.assertEqual( 
    12251390            self.clientWrapper.addresses, 
    1226             [IPv4Address('TCP', clientPeer.host, clientPeer.port)]) 
     1391            [self.addrtype('TCP', clientPeer.host, clientPeer.port)]) 
    12271392 
    12281393 
    12291394    def test_buildProtocolServer(self): 
    class AddressTestCase(unittest.TestCase): 
    12391404 
    12401405        self.assertEqual( 
    12411406            self.serverWrapper.addresses, 
    1242             [IPv4Address('TCP', serverPeer.host, serverPeer.port)]) 
     1407            [self.addrtype('TCP', serverPeer.host, serverPeer.port)]) 
    12431408        self.assertEqual( 
    12441409            self.serverWrapper.addresses, 
    1245             [IPv4Address('TCP', clientHost.host, clientHost.port)]) 
     1410            [self.addrtype('TCP', clientHost.host, clientHost.port)]) 
    12461411 
    12471412 
     1413class AddressIPv6TestCase(AddressTestCase): 
     1414    """ 
     1415    Tests for address-related interactions with client and server IPv6  
     1416    protocols. 
     1417    """ 
     1418    listenMethod = reactor.listenTCP6 
     1419    connectMethod = reactor.connectTCP6 
     1420    loopback = "::1" 
     1421    addrtype = IPv6Address 
     1422 
    12481423 
    12491424class LargeBufferWriterProtocol(protocol.Protocol): 
    12501425 
    class FireOnCloseFactory(policies.WrappingFactory): 
    12921467 
    12931468 
    12941469class LargeBufferTestCase(PortCleanerUpper): 
    1295     """Test that buffering large amounts of data works. 
    12961470    """ 
     1471    Test that buffering large amounts of data works. 
     1472 
     1473    @ivar listenMethod Method used to listen 
     1474    @ivar connectMethod Method used to connect 
     1475    @ivar loopback Loopback interface to use for testing 
     1476    """ 
     1477    listenMethod = reactor.listenTCP 
     1478    connectMethod = reactor.connectTCP 
     1479    loopback = "127.0.0.1" 
    12971480 
    12981481    datalen = 60*1024*1024 
    12991482    def testWriter(self): 
    class LargeBufferTestCase(PortCleanerUpper): 
    13031486        f.problem = 0 
    13041487        f.len = self.datalen 
    13051488        wrappedF = FireOnCloseFactory(f) 
    1306         p = reactor.listenTCP(0, wrappedF, interface="127.0.0.1") 
     1489        p = self.listenMethod(0, wrappedF, interface=self.loopback) 
    13071490        n = p.getHost().port 
    13081491        self.ports.append(p) 
    13091492        clientF = LargeBufferReaderClientFactory() 
    13101493        wrappedClientF = FireOnCloseFactory(clientF) 
    1311         reactor.connectTCP("127.0.0.1", n, wrappedClientF) 
     1494        self.connectMethod(self.loopback, n, wrappedClientF) 
    13121495 
    13131496        d = defer.gatherResults([wrappedF.deferred, wrappedClientF.deferred]) 
    13141497        def check(ignored): 
    class LargeBufferTestCase(PortCleanerUpper): 
    13201503                            "client didn't see connection dropped") 
    13211504        return d.addCallback(check) 
    13221505 
     1506class LargeBufferIPv6TestCase(LargeBufferTestCase): 
     1507    """ 
     1508    Test that buffering large amounts of data works over IPv6 
     1509    """ 
     1510    listenMethod = reactor.listenTCP6 
     1511    connectMethod = reactor.connectTCP6 
     1512    loopback = "::1" 
     1513 
    13231514 
    13241515class MyHCProtocol(MyProtocol): 
    13251516 
    class MyHCFactory(protocol.ServerFactory): 
    13551546 
    13561547 
    13571548class HalfCloseTestCase(PortCleanerUpper): 
    1358     """Test half-closing connections.""" 
     1549    """ 
     1550    Test half-closing connections. 
     1551 
     1552    @ivar listenMethod Method used to listen 
     1553    @ivar connectMethod Method used to connect 
     1554    @ivar creatorConnectMethod Method used to connect with a ClientCreator 
     1555    @ivar loopback Loopback interface to use for testing 
     1556    """ 
     1557    listenMethod = reactor.listenTCP 
     1558    connectMethod = reactor.connectTCP 
     1559    creatorConnectMethod = protocol.ClientCreator.connectTCP 
     1560    loopback = "127.0.0.1" 
    13591561 
    13601562    def setUp(self): 
    13611563        PortCleanerUpper.setUp(self) 
    13621564        self.f = f = MyHCFactory() 
    1363         self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     1565        self.p = p = self.listenMethod(0, f, interface=self.loopback) 
    13641566        self.ports.append(p) 
    13651567        d = loopUntil(lambda :p.connected) 
    13661568 
    13671569        self.cf = protocol.ClientCreator(reactor, MyHCProtocol) 
    13681570 
    1369         d.addCallback(lambda _: self.cf.connectTCP(p.getHost().host, 
    1370                                                    p.getHost().port)) 
     1571        d.addCallback(lambda _: self.creatorConnectMethod(self.cf,  
     1572                                                          p.getHost().host,  
     1573                                                          p.getHost().port)) 
    13711574        d.addCallback(self._setUp) 
    13721575        return d 
    13731576 
    class HalfCloseTestCase(PortCleanerUpper): 
    14361639            f.protocol.readHalfClosed, False)) 
    14371640        return d 
    14381641 
     1642class HalfCloseIPv6TestCase(HalfCloseTestCase): 
     1643    """ 
     1644    Test half-closing IPv6 connections. 
     1645    """ 
     1646    listenMethod = reactor.listenTCP6 
     1647    connectMethod = reactor.connectTCP6 
     1648    creatorConnectMethod = protocol.ClientCreator.connectTCP6 
     1649    loopback = "::1" 
     1650 
    14391651 
    14401652class HalfClose2TestCase(unittest.TestCase): 
     1653    """ 
     1654    Test half-closing connections. 
     1655 
     1656    @ivar listenMethod Method used to listen 
     1657    @ivar creatorConnectMethod Method used to connect with a ClientCreator 
     1658    @ivar loopback Loopback interface to use for testing 
     1659    """ 
     1660    listenMethod = reactor.listenTCP 
     1661    creatorConnectMethod = protocol.ClientCreator.connectTCP 
     1662    loopback = "127.0.0.1" 
    14411663 
    14421664    def setUp(self): 
    14431665        self.f = f = MyServerFactory() 
    14441666        self.f.protocolConnectionMade = defer.Deferred() 
    1445         self.p = p = reactor.listenTCP(0, f, interface="127.0.0.1") 
     1667        self.p = p = self.listenMethod(0, f, interface=self.loopback) 
    14461668 
    14471669        # XXX we don't test server side yet since we don't do it yet 
    1448         d = protocol.ClientCreator(reactor, MyProtocol).connectTCP( 
    1449             p.getHost().host, p.getHost().port) 
     1670        creator = protocol.ClientCreator(reactor, MyProtocol) 
     1671        d = self.creatorConnectMethod(creator, p.getHost().host,  
     1672                                      p.getHost().port) 
    14501673        d.addCallback(self._gotClient) 
    14511674        return d 
    14521675 
    class HalfClose2TestCase(unittest.TestCase): 
    14911714                      self.failUnlessEqual(self.f.protocol.closed, True)) 
    14921715        return defer.gatherResults([d, d2]) 
    14931716 
     1717class HalfClose2IPv6TestCase(HalfClose2TestCase): 
     1718    """ 
     1719    Test half-closing IPv6 connections. 
     1720    """ 
     1721    listenMethod = reactor.listenTCP6 
     1722    creatorConnectMethod = protocol.ClientCreator.connectTCP6 
     1723    loopback = "::1" 
    14941724 
    14951725class HalfCloseBuggyApplicationTests(unittest.TestCase): 
    14961726    """ 
    14971727    Test half-closing connections where notification code has bugs. 
     1728 
     1729    @ivar listenMethod Method used to listen 
     1730    @ivar creatorConnectMethod Method used to connect with a ClientCreator 
     1731    @ivar loopback Loopback interface to use for testing 
    14981732    """ 
     1733    listenMethod = reactor.listenTCP 
     1734    creatorConnectMethod = protocol.ClientCreator.connectTCP 
     1735    loopback = "127.0.0.1" 
    14991736 
    15001737    def setUp(self): 
    15011738        """ 
    class HalfCloseBuggyApplicationTests(unittest.TestCase): 
    15041741        """ 
    15051742        self.serverFactory = MyHCFactory() 
    15061743        self.serverFactory.protocolConnectionMade = defer.Deferred() 
    1507         self.port = reactor.listenTCP( 
    1508             0, self.serverFactory, interface="127.0.0.1") 
     1744        self.port = self.listenMethod( 
     1745            0, self.serverFactory, interface=self.loopback) 
    15091746        self.addCleanup(self.port.stopListening) 
    15101747        addr = self.port.getHost() 
    15111748        creator = protocol.ClientCreator(reactor, MyHCProtocol) 
    1512         clientDeferred = creator.connectTCP(addr.host, addr.port) 
     1749        clientDeferred = self.creatorConnectMethod(creator, addr.host, addr.port) 
    15131750        def setClient(clientProtocol): 
    15141751            self.clientProtocol = clientProtocol 
    15151752        clientDeferred.addCallback(setClient) 
    class HalfCloseBuggyApplicationTests(unittest.TestCase): 
    15591796        self.clientProtocol.writeConnectionLost = self.aBug 
    15601797        return self._notificationRaisesTest() 
    15611798 
     1799class HalfCloseBuggyApplicationIPv6Tests(HalfCloseBuggyApplicationTests): 
     1800    """ 
     1801    Test half-closing IPv6 connections where notification code has bugs. 
     1802    """ 
     1803    listenMethod = reactor.listenTCP6 
     1804    creatorConnectMethod = protocol.ClientCreator.connectTCP6 
     1805    loopback = "::1" 
    15621806 
    15631807 
    15641808class LogTestCase(unittest.TestCase): 
    15651809    """ 
    15661810    Test logging facility of TCP base classes. 
     1811 
     1812    @ivar listenMethod Method used to listen 
     1813    @ivar connectMethod Method used to connect 
     1814    @ivar loopback Loopback interface to use for testing 
    15671815    """ 
     1816    listenMethod = reactor.listenTCP 
     1817    connectMethod = reactor.connectTCP 
     1818    loopback = "127.0.0.1" 
    15681819 
    15691820    def test_logstrClientSetup(self): 
    15701821        """ 
    class LogTestCase(unittest.TestCase): 
    15761827        client = MyClientFactory() 
    15771828        client.protocolConnectionMade = defer.Deferred() 
    15781829 
    1579         port = reactor.listenTCP(0, server, interface='127.0.0.1') 
     1830        port = self.listenMethod(0, server, interface=self.loopback) 
    15801831        self.addCleanup(port.stopListening) 
    15811832 
    1582         connector = reactor.connectTCP( 
     1833        connector = self.connectMethod( 
    15831834            port.getHost().host, port.getHost().port, client) 
    15841835        self.addCleanup(connector.disconnect) 
    15851836 
    class LogTestCase(unittest.TestCase): 
    15931844        client.protocolConnectionMade.addCallback(cb) 
    15941845        return client.protocolConnectionMade 
    15951846 
     1847class LogIPv6TestCase(LogTestCase): 
     1848    """ 
     1849    Test logging facility of TCPv6 base classes. 
     1850    """ 
     1851    listenMethod = reactor.listenTCP6 
     1852    connectMethod = reactor.connectTCP6 
     1853    loopback = "::1" 
    15961854 
    15971855 
    15981856try: 
    except ImportError: 
    16021860else: 
    16031861    numRounds = resource.getrlimit(resource.RLIMIT_NOFILE)[0] + 10 
    16041862    ProperlyCloseFilesTestCase.numberRounds = numRounds 
     1863 
     1864try: 
     1865    s = socket.socket(socket.AF_INET6) 
     1866except socket.error: 
     1867    for klass in [ 
     1868        "ListeningIPv6TestCase", 
     1869        "LoopbackIPv6TestCase", 
     1870        "FactoryIPv6TestCase", 
     1871        "ConnectorIPv6TestCase", 
     1872        "CannotBindIPv6TestCase", 
     1873        "LocalRemoteAddressIPv6TestCase", 
     1874        "WriteDataIPv6TestCase", 
     1875        "ProperlyCloseFilesIPv6TestCase", 
     1876        "AddressIPv6TestCase", 
     1877        "LargeBufferIPv6TestCase", 
     1878        "HalfCloseIPv6TestCase", 
     1879        "HalfClose2IPv6TestCase", 
     1880        "HalfCloseBuggyApplicationIPv6Tests", 
     1881        "LogIPv6TestCase", 
     1882    ]: 
     1883        klass.skip = "IPv6 is not enabled" 
     1884