Example #1
0
    def __init__(self,
                 simulation_cfg,
                 superlog_path_or_dag,
                 create_event_scheduler=None,
                 **kwargs):
        ControlFlow.__init__(self, simulation_cfg)
        self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

        if type(superlog_path_or_dag) == str:
            superlog_path = superlog_path_or_dag
            # The dag is codefied as a list, where each element has
            # a list of its dependents
            self.dag = EventDag(superlog_parser.parse_path(superlog_path))
        else:
            self.dag = superlog_path_or_dag

        # compute interpolate to time to be just before first event
        self.compute_interpolated_time(self.dag.events[0])

        if create_event_scheduler:
            self.create_event_scheduler = create_event_scheduler
        else:
            self.create_event_scheduler = \
              lambda simulation: EventScheduler(simulation,
                  **{ k: v for k,v in kwargs.items()
                      if k in EventScheduler.kwargs })
Example #2
0
  def __init__(self, simulation_cfg, fuzzer_params="config.fuzzer_params",
               check_interval=None, traffic_inject_interval=10, random_seed=None,
               delay=0.1, steps=None, input_logger=None,
               invariant_check=InvariantChecker.check_correspondence,
               halt_on_violation=False, log_invariant_checks=True):
    ControlFlow.__init__(self, simulation_cfg)
    self.sync_callback = RecordingSyncCallback(input_logger)

    self.check_interval = check_interval
    self.invariant_check = invariant_check
    self.log_invariant_checks = log_invariant_checks
    self.traffic_inject_interval = traffic_inject_interval
    # Make execution deterministic to allow the user to easily replay
    if random_seed is None:
      self.random = random.Random()
    else:
      self.random = random.Random(random_seed)
    self.traffic_generator = TrafficGenerator(self.random)

    self.delay = delay
    self.steps = steps
    self.params = object()
    self._load_fuzzer_params(fuzzer_params)
    self._input_logger = input_logger
    self.halt_on_violation = halt_on_violation

    # Logical time (round #) for the simulation execution
    self.logical_time = 0
Example #3
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None,
               print_buffers=True, wait_on_deterministic_values=False,
               fail_to_interactive=False, **kwargs):
    ControlFlow.__init__(self, simulation_cfg)
    if wait_on_deterministic_values:
      self.sync_callback = ReplaySyncCallback()
    else:
      self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(superlog_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    self.dp_checker = DataplaneChecker(self.dag)

    self.print_buffers = print_buffers

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])
    self.unexpected_state_changes = []
    self.early_state_changes = []
    self.event_scheduler_stats = None
    self.fail_to_interactive = fail_to_interactive

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })
Example #4
0
    def __init__(self,
                 simulation_cfg,
                 fuzzer_params="config.fuzzer_params",
                 check_interval=None,
                 traffic_inject_interval=10,
                 random_seed=None,
                 delay=0.1,
                 steps=None,
                 input_logger=None,
                 invariant_check=InvariantChecker.check_correspondence,
                 halt_on_violation=False,
                 log_invariant_checks=True):
        ControlFlow.__init__(self, simulation_cfg)
        self.sync_callback = RecordingSyncCallback(input_logger)

        self.check_interval = check_interval
        self.invariant_check = invariant_check
        self.log_invariant_checks = log_invariant_checks
        self.traffic_inject_interval = traffic_inject_interval
        # Make execution deterministic to allow the user to easily replay
        if random_seed is None:
            self.random = random.Random()
        else:
            self.random = random.Random(random_seed)
        self.traffic_generator = TrafficGenerator(self.random)

        self.delay = delay
        self.steps = steps
        self.params = object()
        self._load_fuzzer_params(fuzzer_params)
        self._input_logger = input_logger
        self.halt_on_violation = halt_on_violation

        # Logical time (round #) for the simulation execution
        self.logical_time = 0
Example #5
0
 def __init__(self, simulation_cfg, input_logger=None,
              pass_through_of_messages=True):
   ControlFlow.__init__(self, simulation_cfg)
   self.sync_callback = RecordingSyncCallback(input_logger)
   self.logical_time = 0
   self._input_logger = input_logger
   self.traffic_generator = TrafficGenerator(random.Random())
   # TODO(cs): we don't actually have a way to support pass_through=False, in
   # a reasonable way -- the user has no (easy) way to examine and route
   # OpenFlowBuffer's pending_receives and pending_sends.
   self.pass_through_of_messages = pass_through_of_messages
