Exemplo n.º 1
0
class Listener(object):
    _family_AFI_map = {
        socket.AF_INET: AFI.ipv4,
        socket.AF_INET6: AFI.ipv6,
    }

    def __init__(self, reactor, backlog=200):
        self.serving = False
        self.logger = Logger()

        self._reactor = reactor
        self._backlog = backlog
        self._sockets = {}
        self._accepted = {}
        self._pending = 0

    def _new_socket(self, ip):
        if ip.afi == AFI.ipv6:
            return socket.socket(socket.AF_INET6, socket.SOCK_STREAM,
                                 socket.IPPROTO_TCP)
        if ip.afi == AFI.ipv4:
            return socket.socket(socket.AF_INET, socket.SOCK_STREAM,
                                 socket.IPPROTO_TCP)
        raise NetworkError(
            'Can not create socket for listening, family of IP %s is unknown' %
            ip)

    def _listen(self, local_ip, peer_ip, local_port, md5, md5_base64, ttl_in):
        self.serving = True

        for sock, (local, port, peer, md) in self._sockets.items():
            if local_ip.top() != local:
                continue
            if local_port != port:
                continue
            MD5(sock, peer_ip.top(), 0, md5, md5_base64)
            if ttl_in:
                MIN_TTL(sock, peer_ip, ttl_in)
            return

        try:
            sock = self._new_socket(local_ip)
            # MD5 must match the peer side of the TCP, not the local one
            MD5(sock, peer_ip.top(), 0, md5, md5_base64)
            if ttl_in:
                MIN_TTL(sock, peer_ip, ttl_in)
            try:
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                if local_ip.ipv6():
                    sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
            except (socket.error, AttributeError):
                pass
            sock.setblocking(0)
            # s.settimeout(0.0)
            sock.bind((local_ip.top(), local_port))
            sock.listen(self._backlog)
            self._sockets[sock] = (local_ip.top(), local_port, peer_ip.top(),
                                   md5)
        except socket.error as exc:
            if exc.args[0] == errno.EADDRINUSE:
                raise BindingError(
                    'could not listen on %s:%d, the port may already be in use by another application'
                    % (local_ip, local_port))
            elif exc.args[0] == errno.EADDRNOTAVAIL:
                raise BindingError(
                    'could not listen on %s:%d, this is an invalid address' %
                    (local_ip, local_port))
            raise NetworkError(str(exc))
        except NetworkError as exc:
            self.logger.critical(str(exc), 'network')
            raise exc

    def listen_on(self, local_addr, remote_addr, port, md5_password,
                  md5_base64, ttl_in):
        try:
            if not remote_addr:
                remote_addr = IP.create(
                    '0.0.0.0') if local_addr.ipv4() else IP.create('::')
            self._listen(local_addr, remote_addr, port, md5_password,
                         md5_base64, ttl_in)
            self.logger.debug(
                'listening for BGP session(s) on %s:%d%s' %
                (local_addr, port, ' with MD5' if md5_password else ''),
                'network')
            return True
        except NetworkError as exc:
            if os.geteuid() != 0 and port <= 1024:
                self.logger.critical(
                    'can not bind to %s:%d, you may need to run ExaBGP as root'
                    % (local_addr, port), 'network')
            else:
                self.logger.critical(
                    'can not bind to %s:%d (%s)' %
                    (local_addr, port, str(exc)), 'network')
            self.logger.critical(
                'unset exabgp.tcp.bind if you do not want listen for incoming connections',
                'network')
            self.logger.critical(
                'and check that no other daemon is already binding to port %d'
                % port, 'network')
            return False

    def incoming(self):
        if not self.serving:
            return False

        for sock in self._sockets:
            if sock in self._accepted:
                continue
            try:
                io, _ = sock.accept()
                self._accepted[sock] = io
                self._pending += 1
            except socket.error as exc:
                if exc.errno in error.block:
                    continue
                self.logger.critical(str(exc), 'network')
        if self._pending:
            self._pending -= 1
            return True
        return False

    def _connected(self):
        try:
            for sock, io in list(self._accepted.items()):
                del self._accepted[sock]
                if sock.family == socket.AF_INET:
                    local_ip = io.getpeername()[0]  # local_ip,local_port
                    remote_ip = io.getsockname()[0]  # remote_ip,remote_port
                elif sock.family == socket.AF_INET6:
                    local_ip = io.getpeername()[
                        0]  # local_ip,local_port,local_flow,local_scope
                    remote_ip = io.getsockname()[
                        0]  # remote_ip,remote_port,remote_flow,remote_scope
                else:
                    raise AcceptError('unexpected address family (%d)' %
                                      sock.family)
                fam = self._family_AFI_map[sock.family]
                yield Incoming(fam, remote_ip, local_ip, io)
        except NetworkError as exc:
            self.logger.critical(str(exc), 'network')

    def new_connections(self):
        if not self.serving:
            return
        yield None

        reactor = self._reactor
        ranged_neighbor = []

        for connection in self._connected():
            for key in reactor.peers:
                peer = reactor.peers[key]
                neighbor = peer.neighbor

                connection_local = IP.create(connection.local).address()
                neighbor_peer_start = neighbor.peer_address.address()
                neighbor_peer_next = neighbor_peer_start + neighbor.range_size

                if not neighbor_peer_start <= connection_local < neighbor_peer_next:
                    continue

                connection_peer = IP.create(connection.peer).address()
                neighbor_local = neighbor.local_address.address()

                if connection_peer != neighbor_local:
                    if not neighbor.auto_discovery:
                        continue

                # we found a range matching for this connection
                # but the peer may already have connected, so
                # we need to iterate all individual peers before
                # handling "range" peers
                if neighbor.range_size > 1:
                    ranged_neighbor.append(peer.neighbor)
                    continue

                denied = peer.handle_connection(connection)
                if denied:
                    self.logger.debug(
                        'refused connection from %s due to the state machine' %
                        connection.name(), 'network')
                    break
                self.logger.debug(
                    'accepted connection from %s' % connection.name(),
                    'network')
                break
            else:
                # we did not break (and nothign was found/done or we have group match)
                matched = len(ranged_neighbor)
                if matched > 1:
                    self.logger.debug(
                        'could not accept connection from %s (more than one neighbor match)'
                        % connection.name(), 'network')
                    reactor. async .schedule(
                        str(uuid.uuid1()), 'sending notification (6,5)',
                        connection.notification(
                            6, 5,
                            b'could not accept the connection (more than one neighbor match)'
                        ))
                    return
                if not matched:
                    self.logger.debug(
                        'no session configured for %s' % connection.name(),
                        'network')
                    reactor. async .schedule(
                        str(uuid.uuid1()), 'sending notification (6,3)',
                        connection.notification(
                            6, 3, b'no session configured for the peer'))
                    return

                new_neighbor = copy.copy(ranged_neighbor[0])
                new_neighbor.range_size = 1
                new_neighbor.generated = True
                new_neighbor.local_address = IP.create(connection.peer)
                new_neighbor.peer_address = IP.create(connection.local)

                new_peer = Peer(new_neighbor, self)
                denied = new_peer.handle_connection(connection)
                if denied:
                    self.logger.debug(
                        'refused connection from %s due to the state machine' %
                        connection.name(), 'network')
                    return

                reactor.peers[new_neighbor.name()] = new_peer
                return

    def stop(self):
        if not self.serving:
            return

        for sock, (ip, port, _, _) in self._sockets.items():
            sock.close()
            self.logger.info('stopped listening on %s:%d' % (ip, port),
                             'network')

        self._sockets = {}
        self.serving = False
