find_server_and_update_current_info(HttpTransact::State* s)
{
  int host_len;
  const char *host = s->hdr_info.client_request.host_get(&host_len);

  if (ptr_len_cmp(host, host_len, local_host_ip_str, sizeof(local_host_ip_str) - 1) == 0) {
    // Do not forward requests to local_host onto a parent.
    // I just wanted to do this for cop heartbeats, someone else
    // wanted it for all requests to local_host.
    s->parent_result.r = PARENT_DIRECT;
  } else if (s->method == HTTP_WKSIDX_CONNECT && s->http_config_param->disable_ssl_parenting) {
    s->parent_result.r = PARENT_DIRECT;
  } else if (s->http_config_param->uncacheable_requests_bypass_parent &&
             s->http_config_param->no_dns_forward_to_parent == 0 &&
             !HttpTransact::is_request_cache_lookupable(s)) {
    // request not lookupable and cacheable, so bypass parent
    // Note that the configuration of the proxy as well as the request
    // itself affects the result of is_request_cache_lookupable();
    // we are assuming both child and parent have similar configuration
    // with respect to whether a request is cacheable or not.
    // For example, the cache_urls_that_look_dynamic variable.
    DebugTxn("http_trans", "request not cacheable, so bypass parent");
    s->parent_result.r = PARENT_DIRECT;
  } else {
    switch (s->parent_result.r) {
    case PARENT_UNDEFINED:
      s->parent_params->findParent(&s->request_data, &s->parent_result);
      break;
    case PARENT_SPECIFIED:
      s->parent_params->nextParent(&s->request_data, &s->parent_result);

      // Hack!
      // We already have a parent that failed, if we are now told
      //  to go the origin server, we can only obey this if we
      //  dns'ed the origin server
      if (s->parent_result.r == PARENT_DIRECT && s->http_config_param->no_dns_forward_to_parent != 0) {
        ink_assert(!ats_is_ip(&s->server_info.addr));
        s->parent_result.r = PARENT_FAIL;
      }
      break;
    case PARENT_FAIL:
      // Check to see if should bypass the parent and go direct
      //   We can only do this if
      //   1) the parent was not set from API
      //   2) the config permits us
      //   3) the config permitted us to dns the origin server
      if (!s->parent_params->apiParentExists(&s->request_data) && s->parent_result.rec->bypass_ok() &&
          s->http_config_param->no_dns_forward_to_parent == 0) {
        s->parent_result.r = PARENT_DIRECT;
      }
      break;
    default:
      ink_assert(0);
      // FALL THROUGH
    case PARENT_DIRECT:
      //              // if we have already decided to go direct
      //              // dont bother calling nextParent.
      //              // do nothing here, guy.
      break;
    }
  }

  switch (s->parent_result.r) {
  case PARENT_SPECIFIED:
    s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname));
    s->parent_info.port = s->parent_result.port;
    update_current_info(&s->current, &s->parent_info, HttpTransact::PARENT_PROXY, (s->current.attempts)++);
    update_dns_info(&s->dns_info, &s->current, 0, &s->arena);
    ink_assert(s->dns_info.looking_up == HttpTransact::PARENT_PROXY);
    s->next_hop_scheme = URL_WKSIDX_HTTP;

    return HttpTransact::PARENT_PROXY;
  case PARENT_FAIL:
    // No more parents - need to return an error message
    s->current.request_to = HttpTransact::HOST_NONE;
    return HttpTransact::HOST_NONE;

  case PARENT_DIRECT:
    /* fall through */
  default:
    update_current_info(&s->current, &s->server_info, HttpTransact::ORIGIN_SERVER, (s->current.attempts)++);
    update_dns_info(&s->dns_info, &s->current, 0, &s->arena);
    ink_assert(s->dns_info.looking_up == HttpTransact::ORIGIN_SERVER);
    s->next_hop_scheme = s->scheme;
    return HttpTransact::ORIGIN_SERVER;
  }
}