1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00

s3:lib: avoid calling async_connect_send() again and again in open_socket_out*()

There's really no need to do that!

Once connect() is called and returned EINPROGRESS, the kernel
knowns what to do and reports any state change via
TEVENT_FD_READ or TEVENT_FD_WRITE.
The actual success or failure is available via
getsockopt(.., SOL_SOCKET, SO_ERROR, ...).

Before this commit we called connect() (via async_connect_send()) again
and again until we reached the final caller provided timeout,
even if the kernel already found out that the destination is
unreachable.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2020-02-26 13:36:05 +01:00 committed by Jeremy Allison
parent d48fba7c09
commit a26be7eeed

View File

@ -417,7 +417,6 @@ struct open_socket_out_state {
struct sockaddr_storage ss;
socklen_t salen;
uint16_t port;
int wait_usec;
struct tevent_req *connect_subreq;
};
@ -471,7 +470,6 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->ss = *pss;
state->port = port;
state->wait_usec = 10000;
state->salen = -1;
state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
@ -522,12 +520,6 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(state->connect_subreq, NULL)) {
return tevent_req_post(req, ev);
}
if (!tevent_req_set_endtime(
state->connect_subreq, state->ev,
timeval_current_ofs(0, state->wait_usec))) {
tevent_req_oom(req);
return tevent_req_post(req, ev);
}
tevent_req_set_callback(state->connect_subreq,
open_socket_out_connected, req);
return req;
@ -550,46 +542,6 @@ static void open_socket_out_connected(struct tevent_req *subreq)
return;
}
if (
#ifdef ETIMEDOUT
(sys_errno == ETIMEDOUT) ||
#endif
(sys_errno == EINPROGRESS) ||
(sys_errno == EALREADY) ||
(sys_errno == EAGAIN)) {
/*
* retry
*/
if (state->wait_usec < 250000) {
state->wait_usec *= 1.5;
}
subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss,
state->salen, NULL, NULL, NULL);
if (tevent_req_nomem(subreq, req)) {
return;
}
if (!tevent_req_set_endtime(
subreq, state->ev,
timeval_current_ofs_usec(state->wait_usec))) {
return;
}
state->connect_subreq = subreq;
tevent_req_set_callback(subreq, open_socket_out_connected, req);
return;
}
#ifdef EISCONN
if (sys_errno == EISCONN) {
tevent_req_done(req);
return;
}
#endif
/* real error */
tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
}