# Buggy code
def resolve_service(service_name, dns_client=client, cache=SERVER_CACHE, clock=time):
    cache_entry = cache.get(service_name, None)
    if cache_entry:
        if all(s.expires > int(clock.time()) for s in cache_entry):
            servers = list(cache_entry)
            defer.returnValue(servers)

    servers = []

    try:
        try:
            answers, _, _ = yield dns_client.lookupService(service_name)
        except DNSNameError:
            defer.returnValue([])

        if (
            len(answers) == 1
            and answers[0].type == dns.SRV
            and answers[0].payload
            and answers[0].payload.target == dns.Name(".")
        ):
            raise ConnectError("Service %s unavailable" % service_name)

        for answer in answers:
            if answer.type != dns.SRV or not answer.payload:
                continue

            payload = answer.payload

            hosts = yield _get_hosts_for_srv_record(dns_client, str(payload.target))

            for ip, ttl in hosts:
                host_ttl = min(answer.ttl, ttl)

                servers.append(
                    _Server(
                        host=ip,
                        port=int(payload.port),
                        priority=int(payload.priority),
                        weight=int(payload.weight),
                        expires=int(clock.time()) + host_ttl,
                    )
                )

        servers.sort()
        cache[service_name] = list(servers)
    except DomainError as e:
        # We failed to resolve the name (other than a NameError)
        # Try something in the cache, else rereaise
        cache_entry = cache.get(service_name, None)
        if cache_entry:
            logger.warn(
                "Failed to resolve %r, falling back to cache. %r", service_name, e
            )
            servers = list(cache_entry)
        else:
            raise e

    defer.returnValue(servers)


# Traceback (NoRouteError)
2018-02-05 19:14:51,585 - synapse.access.http.8008 - 59 - INFO - GET-131021- - - 8008 - Received request: GET /_matrix/client/r0/directory/room/%23test%3Amatrix.org?access_token=<redacted>
2018-02-05 19:14:51,589 - synapse.http.outbound - 154 - INFO - GET-131021- {GET-O-1317} [matrix.org] Sending request: GET matrix://matrix.org/_matrix/federation/v1/query/directory?room_alias=%23test%3Amatrix.org
2018-02-05 19:14:51,590 - synapse.http.endpoint - 264 - INFO - - Connecting to 2a04:3541:1000:500:6866:a4ff:fe4c:21ac:8448
2018-02-05 19:14:51,592 - twisted - 131 - INFO - - Starting factory _HTTP11ClientFactory(<function quiescentCallback at 0x7f9d7826ad70>, <synapse.http.endpoint._WrappingEndpointFac object at 0x7f9d9c993190>)
2018-02-05 19:14:51,593 - twisted - 131 - INFO - - Stopping factory _HTTP11ClientFactory(<function quiescentCallback at 0x7f9d7826ad70>, <synapse.http.endpoint._WrappingEndpointFac object at 0x7f9d9c993190>)
2018-02-05 19:14:51,892 - synapse.http.matrixfederationclient - 212 - WARNING - GET-131021- {GET-O-1317} Sending request failed to matrix.org: GET matrix://matrix.org/_matrix/federation/v1/query/directory?room_alias=%23test%3Amatrix.org: NoRouteError('Network is unreachable',)
2018-02-05 19:14:51,892 - synapse.http.outbound - 236 - INFO - GET-131021- {GET-O-1317} [matrix.org] Result: NoRouteError('Network is unreachable',)
2018-02-05 19:14:51,893 - synapse.http.server - 183 - ERROR - GET-131021- Failed handle request synapse.http.server._async_render on <synapse.rest.ClientRestResource object at 0x7f9dae55b590>: <XForwardedForRequest at 0x7f9d78220bd8 method=GET uri=/_matrix/client/r0/directory/room/%23test%3Amatrix.org?access_token=<redacted> clientproto=HTTP/1.1 site=8008>: Traceback (most recent call last): Failure: twisted.internet.error.NoRouteError: No route to host: 101: Network is unreachable.
2018-02-05 19:14:51,895 - synapse.access.http.8008 - 93 - INFO - GET-131021- - - 8008 - {None} Processed request: 309ms (4ms, 0ms) (1ms/1ms/1) 69B 500 "GET /_matrix/client/r0/directory/room/%23test%3Amatrix.org?access_token=<redacted> HTTP/1.1" "curl/7.47.0"

# Fixed code
def resolve_service(service_name, dns_client=client, cache=SERVER_CACHE, clock=time):
    cache_entry = cache.get(service_name, None)
    if cache_entry:
        if all(s.expires > int(clock.time()) for s in cache_entry):
            servers = list(cache_entry)
            defer.returnValue(servers)

    servers = []

    try:
        try:
            answers, _, _ = yield dns_client.lookupService(service_name)
        except DNSNameError:
            defer.returnValue([])

        if (
            len(answers) == 1
            and answers[0].type == dns.SRV
            and answers[0].payload
            and answers[0].payload.target == dns.Name(".")
        ):
            raise ConnectError("Service %s unavailable" % service_name)

        for answer in answers:
            if answer.type != dns.SRV or not answer.payload:
                continue

            payload = answer.payload

            servers.append(
                _Server(
                    host=str(payload.target),
                    port=int(payload.port),
                    priority=int(payload.priority),
                    weight=int(payload.weight),
                    expires=int(clock.time()) + answer.ttl,
                )
            )

        servers.sort()
        cache[service_name] = list(servers)
    except DomainError as e:
        # We failed to resolve the name (other than a NameError)
        # Try something in the cache, else rereaise
        cache_entry = cache.get(service_name, None)
        if cache_entry:
            logger.warn(
                "Failed to resolve %r, falling back to cache. %r", service_name, e
            )
            servers = list(cache_entry)
        else:
            raise e

    defer.returnValue(servers)