Exemplo n.º 1
0
    def test_connections(self, open_mock, readlink_mock, listdir_mock):
        """
    Tests the connections function.
    """

        pid = 1111

        listdir_mock.side_effect = lambda param: {
            '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
        }[param]

        readlink_mock.side_effect = lambda param: {
            '/proc/%s/fd/1' % pid: 'socket:[99999999]',
            '/proc/%s/fd/2' % pid: 'socket:[IIIIIIII]',
            '/proc/%s/fd/3' % pid: 'pipe:[30303]',
            '/proc/%s/fd/4' % pid: 'pipe:[40404]',
        }[param]

        tcp = '\n 0: 11111111:1111 22222222:2222 01 44444444:44444444 55:55555555 66666666 1111 8 99999999'
        udp = '\n A: BBBBBBBB:BBBB CCCCCCCC:CCCC DD EEEEEEEE:EEEEEEEE FF:FFFFFFFF GGGGGGGG 1111 H IIIIIIII'

        open_mock.side_effect = lambda param: {
            '/proc/net/tcp': StringIO(tcp),
            '/proc/net/udp': StringIO(udp)
        }[param]

        # tests the edge case of pid = 0
        self.assertEqual([], proc.connections(0))

        expected_results = [
            ('17.17.17.17', 4369, '34.34.34.34', 8738, 'tcp'),
            ('187.187.187.187', 48059, '204.204.204.204', 52428, 'udp'),
        ]

        self.assertEqual(expected_results, proc.connections(pid))
Exemplo n.º 2
0
  def test_connections(self, open_mock, readlink_mock, listdir_mock):
    """
    Tests the connections function.
    """

    pid = 1111

    listdir_mock.side_effect = lambda param: {
      '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
    }[param]

    readlink_mock.side_effect = lambda param: {
      '/proc/%s/fd/1' % pid: 'socket:[99999999]',
      '/proc/%s/fd/2' % pid: 'socket:[IIIIIIII]',
      '/proc/%s/fd/3' % pid: 'pipe:[30303]',
      '/proc/%s/fd/4' % pid: 'pipe:[40404]',
    }[param]

    tcp = '\n 0: 11111111:1111 22222222:2222 01 44444444:44444444 55:55555555 66666666 1111 8 99999999'
    udp = '\n A: BBBBBBBB:BBBB CCCCCCCC:CCCC DD EEEEEEEE:EEEEEEEE FF:FFFFFFFF GGGGGGGG 1111 H IIIIIIII'

    open_mock.side_effect = lambda param: {
      '/proc/net/tcp': StringIO(tcp),
      '/proc/net/udp': StringIO(udp)
    }[param]

    # tests the edge case of pid = 0
    self.assertEqual([], proc.connections(0))

    expected_results = [
      ('17.17.17.17', 4369, '34.34.34.34', 8738, 'tcp'),
      ('187.187.187.187', 48059, '204.204.204.204', 52428, 'udp'),
    ]

    self.assertEqual(expected_results, proc.connections(pid))
Exemplo n.º 3
0
    def test_connections_ipv6_by_user(self, open_mock, getpwnam_mock,
                                      path_exists_mock):
        """
    Tests the connections function with ipv6 addresses.
    """

        getpwnam_mock('me').pw_uid = 106

        path_exists_mock.side_effect = lambda param: {
            '/proc/net/tcp6': True,
            '/proc/net/udp6': False
        }[param]

        open_mock.side_effect = lambda param, mode: {
            '/proc/net/tcp': io.BytesIO(TITLE_LINE),
            '/proc/net/tcp6': io.BytesIO(TCP6_CONTENT),
            '/proc/net/udp': io.BytesIO(TITLE_LINE),
        }[param]

        expected = [
            Connection('0000:0000:0000:0000:0000:ffff:0509:9e4b', 5222,
                       '0000:0000:0000:0000:0000:ffff:4e36:8621', 38330, 'tcp',
                       True),
            Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 5269,
                       '2001:06f8:126f:0011:0000:0000:0000:0026', 50594, 'tcp',
                       True),
            Connection('0000:0000:0000:0000:0000:ffff:0509:9e4b', 5222,
                       '0000:0000:0000:0000:0000:ffff:4e36:8621', 38174, 'tcp',
                       True),
        ]

        self.assertEqual(expected, proc.connections(user='******'))
