예제 #1
0
static int mod_detach(void *instance)
{
	rlm_unbound_t *inst = instance;

	if (inst->log_fd >= 0) {
		fr_event_fd_delete(inst->el, inst->log_fd, FR_EVENT_FILTER_IO);
		if (inst->ub) {
			ub_process(inst->ub);
			/* This can hang/leave zombies currently
			 * see upstream bug #519
			 * ...so expect valgrind to complain with -m
			 */
#if 0
			ub_ctx_delete(inst->ub);
#endif
		}
	}

	if (inst->log_pipe_stream[1]) {
		fclose(inst->log_pipe_stream[1]);
	}

	if (inst->log_pipe_stream[0]) {
		if (inst->log_pipe_in_use) {
			fr_event_fd_delete(inst->el, inst->log_pipe[0], FR_EVENT_FILTER_IO);
		}
		fclose(inst->log_pipe_stream[0]);
	}

	if (inst->log_stream) {
		fclose(inst->log_stream);
	}

	return 0;
}
예제 #2
0
/*
 *	Even when run in asyncronous mode, callbacks sent to libunbound still
 *	must be run in an application-side thread (via ub_process.)  This is
 *	probably to keep the API usage consistent across threaded and forked
 *	embedded client modes.  This callback function lets an event loop call
 *	ub_process when the instance's file descriptor becomes ready.
 */
static void ub_fd_handler(UNUSED fr_event_list_t *el, UNUSED int sock, UNUSED int flags, void *ctx)
{
	rlm_unbound_t *inst = ctx;
	int err;

	err = ub_process(inst->ub);
	if (err) {
		ERROR("Async ub_process: %s", ub_strerror(err));
	}
}
예제 #3
0
static int ub_common_wait(rlm_unbound_t const *inst, REQUEST *request,
			  char const *name, struct ub_result **ub, int async_id)
{
	useconds_t iv, waited;

	iv = inst->timeout > 64 ? 64000 : inst->timeout * 1000;
	ub_process(inst->ub);

	for (waited = 0; (void const *)*ub == (void const *)inst; waited += iv, iv *= 2) {

		if (waited + iv > (useconds_t)inst->timeout * 1000) {
			usleep(inst->timeout * 1000 - waited);
			ub_process(inst->ub);
			break;
		}

		usleep(iv);

		/* Check if already handled by event loop */
		if ((void const *)*ub != (void const *)inst) {
			break;
		}

		/* In case we are running single threaded */
		ub_process(inst->ub);
	}

	if ((void const *)*ub == (void const *)inst) {
		int res;

		REDEBUG2("%s - DNS took too long", name);

		res = ub_cancel(inst->ub, async_id);
		if (res) {
			REDEBUG("%s - ub_cancel: %s", name, ub_strerror(res));
		}
		return -1;
	}

	return 0;
}
예제 #4
0
파일: ubchk.c 프로젝트: sveniu/ubchk
int main(void)
{
	struct ub_ctx* ctx;
	volatile int qlen = 0;
	int retval;
	char qname[QNAME_MAX];
	char *moredata, *nl;

	/* basic checks */
	if(QUEUE_MAX < 1) {
		printf("error: queue length must be >0\n");
		return 1;
	}

	/* create context */
	ctx = ub_ctx_create();
	if(!ctx) {
		printf("error: could not create unbound context\n");
		return 1;
	}

	fprintf(stderr, "HOST;ERR;RCODE;DATA;NXDOMAIN\n");

	/* we keep running, lets do something while waiting */
	moredata = (char*)-1;
	do {
		/* queue has room && more data on stdin? */
		if(qlen < QUEUE_MAX && moredata) {
			/* read and prepare qname from stdin */
			moredata = fgets(qname, QNAME_MAX, stdin);
			if(moredata != NULL) {
				nl = strrchr(qname, '\n');
				if(nl) *nl = '\0';
				if((int)nl == (int)&qname)
				{
					printf("empty input\n");
					continue;
				}

				/* add async query to queue */
				retval = ub_resolve_async(ctx, qname,
						1,
						1,
						(void*)&qlen, mycallback, NULL);
				if(retval != 0) {
					printf("resolve error for %s: %s\n", qname, ub_strerror(retval));
					continue;
				}
				qlen++;
			}
			usleep(50000); /* wait 1/50 of a second */
		} else {
			/* queue is full || eof stdin reached */
			usleep(100000); /* wait 1/10 of a second */
			retval = ub_process(ctx);
			if(retval != 0) {
				printf("resolve error: %s\n", ub_strerror(retval));
				return 1;
			}
		}
	} while(qlen || moredata);

	ub_ctx_delete(ctx);
	return 0;
}
예제 #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;
}