Пример #1
0
static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) {
  dns_add_srch(ctx, NULL);
  for(srch = strtok(srch, space); srch; srch = strtok(NULL, space))
    dns_add_srch(ctx, srch);
}
Пример #2
0
static int dns_init_resolvconf(struct dns_ctx *ctx) {
  char *v;
  char buf[4097];	/* this buffer is used to hold /etc/resolv.conf */
  int has_srch = 0;

  /* read resolv.conf... */
  { int fd = open("/etc/resolv.conf", O_RDONLY);
    if (fd >= 0) {
      int l = read(fd, buf, sizeof(buf) - 1);
      close(fd);
      buf[l < 0 ? 0 : l] = '\0';
    }
    else
      buf[0] = '\0';
  }
  if (buf[0]) {	/* ...and parse it */
    char *line, *nextline;
    line = buf;
    do {
      nextline = strchr(line, '\n');
      if (nextline) *nextline++ = '\0';
      v = line;
      while(*v && !ISSPACE(*v)) ++v;
      if (!*v) continue;
      *v++ = '\0';
      while(ISSPACE(*v)) ++v;
      if (!*v) continue;
      if (strcmp(line, "domain") == 0) {
        dns_set_srch_internal(ctx, strtok(v, space));
	has_srch = 1;
      }
      else if (strcmp(line, "search") == 0) {
        dns_set_srch_internal(ctx, v);
	has_srch = 1;
      }
      else if (strcmp(line, "nameserver") == 0)
        dns_add_serv(ctx, strtok(v, space));
      else if (strcmp(line, "options") == 0)
        dns_set_opts(ctx, v);
    } while((line = nextline) != NULL);
  }

  buf[sizeof(buf)-1] = '\0';

#if TARGET_OS_IPHONE
  // SOLUTION FOUND:
  // http://iphone.galloway.me.uk/2009/11/iphone-dns-servers/
  
  // ORIGINAL CODE EXAMPLE:
  //
  //      #if TARGET_OS_IPHONE
  //      #include <resolv.h>
  //      #endif
  // 
  //      ...
  // 
  //      #if TARGET_OS_IPHONE
  //      // XXX: On the iPhone we need to get the DNS servers using resolv.h magic
  //      if ((_res.options & RES_INIT) == 0) res_init();
  //      channel->nservers = _res.nscount;
  //      channel->servers = malloc(channel->nservers * sizeof(struct server_state));
  //      memset(channel->servers, '\0', channel->nservers * sizeof(struct server_state));
  // 
  //      int i;
  //      for (i = 0; i < channel->nservers; i++)
  //      {
  //          memcpy(&channel->servers[i].addr, &_res.nsaddr_list[i].sin_addr, sizeof(struct in_addr));
  //      }
  //      #endif

  if ((_res.options & RES_INIT) == 0) res_init();
  
  int i;
  for (i = 0; i < _res.nscount; i++)
  {
    struct sockaddr_in address;
    memset(&address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr = _res.nsaddr_list[i].sin_addr;              // loopback is a special case since it could be stored as ::1 in IPv6

    dns_add_serv_s(ctx, (struct sockaddr *)&address);
  }
#endif //TARGET_OS_IPHONE

  /* get list of nameservers from env. vars. */
  if ((v = getenv("NSCACHEIP")) != NULL ||
      (v = getenv("NAMESERVERS")) != NULL) {
    strncpy(buf, v, sizeof(buf) - 1);
    dns_set_serv_internal(ctx, buf);
  }
  /* if $LOCALDOMAIN is set, use it for search list */
  if ((v = getenv("LOCALDOMAIN")) != NULL) {
    strncpy(buf, v, sizeof(buf) - 1);
    dns_set_srch_internal(ctx, buf);
    has_srch = 1;
  }
  if ((v = getenv("RES_OPTIONS")) != NULL)
    dns_set_opts(ctx, v);

  /* if still no search list, use local domain name */
  if (has_srch &&
      gethostname(buf, sizeof(buf) - 1) == 0 &&
      (v = strchr(buf, '.')) != NULL &&
      *++v != '\0')
    dns_add_srch(ctx, v);

  return 0;
}
Пример #3
0
static int dns_init_resolvconf(struct dns_ctx *ctx) {
  char *v;
  char buf[2049];	/* this buffer is used to hold /etc/resolv.conf */
  int has_srch = 0;

  /* read resolv.conf... */
  { int fd = open("/etc/resolv.conf", O_RDONLY);
    if (fd >= 0) {
      int l = read(fd, buf, sizeof(buf) - 1);
      close(fd);
      buf[l < 0 ? 0 : l] = '\0';
    }
    else
      buf[0] = '\0';
  }
  if (buf[0]) {	/* ...and parse it */
    char *line, *nextline;
    line = buf;
    do {
      nextline = strchr(line, '\n');
      if (nextline) *nextline++ = '\0';
      v = line;
      while(*v && !ISSPACE(*v)) ++v;
      if (!*v) continue;
      *v++ = '\0';
      while(ISSPACE(*v)) ++v;
      if (!*v) continue;
      if (strcmp(line, "domain") == 0) {
        dns_set_srch_internal(ctx, strtok(v, space));
	has_srch = 1;
      }
      else if (strcmp(line, "search") == 0) {
        dns_set_srch_internal(ctx, v);
	has_srch = 1;
      }
      else if (strcmp(line, "nameserver") == 0)
        dns_add_serv(ctx, strtok(v, space));
      else if (strcmp(line, "options") == 0)
        dns_set_opts(ctx, v);
    } while((line = nextline) != NULL);
  }

  buf[sizeof(buf)-1] = '\0';

  /* get list of nameservers from env. vars. */
  if ((v = getenv("NSCACHEIP")) != NULL ||
      (v = getenv("NAMESERVERS")) != NULL) {
    strncpy(buf, v, sizeof(buf) - 1);
    dns_set_serv_internal(ctx, buf);
  }
  /* if $LOCALDOMAIN is set, use it for search list */
  if ((v = getenv("LOCALDOMAIN")) != NULL) {
    strncpy(buf, v, sizeof(buf) - 1);
    dns_set_srch_internal(ctx, buf);
    has_srch = 1;
  }
  if ((v = getenv("RES_OPTIONS")) != NULL)
    dns_set_opts(ctx, v);

  /* if still no search list, use local domain name */
  if (has_srch &&
      gethostname(buf, sizeof(buf) - 1) == 0 &&
      (v = strchr(buf, '.')) != NULL &&
      *++v != '\0')
    dns_add_srch(ctx, v);

  return 0;
}
Пример #4
0
void noit_check_resolver_init() {
  int cnt;
  mtev_conf_section_t *servers, *searchdomains;
  eventer_t e;
  if(dns_init(NULL, 0) < 0)
    mtevL(noit_error, "dns initialization failed.\n");
  dns_ctx = dns_new(NULL);
  if(dns_init(dns_ctx, 0) != 0) {
    mtevL(noit_error, "dns initialization failed.\n");
    exit(-1);
  }

  /* Optional servers */
  servers = mtev_conf_get_sections(NULL, "//resolver//server", &cnt);
  if(cnt) {
    int i;
    char server[128];
    dns_add_serv(dns_ctx, NULL); /* reset */
    for(i=0;i<cnt;i++) {
      if(mtev_conf_get_stringbuf(servers[i], "self::node()",
                                 server, sizeof(server))) {
        if(dns_add_serv(dns_ctx, server) < 0) {
          mtevL(noit_error, "Failed adding DNS server: %s\n", server);
        }
      }
    }
    free(servers);
  }
  searchdomains = mtev_conf_get_sections(NULL, "//resolver//search", &cnt);
  if(cnt) {
    int i;
    char search[128];
    dns_add_srch(dns_ctx, NULL); /* reset */
    for(i=0;i<cnt;i++) {
      if(mtev_conf_get_stringbuf(searchdomains[i], "self::node()",
                                 search, sizeof(search))) {
        if(dns_add_srch(dns_ctx, search) < 0) {
          mtevL(noit_error, "Failed adding DNS search path: %s\n", search);
        }
        else if(dns_search_flag) dns_search_flag = 0; /* enable search */
      }
    }
    free(searchdomains);
  }

  if(mtev_conf_get_int(NULL, "//resolver/@ndots", &cnt))
    dns_set_opt(dns_ctx, DNS_OPT_NDOTS, cnt);

  if(mtev_conf_get_int(NULL, "//resolver/@ntries", &cnt))
    dns_set_opt(dns_ctx, DNS_OPT_NTRIES, cnt);

  if(mtev_conf_get_int(NULL, "//resolver/@timeout", &cnt))
    dns_set_opt(dns_ctx, DNS_OPT_TIMEOUT, cnt);

  if(dns_open(dns_ctx) < 0) {
    mtevL(noit_error, "dns open failed.\n");
    exit(-1);
  }
  eventer_name_callback("dns_cache_callback", dns_cache_callback);
  dns_set_tmcbck(dns_ctx, dns_cache_utm_fn, dns_ctx);
  e = eventer_alloc();
  e->mask = EVENTER_READ | EVENTER_EXCEPTION;
  e->closure = dns_ctx;
  e->callback = dns_cache_callback;
  e->fd = dns_sock(dns_ctx);
  eventer_add(e);

  mtev_skiplist_init(&nc_dns_cache);
  mtev_skiplist_set_compare(&nc_dns_cache, name_lookup, name_lookup_k);
  mtev_skiplist_add_index(&nc_dns_cache, refresh_idx, refresh_idx_k);

  /* maybe load it from cache */
  if(noit_resolver_cache_load_hook_exists()) {
    struct timeval now;
    char *key;
    void *data;
    int len;
    gettimeofday(&now, NULL);
    while(noit_resolver_cache_load_hook_invoke(&key, &data, &len) == MTEV_HOOK_CONTINUE) {
      dns_cache_node *n;
      n = calloc(1, sizeof(*n));
      if(dns_cache_node_deserialize(n, data, len) >= 0) {
        n->target = strdup(key);
        /* if the TTL indicates that it will expire in less than 60 seconds
         * (including stuff that should have already expired), then fudge
         * the last_updated time to make it expire some random time within
         * the next 60 seconds.
         */
        if(n->last_needed > now.tv_sec || n->last_updated > now.tv_sec)
          break; /* impossible */

        n->last_needed = now.tv_sec;
        if(n->last_updated + n->ttl < now.tv_sec + 60) {
          int fudge = MIN(60, n->ttl) + 1;
          n->last_updated = now.tv_sec - n->ttl + (lrand48() % fudge);
        }
        DCLOCK();
        mtev_skiplist_insert(&nc_dns_cache, n);
        DCUNLOCK();
        n = NULL;
      }
      else {
        mtevL(noit_error, "Failed to deserialize resolver cache record.\n");
      }
      if(n) dns_cache_node_free(n);
      if(key) free(key);
      if(data) free(data);
    }
  }

  noit_check_resolver_loop(NULL, 0, NULL, NULL);
  register_console_dns_cache_commands();

  mtev_hash_init(&etc_hosts_cache);
  noit_check_etc_hosts_cache_refresh(NULL, 0, NULL, NULL);
}