Exemplo n.º 1
0
    def __init__(self, host, port, bindAddress, connector, reactor=None):
        # BaseClient.__init__ is invoked later
        self.connector = connector
        self.addr = (host, port)

        whenDone = self.resolveAddress
        err = None
        skt = None

        if abstract.isIPAddress(host):
            self._requiresResolution = False
        elif abstract.isIPv6Address(host):
            self._requiresResolution = False
            self.addr = _resolveIPv6(host, port)
            self.addressFamily = socket.AF_INET6
            self._addressType = address.IPv6Address
        else:
            self._requiresResolution = True
        try:
            skt = self.createInternetSocket()
        except socket.error as se:
            err = error.ConnectBindError(se.args[0], se.args[1])
            whenDone = None
        if whenDone and bindAddress is not None:
            try:
                if abstract.isIPv6Address(bindAddress[0]):
                    bindinfo = _resolveIPv6(*bindAddress)
                else:
                    bindinfo = bindAddress
                skt.bind(bindinfo)
            except socket.error as se:
                err = error.ConnectBindError(se.args[0], se.args[1])
                whenDone = None
        self._finishInit(whenDone, skt, err, reactor)
Exemplo n.º 2
0
class _SubConnector:
    state = "connecting"
    socket = None

    def __init__(self, sf):
        self.sf = sf

    def startConnecting(self):
        d = defer.maybeDeferred(self.sf.resolveAddress)
        d.addCallback(self._cbResolveDone)
        d.addErrback(self._ebResolveErr)

    def _cbResolveDone(self, addr):
        if self.state == "dead":
            return

        try:
            skt = socket.socket(*self.sf.sockinfo)
        except socket.error, se:
            raise error.ConnectBindError(se[0], se[1])
        try:
            if self.sf.bindAddress is None:
                self.sf.bindAddress = ("", 0)  # necessary for ConnectEx
            skt.bind(self.sf.bindAddress)
        except socket.error, se:
            raise error.ConnectBindError(se[0], se[1])
Exemplo n.º 3
0
    def _cbResolveDone(self, addr):
        if self.state == "dead":
            return

        try:
            skt = socket.socket(*self.sf.sockinfo)
        except socket.error, se:
            raise error.ConnectBindError(se[0], se[1])
Exemplo n.º 4
0
    def initConnection(self):
        """
        Initialize connection by creating the appropriate socket.
        """
        err = None
        skt = None
        result = True

        try:
            skt = self.createInternetSocket()
        except socket.error, se:
            err = error.ConnectBindError(se[0], se[1])
            result = None
Exemplo n.º 5
0
    def __init__(self, host, port, bindAddress, connector, reactor=None):
        # BaseClient.__init__ is invoked later
        self.connector = connector
        self.addr = (host, port)

        whenDone = self.resolveAddress
        err = None
        skt = None

        try:
            skt = self.createInternetSocket()
        except socket.error, se:
            err = error.ConnectBindError(se[0], se[1])
            whenDone = None
Exemplo n.º 6
0
    def __init__(self, host, port, bindAddress, connector, reactor):
        self.connector = connector
        self.addr = (host, port)
        self.reactor = reactor
        # ConnectEx documentation says socket _has_ to be bound
        if bindAddress is None:
            bindAddress = ('', 0)

        try:
            try:
                skt = reactor.createSocket(self.addressFamily, self.socketType)
            except socket.error, se:
                raise error.ConnectBindError(se[0], se[1])
            else:
Exemplo n.º 7
0
class Client(BaseClient):
    """A TCP client."""
    def __init__(self, host, port, bindAddress, connector, reactor=None):
        # BaseClient.__init__ is invoked later
        self.connector = connector
        self.addr = (host, port)

        whenDone = self.resolveAddress
        err = None
        skt = None

        try:
            skt = self.createInternetSocket()
        except socket.error, se:
            err = error.ConnectBindError(se.args[0], se.args[1])
            whenDone = None
        if whenDone and bindAddress is not None:
            try:
                skt.bind(bindAddress)
            except socket.error, se:
                err = error.ConnectBindError(se.args[0], se.args[1])
                whenDone = None
Exemplo n.º 8
0
def connectUTP(self, host, port, factory, timeout=30, bindAddress=None):
    if bindAddress is None:
        bindAddress = ['', 0]
    adapter = None
    try:
        adapter = self.createUTPAdapter(bindAddress[1], Protocol(), interface=bindAddress[0])
    except error.CannotListenError:
        e = sys.exc_info()[1]
        c = Connector(host, port, factory, None, timeout, self)
        se = e.socketError
        # We have to call connect to trigger the factory start and connection
        # start events, but we already know the connection failed because the
        # UDP socket couldn't bind. So we set soError, which causes the connect
        # call to fail.
        c.soError = error.ConnectBindError(se[0], se[1])
        c.connect()
        return c
    try:
        return self.connectUTPUsingAdapter(host, port, factory, adapter, timeout=timeout)
    except:
        adapter.maybeStopUDPPort()
        raise