Exemplo n.º 2
0
def run(env, comment, configurations, root, validate, pid=0):
    logger = Logger()

    logger.notice('Thank you for using ExaBGP', 'welcome')
    logger.notice('%s' % version, 'version')
    logger.notice('%s' % sys.version.replace('\n', ' '), 'interpreter')
    logger.notice('%s' % ' '.join(platform.uname()[:5]), 'os')
    logger.notice('%s' % root, 'installation')

    if comment:
        logger.notice(comment, 'advice')

    warning = warn()
    if warning:
        logger.warning(warning, 'advice')

    if env.api.cli:
        pipename = 'exabgp' if env.api.pipename is None else env.api.pipename
        pipes = named_pipe(root, pipename)
        if len(pipes) != 1:
            env.api.cli = False
            logger.error(
                'could not find the named pipes (%s.in and %s.out) required for the cli'
                % (pipename, pipename), 'cli')
            logger.error(
                'we scanned the following folders (the number is your PID):',
                'cli')
            for location in pipes:
                logger.error(' - %s' % location, 'cli control')
            logger.error(
                'please make them in one of the folder with the following commands:',
                'cli control')
            logger.error(
                '> mkfifo %s/run/%s.{in,out}' % (os.getcwd(), pipename),
                'cli control')
            logger.error(
                '> chmod 600 %s/run/%s.{in,out}' % (os.getcwd(), pipename),
                'cli control')
            if os.getuid() != 0:
                logger.error(
                    '> chown %d:%d %s/run/%s.{in,out}' %
                    (os.getuid(), os.getgid(), os.getcwd(), pipename),
                    'cli control')
        else:
            pipe = pipes[0]
            os.environ['exabgp_cli_pipe'] = pipe
            os.environ['exabgp_api_pipename'] = pipename

            logger.info('named pipes for the cli are:', 'cli control')
            logger.info('to send commands  %s%s.in' % (pipe, pipename),
                        'cli control')
            logger.info('to read responses %s%s.out' % (pipe, pipename),
                        'cli control')

    if not env.profile.enable:
        exit_code = Reactor(configurations).run(validate, root)
        __exit(env.debug.memory, exit_code)

    try:
        import cProfile as profile
    except ImportError:
        import profile

    if env.profile.file == 'stdout':
        profiled = 'Reactor(%s).run(%s,"%s")' % (str(configurations),
                                                 str(validate), str(root))
        exit_code = profile.run(profiled)
        __exit(env.debug.memory, exit_code)

    if pid:
        profile_name = "%s-pid-%d" % (env.profile.file, pid)
    else:
        profile_name = env.profile.file

    notice = ''
    if os.path.isdir(profile_name):
        notice = 'profile can not use this filename as output, it is not a directory (%s)' % profile_name
    if os.path.exists(profile_name):
        notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name

    if not notice:
        cwd = os.getcwd()
        logger.debug('profiling ....', 'reactor')
        profiler = profile.Profile()
        profiler.enable()
        try:
            exit_code = Reactor(configurations).run(validate, root)
        except Exception:
            exit_code = Reactor.Exit.unknown
            raise
        finally:
            profiler.disable()
            kprofile = lsprofcalltree.KCacheGrind(profiler)
            try:
                destination = profile_name if profile_name.startswith(
                    '/') else os.path.join(cwd, profile_name)
                with open(destination, 'w+') as write:
                    kprofile.output(write)
            except IOError:
                notice = 'could not save profiling in formation at: ' + destination
                logger.debug("-" * len(notice), 'reactor')
                logger.debug(notice, 'reactor')
                logger.debug("-" * len(notice), 'reactor')
            __exit(env.debug.memory, exit_code)
    else:
        logger.debug("-" * len(notice), 'reactor')
        logger.debug(notice, 'reactor')
        logger.debug("-" * len(notice), 'reactor')
        Reactor(configurations).run(validate, root)
        __exit(env.debug.memory, 1)