Example #6
0
 def __init__(self, simulation_cfg, input_logger=None,
              pass_through_of_messages=True):
   ControlFlow.__init__(self, simulation_cfg)
   self.sync_callback = RecordingSyncCallback(input_logger)
   self.logical_time = 0
   self._input_logger = input_logger
   self.traffic_generator = TrafficGenerator(random.Random())
   # TODO(cs): we don't actually have a way to support pass_through=False, in
   # a reasonable way -- the user has no (easy) way to examine and route
   # OpenFlowBuffer's pending_receives and pending_sends.
   self.pass_through_of_messages = pass_through_of_messages
Example #7
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None, **kwargs):
    ControlFlow.__init__(self, simulation_cfg)
    self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(superlog_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })
Example #8
0
    def __init__(self,
                 simulation_cfg,
                 fuzzer_params="config.fuzzer_params",
                 check_interval=None,
                 traffic_inject_interval=10,
                 random_seed=None,
                 delay=0.1,
                 steps=None,
                 input_logger=None,
                 invariant_check_name="InvariantChecker.check_correspondence",
                 halt_on_violation=False,
                 log_invariant_checks=True,
                 delay_startup=True,
                 print_buffers=True,
                 record_deterministic_values=False,
                 mock_link_discovery=False,
                 never_drop_whitelisted_packets=True,
                 initialization_rounds=0):
        '''
    Options:
      - fuzzer_params: path to event probabilities
      - check_interval: the period for checking invariants, in terms of
        logical rounds
      - traffic_inject_interval: how often to inject dataplane trace packets
      - random_seed: optionally set the seed of the random number generator
      - delay: how long to sleep between each logical round
      - input_logger: None, or a InputLogger instance
      - invariant_check_name: the name of the invariant check, from
        config/invariant_checks.py
      - halt_on_violation: whether to stop after a bug has been detected
      - log_invariant_checks: whether to log InvariantCheck events
      - delay_startup: whether to until the first OpenFlow message is received
        before proceeding with fuzzing
      - print_buffers: whether to print the remaining contents of the
        dataplane/controlplane buffers at the end of the execution
      - record_deterministic_values: whether to record gettimeofday requests
        for replay
      - mock_link_discovery: optional module for POX to experiment with
        better determinism -- tell POX exactly when links should be discovered
      - initialization_rounds: if non-zero, will wait the specified rounds to
        let the controller discover the topology before injecting inputs
    '''
        ControlFlow.__init__(self, simulation_cfg)
        self.sync_callback = RecordingSyncCallback(
            input_logger,
            record_deterministic_values=record_deterministic_values)

        self.check_interval = check_interval
        if self.check_interval is None:
            print >> sys.stderr, "Fuzzer Warning: Check interval is not specified... not checking invariants"
        if invariant_check_name not in name_to_invariant_check:
            raise ValueError(
                '''Unknown invariant check %s.\n'''
                '''Invariant check name must be defined in config.invariant_checks''',
                invariant_check_name)
        self.invariant_check_name = invariant_check_name
        self.invariant_check = name_to_invariant_check[invariant_check_name]
        self.log_invariant_checks = log_invariant_checks
        self.traffic_inject_interval = traffic_inject_interval
        # Make execution deterministic to allow the user to easily replay
        if random_seed is None:
            random_seed = random.randint(0, sys.maxint)

        self.random_seed = random_seed
        self.random = random.Random(random_seed)
        self.traffic_generator = TrafficGenerator(self.random)

        self.delay = delay
        self.steps = steps
        self.params = object()
        self._load_fuzzer_params(fuzzer_params)
        self._input_logger = input_logger
        self.halt_on_violation = halt_on_violation
        self.delay_startup = delay_startup
        self.print_buffers = print_buffers
        self.mock_link_discovery = mock_link_discovery
        # How many rounds to let the controller initialize:
        # send one round of packets directed at the source host itself (to facilitate
        # learning), then send all-to-all packets until all pairs have been
        # pinged. Tell MCSFinder not to prune initial inputs during this period.
        self.initialization_rounds = initialization_rounds
        # If initialization_rounds isn't 0, also make sure to send all-to-all
        # pings before starting any events
        self._pending_all_to_all = initialization_rounds != 0
        # Our current place in the all-to-all cycle. Stop when == len(hosts)
        self._all_to_all_iterations = 0
        # How often (in terms of logical rounds) to inject all-to-all packets
        self._all_to_all_interval = 5
        self.blocked_controller_pairs = []
        self.unblocked_controller_pairs = []

        # Logical time (round #) for the simulation execution
        self.logical_time = 0
        self.never_drop_whitelisted_packets = never_drop_whitelisted_packets

        # Determine whether to use delayed and randomized flow mod processing
        # (Set by fuzzer_params, not by an optional __init__ argument)
        self.delay_flow_mods = False