Exemplo n.º 9
0
class _BaseTCPClient(object):
    """
    Code shared with other (non-POSIX) reactors for management of outgoing TCP
    connections (both TCPv4 and TCPv6).

    @note: In order to be functional, this class must be mixed into the same
        hierarchy as L{_BaseBaseClient}.  It would subclass L{_BaseBaseClient}
        directly, but the class hierarchy here is divided in strange ways out
        of the need to share code along multiple axes; specifically, with the
        IOCP reactor and also with UNIX clients in other reactors.

    @ivar _addressType: The Twisted _IPAddress implementation for this client
    @type _addressType: L{IPv4Address} or L{IPv6Address}

    @ivar connector: The L{Connector} which is driving this L{_BaseTCPClient}'s
        connection attempt.

    @ivar addr: The address that this socket will be connecting to.
    @type addr: If IPv4, a 2-C{tuple} of C{(str host, int port)}.  If IPv6, a
        4-C{tuple} of (C{str host, int port, int ignored, int scope}).

    @ivar createInternetSocket: Subclasses must implement this as a method to
        create a python socket object of the appropriate address family and
        socket type.
    @type createInternetSocket: 0-argument callable returning
        C{socket._socketobject}.
    """

    _addressType = address.IPv4Address

    def __init__(self, host, port, bindAddress, connector, reactor=None):
        # BaseClient.__init__ is invoked later
        self.connector = connector
        self.addr = (host, port)

        whenDone = self.resolveAddress
        err = None
        skt = None

        if abstract.isIPAddress(host):
            self._requiresResolution = False
        elif abstract.isIPv6Address(host):
            self._requiresResolution = False
            self.addr = _resolveIPv6(host, port)
            self.addressFamily = socket.AF_INET6
            self._addressType = address.IPv6Address
        else:
            self._requiresResolution = True
        try:
            skt = self.createInternetSocket()
        except socket.error, se:
            err = error.ConnectBindError(se.args[0], se.args[1])
            whenDone = None
        if whenDone and bindAddress is not None:
            try:
                if abstract.isIPv6Address(bindAddress[0]):
                    bindinfo = _resolveIPv6(*bindAddress)
                else:
                    bindinfo = bindAddress
                skt.bind(bindinfo)
            except socket.error, se:
                err = error.ConnectBindError(se.args[0], se.args[1])
                whenDone = None
Exemplo n.º 10
0
        self.addr = (host, port)
        self.reactor = reactor
        # ConnectEx documentation says socket _has_ to be bound
        if bindAddress is None:
            bindAddress = ('', 0)

        try:
            try:
                skt = reactor.createSocket(self.addressFamily, self.socketType)
            except socket.error, se:
                raise error.ConnectBindError(se[0], se[1])
            else:
                try:
                    skt.bind(bindAddress)
                except socket.error, se:
                    raise error.ConnectBindError(se[0], se[1])
                self.socket = skt
                Connection.__init__(self, skt, None, reactor)
                reactor.callLater(0, self.resolveAddress)
        except error.ConnectBindError, err:
            reactor.callLater(0, self.failIfNotConnected, err)

    def resolveAddress(self):
        if isIPAddress(self.addr[0]):
            self._setRealAddress(self.addr[0])
        else:
            d = self.reactor.resolve(self.addr[0])
            d.addCallbacks(self._setRealAddress, self.failIfNotConnected)

    def _setRealAddress(self, address):
        self.realAddress = (address, self.addr[1])
Exemplo n.º 11
0
class BaseClient(Connection):
    """A base class for client TCP (and similiar) sockets.
    """
    _addressType = address.IPv4Address

    addressFamily = socket.AF_INET
    socketType = socket.SOCK_STREAM

    def _finishInit(self, whenDone, skt, error, reactor):
        """Called by base classes to continue to next stage of initialization."""
        if whenDone:
            Connection.__init__(self, skt, None, reactor)
            self.doWrite = self.doConnect
            self.doRead = self.doConnect
            self.doConnect()
        else:
            reactor.callLater(0, self.failIfNotConnected, error)

    def startTLS(self, ctx, client=1):
        if Connection.startTLS(self, ctx, client):
            if client:
                self.socket.set_connect_state()
            else:
                self.socket.set_accept_state()

    def stopConnecting(self):
        """Stop attempt to connect."""
        self.failIfNotConnected(error.UserError())

    def failIfNotConnected(self, err):
        """
        Generic method called when the attemps to connect failed. It basically
        cleans everything it can: call connectionFailed, stop read and write,
        delete socket related members.
        """
        if (self.connected or self.disconnected
                or not hasattr(self, "connector")):
            return

        self.connector.connectionFailed(failure.Failure(err))
        if hasattr(self, "reactor"):
            # this doesn't happen if we failed in __init__
            self.stopReading()
            self.stopWriting()
            del self.connector

        try:
            self._closeSocket()
        except AttributeError:
            pass
        else:
            del self.socket, self.fileno

    def createInternetSocket(self):
        """(internal) Create a non-blocking socket using
        self.addressFamily, self.socketType.
        """
        s = socket.socket(self.addressFamily, self.socketType)
        s.setblocking(0)
        fdesc._setCloseOnExec(s.fileno())
        return s

    def resolveAddress(self):
        if abstract.isIPAddress(self.addr[0]) or abstract.isIPv6Address(
                self.addr[0]):
            self._setRealAddress(self.addr[0])
        else:
            d = self.reactor.resolve(self.addr[0])
            d.addCallbacks(self._setRealAddress, self.failIfNotConnected)

    def _setRealAddress(self, addr):
        """
        Set the real IP address for this client.
        Once the IP address is set, the socket is created using the correct
        address family.
        """
        if abstract.isIPv6Address(addr):
            self.addressFamily = socket.AF_INET6
            self._addressType = address.IPv6Address
        self.realAddress = (addr, self.addr[1])

        # create the socket and wait finish init after that
        self.initConnection()

    def initConnection(self):
        """
        Initialize connection by creating the appropriate socket.
        """
        err = None
        skt = None
        result = True

        try:
            skt = self.createInternetSocket()
        except socket.error, se:
            err = error.ConnectBindError(se[0], se[1])
            result = None
        if result and self.bindAddress is not None:
            try:
                skt.bind(self.bindAddress)
            except socket.error, se:
                err = error.ConnectBindError(se[0], se[1])
                result = None