Exemplo n.º 4
0
  def test_connections(self):
    """
    Checks for our control port in the stem.util.proc.connections output if
    we have one.
    """

    runner = test.runner.get_runner()

    if not proc.is_available():
      test.runner.skip(self, '(proc unavailable)')
      return
    elif test.runner.Torrc.PORT not in runner.get_options():
      test.runner.skip(self, '(no control port)')
      return
    elif not test.runner.get_runner().is_ptraceable():
      test.runner.skip(self, '(DisableDebuggerAttachment is set)')
      return
    elif not os.access('/proc/net/tcp', os.R_OK) or not os.access('/proc/net/udp', os.R_OK):
      test.runner.skip(self, '(proc lacks read permissions)')
      return

    # making a controller connection so that we have something to query for
    with runner.get_tor_socket():
      tor_pid = test.runner.get_runner().get_pid()

      for conn in proc.connections(tor_pid):
        if ('127.0.0.1', test.runner.CONTROL_PORT) == conn[:2]:
          return

      self.fail()
Exemplo n.º 5
0
    def test_connections(self):
        """
    Checks for our control port in the stem.util.proc.connections output if
    we have one.
    """

        runner = test.runner.get_runner()

        if test.runner.Torrc.PORT not in runner.get_options():
            self.skiTestp('(no control port)')
            return
        elif not os.access('/proc/net/tcp', os.R_OK) or not os.access(
                '/proc/net/udp', os.R_OK):
            self.skipTest('(proc lacks read permissions)')
            return

        # making a controller connection so that we have something to query for
        with runner.get_tor_socket():
            tor_pid = test.runner.get_runner().get_pid()

            for conn in proc.connections(tor_pid):
                if ('127.0.0.1', test.runner.CONTROL_PORT) == conn[:2]:
                    return

            self.fail()
Exemplo n.º 6
0
  def test_connections_ipv6_by_user(self, open_mock, getpwnam_mock, path_exists_mock):
    """
    Tests the connections function with ipv6 addresses.
    """

    getpwnam_mock('me').pw_uid = 106

    path_exists_mock.side_effect = lambda param: {
      '/proc/net/tcp6': True,
      '/proc/net/udp6': False
    }[param]

    open_mock.side_effect = lambda param, mode: {
      '/proc/net/tcp': io.BytesIO(b''),
      '/proc/net/tcp6': io.BytesIO(TCP6_CONTENT),
      '/proc/net/udp': io.BytesIO(b''),
    }[param]

    expected_results = [
      Connection('0000:0000:0000:0000:0000:ffff:0509:9e4b', 5222, '0000:0000:0000:0000:0000:ffff:4e36:8621', 38330, 'tcp', True),
      Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 5269, '2001:06f8:126f:0011:0000:0000:0000:0026', 50594, 'tcp', True),
      Connection('0000:0000:0000:0000:0000:ffff:0509:9e4b', 5222, '0000:0000:0000:0000:0000:ffff:4e36:8621', 38174, 'tcp', True),
    ]

    self.assertEqual(expected_results, proc.connections(user = '******'))
Exemplo n.º 7
0
  def test_connections_ipv6(self, open_mock, readlink_mock, path_exists_mock, listdir_mock):
    """
    Tests the connections function with ipv6 addresses.
    """

    pid = 1111

    listdir_mock.side_effect = lambda param: {
      '/proc/%s/fd' % pid: ['1', '2'],
    }[param]

    readlink_mock.side_effect = lambda param: {
      '/proc/%s/fd/1' % pid: 'socket:[42088802]',
      '/proc/%s/fd/2' % pid: 'socket:[41691357]',
    }[param]

    path_exists_mock.side_effect = lambda param: {
      '/proc/net/tcp6': True,
      '/proc/net/udp6': False
    }[param]

    open_mock.side_effect = lambda param, mode: {
      '/proc/net/tcp': io.BytesIO(b''),
      '/proc/net/tcp6': io.BytesIO(TCP6_CONTENT),
      '/proc/net/udp': io.BytesIO(b''),
    }[param]

    expected_results = [
      Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 443, '2001:0638:a000:4140:0000:0000:ffff:0189', 40435, 'tcp', True),
      Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 443, '2001:0858:0002:0002:aabb:0000:563b:1526', 44469, 'tcp', True),
    ]

    self.assertEqual(expected_results, proc.connections(pid = pid))