Example #9
0
    def __init__(self,
                 simulation_cfg,
                 superlog_path_or_dag,
                 create_event_scheduler=None,
                 print_buffers=True,
                 wait_on_deterministic_values=False,
                 default_dp_permit=False,
                 fail_to_interactive=False,
                 fail_to_interactive_on_persistent_violations=False,
                 end_in_interactive=False,
                 input_logger=None,
                 allow_unexpected_messages=False,
                 expected_message_round_window=3,
                 pass_through_whitelisted_messages=False,
                 delay_flow_mods=False,
                 invariant_check_name="",
                 bug_signature="",
                 end_wait_seconds=0.5,
                 transform_dag=None,
                 pass_through_sends=False,
                 fail_fast=False,
                 check_interval=5,
                 **kwargs):
        '''
     - If invariant_check_name is not None, check it at the end for the
       execution
     - If bug_signature is not None, check whether this particular signature
       appears in the output of the invariant check at the end of the
       execution
    '''
        ControlFlow.__init__(self, simulation_cfg)
        # Label uniquely identifying this replay, set in init_results()
        self.replay_id = "N/A"
        self.logical_time = 0
        if wait_on_deterministic_values:
            self.sync_callback = ReplaySyncCallback()
        else:
            self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

        if type(superlog_path_or_dag) == str:
            superlog_path = superlog_path_or_dag
            # The dag is codefied as a list, where each element has
            # a list of its dependents
            self.dag = EventDag(log_parser.parse_path(superlog_path))
        else:
            self.dag = superlog_path_or_dag

        if len(self.dag.events) == 0:
            raise ValueError("No events to replay!")

        self.default_dp_permit = default_dp_permit
        self.dp_checker = self._setup_dp_checker(default_dp_permit)
        if self.default_dp_permit:
            # Set DataplanePermit and DataplaneDrop to passive if permit is set
            # to default
            # TODO(cs): rather than setting these to passive (which still causes them to
            # be scheduled as regular events) should these just be removed from the
            # event dag altogether?
            for event in [e for e in self.dag.events if type(e) in dp_events]:
                event.passive = default_dp_permit

        self.print_buffers_flag = print_buffers
        self.fail_fast = fail_fast
        self.check_interval = check_interval

        # compute interpolate to time to be just before first event
        self.compute_interpolated_time(self.dag.events[0])
        # String repesentations of unexpected state changes we've passed through, for
        # statistics purposes.
        self.unexpected_state_changes = []
        self.early_state_changes = []
        self.event_scheduler_stats = None
        self.end_in_interactive = end_in_interactive
        self.fail_to_interactive = fail_to_interactive
        self.fail_to_interactive_on_persistent_violations =\
          fail_to_interactive_on_persistent_violations
        self._input_logger = input_logger
        self.allow_unexpected_messages = allow_unexpected_messages
        self.expected_message_round_window = expected_message_round_window
        self.pass_through_whitelisted_messages = pass_through_whitelisted_messages
        self.pass_through_sends = pass_through_sends
        # How many logical rounds to peek ahead when deciding if a message is
        # expected or not.
        # String repesentations of unexpected messages we've passed through, for
        # statistics purposes.
        self.passed_unexpected_messages = []
        self.delay_flow_mods = delay_flow_mods
        self.end_wait_seconds = end_wait_seconds
        self.transform_dag = transform_dag
        self.bug_signature = bug_signature
        self.invariant_check_name = invariant_check_name
        self.invariant_check = None
        if self.invariant_check_name:
            if self.invariant_check_name not in name_to_invariant_check:
                raise ValueError(
                    '''Unknown invariant check %s.\n'''
                    '''Invariant check name must be defined in config.invariant_checks''',
                    self.invariant_check_name)
            self.invariant_check = name_to_invariant_check[
                self.invariant_check_name]

        if self.pass_through_whitelisted_messages:
            for event in self.dag.events:
                if hasattr(event, "ignore_whitelisted_packets"):
                    event.ignore_whitelisted_packets = True

        if self.simulation_cfg.ignore_interposition:
            self._ignore_interposition()

        if create_event_scheduler:
            self.create_event_scheduler = create_event_scheduler
        else:
            if self.default_dp_permit:
                # Tell EventScheduler to use call into us whenever it wants to sleep or
                # select, so that we can keep forwarding dataplane packets.
                kwargs[
                    'sleep_continuation'] = self._sleep_with_dataplane_passthrough
                kwargs[
                    'select_continuation'] = self._select_with_dataplane_passthrough

            self.create_event_scheduler = \
              lambda simulation: EventScheduler(simulation,
                  **{ k: v for k,v in kwargs.items()
                      if k in EventScheduler.kwargs })

        unknown_kwargs = [
            k for k in kwargs.keys() if k not in EventScheduler.kwargs
        ]
        if unknown_kwargs != []:
            raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
