Esempio n. 1
0
    def doConnect(self):
        """I connect the socket.

		Then, call the protocol's makeConnection, and start waiting for data.
		"""
        if not hasattr(self, "connector"):
            # this happens when connection failed but doConnect
            # was scheduled via a callLater in self._finishInit
            return

        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err:
            self.failIfNotConnected(error.getConnectError(
                (err, strerror(err))))
            return

        # doConnect gets called twice.  The first time we actually need to
        # start the connection attempt.  The second time we don't really
        # want to (SO_ERROR above will have taken care of any errors, and if
        # it reported none, the mere fact that doConnect was called again is
        # sufficient to indicate that the connection has succeeded), but it
        # is not /particularly/ detrimental to do so.  This should get
        # cleaned up some day, though.
        try:
            connectResult = self.socket.connect_ex(self.realAddress)
        except socket.error, se:
            connectResult = se.args[0]
Esempio n. 2
0
	def doConnect(self):
		"""I connect the socket.

		Then, call the protocol's makeConnection, and start waiting for data.
		"""
		if not hasattr(self, "connector"):
			# this happens when connection failed but doConnect
			# was scheduled via a callLater in self._finishInit
			return

		err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
		if err:
			self.failIfNotConnected(error.getConnectError((err, strerror(err))))
			return


		# doConnect gets called twice.  The first time we actually need to
		# start the connection attempt.  The second time we don't really
		# want to (SO_ERROR above will have taken care of any errors, and if
		# it reported none, the mere fact that doConnect was called again is
		# sufficient to indicate that the connection has succeeded), but it
		# is not /particularly/ detrimental to do so.  This should get
		# cleaned up some day, though.
		try:
			connectResult = self.socket.connect_ex(self.realAddress)
		except socket.error, se:
			connectResult = se.args[0]
Esempio n. 3
0
	def cbConnect(self, rc, bytes, evt):
		if rc:
			rc = connectExErrors.get(rc, rc)
			self.failIfNotConnected(error.getConnectError((rc,
									errno.errorcode.get(rc, 'Unknown error'))))
		else:
			self.socket.setsockopt(socket.SOL_SOCKET,
								   SO_UPDATE_CONNECT_CONTEXT,
								   struct.pack('I', self.socket.fileno()))
			self.protocol = self.connector.buildProtocol(self.getPeer())
			self.connected = True
			self.logstr = self.protocol.__class__.__name__+",client"
			self.protocol.makeConnection(self)
			self.startReading()
Esempio n. 4
0
 def cbConnect(self, rc, bytes, evt):
     if rc:
         rc = connectExErrors.get(rc, rc)
         self.failIfNotConnected(
             error.getConnectError(
                 (rc, errno.errorcode.get(rc, 'Unknown error'))))
     else:
         self.socket.setsockopt(socket.SOL_SOCKET,
                                SO_UPDATE_CONNECT_CONTEXT,
                                struct.pack('I', self.socket.fileno()))
         self.protocol = self.connector.buildProtocol(self.getPeer())
         self.connected = True
         self.logstr = self.protocol.__class__.__name__ + ",client"
         self.protocol.makeConnection(self)
         self.startReading()
Esempio n. 5
0
class BaseClient(Connection):
    """A base class for client TCP (and similiar) sockets.
	"""
    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
            reactor.callLater(0, whenDone)
        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]):
            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])
        self.doConnect()

    def doConnect(self):
        """I connect the socket.

		Then, call the protocol's makeConnection, and start waiting for data.
		"""
        if not hasattr(self, "connector"):
            # this happens when connection failed but doConnect
            # was scheduled via a callLater in self._finishInit
            return

        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
        if err:
            self.failIfNotConnected(error.getConnectError(
                (err, strerror(err))))
            return

        # doConnect gets called twice.  The first time we actually need to
        # start the connection attempt.  The second time we don't really
        # want to (SO_ERROR above will have taken care of any errors, and if
        # it reported none, the mere fact that doConnect was called again is
        # sufficient to indicate that the connection has succeeded), but it
        # is not /particularly/ detrimental to do so.  This should get
        # cleaned up some day, though.
        try:
            connectResult = self.socket.connect_ex(self.realAddress)
        except socket.error, se:
            connectResult = se.args[0]
        if connectResult:
            if connectResult == EISCONN:
                pass
            # on Windows EINVAL means sometimes that we should keep trying:
            # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp
            elif ((connectResult in (EWOULDBLOCK, EINPROGRESS, EALREADY))
                  or (connectResult == EINVAL and platformType == "win32")):
                self.startReading()
                self.startWriting()
                return
            else:
                self.failIfNotConnected(
                    error.getConnectError(
                        (connectResult, strerror(connectResult))))
                return

        # If I have reached this point without raising or returning, that means
        # that the socket is connected.
        del self.doWrite
        del self.doRead
        # we first stop and then start, to reset any references to the old doRead
        self.stopReading()
        self.stopWriting()
        self._connectDone()