#ifndef SYNC_DNS
-static int fd_in = -1, fd_out = -1;
-static pid_t child_pid = -1;
+struct asyncdns_state {
+ struct messaging_context *msg;
+ pid_t child_pid;
+ int fd_in;
+ struct tevent_fd *fde_in;
+ int fd_out;
+};
+static struct asyncdns_state *adns_state;
static int in_dns;
/* this is the structure that is passed between the parent and child */
loop
****************************************************************************/
-int asyncdns_fd(void)
-{
- return fd_in;
-}
-
/***************************************************************************
handle DNS queries arriving from the parent
****************************************************************************/
while (1) {
NTSTATUS status;
- status = read_data(fd_in, (char *)&r, sizeof(r));
+ status = read_data(adns_state->fd_in, (char *)&r, sizeof(r));
if (!NT_STATUS_IS_OK(status)) {
break;
pull_ascii_nstring( qname, sizeof(qname), r.name.name);
r.result.s_addr = interpret_addr(qname);
- if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
+ if (write_data(adns_state->fd_out, (char *)&r, sizeof(r)) != sizeof(r))
break;
}
_exit(0);
}
+static int asyncdns_state_destructor(struct asyncdns_state *state)
+{
+ if (state->child_pid > 0) {
+ kill(state->child_pid, SIGTERM);
+ state->child_pid = -1;
+ }
+
+ TALLOC_FREE(state->fde_in);
+
+ if (state->fd_in != -1) {
+ close(state->fd_in);
+ state->fd_in = -1;
+ }
+ if (state->fd_out != -1) {
+ close(state->fd_out);
+ state->fd_out = -1;
+ }
+ return 0;
+}
+
/***************************************************************************
Called by the parent process when it receives a SIGTERM - also kills the
child so we don't get child async dns processes lying around, causing trouble.
void kill_async_dns_child(void)
{
- if (child_pid > 0) {
- kill(child_pid, SIGTERM);
- child_pid = -1;
- }
+ TALLOC_FREE(adns_state);
}
+static void asyncdns_run_queue(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
/***************************************************************************
create a child process to handle DNS lookups
****************************************************************************/
int fd1[2], fd2[2];
NTSTATUS status;
+ kill_async_dns_child();
+
+ adns_state = talloc_zero(msg, struct asyncdns_state);
+ if (adns_state == NULL) {
+ DEBUG(0,("can't allocate asyncdns state\n"));
+ return;
+ }
+ adns_state->msg = msg;
+ adns_state->fd_in = -1;
+ adns_state->fd_out = -1;
+ talloc_set_destructor(adns_state, asyncdns_state_destructor);
+
CatchChild();
if (pipe(fd1) || pipe(fd2)) {
return;
}
- child_pid = fork();
+ adns_state->child_pid = fork();
- if (child_pid) {
- fd_in = fd1[0];
- fd_out = fd2[1];
+ if (adns_state->child_pid) {
+ adns_state->fd_in = fd1[0];
+ adns_state->fd_out = fd2[1];
close(fd1[1]);
close(fd2[0]);
- DEBUG(0,("started asyncdns process %d\n", (int)child_pid));
+ adns_state->fde_in = tevent_add_fd(nmbd_event_context(),
+ adns_state,
+ adns_state->fd_in,
+ TEVENT_FD_READ,
+ asyncdns_run_queue,
+ NULL);
+ if (adns_state->fde_in == NULL) {
+ DEBUG(0,("can't create asyncdns fde_in\n"));
+ kill_async_dns_child();
+ }
+ DEBUG(0,("started asyncdns process %d\n",
+ (int)adns_state->child_pid));
return;
}
- fd_in = fd2[0];
- fd_out = fd1[1];
+ adns_state->fd_in = fd2[0];
+ adns_state->fd_out = fd1[1];
CatchSignal(SIGUSR2, SIG_IGN);
CatchSignal(SIGUSR1, SIG_IGN);
{
struct query_record r;
+ if (adns_state == NULL) {
+ return false;
+ }
+
r.name = p->packet.nmb.question.question_name;
- return write_data(fd_out, (char *)&r, sizeof(r)) == sizeof(r);
+ return write_data(adns_state->fd_out, (char *)&r, sizeof(r)) == sizeof(r);
}
/***************************************************************************
check the DNS queue
****************************************************************************/
-void run_dns_queue(struct messaging_context *msg)
+static void asyncdns_run_queue(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
{
struct query_record r;
struct packet_struct *p, *p2;
struct name_record *namerec;
NTSTATUS status;
- if (fd_in == -1)
- return;
-
- if (!process_exists_by_pid(child_pid)) {
- close(fd_in);
- close(fd_out);
- start_async_dns(msg);
- }
-
- status = read_data(fd_in, (char *)&r, sizeof(r));
+ status = read_data(adns_state->fd_in, (char *)&r, sizeof(r));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("read from child failed: %s\n", nt_errstr(status)));
- fd_in = -1;
+ start_async_dns(adns_state->msg);
return;
}
bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
{
- if (in_dns || fd_in == -1)
+ if (in_dns || adns_state == NULL)
return False;
if (!dns_current) {