예제 #1
0
    def test_non_srv_answer(self):
        """
        test the behaviour when the dns server gives us a spurious non-SRV response
        """
        service_name = b"test_service.example.com"

        lookup_deferred = Deferred()
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = lookup_deferred
        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        resolve_d = resolver.resolve_service(service_name)
        self.assertNoResult(resolve_d)

        lookup_deferred.callback(
            (
                [
                    dns.RRHeader(type=dns.A, payload=dns.Record_A()),
                    dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"host")),
                ],
                None,
                None,
            )
        )

        servers = self.successResultOf(resolve_d)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
        self.assertEquals(servers[0].host, b"host")
예제 #2
0
    def test_disabled_service(self):
        """
        test the behaviour when there is a single record which is ".".
        """
        service_name = b"test_service.example.com"

        lookup_deferred = Deferred()
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = lookup_deferred
        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        # Old versions of Twisted don't have an ensureDeferred in failureResultOf.
        resolve_d = defer.ensureDeferred(resolver.resolve_service(service_name))

        # returning a single "." should make the lookup fail with a ConenctError
        lookup_deferred.callback(
            (
                [dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"."))],
                None,
                None,
            )
        )

        self.failureResultOf(resolve_d, ConnectError)
예제 #3
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=["lookupService"])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires", "priority", "weight"])
        entry.expires = 999999999
        entry.priority = 0
        entry.weight = 0

        cache = {service_name: [entry]}
        resolver = SrvResolver(dns_client=dns_client_mock,
                               cache=cache,
                               get_time=clock.time)

        servers = yield defer.ensureDeferred(
            resolver.resolve_service(service_name))

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
예제 #4
0
    def test_disabled_service(self):
        """
        test the behaviour when there is a single record which is ".".
        """
        service_name = b"test_service.example.com"

        lookup_deferred = Deferred()
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = lookup_deferred
        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        resolve_d = resolver.resolve_service(service_name)
        self.assertNoResult(resolve_d)

        # returning a single "." should make the lookup fail with a ConenctError
        lookup_deferred.callback(
            (
                [dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"."))],
                None,
                None,
            )
        )

        self.failureResultOf(resolve_d, ConnectError)
예제 #5
0
    def test_non_srv_answer(self):
        """
        test the behaviour when the dns server gives us a spurious non-SRV response
        """
        service_name = b"test_service.example.com"

        lookup_deferred = Deferred()
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = lookup_deferred
        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        resolve_d = resolver.resolve_service(service_name)
        self.assertNoResult(resolve_d)

        lookup_deferred.callback((
            [
                dns.RRHeader(type=dns.A, payload=dns.Record_A()),
                dns.RRHeader(type=dns.SRV,
                             payload=dns.Record_SRV(target=b"host")),
            ],
            None,
            None,
        ))

        servers = self.successResultOf(resolve_d)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
        self.assertEquals(servers[0].host, b"host")
예제 #6
0
    def test_empty_cache(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError())

        service_name = b"test_service.example.com"

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        with self.assertRaises(error.DNSServerError):
            yield defer.ensureDeferred(resolver.resolve_service(service_name))
예제 #7
0
    def test_empty_cache(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError())

        service_name = b"test_service.example.com"

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        with self.assertRaises(error.DNSServerError):
            yield resolver.resolve_service(service_name)
예제 #8
0
    def test_name_error(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError())

        service_name = b"test_service.example.com"

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        servers = yield defer.ensureDeferred(resolver.resolve_service(service_name))

        self.assertEqual(len(servers), 0)
        self.assertEqual(len(cache), 0)
예제 #9
0
    def test_name_error(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError())

        service_name = b"test_service.example.com"

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        servers = yield resolver.resolve_service(service_name)

        self.assertEquals(len(servers), 0)
        self.assertEquals(len(cache), 0)
예제 #10
0
    def __init__(
        self,
        reactor,
        tls_client_options_factory,
        _srv_resolver=None,
        _well_known_cache=None,
    ):
        self._reactor = reactor
        self._clock = Clock(reactor)

        self._tls_client_options_factory = tls_client_options_factory
        if _srv_resolver is None:
            _srv_resolver = SrvResolver()
        self._srv_resolver = _srv_resolver

        self._pool = HTTPConnectionPool(reactor)
        self._pool.retryAutomatically = False
        self._pool.maxPersistentPerHost = 5
        self._pool.cachedConnectionTimeout = 2 * 60

        self._well_known_resolver = WellKnownResolver(
            self._reactor,
            agent=Agent(
                self._reactor,
                pool=self._pool,
                contextFactory=tls_client_options_factory,
            ),
            well_known_cache=_well_known_cache,
        )
