Ejemplo n.º 1
0
  def loop(self):
    if self.steps:
      end_time = self.logical_time + self.steps
    else:
      end_time = sys.maxint

    exit_code = 0
    self.interrupted = False
    old_interrupt = None

    def interrupt(sgn, frame):
      msg.interactive("Interrupting fuzzer, dropping to console (press ^C again to terminate)")
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      self.interrupted = True
      raise KeyboardInterrupt()

    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      # Always connect to controllers explicitly
      self.simulation.connect_to_controllers()
      self._log_input_event(ConnectToControllers())

      if self.delay_startup:
        # Wait until the first OpenFlow message is received
        log.info("Waiting until first OpenfFlow message received..")
        while self.simulation.god_scheduler.pending_receives() == []:
          self.simulation.io_master.select(self.delay)

      while self.logical_time < end_time:
        self.logical_time += 1
        try:
          self.trigger_events()
          msg.event("Round %d completed." % self.logical_time)
          halt = self.maybe_check_invariant()
          if halt:
            exit_code = 5
            break
          self.maybe_inject_trace_event()
          time.sleep(self.delay)
        except KeyboardInterrupt as e:
          if self.interrupted:
            interactive = Interactive(self.simulation_cfg, self._input_logger)
            interactive.simulate(self.simulation, bound_objects=( ('fuzzer', self), ))
            self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
          else:
            raise e

      log.info("Terminating fuzzing after %d rounds" % self.logical_time)
      if self.print_buffers:
        self._print_buffers()

    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      if self._input_logger is not None:
        self._input_logger.close(self, self.simulation_cfg)

    return exit_code
Ejemplo n.º 2
0
  def run_simulation_forward(self, dag, post_bootstrap_hook=None):
    event_scheduler = self.create_event_scheduler(self.simulation)
    event_scheduler.set_input_logger(self._input_logger)
    self.event_scheduler_stats = event_scheduler.stats
    if post_bootstrap_hook is not None:
      post_bootstrap_hook()

    def interrupt(sgn, frame):
      msg.interactive("Interrupting replayer, dropping to console (press ^C again to terminate)")
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      raise KeyboardInterrupt()
    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      for i, event in enumerate(dag.events):
        try:
          self.compute_interpolated_time(event)
          if self.default_dp_permit:
            self.dp_checker.check_dataplane(i, self.simulation)
          if isinstance(event, InputEvent):
            self._check_early_state_changes(dag, i, event)
          self._check_new_state_changes(dag, i)
          self._check_unexpected_cp_messages(dag, i)
          # TODO(cs): quasi race-condition here. If unexpected state change
          # happens *while* we're waiting for event, we basically have a
          # deadlock (if controller logging is set to blocking) until the
          # timeout occurs
          # TODO(cs): we don't actually allow new internal message events
          # through.. we only let new state changes through. Should experiment
          # with whether we would get better fidelity if we let them through.
          event_scheduler.schedule(event)
          if self.logical_time != event.round:
            self.logical_time = event.round
            self.increment_round()
        except KeyboardInterrupt:
          interactive = Interactive(self.simulation_cfg,
                                    input_logger=self._input_logger)
          interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
          self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      msg.event(color.B_BLUE+"Event Stats: %s" % str(event_scheduler.stats))
      if self.default_dp_permit:
        msg.event(color.B_BLUE+"DataplaneDrop Stats: %s" % str(self.dp_checker.stats))
    if self.end_in_interactive:
      interactive = Interactive(self.simulation_cfg,
          input_logger=self._input_logger)
      interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
Ejemplo n.º 3
0
  def run_simulation_forward(self, dag, post_bootstrap_hook=None):
    event_scheduler = self.create_event_scheduler(self.simulation)
    event_scheduler.set_input_logger(self._input_logger)
    self.event_scheduler_stats = event_scheduler.stats
    if post_bootstrap_hook is not None:
      post_bootstrap_hook()

    def interrupt(sgn, frame):
      msg.interactive("Interrupting replayer, dropping to console (press ^C again to terminate)")
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      raise KeyboardInterrupt()
    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      for i, event in enumerate(dag.events):
        try:
          self.compute_interpolated_time(event)
          if self.default_dp_permit:
            self.dp_checker.check_dataplane(i, self.simulation)
          if isinstance(event, InputEvent):
            self._check_early_state_changes(dag, i, event)
          self._check_new_state_changes(dag, i)
          self._check_unexpected_dp_messages(dag, i)
          # TODO(cs): quasi race-condition here. If unexpected state change
          # happens *while* we're waiting for event, we basically have a
          # deadlock (if controller logging is set to blocking) until the
          # timeout occurs
          # TODO(cs): we don't actually allow new internal message events
          # through.. we only let new state changes through. Should experiment
          # with whether we would get better fidelity if we let them through.
          event_scheduler.schedule(event)
          if self.logical_time != event.round:
            self.logical_time = event.round
            self.increment_round()
        except KeyboardInterrupt:
          interactive = Interactive(self.simulation_cfg,
                                    input_logger=self._input_logger)
          interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
          self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      msg.event(color.B_BLUE+"Event Stats: %s" % str(event_scheduler.stats))
      if self.default_dp_permit:
        msg.event(color.B_BLUE+"DataplaneDrop Stats: %s" % str(self.dp_checker.stats))
    if self.end_in_interactive:
      interactive = Interactive(self.simulation_cfg,
          input_logger=self._input_logger)
      interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
