summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-01-21 12:51:21 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-01-22 09:09:57 -0500
commitf89cb099c87e4caa89d75358e94b559d8c3e03d3 (patch)
tree8461008ce968b79d4b9d3f333e722055ee74df1c /server
parent743d22b5f0592d0dba1d4d9040d998c9d711603e (diff)
downloadsssd-f89cb099c87e4caa89d75358e94b559d8c3e03d3.tar.gz
sssd-f89cb099c87e4caa89d75358e94b559d8c3e03d3.tar.xz
sssd-f89cb099c87e4caa89d75358e94b559d8c3e03d3.zip
Fix async resolver integration with tevent
We weren't properly setting read/write flags on the tevent fd events, so c-ares was unable to perform bidirectional communication for TCP DNS (in situations where the response is too large to send by UDP)
Diffstat (limited to 'server')
-rw-r--r--server/resolv/async_resolv.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/server/resolv/async_resolv.c b/server/resolv/async_resolv.c
index ce92c8a7d..7973a78f3 100644
--- a/server/resolv/async_resolv.c
+++ b/server/resolv/async_resolv.c
@@ -59,6 +59,7 @@ struct fd_watch {
int fd;
struct resolv_ctx *ctx;
+ struct tevent_fd *fde;
};
struct resolv_ctx {
@@ -123,7 +124,13 @@ fd_input_available(struct tevent_context *ev, struct tevent_fd *fde,
DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
return;
}
- ares_process_fd(watch->ctx->channel, watch->fd, watch->fd);
+
+ if (flags & TEVENT_FD_READ) {
+ ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD);
+ }
+ if (flags & TEVENT_FD_WRITE) {
+ ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd);
+ }
}
static void
@@ -206,7 +213,7 @@ unschedule_timeout_watcher(struct resolv_ctx *ctx)
}
}
-static void fd_event_add(struct resolv_ctx *ctx, int s);
+static void fd_event_add(struct resolv_ctx *ctx, int s, int flags);
static void fd_event_close(struct resolv_ctx *ctx, int s);
/*
@@ -220,6 +227,7 @@ fd_event(void *data, int s, int fd_read, int fd_write)
{
struct resolv_ctx *ctx = talloc_get_type(data, struct resolv_ctx);
struct fd_watch *watch;
+ int flags;
/* The socket is about to get closed. */
if (fd_read == 0 && fd_write == 0) {
@@ -227,23 +235,26 @@ fd_event(void *data, int s, int fd_read, int fd_write)
return;
}
+ flags = fd_read ? TEVENT_FD_READ : 0;
+ flags |= fd_write ? TEVENT_FD_WRITE : 0;
+
/* Are we already watching this file descriptor? */
watch = ctx->fds;
while (watch) {
if (watch->fd == s) {
+ tevent_fd_set_flags(watch->fde, flags);
return;
}
watch = watch->next;
}
- fd_event_add(ctx, s);
+ fd_event_add(ctx, s, flags);
}
static void
-fd_event_add(struct resolv_ctx *ctx, int s)
+fd_event_add(struct resolv_ctx *ctx, int s, int flags)
{
struct fd_watch *watch;
- struct tevent_fd *fde;
/* The file descriptor is new, register it with tevent. */
watch = talloc(ctx, struct fd_watch);
@@ -256,8 +267,9 @@ fd_event_add(struct resolv_ctx *ctx, int s)
watch->fd = s;
watch->ctx = ctx;
- fde = tevent_add_fd(ctx->ev_ctx, watch, s, TEVENT_FD_READ, fd_input_available, watch);
- if (fde == NULL) {
+ watch->fde = tevent_add_fd(ctx->ev_ctx, watch, s, flags,
+ fd_input_available, watch);
+ if (watch->fde == NULL) {
DEBUG(1, ("tevent_add_fd() failed\n"));
talloc_free(watch);
return;