Exemplo n.º 3
0
class Listener (object):
	_family_AFI_map = {
		socket.AF_INET: AFI.ipv4,
		socket.AF_INET6: AFI.ipv6,
	}

	def __init__ (self, reactor, backlog=200):
		self.serving = False
		self.logger = Logger()

		self._reactor = reactor
		self._backlog = backlog
		self._sockets = {}
		self._accepted = {}
		self._pending = 0

	def _new_socket (self, ip):
		if ip.afi == AFI.ipv6:
			return socket.socket(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP)
		if ip.afi == AFI.ipv4:
			return socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
		raise NetworkError('Can not create socket for listening, family of IP %s is unknown' % ip)

	def _listen (self, local_ip, peer_ip, local_port, md5, md5_base64, ttl_in):
		self.serving = True

		for sock,(local,port,peer,md) in self._sockets.items():
			if local_ip.top() != local:
				continue
			if local_port != port:
				continue
			MD5(sock,peer_ip.top(),0,md5,md5_base64)
			if ttl_in:
				MIN_TTL(sock,peer_ip,ttl_in)
			return

		try:
			sock = self._new_socket(local_ip)
			# MD5 must match the peer side of the TCP, not the local one
			MD5(sock,peer_ip.top(),0,md5,md5_base64)
			if ttl_in:
				MIN_TTL(sock,peer_ip,ttl_in)
			try:
				sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
				if local_ip.ipv6():
					sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
			except (socket.error,AttributeError):
				pass
			sock.setblocking(0)
			# s.settimeout(0.0)
			sock.bind((local_ip.top(),local_port))
			sock.listen(self._backlog)
			self._sockets[sock] = (local_ip.top(),local_port,peer_ip.top(),md5)
		except socket.error as exc:
			if exc.args[0] == errno.EADDRINUSE:
				raise BindingError('could not listen on %s:%d, the port may already be in use by another application' % (local_ip,local_port))
			elif exc.args[0] == errno.EADDRNOTAVAIL:
				raise BindingError('could not listen on %s:%d, this is an invalid address' % (local_ip,local_port))
			raise NetworkError(str(exc))
		except NetworkError as exc:
			self.logger.critical(str(exc),'network')
			raise exc

	def listen_on (self, local_addr, remote_addr, port, md5_password, md5_base64, ttl_in):
		try:
			if not remote_addr:
				remote_addr = IP.create('0.0.0.0') if local_addr.ipv4() else IP.create('::')
			self._listen(local_addr, remote_addr, port, md5_password, md5_base64, ttl_in)
			self.logger.debug('listening for BGP session(s) on %s:%d%s' % (local_addr, port,' with MD5' if md5_password else ''),'network')
			return True
		except NetworkError as exc:
			if os.geteuid() != 0 and port <= 1024:
				self.logger.critical('can not bind to %s:%d, you may need to run ExaBGP as root' % (local_addr, port),'network')
			else:
				self.logger.critical('can not bind to %s:%d (%s)' % (local_addr, port,str(exc)),'network')
			self.logger.critical('unset exabgp.tcp.bind if you do not want listen for incoming connections','network')
			self.logger.critical('and check that no other daemon is already binding to port %d' % port,'network')
			return False

	def incoming (self):
		if not self.serving:
			return False

		for sock in self._sockets:
			if sock in self._accepted:
				continue
			try:
				io, _ = sock.accept()
				self._accepted[sock] = io
				self._pending += 1
			except socket.error as exc:
				if exc.errno in error.block:
					continue
				self.logger.critical(str(exc),'network')
		if self._pending:
			self._pending -= 1
			return True
		return False

	def _connected (self):
		try:
			for sock,io in list(self._accepted.items()):
				del self._accepted[sock]
				if sock.family == socket.AF_INET:
					local_ip  = io.getpeername()[0]  # local_ip,local_port
					remote_ip = io.getsockname()[0]  # remote_ip,remote_port
				elif sock.family == socket.AF_INET6:
					local_ip  = io.getpeername()[0]  # local_ip,local_port,local_flow,local_scope
					remote_ip = io.getsockname()[0]  # remote_ip,remote_port,remote_flow,remote_scope
				else:
					raise AcceptError('unexpected address family (%d)' % sock.family)
				fam = self._family_AFI_map[sock.family]
				yield Incoming(fam,remote_ip,local_ip,io)
		except NetworkError as exc:
			self.logger.critical(str(exc),'network')

	def new_connections (self):
		if not self.serving:
			return
		yield None

		reactor = self._reactor
		ranged_neighbor = []

		for connection in self._connected():
			self.logger.debug('new connection received %s' % connection.name(),'network')
			for key in reactor.peers:
				peer = reactor.peers[key]
				neighbor = peer.neighbor

				connection_local = IP.create(connection.local).address()
				neighbor_peer_start = neighbor.peer_address.address()
				neighbor_peer_next = neighbor_peer_start + neighbor.range_size

				if not neighbor_peer_start <= connection_local < neighbor_peer_next:
					continue

				connection_peer = IP.create(connection.peer).address()
				neighbor_local = neighbor.local_address.address()

				if connection_peer != neighbor_local:
					if not neighbor.auto_discovery:
						continue

				# we found a range matching for this connection
				# but the peer may already have connected, so
				# we need to iterate all individual peers before
				# handling "range" peers
				if neighbor.range_size > 1:
					ranged_neighbor.append(peer.neighbor)
					continue

				denied = peer.handle_connection(connection)
				if denied:
					self.logger.debug('refused connection from %s due to the state machine' % connection.name(),'network')
					break
				self.logger.debug('accepted connection from %s' % connection.name(),'network')
				break
			else:
				# we did not break (and nothign was found/done or we have group match)
				matched = len(ranged_neighbor)
				if matched > 1:
					self.logger.debug('could not accept connection from %s (more than one neighbor match)' % connection.name(),'network')
					reactor.asynchronous.schedule(str(uuid.uuid1()), 'sending notification (6,5)', connection.notification(
						6, 5, 'could not accept the connection (more than one neighbor match)'))
					return
				if not matched:
					self.logger.debug('no session configured for %s' % connection.name(),'network')
					reactor.asynchronous.schedule(str(uuid.uuid1()), 'sending notification (6,3)', connection.notification(
						6, 3, 'no session configured for the peer'))
					return

				new_neighbor = copy.copy(ranged_neighbor[0])
				new_neighbor.range_size = 1
				new_neighbor.generated = True
				new_neighbor.local_address = IP.create(connection.peer)
				new_neighbor.peer_address = IP.create(connection.local)
				new_neighbor.router_id = RouterID.create(connection.local)

				new_peer = Peer(new_neighbor,self)
				denied = new_peer.handle_connection(connection)
				if denied:
					self.logger.debug('refused connection from %s due to the state machine' % connection.name(),'network')
					return

				reactor.peers[new_neighbor.name()] = new_peer
				return

	def stop (self):
		if not self.serving:
			return

		for sock,(ip,port,_,_) in self._sockets.items():
			sock.close()
			self.logger.info('stopped listening on %s:%d' % (ip,port),'network')

		self._sockets = {}
		self.serving = False
