Example #1
0
static void
nss_ubdns_load_resolvconf(void) {
	struct stat sb;

	if (stat(NSS_UBDNS_RESOLVCONF, &sb) == 0) {
		ub_ctx_resolvconf(ctx, NSS_UBDNS_RESOLVCONF);
	} else {
		ub_ctx_set_fwd(ctx, "127.0.0.1");
	}
}
Example #2
0
DNSResolver::DNSResolver() : m_data(new DNSResolverData())
{
  int use_dns_public = 0;
  const char* dns_public_addr = "8.8.4.4";
  if (auto res = getenv("DNS_PUBLIC"))
  {
    std::string dns_public(res);
    // TODO: could allow parsing of IP and protocol: e.g. DNS_PUBLIC=tcp:8.8.8.8
    if (dns_public == "tcp")
    {
      LOG_PRINT_L0("Using public DNS server: " << dns_public_addr << " (TCP)");
      use_dns_public = 1;
    }
  }

  // init libunbound context
  m_data->m_ub_context = ub_ctx_create();

  if (use_dns_public)
  {
    ub_ctx_set_fwd(m_data->m_ub_context, dns_public_addr);
    ub_ctx_set_option(m_data->m_ub_context, "do-udp:", "no");
    ub_ctx_set_option(m_data->m_ub_context, "do-tcp:", "yes");
  }
  else {
    // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent
    ub_ctx_resolvconf(m_data->m_ub_context, NULL);
    ub_ctx_hosts(m_data->m_ub_context, NULL);
  }

  #ifdef DEVELOPER_LIBUNBOUND_OLD
    #pragma message "Using the work around for old libunbound"
    { // work around for bug https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=515 needed for it to compile on e.g. Debian 7
      char * ds_copy = NULL; // this will be the writable copy of string that bugged version of libunbound requires
      try {
        char * ds_copy = strdup( ::get_builtin_ds() );
        ub_ctx_add_ta(m_data->m_ub_context, ds_copy);
      } catch(...) { // probably not needed but to work correctly in every case...
        if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup
        throw ;
      }
      if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup
    }
  #else
    // normal version for fixed libunbound
    ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds() );
  #endif

}
Example #3
0
DNSResolver::DNSResolver() : m_data(new DNSResolverData())
{
  int use_dns_public = 0;
  std::vector<std::string> dns_public_addr;
  if (auto res = getenv("DNS_PUBLIC"))
  {
    dns_public_addr = tools::dns_utils::parse_dns_public(res);
    if (!dns_public_addr.empty())
    {
      MGINFO("Using public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)");
      use_dns_public = 1;
    }
    else
    {
      MERROR("Failed to parse DNS_PUBLIC");
    }
  }

  // init libunbound context
  m_data->m_ub_context = ub_ctx_create();

  if (use_dns_public)
  {
    for (const auto &ip: dns_public_addr)
      ub_ctx_set_fwd(m_data->m_ub_context, string_copy(ip.c_str()));
    ub_ctx_set_option(m_data->m_ub_context, string_copy("do-udp:"), string_copy("no"));
    ub_ctx_set_option(m_data->m_ub_context, string_copy("do-tcp:"), string_copy("yes"));
  }
  else {
    // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent
    ub_ctx_resolvconf(m_data->m_ub_context, NULL);
    ub_ctx_hosts(m_data->m_ub_context, NULL);
  }

  const char * const *ds = ::get_builtin_ds();
  while (*ds)
  {
    MINFO("adding trust anchor: " << *ds);
    ub_ctx_add_ta(m_data->m_ub_context, string_copy(*ds++));
  }
}
Example #4
0
int
ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname)
{
    FILE* in;
    int numserv = 0;
    char buf[1024];
    char* parse, *addr;
    int r;

    if(fname == NULL) {
#if !defined(UB_ON_WINDOWS) || !defined(HAVE_WINDOWS_H)
        fname = "/etc/resolv.conf";
#else
        FIXED_INFO *info;
        ULONG buflen = sizeof(*info);
        IP_ADDR_STRING *ptr;

        info = (FIXED_INFO *) malloc(sizeof (FIXED_INFO));
        if (info == NULL)
            return UB_READFILE;

        if (GetNetworkParams(info, &buflen) == ERROR_BUFFER_OVERFLOW) {
            free(info);
            info = (FIXED_INFO *) malloc(buflen);
            if (info == NULL)
                return UB_READFILE;
        }

        if (GetNetworkParams(info, &buflen) == NO_ERROR) {
            int retval=0;
            ptr = &(info->DnsServerList);
            while (ptr) {
                numserv++;
                if((retval=ub_ctx_set_fwd(ctx,
                                          ptr->IpAddress.String)!=0)) {
                    free(info);
                    return retval;
                }
                ptr = ptr->Next;
            }
            free(info);
            if (numserv==0)
                return UB_READFILE;
            return UB_NOERROR;
        }
        free(info);
        return UB_READFILE;
#endif /* WINDOWS */
    }
    in = fopen(fname, "r");
    if(!in) {
        /* error in errno! perror(fname) */
        return UB_READFILE;
    }
    while(fgets(buf, (int)sizeof(buf), in)) {
        buf[sizeof(buf)-1] = 0;
        parse=buf;
        while(*parse == ' ' || *parse == '\t')
            parse++;
        if(strncmp(parse, "nameserver", 10) == 0) {
            numserv++;
            parse += 10; /* skip 'nameserver' */
            /* skip whitespace */
            while(*parse == ' ' || *parse == '\t')
                parse++;
            addr = parse;
            /* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */
            while(isxdigit(*parse) || *parse=='.' || *parse==':')
                parse++;
            /* terminate after the address, remove newline */
            *parse = 0;

            if((r = ub_ctx_set_fwd(ctx, addr)) != UB_NOERROR) {
                fclose(in);
                return r;
            }
        }
    }
    fclose(in);
    if(numserv == 0) {
        /* from resolv.conf(5) if none given, use localhost */
        return ub_ctx_set_fwd(ctx, "127.0.0.1");
    }
    return UB_NOERROR;
}
Example #5
0
/** main program for asynclook */
int main(int argc, char** argv) 
{
	int c;
	struct ub_ctx* ctx;
	struct lookinfo* lookups;
	int i, r, cancel=0, blocking=0, ext=0;

	/* init log now because solaris thr_key_create() is not threadsafe */
	log_init(0,0,0);
	/* lock debug start (if any) */
	checklock_start();

	/* create context */
	ctx = ub_ctx_create();
	if(!ctx) {
		printf("could not create context, %s\n", strerror(errno));
		return 1;
	}

	/* command line options */
	if(argc == 1) {
		usage(argv);
	}
	while( (c=getopt(argc, argv, "bcdf:hH:r:tx")) != -1) {
		switch(c) {
			case 'd':
				r = ub_ctx_debuglevel(ctx, 3);
				checkerr("ub_ctx_debuglevel", r);
				break;
			case 't':
				r = ub_ctx_async(ctx, 1);
				checkerr("ub_ctx_async", r);
				break;
			case 'c':
				cancel = 1;
				break;
			case 'b':
				blocking = 1;
				break;
			case 'r':
				r = ub_ctx_resolvconf(ctx, optarg);
				if(r != 0) {
					printf("ub_ctx_resolvconf "
						"error: %s : %s\n",
						ub_strerror(r), 
						strerror(errno));
					return 1;
				}
				break;
			case 'H':
				r = ub_ctx_hosts(ctx, optarg);
				if(r != 0) {
					printf("ub_ctx_hosts "
						"error: %s : %s\n",
						ub_strerror(r), 
						strerror(errno));
					return 1;
				}
				break;
			case 'f':
				r = ub_ctx_set_fwd(ctx, optarg);
				checkerr("ub_ctx_set_fwd", r);
				break;
			case 'x':
				ext = 1;
				break;
			case 'h':
			case '?':
			default:
				usage(argv);
		}
	}
	argc -= optind;
	argv += optind;

	if(ext)
		return ext_test(ctx, argc, argv);

	/* allocate array for results. */
	lookups = (struct lookinfo*)calloc((size_t)argc, 
		sizeof(struct lookinfo));
	if(!lookups) {
		printf("out of memory\n");
		return 1;
	}

	/* perform asynchronous calls */
	num_wait = argc;
	for(i=0; i<argc; i++) {
		lookups[i].name = argv[i];
		if(blocking) {
			fprintf(stderr, "lookup %s\n", argv[i]);
			r = ub_resolve(ctx, argv[i], LDNS_RR_TYPE_A,
				LDNS_RR_CLASS_IN, &lookups[i].result);
			checkerr("ub_resolve", r);
		} else {
			fprintf(stderr, "start async lookup %s\n", argv[i]);
			r = ub_resolve_async(ctx, argv[i], LDNS_RR_TYPE_A,
				LDNS_RR_CLASS_IN, &lookups[i], &lookup_is_done, 
				&lookups[i].async_id);
			checkerr("ub_resolve_async", r);
		}
	}
	if(blocking)
		num_wait = 0;
	else if(cancel) {
		for(i=0; i<argc; i++) {
			fprintf(stderr, "cancel %s\n", argv[i]);
			r = ub_cancel(ctx, lookups[i].async_id);
			if(r != UB_NOID) 
				checkerr("ub_cancel", r);
		}
		num_wait = 0;
	}

	/* wait while the hostnames are looked up. Do something useful here */
	if(num_wait > 0)
	    for(i=0; i<1000; i++) {
		usleep(100000);
		fprintf(stderr, "%g seconds passed\n", 0.1*(double)i);
		r = ub_process(ctx);
		checkerr("ub_process", r);
		if(num_wait == 0)
			break;
	}
	if(i>=999) {
		printf("timed out\n");
		return 0;
	}
	printf("lookup complete\n");

	/* print lookup results */
	for(i=0; i<argc; i++) {
		print_result(&lookups[i]);
		ub_resolve_free(lookups[i].result);
	}

	ub_ctx_delete(ctx);
	free(lookups);
	checklock_stop();
	return 0;
}