From 9b93fb29b1c41d523da87cdf7be226cc8322df66 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 3 Nov 2009 16:24:25 +0100 Subject: Change ares usage to be c-ares 1.7.0 compatible * Rename structure accordingly to ares upstream * Use new ares parsing functions in the wrappers * fix tests for ares 1.7 --- server/resolv/async_resolv.c | 157 ++++++++++++++++++++++++------------------- server/resolv/async_resolv.h | 6 +- server/tests/resolv-tests.c | 26 ++++--- 3 files changed, 102 insertions(+), 87 deletions(-) diff --git a/server/resolv/async_resolv.c b/server/resolv/async_resolv.c index 6ac5e41ff..be2107a22 100644 --- a/server/resolv/async_resolv.c +++ b/server/resolv/async_resolv.c @@ -43,13 +43,13 @@ #include "util/util.h" #ifndef HAVE_ARES_PARSE_SRV -#define ares_parse_srv_reply(abuf, alen, srv_out, nsrvreply) \ - _ares_parse_srv_reply(abuf, alen, srv_out, nsrvreply) +#define ares_parse_srv_reply(abuf, alen, srv_out) \ + _ares_parse_srv_reply(abuf, alen, srv_out) #endif /* HAVE_ARES_PARSE_SRV */ #ifndef HAVE_ARES_PARSE_TXT -#define ares_parse_txt_reply(abuf, alen, txt_out, ntxtreply) \ - _ares_parse_txt_reply(abuf, alen, txt_out, ntxtreply) +#define ares_parse_txt_reply(abuf, alen, txt_out) \ + _ares_parse_txt_reply(abuf, alen, txt_out) #endif /* HAVE_ARES_PARSE_TXT */ struct fd_watch { @@ -442,40 +442,57 @@ ares_gethostbyname_wakeup(struct tevent_req *subreq) } /* - * A simple helper function that will take an array of struct srv_reply that + * A simple helper function that will take an array of struct ares_srv_reply that * was allocated by malloc() in c-ares and copies it using talloc. The old one * is freed and the talloc one is put into 'reply_list' instead. */ static int -rewrite_talloc_srv_reply(TALLOC_CTX *mem_ctx, struct srv_reply **reply_list, - int num_replies) +rewrite_talloc_srv_reply(TALLOC_CTX *mem_ctx, struct ares_srv_reply **reply_list) { - int i; - struct srv_reply *new_list; - struct srv_reply *old_list = *reply_list; + struct ares_srv_reply *ptr = NULL; + struct ares_srv_reply *new_list = NULL; + struct ares_srv_reply *old_list = *reply_list; - new_list = talloc_array(mem_ctx, struct srv_reply, num_replies); - if (new_list == NULL) { - return ENOMEM; + /* Nothing to do, but not an error */ + if (!old_list) { + return EOK; } - /* Copy the new_list array. */ - for (i = 0; i < num_replies; i++) { - new_list[i].weight = old_list[i].weight; - new_list[i].priority = old_list[i].priority; - new_list[i].port = old_list[i].port; - new_list[i].host = talloc_strdup(new_list, old_list[i].host); - if (new_list[i].host == NULL) { + /* Copy the linked list */ + while (old_list) { + /* Special case for the first node */ + if (!new_list) { + new_list = talloc_zero(mem_ctx, struct ares_srv_reply); + if (new_list == NULL) { + ares_free_data(*reply_list); + return ENOMEM; + } + ptr = new_list; + } else { + ptr->next = talloc_zero(new_list, struct ares_srv_reply); + if (ptr->next == NULL) { + ares_free_data(*reply_list); + talloc_free(new_list); + return ENOMEM; + } + ptr = ptr->next; + } + + ptr->weight = old_list->weight; + ptr->priority = old_list->priority; + ptr->port = old_list->port; + ptr->host = talloc_strdup(ptr, old_list->host); + if (ptr->host == NULL) { + ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } + + old_list = old_list->next; } /* Free the old one (uses malloc). */ - for (i = 0; i < num_replies; i++) { - free(old_list[i].host); - } - free(old_list); + ares_free_data(*reply_list); /* And now put our own new_list in place. */ *reply_list = new_list; @@ -493,8 +510,7 @@ struct getsrv_state { const char *query; /* parsed data returned by ares */ - struct srv_reply *reply_list; - int num_replies; + struct ares_srv_reply *reply_list; int status; int timeouts; }; @@ -522,7 +538,6 @@ resolv_getsrv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, state->resolv_ctx = ctx; state->query = query; state->reply_list = NULL; - state->num_replies = 0; state->status = 0; state->timeouts = 0; @@ -543,8 +558,7 @@ resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int struct tevent_req *req = talloc_get_type(arg, struct tevent_req); struct getsrv_state *state = tevent_req_data(req, struct getsrv_state); int ret; - int num_replies; - struct srv_reply *reply_list; + struct ares_srv_reply *reply_list; state->status = status; state->timeouts = timeouts; @@ -555,32 +569,29 @@ resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int goto fail; } - ret = ares_parse_srv_reply(abuf, alen, &reply_list, &num_replies); + ret = ares_parse_srv_reply(abuf, alen, &reply_list); if (status != ARES_SUCCESS) { DEBUG(2, ("SRV record parsing failed: %d: %s\n", ret, ares_strerror(ret))); ret = return_code(ret); goto fail; } - ret = rewrite_talloc_srv_reply(req, &reply_list, num_replies); + ret = rewrite_talloc_srv_reply(req, &reply_list); if (ret != EOK) { goto fail; } state->reply_list = reply_list; - state->num_replies = num_replies; tevent_req_done(req); return; fail: state->reply_list = NULL; - state->num_replies = 0; tevent_req_error(req, ret); } int resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, - int *timeouts, struct srv_reply **reply_list, - int *num_replies) + int *timeouts, struct ares_srv_reply **reply_list) { struct getsrv_state *state = tevent_req_data(req, struct getsrv_state); @@ -590,8 +601,6 @@ resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, *timeouts = state->timeouts; if (reply_list) *reply_list = talloc_steal(mem_ctx, state->reply_list); - if (num_replies) - *num_replies = state->num_replies; TEVENT_REQ_RETURN_ON_ERROR(req); @@ -627,34 +636,52 @@ ares_getsrv_wakeup(struct tevent_req *subreq) * is freed and the talloc one is put into 'reply_list' instead. */ static int -rewrite_talloc_txt_reply(TALLOC_CTX *mem_ctx, struct txt_reply **reply_list, - int num_replies) +rewrite_talloc_txt_reply(TALLOC_CTX *mem_ctx, struct ares_txt_reply **reply_list) { - int i; - struct txt_reply *new_list; - struct txt_reply *old_list = *reply_list; + struct ares_txt_reply *ptr = NULL; + struct ares_txt_reply *new_list = NULL; + struct ares_txt_reply *old_list = *reply_list; - new_list = talloc_array(mem_ctx, struct txt_reply, num_replies); - if (new_list == NULL) { - return ENOMEM; + /* Nothing to do, but not an error */ + if (!old_list) { + return EOK; } - /* Copy the new_list array. */ - for (i = 0; i < num_replies; i++) { - new_list[i].length = old_list[i].length; - new_list[i].txt = talloc_memdup(new_list, old_list[i].txt, - old_list[i].length); - if (new_list[i].txt == NULL) { + /* Copy the linked list */ + while (old_list) { + + /* Special case for the first node */ + if (!new_list) { + new_list = talloc_zero(mem_ctx, struct ares_txt_reply); + if (new_list == NULL) { + ares_free_data(*reply_list); + talloc_free(new_list); + return ENOMEM; + } + ptr = new_list; + } else { + ptr->next = talloc_zero(new_list, struct ares_txt_reply); + if (ptr->next == NULL) { + ares_free_data(*reply_list); + talloc_free(new_list); + return ENOMEM; + } + ptr = ptr->next; + } + + ptr->length = old_list->length; + ptr->txt = talloc_memdup(ptr, old_list->txt, + old_list->length); + if (ptr->txt == NULL) { + ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } - } - /* Free the old one (uses malloc). */ - for (i = 0; i < num_replies; i++) { - free(old_list[i].txt); + old_list = old_list->next; } - free(old_list); + + ares_free_data(*reply_list); /* And now put our own new_list in place. */ *reply_list = new_list; @@ -672,8 +699,7 @@ struct gettxt_state { const char *query; /* parsed data returned by ares */ - struct txt_reply *reply_list; - int num_replies; + struct ares_txt_reply *reply_list; int status; int timeouts; }; @@ -701,7 +727,6 @@ resolv_gettxt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, state->resolv_ctx = ctx; state->query = query; state->reply_list = NULL; - state->num_replies = 0; state->status = 0; state->timeouts = 0; @@ -723,8 +748,7 @@ resolv_gettxt_done(void *arg, int status, int timeouts, unsigned char *abuf, int struct tevent_req *req = talloc_get_type(arg, struct tevent_req); struct gettxt_state *state = tevent_req_data(req, struct gettxt_state); int ret; - int num_replies; - struct txt_reply *reply_list; + struct ares_txt_reply *reply_list; state->status = status; state->timeouts = timeouts; @@ -734,32 +758,29 @@ resolv_gettxt_done(void *arg, int status, int timeouts, unsigned char *abuf, int goto fail; } - ret = ares_parse_txt_reply(abuf, alen, &reply_list, &num_replies); + ret = ares_parse_txt_reply(abuf, alen, &reply_list); if (status != ARES_SUCCESS) { DEBUG(2, ("TXT record parsing failed: %d: %s\n", ret, ares_strerror(ret))); ret = return_code(ret); goto fail; } - ret = rewrite_talloc_txt_reply(req, &reply_list, num_replies); + ret = rewrite_talloc_txt_reply(req, &reply_list); if (ret != EOK) { goto fail; } state->reply_list = reply_list; - state->num_replies = num_replies; tevent_req_done(req); return; fail: state->reply_list = NULL; - state->num_replies = 0; tevent_req_error(req, ret); } int resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, - int *timeouts, struct txt_reply **reply_list, - int *num_replies) + int *timeouts, struct ares_txt_reply **reply_list) { struct gettxt_state *state = tevent_req_data(req, struct gettxt_state); @@ -769,8 +790,6 @@ resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, *timeouts = state->timeouts; if (reply_list) *reply_list = talloc_steal(mem_ctx, state->reply_list); - if (num_replies) - *num_replies = state->num_replies; TEVENT_REQ_RETURN_ON_ERROR(req); diff --git a/server/resolv/async_resolv.h b/server/resolv/async_resolv.h index 702d4dd7b..9d080ec69 100644 --- a/server/resolv/async_resolv.h +++ b/server/resolv/async_resolv.h @@ -77,8 +77,7 @@ int resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, - struct srv_reply **reply_list, - int *num_replies); + struct ares_srv_reply **reply_list); /** Get TXT record **/ struct tevent_req *resolv_gettxt_send(TALLOC_CTX *mem_ctx, @@ -90,7 +89,6 @@ int resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, - struct txt_reply **reply_list, - int *num_replies); + struct ares_txt_reply **reply_list); #endif /* __ASYNC_RESOLV_H__ */ diff --git a/server/tests/resolv-tests.c b/server/tests/resolv-tests.c index bf76849a0..d6b8c4f38 100644 --- a/server/tests/resolv-tests.c +++ b/server/tests/resolv-tests.c @@ -253,15 +253,13 @@ END_TEST static void test_internet(struct tevent_req *req) { - int i; int recv_status; int status; struct resolv_test_ctx *test_ctx; void *tmp_ctx; struct hostent *hostent = NULL; - struct txt_reply *txt_replies = NULL; - struct srv_reply *srv_replies = NULL; - int count; + struct ares_txt_reply *txt_replies = NULL, *txtptr; + struct ares_srv_reply *srv_replies = NULL, *srvptr; test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); @@ -278,20 +276,20 @@ static void test_internet(struct tevent_req *req) break; case TESTING_TXT: recv_status = resolv_gettxt_recv(tmp_ctx, req, &status, NULL, - &txt_replies, &count); - test_ctx->error = (count == 0) ? ENOENT : EOK; - for (i = 0; i < count; i++) { - DEBUG(2, ("TXT Record: %s\n", txt_replies[i].txt)); + &txt_replies); + test_ctx->error = (txt_replies == NULL) ? ENOENT : EOK; + for (txtptr = txt_replies; txtptr != NULL; txtptr = txtptr->next) { + DEBUG(2, ("TXT Record: %s\n", txtptr->txt)); } break; case TESTING_SRV: recv_status = resolv_getsrv_recv(tmp_ctx, req, &status, NULL, - &srv_replies, &count); - test_ctx->error = (count == 0) ? ENOENT : EOK; - for (i = 0; i < count; i++) { - DEBUG(2, ("SRV Record: %d %d %d %s\n", srv_replies[i].weight, - srv_replies[i].priority, srv_replies[i].port, - srv_replies[i].host)); + &srv_replies); + test_ctx->error = (srv_replies == NULL) ? ENOENT : EOK; + for (srvptr = srv_replies; srvptr != NULL; srvptr = srvptr->next) { + DEBUG(2, ("SRV Record: %d %d %d %s\n", srvptr->weight, + srvptr->priority, srvptr->port, + srvptr->host)); } break; } -- cgit