Exemplo n.º 8
0
  def test_connections_ipv6(self, open_mock, readlink_mock, path_exists_mock, listdir_mock):
    """
    Tests the connections function with ipv6 addresses.
    """

    pid = 1111

    listdir_mock.side_effect = lambda param: {
      '/proc/%s/fd' % pid: ['1', '2'],
    }[param]

    readlink_mock.side_effect = lambda param: {
      '/proc/%s/fd/1' % pid: 'socket:[42088802]',
      '/proc/%s/fd/2' % pid: 'socket:[41691357]',
    }[param]

    path_exists_mock.side_effect = lambda param: {
      '/proc/net/tcp6': True,
      '/proc/net/udp6': False
    }[param]

    open_mock.side_effect = lambda param, mode: {
      '/proc/net/tcp': io.BytesIO(b''),
      '/proc/net/tcp6': io.BytesIO(TCP6_CONTENT),
      '/proc/net/udp': io.BytesIO(b''),
    }[param]

    expected_results = [
      Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 443, '2001:0638:a000:4140:0000:0000:ffff:0189', 40435, 'tcp', True),
      Connection('2a01:04f8:0190:514a:0000:0000:0000:0002', 443, '2001:0858:0002:0002:aabb:0000:563b:1526', 44469, 'tcp', True),
    ]

    self.assertEqual(expected_results, proc.connections(pid = pid))
Exemplo n.º 9
0
Arquivo: proc.py Projeto: E3V3A/stem
    def test_connections(self, open_mock, readlink_mock, path_exists_mock,
                         listdir_mock):
        """
    Tests the connections function.
    """

        pid = 1111

        listdir_mock.side_effect = lambda param: {
            '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
        }[param]

        readlink_mock.side_effect = lambda param: {
            '/proc/%s/fd/1' % pid: 'socket:[99999999]',
            '/proc/%s/fd/2' % pid: 'socket:[IIIIIIII]',
            '/proc/%s/fd/3' % pid: 'pipe:[30303]',
            '/proc/%s/fd/4' % pid: 'pipe:[40404]',
        }[param]

        tcp = TITLE_LINE + b'\n 0: 11111111:1111 22222222:2222 01 44444444:44444444 55:55555555 66666666 1111        8 99999999'
        udp = TITLE_LINE + b'\n A: BBBBBBBB:BBBB CCCCCCCC:CCCC DD EEEEEEEE:EEEEEEEE FF:FFFFFFFF GGGGGGGG 1111        H IIIIIIII'

        path_exists_mock.side_effect = lambda param: {
            '/proc/net/tcp': True,
            '/proc/net/tcp6': False,
            '/proc/net/udp': True,
            '/proc/net/udp6': False
        }[param]

        open_mock.side_effect = lambda param, mode: {
            '/proc/net/tcp': io.BytesIO(tcp),
            '/proc/net/udp': io.BytesIO(udp)
        }[param]

        expected_results = [
            Connection('17.17.17.17', 4369, '34.34.34.34', 8738, 'tcp', False),
            Connection('187.187.187.187', 48059, '204.204.204.204', 52428,
                       'udp', False),
        ]

        self.assertEqual(expected_results, proc.connections(pid))
