Exemple #1
0
	def _accept (self):
		self._incoming.fsm.change(FSM.CONNECT)

		# we can do this as Protocol is a mutable object
		proto = self._incoming.proto

		# send OPEN
		message = Message.CODE.NOP

		for message in proto.new_open(self._restarted):
			if ord(message.TYPE) == Message.CODE.NOP:
				yield ACTION.NOW

		proto.negotiated.sent(message)

		self._incoming.fsm.change(FSM.OPENSENT)

		# Read OPEN
		wait = environment.settings().bgp.openwait
		opentimer = ReceiveTimer(self.me,wait,1,1,'waited for open too long, we do not like stuck in active')
		# Only yield if we have not the open, otherwise the reactor can run the other connection
		# which would be bad as we need to do the collission check without going to the other peer
		for message in proto.read_open(self.neighbor.peer_address.top()):
			opentimer.check_ka(message)
			if ord(message.TYPE) == Message.CODE.NOP:
				yield ACTION.LATER

		self._incoming.fsm.change(FSM.OPENCONFIRM)
		proto.negotiated.received(message)
		proto.validate_open()

		if self._outgoing.fsm == FSM.OPENCONFIRM:
			self.logger.network('incoming connection finds the outgoing connection is in openconfirm')
			local_id = self.neighbor.router_id.pack()
			remote_id = proto.negotiated.received_open.router_id.pack()

			if local_id < remote_id:
				self.logger.network('closing the outgoing connection')
				self._stop(self._outgoing,'collision local id < remote id')
				yield ACTION.LATER
			else:
				self.logger.network('aborting the incoming connection')
				raise Interrupted(self._incoming)

		# Send KEEPALIVE
		for message in self._incoming.proto.new_keepalive('OPENCONFIRM'):
			yield ACTION.NOW

		# Start keeping keepalive timer
		self.recv_timer = ReceiveTimer(self.me,proto.negotiated.holdtime,4,0)
		# Read KEEPALIVE
		for message in proto.read_keepalive():
			self.recv_timer.check_ka(message)
			yield ACTION.NOW

		self._incoming.fsm.change(FSM.ESTABLISHED)
		# let the caller know that we were sucesfull
		yield ACTION.NOW
Exemple #2
0
	def _accept (self):
		# we can do this as Protocol is a mutable object
		proto = self._['in']['proto']

		# send OPEN
		for message in proto.new_open(self._restarted):
			if ord(message.TYPE) == Message.ID.NOP:
				yield ACTION.immediate

		proto.negotiated.sent(message)

		self._['in']['state'] = STATE.opensent

		# Read OPEN
		wait = environment.settings().bgp.openwait
		opentimer = ReceiveTimer(self.me,wait,1,1,'waited for open too long, we do not like stuck in active')
		# Only yield if we have not the open, otherwise the reactor can run the other connection
		# which would be bad as we need to do the collission check without going to the other peer
		for message in proto.read_open(self.neighbor.peer_address.ip):
			opentimer.check_ka(message)
			if ord(message.TYPE) == Message.ID.NOP:
				yield ACTION.later

		self._['in']['state'] = STATE.openconfirm
		proto.negotiated.received(message)
		proto.validate_open()

		if self._['out']['state'] == STATE.openconfirm:
			self.logger.network('incoming connection finds the outgoing connection is in openconfirm')
			local_id = self.neighbor.router_id.packed
			remote_id = proto.negotiated.received_open.router_id.packed

			if local_id < remote_id:
				self.logger.network('closing the outgoing connection')
				self._stop('out','collision local id < remote id')
				yield ACTION.later
			else:
				self.logger.network('aborting the incoming connection')
				stop = Interrupted()
				stop.direction = 'in'
				raise stop

		# Send KEEPALIVE
		for message in self._['in']['proto'].new_keepalive('OPENCONFIRM'):
			yield ACTION.immediate

		# Start keeping keepalive timer
		self.recv_timer = ReceiveTimer(self.me,proto.negotiated.holdtime,4,0)
		# Read KEEPALIVE
		for message in proto.read_keepalive():
			self.recv_timer.check_ka(message)
			yield ACTION.immediate

		self._['in']['state'] = STATE.established
		# let the caller know that we were sucesfull
		yield ACTION.immediate
Exemple #3
0
    def _establish(self):
        # try to establish the outgoing connection
        self.fsm.change(FSM.ACTIVE)

        if getenv().bgp.passive:
            while not self.proto:
                yield ACTION.LATER

        self.fsm.change(FSM.IDLE)

        if not self.proto:
            for action in self._connect():
                if action in ACTION.ALL:
                    yield action
        self.fsm.change(FSM.CONNECT)

        # normal sending of OPEN first ...
        if self.neighbor['local-as']:
            for sent_open in self._send_open():
                if sent_open in ACTION.ALL:
                    yield sent_open
            self.proto.negotiated.sent(sent_open)
            self.fsm.change(FSM.OPENSENT)

        # read the peer's open
        for received_open in self._read_open():
            if received_open in ACTION.ALL:
                yield received_open
        self.proto.negotiated.received(received_open)

        self.proto.connection.msg_size = self.proto.negotiated.msg_size

        # if we mirror the ASN, we need to read first and send second
        if not self.neighbor['local-as']:
            for sent_open in self._send_open():
                if sent_open in ACTION.ALL:
                    yield sent_open
            self.proto.negotiated.sent(sent_open)
            self.fsm.change(FSM.OPENSENT)

        self.proto.validate_open()
        self.fsm.change(FSM.OPENCONFIRM)

        self.recv_timer = ReceiveTimer(self.proto.connection.session,
                                       self.proto.negotiated.holdtime, 4, 0)
        for action in self._send_ka():
            yield action
        for action in self._read_ka():
            yield action
        self.fsm.change(FSM.ESTABLISHED)
        self.stats['complete'] = time.time()

        # let the caller know that we were sucesfull
        yield ACTION.NOW