Exemplo n.º 4
0
def check_update (neighbor, raw):
	logger = Logger()
	logger._option['parser'] = True
	logger.debug('\ndecoding routes in configuration','parser')

	neighbor = neighbor[list(neighbor)[0]]

	path = {}
	for f in NLRI.known_families():
		if neighbor.add_path:
			path[f] = neighbor.add_path

	capa = Capabilities().new(neighbor,False)
	capa[Capability.CODE.ADD_PATH] = path
	capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()
	# capa[Capability.CODE.FOUR_BYTES_ASN] = True

	routerid_1 = str(neighbor.router_id)
	routerid_2 = '.'.join(str((int(_)+1) % 250) for _ in str(neighbor.router_id).split('.',-1))

	o1 = Open(Version(4),ASN(neighbor.local_as),HoldTime(180),RouterID(routerid_1),capa)
	o2 = Open(Version(4),ASN(neighbor.peer_as),HoldTime(180),RouterID(routerid_2),capa)
	negotiated = Negotiated(neighbor)
	negotiated.sent(o1)
	negotiated.received(o2)
	# grouped = False

	while raw:
		if raw.startswith(b'\xff'*16):
			kind = ordinal(raw[18])
			size = (ordinal(raw[16]) << 16) + (ordinal(raw[17]))

			injected,raw = raw[19:size],raw[size:]

			if kind == 2:
				logger.debug('the message is an update','parser')
				decoding = 'update'
			else:
				logger.debug('the message is not an update (%d) - aborting' % kind,'parser')
				return False
		else:
			logger.debug('header missing, assuming this message is ONE update','parser')
			decoding = 'update'
			injected,raw = raw,''

		try:
			# This does not take the BGP header - let's assume we will not break that :)
			update = Update.unpack_message(injected,negotiated)
		except KeyboardInterrupt:
			raise
		except Notify:
			logger.error('could not parse the message','parser')
			logger.error(traceback.format_exc(),'parser')
			return False
		except StandardError:
			logger.error('could not parse the message','parser')
			logger.error(traceback.format_exc(),'parser')
			return False

		logger.debug('','parser')  # new line
		for number in range(len(update.nlris)):
			change = Change(update.nlris[number],update.attributes)
			logger.info('decoded %s %s %s' % (decoding,change.nlri.action,change.extensive()),'parser')
		logger.info('update json %s' % Response.JSON(json_version).update(neighbor,'in',update,None,'',''),'parser')

	return True