Ejemplo n.º 4
0
  def run_simulation_forward(self, dag, post_bootstrap_hook=None):
    event_scheduler = self.create_event_scheduler(self.simulation)
    self.event_scheduler_stats = event_scheduler.stats
    if post_bootstrap_hook is not None:
      post_bootstrap_hook()

    self.interrupted = False
    old_interrupt = None

    def interrupt(sgn, frame):
      msg.interactive("Interrupting replayer, dropping to console (press ^C again to terminate)")
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      self.interrupted = True
      raise KeyboardInterrupt()
    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      for i, event in enumerate(dag.events):
        try:
          self.logical_time += 1
          self.compute_interpolated_time(event)
          if isinstance(event, InputEvent):
            self._check_early_state_changes(dag, i, event)
          self._check_new_state_changes(dag, i)
          # TODO(cs): quasi race-condition here. If unexpected state change
          # happens *while* we're waiting for event, we basically have a
          # deadlock (if controller logging is set to blocking) until the
          # timeout occurs
          event_scheduler.schedule(event)
          if self.auto_permit_dp_events:
            self._permit_dp_events()
          self.increment_round()
        except KeyboardInterrupt as e:
          if self.interrupted:
            interactive = Interactive(self.simulation_cfg)
            interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
            self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
          else:
            raise e
    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      msg.event(color.B_BLUE+"Event Stats: %s" % str(event_scheduler.stats))
Ejemplo n.º 5
0
    def loop(self):
        if self.steps:
            end_time = self.logical_time + self.steps
        else:
            end_time = sys.maxint

        self.interrupted = False
        self.old_interrupt = None

        def interrupt(sgn, frame):
            msg.interactive(
                "Interrupting fuzzer, dropping to console (press ^C again to terminate)"
            )
            signal.signal(signal.SIGINT, self.old_interrupt)
            self.old_interrupt = None
            self.interrupted = True
            raise KeyboardInterrupt()

        self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

        try:
            # Always connect to controllers explicitly
            self.simulation.connect_to_controllers()
            self._log_input_event(ConnectToControllers())

            if self.delay_startup:
                # Wait until the first OpenFlow message is received
                log.info("Waiting until first OpenFlow message received..")
                while self.simulation.openflow_buffer.pending_receives() == []:
                    self.simulation.io_master.select(self.delay)

            sent_self_packets = False

            while self.logical_time < end_time:
                self.logical_time += 1
                try:
                    if not self._initializing():
                        self.trigger_events()
                        halt = self.maybe_check_invariant()
                        if halt:
                            self.simulation.set_exit_code(5)
                            break
                        self.maybe_inject_trace_event()
                    else:  # Initializing
                        self.check_pending_messages(pass_through=True)
                        if not sent_self_packets and (
                                self.logical_time %
                                self._all_to_all_interval) == 0:
                            # Only need to send self packets once
                            self._send_initialization_packets(
                                send_to_self=True)
                            sent_self_packets = True
                        elif self.logical_time > self.initialization_rounds:
                            # All-to-all mode
                            if (self.logical_time %
                                    self._all_to_all_interval) == 0:
                                self._send_initialization_packets(
                                    send_to_self=False)
                                self._all_to_all_iterations += 1
                                if self._all_to_all_iterations > len(
                                        self.simulation.topology.hosts):
                                    log.info("Done initializing")
                                    self._pending_all_to_all = False
                        self.check_dataplane(pass_through=True)

                    msg.event("Round %d completed." % self.logical_time)
                    time.sleep(self.delay)
                except KeyboardInterrupt as e:
                    if self.interrupted:
                        interactive = Interactive(self.simulation_cfg,
                                                  self._input_logger)
                        interactive.simulate(self.simulation,
                                             bound_objects=(('fuzzer',
                                                             self), ))
                        self.old_interrupt = signal.signal(
                            signal.SIGINT, interrupt)
                    else:
                        raise e

            log.info("Terminating fuzzing after %d rounds" % self.logical_time)
            if self.print_buffers:
                self._print_buffers()

        finally:
            if self.old_interrupt:
                signal.signal(signal.SIGINT, self.old_interrupt)
            if self._input_logger is not None:
                self._input_logger.close(self, self.simulation_cfg)

        return self.simulation