Example #10
0
  def __init__(self, simulation_cfg, fuzzer_params="config.fuzzer_params",
               check_interval=None, traffic_inject_interval=10, random_seed=None,
               delay=0.1, steps=None, input_logger=None,
               invariant_check_name="InvariantChecker.check_correspondence",
               halt_on_violation=False, log_invariant_checks=True,
               delay_startup=True, print_buffers=True,
               record_deterministic_values=False,
               mock_link_discovery=False,
               never_drop_whitelisted_packets=True,
               initialization_rounds=0):
    '''
    Options:
      - fuzzer_params: path to event probabilities
      - check_interval: the period for checking invariants, in terms of
        logical rounds
      - traffic_inject_interval: how often to inject dataplane trace packets
      - random_seed: optionally set the seed of the random number generator
      - delay: how long to sleep between each logical round
      - input_logger: None, or a InputLogger instance
      - invariant_check_name: the name of the invariant check, from
        config/invariant_checks.py
      - halt_on_violation: whether to stop after a bug has been detected
      - log_invariant_checks: whether to log InvariantCheck events
      - delay_startup: whether to until the first OpenFlow message is received
        before proceeding with fuzzing
      - print_buffers: whether to print the remaining contents of the
        dataplane/controlplane buffers at the end of the execution
      - record_deterministic_values: whether to record gettimeofday requests
        for replay
      - mock_link_discovery: optional module for POX to experiment with
        better determinism -- tell POX exactly when links should be discovered
      - initialization_rounds: if non-zero, will wait the specified rounds to
        let the controller discover the topology before injecting inputs
    '''
    ControlFlow.__init__(self, simulation_cfg)
    self.sync_callback = RecordingSyncCallback(input_logger,
                           record_deterministic_values=record_deterministic_values)

    self.check_interval = check_interval
    if self.check_interval is None:
      print >> sys.stderr, "Fuzzer Warning: Check interval is not specified... not checking invariants"
    if invariant_check_name not in name_to_invariant_check:
      raise ValueError('''Unknown invariant check %s.\n'''
                       '''Invariant check name must be defined in config.invariant_checks''',
                       invariant_check_name)
    self.invariant_check_name = invariant_check_name
    self.invariant_check = name_to_invariant_check[invariant_check_name]
    self.log_invariant_checks = log_invariant_checks
    self.traffic_inject_interval = traffic_inject_interval
    # Make execution deterministic to allow the user to easily replay
    if random_seed is None:
      random_seed = random.randint(0, sys.maxint)

    self.random_seed = random_seed
    self.random = random.Random(random_seed)
    self.traffic_generator = TrafficGenerator(self.random)

    self.delay = delay
    self.steps = steps
    self.params = object()
    self._load_fuzzer_params(fuzzer_params)
    self._input_logger = input_logger
    self.halt_on_violation = halt_on_violation
    self.delay_startup = delay_startup
    self.print_buffers = print_buffers
    self.mock_link_discovery = mock_link_discovery
    # How many rounds to let the controller initialize:
    # send one round of packets directed at the source host itself (to facilitate
    # learning), then send all-to-all packets until all pairs have been
    # pinged. Tell MCSFinder not to prune initial inputs during this period.
    self.initialization_rounds = initialization_rounds
    # If initialization_rounds isn't 0, also make sure to send all-to-all
    # pings before starting any events
    self._pending_all_to_all = initialization_rounds != 0
    # Our current place in the all-to-all cycle. Stop when == len(hosts)
    self._all_to_all_iterations = 0
    # How often (in terms of logical rounds) to inject all-to-all packets
    self._all_to_all_interval = 5
    self.blocked_controller_pairs = []
    self.unblocked_controller_pairs = []

    # Logical time (round #) for the simulation execution
    self.logical_time = 0
    self.never_drop_whitelisted_packets = never_drop_whitelisted_packets

    # Determine whether to use delayed and randomized flow mod processing
    # (Set by fuzzer_params, not by an optional __init__ argument)
    self.delay_flow_mods = False
