Ejemplo n.º 1
0
	def _reader (self, number):
		# The function must not be called if it does not return with no data with a smaller size as parameter
		if not self.io:
			self.close()
			raise NotConnected('Trying to read on a closed TCP connection')
		if number == 0:
			yield b''
			return

		while not self.reading():
			yield b''
		data = b''
		reported = ''
		while True:
			try:
				while True:
					if self.defensive and random.randint(0,2):
						raise socket.error(errno.EAGAIN,'raising network error on purpose')

					read = self.io.recv(number)
					if not read:
						self.close()
						self.logger.wire("%s %s lost TCP session with peer" % (self.name(),self.peer),source=self.session())
						raise LostConnection('the TCP connection was closed by the remote end')
					data += read

					number -= len(read)
					if not number:
						self.logger.wire(
							LazyFormat(
								"%s %-32s RECEIVED " % (
									self.name(),
									'%s / %s' % (self.local,self.peer)
								),
								read
							),
							source=self.session()
						)
						yield data
						return

					yield b''
			except socket.timeout as exc:
				self.close()
				self.logger.wire("%s %s peer is too slow" % (self.name(),self.peer),source=self.session())
				raise TooSlowError('Timeout while reading data from the network (%s)' % errstr(exc))
			except socket.error as exc:
				if exc.args[0] in error.block:
					message = "%s %s blocking io problem mid-way through reading a message %s, trying to complete" % (self.name(),self.peer,errstr(exc))
					if message != reported:
						reported = message
						self.logger.wire(message,'debug',self.session())
					yield b''
				elif exc.args[0] in error.fatal:
					self.close()
					raise LostConnection('issue reading on the socket: %s' % errstr(exc))
				# what error could it be !
				else:
					self.logger.wire("%s %s undefined error reading on socket" % (self.name(),self.peer),source=self.session())
					raise NetworkError('Problem while reading data from the network (%s)' % errstr(exc))
Ejemplo n.º 2
0
	def _reader (self,number):
		# The function must not be called if it does not return with no data with a smaller size as parameter
		if not self.io:
			self.close()
			raise NotConnected('Trying to read on a close TCP conncetion')
		if number == 0:
			yield ''
			return
		# XXX: one of the socket option is to recover the size of the buffer
		# XXX: we could use it to not have to put together the string with multiple reads
		# XXX: and get rid of the self.read_timeout option
		while not self.reading():
			yield ''
		data = ''
		while True:
			try:
				while True:
					if self._reading is None:
						self._reading = time.time()
					elif time.time() > self._reading + self.read_timeout:
						self.close()
						self.logger.wire("%s %s peer is too slow (we were told there was data on the socket but we can not read up to what should be there)" % (self.name(),self.peer))
						raise TooSlowError('Waited to read for data on a socket for more than %d second(s)' % self.read_timeout)

					if self.defensive and random.randint(0,2):
						raise socket.error(errno.EAGAIN,'raising network error in purpose')

					read = self.io.recv(number)
					if not read:
						self.close()
						self.logger.wire("%s %s lost TCP session with peer" % (self.name(),self.peer))
						raise LostConnection('the TCP connection was closed by the remote end')

					data += read
					number -= len(read)
					if not number:
						self.logger.wire(LazyFormat("%s %-32s RECEIVED " % (self.name(),'%s / %s' % (self.local,self.peer)),od,read))
						self._reading = None
						yield data
						return
			except socket.timeout,e:
				self.close()
				self.logger.wire("%s %s peer is too slow" % (self.name(),self.peer))
				raise TooSlowError('Timeout while reading data from the network (%s)' % errstr(e))
			except socket.error,e:
				if e.args[0] in error.block:
					self.logger.wire("%s %s blocking io problem mid-way through reading a message %s, trying to complete" % (self.name(),self.peer,errstr(e)),'debug')
				elif e.args[0] in error.fatal:
					self.close()
					raise LostConnection('issue reading on the socket: %s' % errstr(e))
				# what error could it be !
				else:
					self.logger.wire("%s %s undefined error reading on socket" % (self.name(),self.peer))
					raise NetworkError('Problem while reading data from the network (%s)' % errstr(e))