예제 #11
0
    def __init__(
        self,
        reactor,
        tls_client_options_factory,
        _well_known_tls_policy=None,
        _srv_resolver=None,
        _well_known_cache=well_known_cache,
    ):
        self._reactor = reactor
        self._clock = Clock(reactor)

        self._tls_client_options_factory = tls_client_options_factory
        if _srv_resolver is None:
            _srv_resolver = SrvResolver()
        self._srv_resolver = _srv_resolver

        self._pool = HTTPConnectionPool(reactor)
        self._pool.retryAutomatically = False
        self._pool.maxPersistentPerHost = 5
        self._pool.cachedConnectionTimeout = 2 * 60

        agent_args = {}
        if _well_known_tls_policy is not None:
            # the param is called 'contextFactory', but actually passing a
            # contextfactory is deprecated, and it expects an IPolicyForHTTPS.
            agent_args['contextFactory'] = _well_known_tls_policy
        _well_known_agent = RedirectAgent(
            Agent(self._reactor, pool=self._pool, **agent_args), )
        self._well_known_agent = _well_known_agent

        # our cache of .well-known lookup results, mapping from server name
        # to delegated name. The values can be:
        #   `bytes`:     a valid server-name
        #   `None`:      there is no (valid) .well-known here
        self._well_known_cache = _well_known_cache
예제 #12
0
    def __init__(self, reactor, tls_client_options_factory, srv_resolver):
        self._reactor = reactor
        self._tls_client_options_factory = tls_client_options_factory

        if srv_resolver is None:
            srv_resolver = SrvResolver()

        self._srv_resolver = srv_resolver
예제 #13
0
    def test_from_cache_expired_and_dns_fail(self):
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError())

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 0

        cache = {service_name: [entry]}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        servers = yield resolver.resolve_service(service_name)

        dns_client_mock.lookupService.assert_called_once_with(service_name)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
예제 #14
0
    def test_from_cache_expired_and_dns_fail(self):
        dns_client_mock = Mock()
        dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError())

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 0

        cache = {service_name: [entry]}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        servers = yield resolver.resolve_service(service_name)

        dns_client_mock.lookupService.assert_called_once_with(service_name)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
예제 #15
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=['lookupService'])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 999999999

        cache = {service_name: [entry]}
        resolver = SrvResolver(dns_client=dns_client_mock,
                               cache=cache,
                               get_time=clock.time)

        servers = yield resolver.resolve_service(service_name)

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
예제 #16
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=['lookupService'])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 999999999

        cache = {service_name: [entry]}
        resolver = SrvResolver(
            dns_client=dns_client_mock, cache=cache, get_time=clock.time
        )

        servers = yield resolver.resolve_service(service_name)

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
예제 #17
0
    def __init__(
        self,
        reactor: IReactorCore,
        tls_client_options_factory: Optional[FederationPolicyForHTTPS],
        srv_resolver: Optional[SrvResolver],
    ):
        self._reactor = reactor
        self._tls_client_options_factory = tls_client_options_factory

        if srv_resolver is None:
            srv_resolver = SrvResolver()

        self._srv_resolver = srv_resolver
예제 #18
0
    def test_resolve(self):
        dns_client_mock = Mock()

        service_name = b"test_service.example.com"
        host_name = b"example.com"

        answer_srv = dns.RRHeader(type=dns.SRV,
                                  payload=dns.Record_SRV(target=host_name))

        result_deferred = Deferred()
        dns_client_mock.lookupService.return_value = result_deferred

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        @defer.inlineCallbacks
        def do_lookup():

            with LoggingContext("one") as ctx:
                resolve_d = resolver.resolve_service(service_name)

                self.assertNoResult(resolve_d)

                # should have reset to the sentinel context
                self.assertIs(LoggingContext.current_context(),
                              LoggingContext.sentinel)

                result = yield resolve_d

                # should have restored our context
                self.assertIs(LoggingContext.current_context(), ctx)

                defer.returnValue(result)

        test_d = do_lookup()
        self.assertNoResult(test_d)

        dns_client_mock.lookupService.assert_called_once_with(service_name)

        result_deferred.callback(([answer_srv], None, None))

        servers = self.successResultOf(test_d)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
        self.assertEquals(servers[0].host, host_name)
예제 #19
0
    def __init__(
        self,
        reactor: IReactorCore,
        proxy_reactor: IReactorCore,
        tls_client_options_factory: Optional[FederationPolicyForHTTPS],
        srv_resolver: Optional[SrvResolver],
        https_proxy: Optional[bytes] = None,
    ):
        self._reactor = reactor
        self._tls_client_options_factory = tls_client_options_factory

        if srv_resolver is None:
            srv_resolver = SrvResolver()

        self._srv_resolver = srv_resolver
        self.https_proxy_creds, https_proxy = parse_username_password(https_proxy)

        self.https_proxy_endpoint = proxyagent.http_proxy_endpoint(
            https_proxy, proxy_reactor
        )