Example #11
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None,
               print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False,
               fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False,
               end_in_interactive=False, input_logger=None,
               allow_unexpected_messages=False,
               expected_message_round_window=3,
               pass_through_whitelisted_messages=False,
               delay_flow_mods=False, invariant_check_name="",
               bug_signature="", end_wait_seconds=0.5,
               transform_dag=None, pass_through_sends=False,
               **kwargs):
    '''
     - If invariant_check_name is not None, check it at the end for the
       execution
     - If bug_signature is not None, check whether this particular signature
       appears in the output of the invariant check at the end of the
       execution
    '''
    ControlFlow.__init__(self, simulation_cfg)
    # Label uniquely identifying this replay, set in init_results()
    self.replay_id = "N/A"
    self.logical_time = 0
    if wait_on_deterministic_values:
      self.sync_callback = ReplaySyncCallback()
    else:
      self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(log_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    if len(self.dag.events) == 0:
      raise ValueError("No events to replay!")

    self.default_dp_permit = default_dp_permit
    # Set DataplanePermit and DataplaneDrop to passive if permit is set
    # to default
    for event in [ e for e in self.dag.events if type(e) in dp_events ]:
      event.passive = default_dp_permit

    self.dp_checker = None
    no_dp_drops = [ e for e in self.dag.events if type(e) == DataplaneDrop ] == []
    if not default_dp_permit and no_dp_drops:
      print >> sys.stderr, ('''No DataplaneDrops to replay. We suggest you '''
                            '''set Replayer's default_dp_permit=True ''')
    if default_dp_permit:
      if no_dp_drops:
        self.dp_checker = AlwaysAllowDataplane(self.dag)
      else:
        self.dp_checker = DataplaneChecker(self.dag)

    self.print_buffers_flag = print_buffers

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])
    # String repesentations of unexpected state changes we've passed through, for
    # statistics purposes.
    self.unexpected_state_changes = []
    self.early_state_changes = []
    self.event_scheduler_stats = None
    self.end_in_interactive = end_in_interactive
    self.fail_to_interactive = fail_to_interactive
    self.fail_to_interactive_on_persistent_violations =\
      fail_to_interactive_on_persistent_violations
    self._input_logger = input_logger
    self.allow_unexpected_messages = allow_unexpected_messages
    self.expected_message_round_window = expected_message_round_window
    self.pass_through_whitelisted_messages = pass_through_whitelisted_messages
    self.pass_through_sends = pass_through_sends
    # How many logical rounds to peek ahead when deciding if a message is
    # expected or not.
    # String repesentations of unexpected messages we've passed through, for
    # statistics purposes.
    self.passed_unexpected_messages = []
    self.delay_flow_mods = delay_flow_mods
    self.end_wait_seconds = end_wait_seconds
    self.transform_dag = transform_dag
    self.bug_signature = bug_signature
    self.invariant_check_name = invariant_check_name
    self.invariant_check = None
    if self.invariant_check_name:
      if self.invariant_check_name not in name_to_invariant_check:
        raise ValueError('''Unknown invariant check %s.\n'''
                         '''Invariant check name must be defined in config.invariant_checks''',
                         self.invariant_check_name)
      self.invariant_check = name_to_invariant_check[self.invariant_check_name]

    if self.pass_through_whitelisted_messages:
      for event in self.dag.events:
        if hasattr(event, "ignore_whitelisted_packets"):
          event.ignore_whitelisted_packets = True

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })

    unknown_kwargs = [ k for k in kwargs.keys() if k not in EventScheduler.kwargs ]
    if unknown_kwargs != []:
      raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