Exemplo n.º 10
0
    def test_high_connection_count(self, open_mock, readlink_mock,
                                   path_exists_mock, listdir_mock):
        """
    When we have over ten thousand connections the 'SL' column's width changes.
    Checking that we account for this.
    """

        pid = 1111

        listdir_mock.side_effect = lambda param: {
            '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
        }[param]

        readlink_mock.side_effect = lambda param: {
            '/proc/%s/fd/1' % pid: 'socket:[99999999]',
            '/proc/%s/fd/2' % pid: 'socket:[88888888]',
            '/proc/%s/fd/3' % pid: 'socket:[77777777]',
            '/proc/%s/fd/4' % pid: 'pipe:[30303]',
            '/proc/%s/fd/5' % pid: 'pipe:[40404]',
        }[param]

        path_exists_mock.side_effect = lambda param: {
            '/proc/net/tcp6': False,
            '/proc/net/udp6': False
        }[param]

        open_mock.side_effect = lambda param, mode: {
            '/proc/net/tcp': io.BytesIO(SL_WIDTH_CHANGE),
            '/proc/net/udp': io.BytesIO(TITLE_LINE)
        }[param]

        expected = [
            Connection('17.17.17.17', 4369, '51.34.34.34', 8772, 'tcp', False),
            Connection('34.34.34.34', 8738, '68.51.51.51', 13141, 'tcp',
                       False),
            Connection('51.51.51.51', 13107, '85.68.68.68', 17510, 'tcp',
                       False),
        ]

        self.assertEqual(expected, proc.connections(pid))
Exemplo n.º 11
0
  def test_connections(self, open_mock, readlink_mock, path_exists_mock, listdir_mock):
    """
    Tests the connections function.
    """

    pid = 1111

    listdir_mock.side_effect = lambda param: {
      '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
    }[param]

    readlink_mock.side_effect = lambda param: {
      '/proc/%s/fd/1' % pid: 'socket:[99999999]',
      '/proc/%s/fd/2' % pid: 'socket:[IIIIIIII]',
      '/proc/%s/fd/3' % pid: 'pipe:[30303]',
      '/proc/%s/fd/4' % pid: 'pipe:[40404]',
    }[param]

    tcp = b'\n 0: 11111111:1111 22222222:2222 01 44444444:44444444 55:55555555 66666666 1111 8 99999999'
    udp = b'\n A: BBBBBBBB:BBBB CCCCCCCC:CCCC DD EEEEEEEE:EEEEEEEE FF:FFFFFFFF GGGGGGGG 1111 H IIIIIIII'

    path_exists_mock.side_effect = lambda param: {
      '/proc/net/tcp': True,
      '/proc/net/tcp6': False,
      '/proc/net/udp': True,
      '/proc/net/udp6': False
    }[param]

    open_mock.side_effect = lambda param, mode: {
      '/proc/net/tcp': io.BytesIO(tcp),
      '/proc/net/udp': io.BytesIO(udp)
    }[param]

    expected_results = [
      Connection('17.17.17.17', 4369, '34.34.34.34', 8738, 'tcp', False),
      Connection('187.187.187.187', 48059, '204.204.204.204', 52428, 'udp', False),
    ]

    self.assertEqual(expected_results, proc.connections(pid))
Exemplo n.º 12
0
    def _task(self, process_pid, process_name):
        if self._custom_resolver:
            resolver = self._custom_resolver
            is_default_resolver = False
        elif self._resolvers:
            resolver = self._resolvers[0]
            is_default_resolver = True
        else:
            return False  # nothing to resolve with

        try:
            start_time = time.time()
            new_connections, new_start_times = [], {}

            if resolver == CustomResolver.INFERENCE:
                # provide connections going to a relay or one of our tor ports

                connections = []
                controller = tor_controller()
                consensus_tracker = get_consensus_tracker()

                relay_ports = set(
                    controller.get_ports(stem.control.Listener.OR, []))
                relay_ports.update(
                    controller.get_ports(stem.control.Listener.DIR, []))
                relay_ports.update(
                    controller.get_ports(stem.control.Listener.CONTROL, []))

                for conn in proc.connections(user=controller.get_user(None)):
                    if conn.remote_port in consensus_tracker.get_relay_fingerprints(
                            conn.remote_address):
                        connections.append(conn)  # outbound to another relay
                    elif conn.local_port in relay_ports:
                        connections.append(conn)
            else:
                connections = connection.get_connections(
                    resolver,
                    process_pid=process_pid,
                    process_name=process_name)

            for conn in connections:
                conn_start_time, is_legacy = self._start_times.get(
                    conn, (start_time, self._is_first_run))
                new_start_times[conn] = (conn_start_time, is_legacy)
                new_connections.append(
                    Connection(conn_start_time, is_legacy, *conn))

            self._connections = new_connections
            self._start_times = new_start_times
            self._is_first_run = False

            runtime = time.time() - start_time

            if is_default_resolver:
                self._failure_count = 0

            # Reduce our rate if connection resolution is taking a long time. This is
            # most often an issue for extremely busy relays.

            min_rate = 100 * runtime

            if self.get_rate() < min_rate:
                self._rate_too_low_count += 1

                if self._rate_too_low_count >= 3:
                    min_rate += 1  # little extra padding so we don't frequently update this
                    self.set_rate(min_rate)
                    self._rate_too_low_count = 0
                    stem.util.log.debug(
                        'connection lookup time increasing to %0.1f seconds per call'
                        % min_rate)
            else:
                self._rate_too_low_count = 0

            return True
        except IOError as exc:
            stem.util.log.info(str(exc))

            # Fail over to another resolver if we've repeatedly been unable to use
            # this one.

            if is_default_resolver:
                self._failure_count += 1

                if self._failure_count >= 3:
                    self._resolvers.pop(0)
                    self._failure_count = 0

                    if self._resolvers:
                        stem.util.log.notice(
                            'Unable to query connections with %s, trying %s' %
                            (resolver, self._resolvers[0]))
                    else:
                        stem.util.log.notice(UNABLE_TO_USE_ANY_RESOLVER_MSG)

            return False
