summaryrefslogtreecommitdiff
path: root/lib/async_req
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2013-05-16 16:11:54 +0200
committerChristian Ambach <ambi@samba.org>2013-05-17 11:22:45 +0200
commitd67e614a07cbf143293436d380aba9a022c0e31b (patch)
tree8bbd6a2d278ee96a48761fa5083130080267e888 /lib/async_req
parent272a58afff69f52704bcc9a62947853b638420d5 (diff)
downloadsamba-d67e614a07cbf143293436d380aba9a022c0e31b.tar.gz
lib: Add before/after hooks to async_connect
This will facilitiate [un]become_root for smbd to connect safely to ctdbd. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Christian Ambach <ambi@samba.org>
Diffstat (limited to 'lib/async_req')
-rw-r--r--lib/async_req/async_sock.c35
-rw-r--r--lib/async_req/async_sock.h10
2 files changed, 37 insertions, 8 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index 9909bc6eb3a..59dde885921 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -217,6 +217,10 @@ struct async_connect_state {
long old_sockflags;
socklen_t address_len;
struct sockaddr_storage address;
+
+ void (*before_connect)(void *private_data);
+ void (*after_connect)(void *private_data);
+ void *private_data;
};
static void async_connect_connected(struct tevent_context *ev,
@@ -236,10 +240,12 @@ static void async_connect_connected(struct tevent_context *ev,
* connect in an async state. This will be reset when the request is finished.
*/
-struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len)
+struct tevent_req *async_connect_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
+ const struct sockaddr *address, socklen_t address_len,
+ void (*before_connect)(void *private_data),
+ void (*after_connect)(void *private_data),
+ void *private_data)
{
struct tevent_req *result;
struct async_connect_state *state;
@@ -258,6 +264,9 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
state->fd = fd;
state->sys_errno = 0;
+ state->before_connect = before_connect;
+ state->after_connect = after_connect;
+ state->private_data = private_data;
state->old_sockflags = fcntl(fd, F_GETFL, 0);
if (state->old_sockflags == -1) {
@@ -273,7 +282,16 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
set_blocking(fd, false);
+ if (state->before_connect != NULL) {
+ state->before_connect(state->private_data);
+ }
+
state->result = connect(fd, address, address_len);
+
+ if (state->after_connect != NULL) {
+ state->after_connect(state->private_data);
+ }
+
if (state->result == 0) {
tevent_req_done(result);
goto done;
@@ -328,8 +346,17 @@ static void async_connect_connected(struct tevent_context *ev,
tevent_req_data(req, struct async_connect_state);
int ret;
+ if (state->before_connect != NULL) {
+ state->before_connect(state->private_data);
+ }
+
ret = connect(state->fd, (struct sockaddr *)(void *)&state->address,
state->address_len);
+
+ if (state->after_connect != NULL) {
+ state->after_connect(state->private_data);
+ }
+
if (ret == 0) {
state->sys_errno = 0;
TALLOC_FREE(fde);
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index af917bcb836..494b92eb29f 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -40,10 +40,12 @@ struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
socklen_t *addr_len);
ssize_t recvfrom_recv(struct tevent_req *req, int *perrno);
-struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len);
+struct tevent_req *async_connect_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
+ const struct sockaddr *address, socklen_t address_len,
+ void (*before_connect)(void *private_data),
+ void (*after_connect)(void *private_data),
+ void *private_data);
int async_connect_recv(struct tevent_req *req, int *perrno);
struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,