Ejemplo n.º 6
0
    def run_simulation_forward(self, post_bootstrap_hook=None):
        event_scheduler = self.create_event_scheduler(self.simulation)
        event_scheduler.set_input_logger(self._input_logger)
        self.event_scheduler_stats = event_scheduler.stats
        if post_bootstrap_hook is not None:
            post_bootstrap_hook()

        def interrupt(sgn, frame):
            msg.interactive(
                "Interrupting replayer, dropping to console (press ^C again to terminate)"
            )
            signal.signal(signal.SIGINT, self.old_interrupt)
            self.old_interrupt = None
            raise KeyboardInterrupt()

        self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

        try:
            for i, event in enumerate(self.dag.events):
                try:
                    self.compute_interpolated_time(event)
                    if self.default_dp_permit:
                        self.dp_checker.check_dataplane(i, self.simulation)
                    if isinstance(event, InputEvent):
                        self._check_early_state_changes(self.dag, i, event)
                    self._check_new_state_changes(self.dag, i)
                    self._check_unexpected_cp_messages(self.dag, i)
                    # TODO(cs): quasi race-condition here. If unexpected state change
                    # happens *while* we're waiting for event, we basically have a
                    # deadlock (if controller logging is set to blocking) until the
                    # timeout occurs
                    # TODO(cs): we don't actually allow new internal message events
                    # through.. we only let new state changes through. Should experiment
                    # with whether we would get better fidelity if we let them through.
                    if self.fail_fast and (i % self.check_interval
                                           ) == 0 and self._check_violation():
                        return
                    event_scheduler.schedule(event)
                    if self.logical_time != event.round:
                        self.logical_time = event.round
                        self.increment_round()
                except KeyboardInterrupt:
                    interactive = Interactive(self.simulation_cfg,
                                              input_logger=self._input_logger)
                    interactive.simulate(self.simulation,
                                         bound_objects=(('replayer', self), ))
                    # If Interactive terminated due to ^D, return to our fuzzing loop,
                    # prepared again to drop into Interactive on ^C.
                    self.old_interrupt = signal.signal(signal.SIGINT,
                                                       interrupt)
                except Exception:
                    log.critical(
                        "Exception raised while scheduling event %s, replay %s"
                        % (str(event), self.replay_id))
                    raise

            if self.invariant_check:
                # Wait a bit in case the bug takes awhile to happen
                # TODO(cs): may be redundant with WaitTime events at the end of the
                # trace.
                log.debug("Sleeping %d seconds after run" %
                          self.end_wait_seconds)
                if self.default_dp_permit:
                    self._sleep_with_dataplane_passthrough(
                        self.end_wait_seconds)
                else:
                    time.sleep(self.end_wait_seconds)

                self._check_violation()
        finally:
            if self.old_interrupt:
                signal.signal(signal.SIGINT, self.old_interrupt)
            msg.event(color.B_BLUE +
                      "Event Stats: %s" % str(event_scheduler.stats))
            if self.default_dp_permit:
                msg.event(color.B_BLUE + "DataplaneDrop Stats: %s" %
                          str(self.dp_checker.stats))
        if self.end_in_interactive:
            interactive = Interactive(self.simulation_cfg,
                                      input_logger=self._input_logger)
            interactive.simulate(self.simulation,
                                 bound_objects=(('replayer', self), ))
