diff options
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/lib/util_sock.c | 82 | ||||
-rwxr-xr-x | source3/script/tests/test_smbtorture_s3.sh | 1 | ||||
-rw-r--r-- | source3/torture/torture.c | 55 |
4 files changed, 145 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 9aa9265974..936a724ac5 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 cbd7b983c7..3fd0cc4ad3 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 70c6d34c88..624e968f7b 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 4689d8ff55..50bfa61c55 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<ARRAY_SIZE(names); i++) { + reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL, + NULL); + if (reqs[i] == NULL) { + goto fail; + } + tevent_req_set_callback(reqs[i], getaddrinfo_finished, + names[i]); + } + + for (i=0; i<ARRAY_SIZE(reqs); i++) { + tevent_loop_once(ev); + } + + result = true; +fail: + TALLOC_FREE(frame); + return result; +} + + static double create_procs(bool (*fn)(int), bool *result) { int i, status; @@ -5785,6 +5839,7 @@ static struct { { "CHAIN1", run_chain1, 0}, { "WINDOWS-WRITE", run_windows_write, 0}, { "CLI_ECHO", run_cli_echo, 0}, + { "GETADDRINFO", run_getaddrinfo_send, 0}, { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, { "LOCAL-GENCACHE", run_local_gencache, 0}, { "LOCAL-RBTREE", run_local_rbtree, 0}, |