Exemple #4
0
	def _read_open (self):
		wait = environment.settings().bgp.openwait
		opentimer = ReceiveTimer(self.proto.connection.session,wait,1,1,'waited for open too long, we do not like stuck in active')
		# Only yield if we have not the open, otherwise the reactor can run the other connection
		# which would be bad as we need to do the collission check without going to the other peer
		for message in self.proto.read_open(self.neighbor.peer_address.top()):
			opentimer.check_ka(message)
			# XXX: FIXME: change the whole code to use the ord and not the chr version
			# Only yield if we have not the open, otherwise the reactor can run the other connection
			# which would be bad as we need to do the collission check
			if ordinal(message.TYPE) == Message.CODE.NOP:
				yield ACTION.NOW
		yield message
Exemple #5
0
	def _read_open (self):
		wait = environment.settings().bgp.openwait
		opentimer = ReceiveTimer(self.proto.connection.session,wait,1,1,'waited for open too long, we do not like stuck in active')
		# Only yield if we have not the open, otherwise the reactor can run the other connection
		# which would be bad as we need to do the collission check without going to the other peer
		for message in self.proto.read_open(self.neighbor.peer_address.top()):
			opentimer.check_ka(message)
			# XXX: FIXME: change the whole code to use the ord and not the chr version
			# Only yield if we have not the open, otherwise the reactor can run the other connection
			# which would be bad as we need to do the collission check
			if ordinal(message.TYPE) == Message.CODE.NOP:
				# If a peer does not reply to OPEN message, or not enough bytes
				# yielding ACTION.NOW can cause ExaBGP to busy spin trying to
				# read from peer. See GH #723 .
				yield ACTION.LATER
		yield message
Exemple #6
0
	def _connect (self):
		# try to establish the outgoing connection

		proto = Protocol(self)
		generator = proto.connect()

		connected = False
		try:
			while not connected:
				if self._teardown:
					raise StopIteration()
				connected = generator.next()
				# we want to come back as soon as possible
				yield ACTION.LATER
		except StopIteration:
			# Connection failed
			if not connected:
				proto.close('connection to peer failed',self._['in']['state'] != STATE.ESTABLISHED)
			# A connection arrived before we could establish !
			if not connected or self._['in']['proto']:
				stop = Interrupted()
				stop.direction = 'out'
				yield ACTION.NOW
				raise stop

		self._['out']['state'] = STATE.CONNECT
		self._['out']['proto'] = proto

		# send OPEN
		# Only yield if we have not the open, otherwise the reactor can run the other connection
		# which would be bad as we need to set the state without going to the other peer
		message = Message.CODE.NOP
		for message in proto.new_open(self._restarted):
			if ord(message.TYPE) == Message.CODE.NOP:
				yield ACTION.NOW

		proto.negotiated.sent(message)

		self._['out']['state'] = STATE.OPENSENT

		# Read OPEN
		wait = environment.settings().bgp.openwait
		opentimer = ReceiveTimer(self.me,wait,1,1,'waited for open too long, we do not like stuck in active')
		for message in self._['out']['proto'].read_open(self.neighbor.peer_address.ip):
			opentimer.check_ka(message)
			# XXX: FIXME: change the whole code to use the ord and not the chr version
			# Only yield if we have not the open, otherwise the reactor can run the other connection
			# which would be bad as we need to do the collission check
			if ord(message.TYPE) == Message.CODE.NOP:
				yield ACTION.LATER

		self._['out']['state'] = STATE.OPENCONFIRM
		proto.negotiated.received(message)
		proto.validate_open()

		if self._['in']['state'] == STATE.OPENCONFIRM:
			self.logger.network('outgoing connection finds the incoming connection is in openconfirm')
			local_id = self.neighbor.router_id.packed
			remote_id = proto.negotiated.received_open.router_id.packed

			if local_id < remote_id:
				self.logger.network('aborting the outgoing connection')
				stop = Interrupted()
				stop.direction = 'out'
				raise stop
			else:
				self.logger.network('closing the incoming connection')
				self._stop('in','collision local id < remote id')
				yield ACTION.LATER

		# Send KEEPALIVE
		for message in proto.new_keepalive('OPENCONFIRM'):
			yield ACTION.NOW

		# Start keeping keepalive timer
		self.recv_timer = ReceiveTimer(self.me,proto.negotiated.holdtime,4,0)
		# Read KEEPALIVE
		for message in self._['out']['proto'].read_keepalive():
			self.recv_timer.check_ka(message)
			yield ACTION.NOW

		self._['out']['state'] = STATE.ESTABLISHED
		# let the caller know that we were sucesfull
		yield ACTION.NOW