summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/async_req/async_sock.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index d7f31768ef..fe71b29117 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -167,6 +167,8 @@ struct async_connect_state {
int result;
int sys_errno;
long old_sockflags;
+ socklen_t address_len;
+ struct sockaddr_storage address;
};
static void async_connect_connected(struct tevent_context *ev,
@@ -209,6 +211,13 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
state->fd = fd;
state->sys_errno = 0;
+ state->address_len = address_len;
+ if (address_len > sizeof(state->address)) {
+ errno = EINVAL;
+ goto post_errno;
+ }
+ memcpy(&state->address, address, address_len);
+
state->old_sockflags = fcntl(fd, F_GETFL, 0);
if (state->old_sockflags == -1) {
goto post_errno;
@@ -270,8 +279,6 @@ static void async_connect_connected(struct tevent_context *ev,
struct async_connect_state *state =
tevent_req_data(req, struct async_connect_state);
- TALLOC_FREE(fde);
-
/*
* Stevens, Network Programming says that if there's a
* successful connect, the socket is only writable. Upon an
@@ -279,20 +286,23 @@ static void async_connect_connected(struct tevent_context *ev,
*/
if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE))
== (TEVENT_FD_READ|TEVENT_FD_WRITE)) {
- int sockerr;
- socklen_t err_len = sizeof(sockerr);
-
- if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
- (void *)&sockerr, &err_len) == 0) {
- errno = sockerr;
+ int ret;
+
+ ret = connect(state->fd,
+ (struct sockaddr *)(void *)&state->address,
+ state->address_len);
+ if (ret == 0) {
+ TALLOC_FREE(fde);
+ tevent_req_done(req);
+ return;
}
- state->sys_errno = errno;
-
- DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
- fcntl(state->fd, F_SETFL, state->old_sockflags);
- tevent_req_error(req, state->sys_errno);
+ if (errno == EINPROGRESS) {
+ /* Try again later, leave the fde around */
+ return;
+ }
+ TALLOC_FREE(fde);
+ tevent_req_error(req, errno);
return;
}