Example #12
0
 def __init__(self, simulation_cfg, input_logger=None):
     ControlFlow.__init__(self, simulation_cfg)
     self.sync_callback = RecordingSyncCallback(input_logger)
     self.logical_time = 0
     self._input_logger = input_logger
Example #13
0
File: fuzzer.py Project: NetSys/sts
    def __init__(
        self,
        simulation_cfg,
        fuzzer_params="config.fuzzer_params",
        check_interval=None,
        traffic_inject_interval=10,
        random_seed=None,
        delay=0.1,
        steps=None,
        input_logger=None,
        invariant_check_name="InvariantChecker.check_correspondence",
        halt_on_violation=False,
        log_invariant_checks=True,
        delay_startup=True,
        print_buffers=True,
        record_deterministic_values=False,
        mock_link_discovery=False,
        initialization_rounds=0,
    ):
        ControlFlow.__init__(self, simulation_cfg)
        self.sync_callback = RecordingSyncCallback(
            input_logger, record_deterministic_values=record_deterministic_values
        )

        self.check_interval = check_interval
        if invariant_check_name not in name_to_invariant_check:
            raise ValueError(
                """Unknown invariant check %s.\n"""
                """Invariant check name must be defined in config.invariant_checks""",
                invariant_check_name,
            )
        self.invariant_check_name = invariant_check_name
        self.invariant_check = name_to_invariant_check[invariant_check_name]
        self.log_invariant_checks = log_invariant_checks
        self.traffic_inject_interval = traffic_inject_interval
        # Make execution deterministic to allow the user to easily replay
        if random_seed is None:
            random_seed = random.randint(0, sys.maxint)

        self.random_seed = random_seed
        self.random = random.Random(random_seed)
        self.traffic_generator = TrafficGenerator(self.random)

        self.delay = delay
        self.steps = steps
        self.params = object()
        self._load_fuzzer_params(fuzzer_params)
        self._input_logger = input_logger
        self.halt_on_violation = halt_on_violation
        self.delay_startup = delay_startup
        self.print_buffers = print_buffers
        self.mock_link_discovery = mock_link_discovery
        # How many rounds to let the controller initialize:
        # send one round of packets directed at the source host itself (to facilitate
        # learning), then send all-to-all packets until all pairs have been
        # pinged. Tell MCSFinder not to prune initial inputs during this period.
        self.initialization_rounds = initialization_rounds
        # If initialization_rounds isn't 0, also make sure to send all-to-all
        # pings before starting any events
        self._pending_all_to_all = initialization_rounds != 0
        # Our current place in the all-to-all cycle. Stop when == len(hosts)
        self._all_to_all_iterations = 0
        # How often (in terms of logical rounds) to inject all-to-all packets
        self._all_to_all_interval = 5

        # Logical time (round #) for the simulation execution
        self.logical_time = 0
Example #14
0
 def __init__(self, simulation_cfg, input_logger=None):
   ControlFlow.__init__(self, simulation_cfg)
   self.sync_callback = RecordingSyncCallback(input_logger)
   self.logical_time = 0
   self._input_logger = input_logger
Example #15
0
 def __init__(self, simulation_cfg, input_logger=None):
   ControlFlow.__init__(self, simulation_cfg)
   self.sync_callback = RecordingSyncCallback(input_logger)
   self.logical_time = 0
   self._input_logger = input_logger
   self.traffic_generator = TrafficGenerator(random.Random())
