Add getaddrinfo_send/recv
authorVolker Lendecke <vl@samba.org>
Sat, 25 Apr 2009 22:01:43 +0000 (00:01 +0200)
committerVolker Lendecke <vl@samba.org>
Fri, 1 May 2009 10:30:59 +0000 (12:30 +0200)
source3/include/proto.h
source3/lib/util_sock.c
source3/script/tests/test_smbtorture_s3.sh
source3/torture/torture.c

index 9aa9265974046786dfa5e9f54f68e2be63e28de1..936a724ac500285d60badfe2173786943d798722 100644 (file)
@@ -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  */
 
index cbd7b983c71486e5ee8ee2966e2129dd24e54204..3fd0cc4ad31c83a0fe94ffecc9e2bbe94302b6fc 100644 (file)
@@ -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;
+}
index 70c6d34c88566fb00744dd260d3d04e374fc2a8d..624e968f7bf19fee0eac1af88cf27b40cd36530c 100755 (executable)
@@ -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"
index 4689d8ff55d0e2519409b9005abd26ea0ca0f20b..50bfa61c55794380058312601cc2b638b8ba9069 100644 (file)
@@ -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},