Exemplo n.º 5
0
def check_update(neighbor, raw):
    logger = Logger()
    logger._option['parser'] = True
    logger.debug('\ndecoding routes in configuration', 'parser')

    neighbor = neighbor[list(neighbor)[0]]

    path = {}
    for f in NLRI.known_families():
        if neighbor.add_path:
            path[f] = neighbor.add_path

    capa = Capabilities().new(neighbor, False)
    capa[Capability.CODE.ADD_PATH] = path
    capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families()
    # capa[Capability.CODE.FOUR_BYTES_ASN] = True

    routerid_1 = str(neighbor.router_id)
    routerid_2 = '.'.join(
        str((int(_) + 1) % 250)
        for _ in str(neighbor.router_id).split('.', -1))

    o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180),
              RouterID(routerid_1), capa)
    o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180),
              RouterID(routerid_2), capa)
    negotiated = Negotiated(neighbor)
    negotiated.sent(o1)
    negotiated.received(o2)
    # grouped = False

    while raw:
        if raw.startswith(b'\xff' * 16):
            kind = ordinal(raw[18])
            size = (ordinal(raw[16]) << 16) + (ordinal(raw[17]))

            injected, raw = raw[19:size], raw[size:]

            if kind == 2:
                logger.debug('the message is an update', 'parser')
                decoding = 'update'
            else:
                logger.debug(
                    'the message is not an update (%d) - aborting' % kind,
                    'parser')
                return False
        else:
            logger.debug('header missing, assuming this message is ONE update',
                         'parser')
            decoding = 'update'
            injected, raw = raw, ''

        try:
            # This does not take the BGP header - let's assume we will not break that :)
            update = Update.unpack_message(injected, negotiated)
        except KeyboardInterrupt:
            raise
        except Notify:
            logger.error('could not parse the message', 'parser')
            logger.error(traceback.format_exc(), 'parser')
            return False
        except StandardError:
            logger.error('could not parse the message', 'parser')
            logger.error(traceback.format_exc(), 'parser')
            return False

        logger.debug('', 'parser')  # new line
        for number in range(len(update.nlris)):
            change = Change(update.nlris[number], update.attributes)
            logger.info(
                'decoded %s %s %s' %
                (decoding, change.nlri.action, change.extensive()), 'parser')
        logger.info(
            'update json %s' % Response.JSON(json_version).update(
                neighbor, 'in', update, None, '', ''), 'parser')

    return True