Example #16
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None,
               print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False,
               fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False,
               end_in_interactive=False, input_logger=None,
               allow_unexpected_messages=False,
               expected_message_round_window=3,
               pass_through_whitelisted_messages=False,
               delay_flow_mods=False, invariant_check_name="",
               bug_signature="", end_wait_seconds=0.5,
               transform_dag=None, pass_through_sends=False,
               fail_fast=False, check_interval=5,
               **kwargs):
    '''
     - If invariant_check_name is not None, check it at the end for the
       execution
     - If bug_signature is not None, check whether this particular signature
       appears in the output of the invariant check at the end of the
       execution
    '''
    ControlFlow.__init__(self, simulation_cfg)
    # Label uniquely identifying this replay, set in init_results()
    self.replay_id = "N/A"
    self.logical_time = 0
    if wait_on_deterministic_values:
      self.sync_callback = ReplaySyncCallback()
    else:
      self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(log_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    if len(self.dag.events) == 0:
      raise ValueError("No events to replay!")

    self.default_dp_permit = default_dp_permit
    self.dp_checker = self._setup_dp_checker(default_dp_permit)
    if self.default_dp_permit:
      # Set DataplanePermit and DataplaneDrop to passive if permit is set
      # to default
      # TODO(cs): rather than setting these to passive (which still causes them to
      # be scheduled as regular events) should these just be removed from the
      # event dag altogether?
      for event in [ e for e in self.dag.events if type(e) in dp_events ]:
        event.passive = default_dp_permit

    self.print_buffers_flag = print_buffers
    self.fail_fast = fail_fast
    self.check_interval = check_interval

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])
    # String repesentations of unexpected state changes we've passed through, for
    # statistics purposes.
    self.unexpected_state_changes = []
    self.early_state_changes = []
    self.event_scheduler_stats = None
    self.end_in_interactive = end_in_interactive
    self.fail_to_interactive = fail_to_interactive
    self.fail_to_interactive_on_persistent_violations =\
      fail_to_interactive_on_persistent_violations
    self._input_logger = input_logger
    self.allow_unexpected_messages = allow_unexpected_messages
    self.expected_message_round_window = expected_message_round_window
    self.pass_through_whitelisted_messages = pass_through_whitelisted_messages
    self.pass_through_sends = pass_through_sends
    # How many logical rounds to peek ahead when deciding if a message is
    # expected or not.
    # String repesentations of unexpected messages we've passed through, for
    # statistics purposes.
    self.passed_unexpected_messages = []
    self.delay_flow_mods = delay_flow_mods
    self.end_wait_seconds = end_wait_seconds
    self.transform_dag = transform_dag
    self.bug_signature = bug_signature
    self.invariant_check_name = invariant_check_name
    self.invariant_check = None
    if self.invariant_check_name:
      if self.invariant_check_name not in name_to_invariant_check:
        raise ValueError('''Unknown invariant check %s.\n'''
                         '''Invariant check name must be defined in config.invariant_checks''',
                         self.invariant_check_name)
      self.invariant_check = name_to_invariant_check[self.invariant_check_name]

    if self.pass_through_whitelisted_messages:
      for event in self.dag.events:
        if hasattr(event, "ignore_whitelisted_packets"):
          event.ignore_whitelisted_packets = True

    if self.simulation_cfg.ignore_interposition:
      self._ignore_interposition()

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      if self.default_dp_permit:
        # Tell EventScheduler to use call into us whenever it wants to sleep or
        # select, so that we can keep forwarding dataplane packets.
        kwargs['sleep_continuation'] = self._sleep_with_dataplane_passthrough
        kwargs['select_continuation'] = self._select_with_dataplane_passthrough

      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })

    unknown_kwargs = [ k for k in kwargs.keys() if k not in EventScheduler.kwargs ]
    if unknown_kwargs != []:
      raise ValueError("Unknown kwargs %s" % str(unknown_kwargs))
