summaryrefslogtreecommitdiff
path: root/source4/libcli/resolve/dns_ex.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-12-13 20:50:36 +0100
committerStefan Metzmacher <metze@samba.org>2008-12-17 20:26:38 +0100
commit7d0e78a52cfed797100696725611655227cf01ac (patch)
tree27a53cf8c534b559290720533e8984b278a2c988 /source4/libcli/resolve/dns_ex.c
parent937fdb8a7e348103708adbdafcff28b05cc1fda3 (diff)
downloadsamba-7d0e78a52cfed797100696725611655227cf01ac.tar.gz
samba-7d0e78a52cfed797100696725611655227cf01ac.tar.bz2
samba-7d0e78a52cfed797100696725611655227cf01ac.zip
s4:libcli/resolve: optionally return the name that belongs to the returned address
E.g. this helps for DNS CNAME and SRV results. metze
Diffstat (limited to 'source4/libcli/resolve/dns_ex.c')
-rw-r--r--source4/libcli/resolve/dns_ex.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c
index 36d7269be4..cfe4531654 100644
--- a/source4/libcli/resolve/dns_ex.c
+++ b/source4/libcli/resolve/dns_ex.c
@@ -46,6 +46,7 @@ struct dns_ex_state {
uint32_t flags;
struct nbt_name name;
struct socket_address **addrs;
+ char **names;
pid_t child;
int child_fd;
struct fd_event *fde;
@@ -231,10 +232,11 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
if (!addrs_rr[i]) {
continue;
}
- addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u",
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
first?"":",",
inet_ntoa(*addrs_rr[i]->u.a),
- srv_rr[i]?srv_rr[i]->u.srv->port:0);
+ srv_rr[i]?srv_rr[i]->u.srv->port:0,
+ addrs_rr[i]->domain);
if (!addrs) {
goto done;
}
@@ -289,10 +291,10 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd)
}
in = (struct sockaddr_in *)res->ai_addr;
- addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u",
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
first?"":",",
inet_ntoa(in->sin_addr),
- 0);
+ 0, state->name.name);
if (!addrs) {
goto done;
}
@@ -318,21 +320,31 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
struct composite_context *c = talloc_get_type(private_data, struct composite_context);
struct dns_ex_state *state = talloc_get_type(c->private_data,
struct dns_ex_state);
- char address[2048];
+ char *address;
uint32_t num_addrs, i;
char **addrs;
int ret;
int status;
+ int value = 0;
/* if we get any event from the child then we know that we
won't need to kill it off */
talloc_set_destructor(state, NULL);
- /* yes, we don't care about EAGAIN or other niceities
- here. They just can't happen with this parent/child
- relationship, and even if they did then giving an error is
- the right thing to do */
- ret = read(state->child_fd, address, sizeof(address)-1);
+ if (ioctl(state->child_fd, FIONREAD, &value) != 0) {
+ value = 8192;
+ }
+
+ address = talloc_array(state, char, value+1);
+ if (address) {
+ /* yes, we don't care about EAGAIN or other niceities
+ here. They just can't happen with this parent/child
+ relationship, and even if they did then giving an error is
+ the right thing to do */
+ ret = read(state->child_fd, address, value);
+ } else {
+ ret = -1;
+ }
close(state->child_fd);
if (waitpid(state->child, &status, WNOHANG) == 0) {
kill(state->child, SIGKILL);
@@ -356,9 +368,13 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
num_addrs+1);
if (composite_nomem(state->addrs, c)) return;
+ state->names = talloc_array(state, char *, num_addrs+1);
+ if (composite_nomem(state->names, c)) return;
+
for (i=0; i < num_addrs; i++) {
uint32_t port = 0;
char *p = strrchr(addrs[i], ':');
+ char *n;
if (!p) {
composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -368,6 +384,15 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
*p = '\0';
p++;
+ n = strrchr(p, '/');
+ if (!n) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ *n = '\0';
+ n++;
+
if (strcmp(addrs[i], "0.0.0.0") == 0 ||
inet_addr(addrs[i]) == INADDR_NONE) {
composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -382,8 +407,12 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
addrs[i],
port);
if (composite_nomem(state->addrs[i], c)) return;
+
+ state->names[i] = talloc_strdup(state->names, n);
+ if (composite_nomem(state->names[i], c)) return;
}
state->addrs[i] = NULL;
+ state->names[i] = NULL;
composite_done(c);
}
@@ -470,7 +499,8 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -480,6 +510,9 @@ NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
struct dns_ex_state *state = talloc_get_type(c->private_data,
struct dns_ex_state);
*addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
}
talloc_free(c);