Exemplo n.º 6
0
Arquivo: bgp.py Projeto: aabdnn/exabgp
def run (env, comment, configurations, root, validate, pid=0):
	logger = Logger()

	logger.notice('Thank you for using ExaBGP','welcome')
	logger.notice('%s' % version,'version')
	logger.notice('%s' % sys.version.replace('\n',' '),'interpreter')
	logger.notice('%s' % ' '.join(platform.uname()[:5]),'os')
	logger.notice('%s' % root,'installation')

	if comment:
		logger.notice(comment,'advice')

	warning = warn()
	if warning:
		logger.warning(warning,'advice')

	if env.api.cli:
		pipes = named_pipe(root)
		if len(pipes) != 1:
			env.api.cli = False
			logger.error('could not find the named pipes (exabgp.in and exabgp.out) required for the cli','cli')
			logger.error('we scanned the following folders (the number is your PID):','cli')
			for location in pipes:
				logger.error(' - %s' % location,'cli control')
			logger.error('please make them in one of the folder with the following commands:','cli control')
			logger.error('> mkfifo %s/run/exabgp.{in,out}' % os.getcwd(),'cli control')
			logger.error('> chmod 600 %s/run/exabgp.{in,out}' % os.getcwd(),'cli control')
			if os.getuid() != 0:
				logger.error('> chown %d:%d %s/run/exabgp.{in,out}' % (os.getuid(),os.getgid(),os.getcwd()),'cli control')
		else:
			pipe = pipes[0]
			os.environ['exabgp_cli_pipe'] = pipe

			logger.info('named pipes for the cli are:','cli control')
			logger.info('to send commands  %sexabgp.in' % pipe,'cli control')
			logger.info('to read responses %sexabgp.out' % pipe,'cli control')

	if not env.profile.enable:
		was_ok = Reactor(configurations).run(validate,root)
		__exit(env.debug.memory,0 if was_ok else 1)

	try:
		import cProfile as profile
	except ImportError:
		import profile

	if env.profile.file == 'stdout':
		profiled = 'Reactor(%s).run(%s,"%s")' % (str(configurations),str(validate),str(root))
		was_ok = profile.run(profiled)
		__exit(env.debug.memory,0 if was_ok else 1)

	if pid:
		profile_name = "%s-pid-%d" % (env.profile.file,pid)
	else:
		profile_name = env.profile.file

	notice = ''
	if os.path.isdir(profile_name):
		notice = 'profile can not use this filename as output, it is not a directory (%s)' % profile_name
	if os.path.exists(profile_name):
		notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name

	if not notice:
		cwd = os.getcwd()
		logger.debug('profiling ....','reactor')
		profiler = profile.Profile()
		profiler.enable()
		try:
			was_ok = Reactor(configurations).run(validate,root)
		except Exception:
			was_ok = False
			raise
		finally:
			profiler.disable()
			kprofile = lsprofcalltree.KCacheGrind(profiler)
			try:
				destination = profile_name if profile_name.startswith('/') else os.path.join(cwd,profile_name)
				with open(destination, 'w+') as write:
					kprofile.output(write)
			except IOError:
				notice = 'could not save profiling in formation at: ' + destination
				logger.debug("-"*len(notice),'reactor')
				logger.debug(notice,'reactor')
				logger.debug("-"*len(notice),'reactor')
			__exit(env.debug.memory,0 if was_ok else 1)
	else:
		logger.debug("-"*len(notice),'reactor')
		logger.debug(notice,'reactor')
		logger.debug("-"*len(notice),'reactor')
		Reactor(configurations).run(validate,root)
		__exit(env.debug.memory,1)