Example #17
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None,
               print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False,
               fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False,
               end_in_interactive=False, input_logger=None,
               allow_unexpected_messages=False,
               pass_through_whitelisted_messages=True,
               delay_flow_mods=False,
               **kwargs):
    ControlFlow.__init__(self, simulation_cfg)
    if wait_on_deterministic_values:
      self.sync_callback = ReplaySyncCallback()
    else:
      self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(log_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    if len(self.dag.events) == 0:
      raise ValueError("No events to replay!")

    self.default_dp_permit = default_dp_permit
    # Set DataplanePermit and DataplaneDrop to passive if permit is set
    # to default
    for event in [ e for e in self.dag.events if type(e) in dp_events ]:
      event.passive = default_dp_permit

    self.dp_checker = None
    if default_dp_permit:
      self.dp_checker = DataplaneChecker(self.dag)

    self.print_buffers_flag = print_buffers

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])
    # String repesentations of unexpected state changes we've passed through, for
    # statistics purposes.
    self.unexpected_state_changes = []
    self.early_state_changes = []
    self.event_scheduler_stats = None
    self.end_in_interactive = end_in_interactive
    self.fail_to_interactive = fail_to_interactive
    self.fail_to_interactive_on_persistent_violations =\
      fail_to_interactive_on_persistent_violations
    self._input_logger = input_logger
    self.allow_unexpected_messages = allow_unexpected_messages
    self.pass_through_whitelisted_messages = pass_through_whitelisted_messages
    # How many logical rounds to peek ahead when deciding if a message is
    # expected or not.
    self.expected_message_round_window = 3
    # String repesentations of unexpected messages we've passed through, for
    # statistics purposes.
    self.passed_unexpected_messages = []
    self.delay_flow_mods = delay_flow_mods

    if self.pass_through_whitelisted_messages:
      for event in self.dag.events:
        if hasattr(event, "ignore_whitelisted_packets"):
          event.ignore_whitelisted_packets = True

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })
Example #18
0
  def __init__(self, simulation_cfg, superlog_path_or_dag, create_event_scheduler=None,
               print_buffers=True, wait_on_deterministic_values=False, default_dp_permit=False,
               fail_to_interactive=False, fail_to_interactive_on_persistent_violations=False,
               end_in_interactive=False, input_logger=None,
               allow_unexpected_messages=False,
               pass_through_whitelisted_messages=True,
               delay_flow_mods=False,
               **kwargs):
    ControlFlow.__init__(self, simulation_cfg)
    if wait_on_deterministic_values:
      self.sync_callback = ReplaySyncCallback()
    else:
      self.sync_callback = ReplaySyncCallback(self.get_interpolated_time)

    if type(superlog_path_or_dag) == str:
      superlog_path = superlog_path_or_dag
      # The dag is codefied as a list, where each element has
      # a list of its dependents
      self.dag = EventDag(log_parser.parse_path(superlog_path))
    else:
      self.dag = superlog_path_or_dag

    if len(self.dag.events) == 0:
      raise ValueError("No events to replay!")

    self.default_dp_permit = default_dp_permit
    # Set DataplanePermit and DataplaneDrop to passive if permit is set
    # to default
    for event in [ e for e in self.dag.events if type(e) in dp_events ]:
      event.passive = default_dp_permit

    self.dp_checker = None
    if default_dp_permit:
      self.dp_checker = DataplaneChecker(self.dag)

    self.print_buffers_flag = print_buffers

    # compute interpolate to time to be just before first event
    self.compute_interpolated_time(self.dag.events[0])
    # String repesentations of unexpected state changes we've passed through, for
    # statistics purposes.
    self.unexpected_state_changes = []
    self.early_state_changes = []
    self.event_scheduler_stats = None
    self.end_in_interactive = end_in_interactive
    self.fail_to_interactive = fail_to_interactive
    self.fail_to_interactive_on_persistent_violations =\
      fail_to_interactive_on_persistent_violations
    self._input_logger = input_logger
    self.allow_unexpected_messages = allow_unexpected_messages
    self.pass_through_whitelisted_messages = pass_through_whitelisted_messages
    # How many logical rounds to peek ahead when deciding if a message is
    # expected or not.
    self.expected_message_round_window = 3
    # String repesentations of unexpected messages we've passed through, for
    # statistics purposes.
    self.passed_unexpected_messages = []
    self.delay_flow_mods = delay_flow_mods

    if self.pass_through_whitelisted_messages:
      for event in self.dag.events:
        if hasattr(event, "ignore_whitelisted_packets"):
          event.ignore_whitelisted_packets = True

    if create_event_scheduler:
      self.create_event_scheduler = create_event_scheduler
    else:
      self.create_event_scheduler = \
        lambda simulation: EventScheduler(simulation,
            **{ k: v for k,v in kwargs.items()
                if k in EventScheduler.kwargs })