Ejemplo n.º 3
0
    def writer(self, data):
        if not self.io:
            # XXX: FIXME: Make sure it does not hold the cleanup during the closing of the peering session
            yield True
            return
        while not self.writing():
            yield False
        self.logger.debug(LazyFormat('sending TCP payload', data),
                          self.session())
        # The first while is here to setup the try/catch block once as it is very expensive
        while True:
            try:
                while True:
                    if self.defensive and random.randint(0, 2):
                        raise socket.error(errno.EAGAIN,
                                           'raising network error on purpose')

                    # we can not use sendall as in case of network buffer filling
                    # it does raise and does not let you know how much was sent
                    number = self.io.send(data)
                    if not number:
                        self.close()
                        self.logger.warning(
                            '%s %s lost TCP connection with peer' %
                            (self.name(), self.peer), self.session())
                        raise LostConnection('lost the TCP connection')

                    data = data[number:]
                    if not data:
                        yield True
                        return
                    yield False
            except socket.error as exc:
                if exc.args[0] in error.block:
                    self.logger.debug(
                        '%s %s blocking io problem mid-way through writing a message %s, trying to complete'
                        % (self.name(), self.peer, errstr(exc)),
                        self.session())
                    yield False
                elif exc.errno == errno.EPIPE:
                    # The TCP connection is gone.
                    self.close()
                    raise NetworkError('Broken TCP connection')
                elif exc.args[0] in error.fatal:
                    self.close()
                    self.logger.critical(
                        '%s %s problem sending message (%s)' %
                        (self.name(), self.peer, errstr(exc)), self.session())
                    raise NetworkError(
                        'Problem while writing data to the network (%s)' %
                        errstr(exc))
                # what error could it be !
                else:
                    self.logger.critical(
                        '%s %s undefined error writing on socket' %
                        (self.name(), self.peer), self.session())
                    yield False
Ejemplo n.º 4
0
	def writer (self,data):
		if not self.io:
			# XXX: FIXME: Make sure it does not hold the cleanup during the closing of the peering session
			yield True
			return
		if not self.writing():
			yield False
			return
		self.logger.wire(LazyFormat("%s %-32s SENDING " % (self.name(),'%s / %s' % (self.local,self.peer)),od,data))
		# The first while is here to setup the try/catch block once as it is very expensive
		while True:
			try:
				while True:
					if self._writing is None:
						self._writing = time.time()
					elif time.time() > self._writing + self.read_timeout:
						self.close()
						self.logger.wire("%s %s peer is too slow" % (self.name(),self.peer))
						raise TooSlowError('Waited to write for data on a socket for more than %d second(s)' % self.read_timeout)

					if self.defensive and random.randint(0,2):
						raise socket.error(errno.EAGAIN,'raising network error in purpose')

					# we can not use sendall as in case of network buffer filling
					# it does raise and does not let you know how much was sent
					nb = self.io.send(data)
					if not nb:
						self.close()
						self.logger.wire("%s %s lost TCP connection with peer" % (self.name(),self.peer))
						raise LostConnection('lost the TCP connection')

					data = data[nb:]
					if not data:
						self._writing = None
						yield True
						return
					yield False
			except socket.error,e:
				if e.args[0] in error.block:
					self.logger.wire("%s %s blocking io problem mid-way through writing a message %s, trying to complete" % (self.name(),self.peer,errstr(e)),'debug')
				elif e.errno == errno.EPIPE:
					# The TCP connection is gone.
					self.close()
					raise NetworkError('Broken TCP connection')
				elif e.args[0] in error.fatal:
					self.close()
					self.logger.wire("%s %s problem sending message (%s)" % (self.name(),self.peer,errstr(e)))
					raise NetworkError('Problem while writing data to the network (%s)' % errstr(e))
				# what error could it be !
				else:
					self.logger.wire("%s %s undefined error writing on socket" % (self.name(),self.peer))
					yield False