From 5b7b47f01568200f5064ca4b48457edb5ccc3109 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 26 Apr 2009 00:01:43 +0200 Subject: [PATCH] Add getaddrinfo_send/recv --- source3/include/proto.h | 7 ++ source3/lib/util_sock.c | 82 ++++++++++++++++++++++ source3/script/tests/test_smbtorture_s3.sh | 1 + source3/torture/torture.c | 55 +++++++++++++++ 4 files changed, 145 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9aa92659740..936a724ac50 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1418,6 +1418,13 @@ struct tevent_req *read_smb_send(TALLOC_CTX *mem_ctx, int fd); ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **pbuf, int *perrno); +struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct fncall_context *ctx, + const char *node, + const char *service, + const struct addrinfo *hints); +int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res); /* The following definitions come from lib/util_str.c */ diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index cbd7b983c71..3fd0cc4ad31 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2053,3 +2053,85 @@ ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, *pbuf = talloc_move(mem_ctx, &state->buf); return talloc_get_size(*pbuf); } + +struct getaddrinfo_state { + const char *node; + const char *service; + const struct addrinfo *hints; + struct addrinfo *res; + int ret; +}; + +static void getaddrinfo_do(void *private_data); +static void getaddrinfo_done(struct tevent_req *subreq); + +struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct fncall_context *ctx, + const char *node, + const char *service, + const struct addrinfo *hints) +{ + struct tevent_req *req, *subreq; + struct getaddrinfo_state *state; + + req = tevent_req_create(mem_ctx, &state, struct getaddrinfo_state); + if (req == NULL) { + return NULL; + } + + state->node = node; + state->service = service; + state->hints = hints; + + subreq = fncall_send(state, ev, ctx, getaddrinfo_do, state); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, getaddrinfo_done, req); + return req; +} + +static void getaddrinfo_do(void *private_data) +{ + struct getaddrinfo_state *state = + (struct getaddrinfo_state *)private_data; + + state->ret = getaddrinfo(state->node, state->service, state->hints, + &state->res); +} + +static void getaddrinfo_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + int ret, err; + + ret = fncall_recv(subreq, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_error(req, err); + return; + } + tevent_req_done(req); +} + +int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res) +{ + struct getaddrinfo_state *state = tevent_req_data( + req, struct getaddrinfo_state); + int err; + + if (tevent_req_is_unix_error(req, &err)) { + switch(err) { + case ENOMEM: + return EAI_MEMORY; + default: + return EAI_FAIL; + } + } + if (state->ret == 0) { + *res = state->res; + } + return state->ret; +} diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 70c6d34c885..624e968f7bf 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -28,6 +28,7 @@ tests="$tests OPLOCK1 OPLOCK2 OPLOCK3" tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3" tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K" tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1" +tests="$tests GETADDRINFO" skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN" skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 4689d8ff55d..50bfa61c557 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5628,6 +5628,60 @@ static bool run_local_wbclient(int dummy) return result; } +static void getaddrinfo_finished(struct tevent_req *req) +{ + char *name = (char *)tevent_req_callback_data_void(req); + struct addrinfo *ainfo; + int res; + + res = getaddrinfo_recv(req, &ainfo); + if (res != 0) { + d_printf("gai(%s) returned %s\n", name, gai_strerror(res)); + return; + } + d_printf("gai(%s) succeeded\n", name); + freeaddrinfo(ainfo); +} + +static bool run_getaddrinfo_send(int dummy) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct fncall_context *ctx; + struct tevent_context *ev; + bool result = false; + const char *names[4] = { "www.samba.org", "notfound.samba.org", + "www.slashdot.org", "heise.de" }; + struct tevent_req *reqs[4]; + int i; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + ctx = fncall_context_init(frame, 4); + + for (i=0; i