Ejemplo n.º 7
0
  def loop(self):
    if self.steps:
      end_time = self.logical_time + self.steps
    else:
      end_time = sys.maxint

    self.interrupted = False
    self.old_interrupt = None

    def interrupt(sgn, frame):
      msg.interactive("Interrupting fuzzer, dropping to console (press ^C again to terminate)")
      # If ^C is triggered twice in a row, invoke the original handler.
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      self.interrupted = True
      raise KeyboardInterrupt()

    # signal.signal returns the previous interrupt handler.
    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      # Always connect to controllers explicitly
      self.simulation.connect_to_controllers()
      self._log_input_event(ConnectToControllers())

      if self.delay_startup:
        # Wait until the first OpenFlow message is received
        log.info("Waiting until first OpenFlow message received..")
        while self.simulation.openflow_buffer.pending_receives() == []:
          self.simulation.io_master.select(self.delay)

      sent_self_packets = False

      while self.logical_time < end_time:
        self.logical_time += 1
        try:
          if not self._initializing():
            self.trigger_events()
            halt = self.maybe_check_invariant()
            if halt:
              self.simulation.set_exit_code(5)
              break
            self.maybe_inject_trace_event()
          else:  # Initializing
            self.check_pending_messages(pass_through=True)
            if not sent_self_packets and (self.logical_time % self._all_to_all_interval) == 0:
              # Only need to send self packets once
              self._send_initialization_packets(send_to_self=True)
              sent_self_packets = True
            elif self.logical_time > self.initialization_rounds:
              # All-to-all mode
              if (self.logical_time % self._all_to_all_interval) == 0:
                self._send_initialization_packets(send_to_self=False)
                self._all_to_all_iterations += 1
                if self._all_to_all_iterations > len(self.simulation.topology.hosts):
                  log.info("Done initializing")
                  self._pending_all_to_all = False
            self.check_dataplane(pass_through=True)

          msg.event("Round %d completed." % self.logical_time)
          # Note that time.sleep triggers a round of select.select()
          time.sleep(self.delay)
        except KeyboardInterrupt as e:
          if self.interrupted:
            interactive = Interactive(self.simulation_cfg, self._input_logger)
            interactive.simulate(self.simulation, bound_objects=( ('fuzzer', self), ))
            # If Interactive terminated due to ^D, return to our replaying loop,
            # prepared again to drop into Interactive on ^C.
            self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
          else:
            raise e

      log.info("Terminating fuzzing after %d rounds" % self.logical_time)
      if self.print_buffers:
        self._print_buffers()

    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      if self._input_logger is not None:
        self._input_logger.close(self, self.simulation_cfg)

    return self.simulation
Ejemplo n.º 8
0
  def run_simulation_forward(self, post_bootstrap_hook=None):
    event_scheduler = self.create_event_scheduler(self.simulation)
    event_scheduler.set_input_logger(self._input_logger)
    self.event_scheduler_stats = event_scheduler.stats
    if post_bootstrap_hook is not None:
      post_bootstrap_hook()

    def interrupt(sgn, frame):
      msg.interactive("Interrupting replayer, dropping to console (press ^C again to terminate)")
      signal.signal(signal.SIGINT, self.old_interrupt)
      self.old_interrupt = None
      raise KeyboardInterrupt()
    self.old_interrupt = signal.signal(signal.SIGINT, interrupt)

    try:
      for i, event in enumerate(self.dag.events):
        try:
          self.compute_interpolated_time(event)
          if self.default_dp_permit:
            self.dp_checker.check_dataplane(i, self.simulation)
          if isinstance(event, InputEvent):
            self._check_early_state_changes(self.dag, i, event)
          self._check_new_state_changes(self.dag, i)
          self._check_unexpected_cp_messages(self.dag, i)
          # TODO(cs): quasi race-condition here. If unexpected state change
          # happens *while* we're waiting for event, we basically have a
          # deadlock (if controller logging is set to blocking) until the
          # timeout occurs
          # TODO(cs): we don't actually allow new internal message events
          # through.. we only let new state changes through. Should experiment
          # with whether we would get better fidelity if we let them through.
          if self.fail_fast and (i % self.check_interval) == 0 and self._check_violation():
            return
          event_scheduler.schedule(event)
          if self.logical_time != event.round:
            self.logical_time = event.round
            self.increment_round()
        except KeyboardInterrupt:
          interactive = Interactive(self.simulation_cfg,
                                    input_logger=self._input_logger)
          interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))
          # If Interactive terminated due to ^D, return to our fuzzing loop,
          # prepared again to drop into Interactive on ^C.
          self.old_interrupt = signal.signal(signal.SIGINT, interrupt)
        except Exception:
          log.critical("Exception raised while scheduling event %s, replay %s"
                       % (str(event), self.replay_id))
          raise

      if self.invariant_check:
        # Wait a bit in case the bug takes awhile to happen
        # TODO(cs): may be redundant with WaitTime events at the end of the
        # trace.
        log.debug("Sleeping %d seconds after run" % self.end_wait_seconds)
        if self.default_dp_permit:
          self._sleep_with_dataplane_passthrough(self.end_wait_seconds)
        else:
          time.sleep(self.end_wait_seconds)

        self._check_violation()
    finally:
      if self.old_interrupt:
        signal.signal(signal.SIGINT, self.old_interrupt)
      msg.event(color.B_BLUE+"Event Stats: %s" % str(event_scheduler.stats))
      if self.default_dp_permit:
        msg.event(color.B_BLUE+"DataplaneDrop Stats: %s" % str(self.dp_checker.stats))
    if self.end_in_interactive:
      interactive = Interactive(self.simulation_cfg, input_logger=self._input_logger)
      interactive.simulate(self.simulation, bound_objects=( ('replayer', self), ))