Exemplo n.º 13
0
  def _task(self, process_pid, process_name):
    if self._custom_resolver:
      resolver = self._custom_resolver
      is_default_resolver = False
    elif self._resolvers:
      resolver = self._resolvers[0]
      is_default_resolver = True
    else:
      return False  # nothing to resolve with

    try:
      start_time = time.time()
      new_connections, new_start_times = [], {}

      if resolver == CustomResolver.INFERENCE:
        # provide connections going to a relay or one of our tor ports

        connections = []
        controller = tor_controller()
        consensus_tracker = get_consensus_tracker()

        for conn in proc.connections(user = controller.get_user(None)):
          if conn.remote_port in consensus_tracker.get_relay_fingerprints(conn.remote_address):
            connections.append(conn)  # outbound to another relay
          elif conn.local_port in controller.get_ports(stem.control.Listener.OR, []):
            connections.append(conn)  # inbound to our ORPort
          elif conn.local_port in controller.get_ports(stem.control.Listener.DIR, []):
            connections.append(conn)  # inbound to our DirPort
          elif conn.local_port in controller.get_ports(stem.control.Listener.CONTROL, []):
            connections.append(conn)  # controller connection
      else:
        connections = connection.get_connections(resolver, process_pid = process_pid, process_name = process_name)

      for conn in connections:
        conn_start_time, is_legacy = self._start_times.get(conn, (start_time, self._is_first_run))
        new_start_times[conn] = (conn_start_time, is_legacy)
        new_connections.append(Connection(conn_start_time, is_legacy, *conn))

      self._connections = new_connections
      self._start_times = new_start_times
      self._is_first_run = False

      runtime = time.time() - start_time

      if is_default_resolver:
        self._failure_count = 0

      # Reduce our rate if connection resolution is taking a long time. This is
      # most often an issue for extremely busy relays.

      min_rate = 100 * runtime

      if self.get_rate() < min_rate:
        self._rate_too_low_count += 1

        if self._rate_too_low_count >= 3:
          min_rate += 1  # little extra padding so we don't frequently update this
          self.set_rate(min_rate)
          self._rate_too_low_count = 0
          log.debug('tracker.lookup_rate_increased', seconds = "%0.1f" % min_rate)
      else:
        self._rate_too_low_count = 0

      return True
    except IOError as exc:
      log.info('wrap', text = exc)

      # Fail over to another resolver if we've repeatedly been unable to use
      # this one.

      if is_default_resolver:
        self._failure_count += 1

        if self._failure_count >= 3:
          self._resolvers.pop(0)
          self._failure_count = 0

          if self._resolvers:
            log.notice(
              'tracker.unable_to_use_resolver',
              old_resolver = resolver,
              new_resolver = self._resolvers[0],
            )
          else:
            log.notice('tracker.unable_to_use_all_resolvers')

      return False