#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unbound.h>

#include <pthread.h>

/* The main function of the first thread */
void* thread_one(void* threadarg)
{
	struct ub_ctx* ctx = (struct ub_ctx*)threadarg;
	struct ub_result* result;
	int retval;
	/* query for webserver */
	retval = ub_resolve(ctx, "www.nlnetlabs.nl", 
		1 /* TYPE A (IPv4 address) */, 
		1 /* CLASS IN (internet) */, &result);
	if(retval != 0) {
		printf("resolve error: %s\n", ub_strerror(retval));
		return NULL;
	}

	/* show first result */
	if(result->havedata)
		printf("Thread1: address of %s is %s\n", result->qname,
			inet_ntoa(*(struct in_addr*)result->data[0]));

	/* exit thread */
	ub_resolve_free(result);
	return NULL;
}

/* The main function of the second thread */
void* thread_two(void* threadarg)
{
	struct ub_ctx* ctx = (struct ub_ctx*)threadarg;
	struct ub_result* result;
	int retval;
	/* query for webserver */
	retval = ub_resolve(ctx, "www.google.nl", 
		1 /* TYPE A (IPv4 address) */, 
		1 /* CLASS IN (internet) */, &result);
	if(retval != 0) {
		printf("resolve error: %s\n", ub_strerror(retval));
		return NULL;
	}

	/* show first result */
	if(result->havedata)
		printf("Thread2: address of %s is %s\n", result->qname,
			inet_ntoa(*(struct in_addr*)result->data[0]));

	/* exit thread */
	ub_resolve_free(result);
	return NULL;
}

int main(void)
{
	struct ub_ctx* ctx;
	int retval;
	pthread_t t1, t2;

	/* create context */
	ctx = ub_ctx_create();
	if(!ctx) {
		printf("error: could not create unbound context\n");
		return 1;
	}
	/* read /etc/resolv.conf for DNS proxy settings (from DHCP) */
	if( (retval=ub_ctx_resolvconf(ctx, "/etc/resolv.conf")) != 0) {
		printf("error reading resolv.conf: %s. errno says: %s\n", 
			ub_strerror(retval), strerror(errno));
		return 1;
	}
	/* read /etc/hosts for locally supplied host addresses */
	if( (retval=ub_ctx_hosts(ctx, "/etc/hosts")) != 0) {
		printf("error reading hosts: %s. errno says: %s\n", 
			ub_strerror(retval), strerror(errno));
		return 1;
	}

	/* start two threads, uses pthreads */
	pthread_create(&t1, NULL, thread_one, ctx);
	pthread_create(&t2, NULL, thread_two, ctx);
	/* wait for both threads to complete */
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);

	ub_ctx_delete(ctx);
	return 0;
}
