diff options
author | Martin Schwenke <martin@meltin.net> | 2020-01-28 16:49:14 +1100 |
---|---|---|
committer | Amitay Isaacs <amitay@samba.org> | 2020-02-12 03:11:39 +0000 |
commit | a40fc709cc972dadb40efbf1394b10fae3cfcc07 (patch) | |
tree | 910cbc279469d59216b769a50b194779dd32cdf2 /ctdb | |
parent | ad78496664c1f613237539983b0a30b4cd94737a (diff) | |
download | samba-a40fc709cc972dadb40efbf1394b10fae3cfcc07.tar.gz |
ctdb-tcp: Make error handling for outbound connection consistent
If we can't bind the local end of an outgoing connection then
something has gone wrong. Retrying is better than failing into a
zombie state. The interface might come back up and/or the address my
be reconfigured.
While here, do the same thing for the other (potentially transient)
failures.
The unknown address family failure is special but just handle it via a
retry. Technically it can't happen because the node address parsing
can only return values with address family AF_INET or AF_INET6.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14274
Reported-by: 耿纪超 <gengjichao@jd.com>
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/tcp/tcp_connect.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c index f54086fcd3c..559442f14bf 100644 --- a/ctdb/tcp/tcp_connect.c +++ b/ctdb/tcp/tcp_connect.c @@ -181,16 +181,14 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te, tnode->out_fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); if (tnode->out_fd == -1) { DBG_ERR("Failed to create socket\n"); - return; + goto failed; } ret = set_blocking(tnode->out_fd, false); if (ret != 0) { DBG_ERR("Failed to set socket non-blocking (%s)\n", strerror(errno)); - close(tnode->out_fd); - tnode->out_fd = -1; - return; + goto failed; } set_close_on_exec(tnode->out_fd); @@ -222,32 +220,22 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te, sockout_size = sizeof(sock_out.ip6); break; default: - DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n", - sock_in.sa.sa_family)); - close(tnode->out_fd); - tnode->out_fd = -1; - return; + DBG_ERR("Unknown address family %u\n", sock_in.sa.sa_family); + /* Can't happen to due to address parsing restrictions */ + goto failed; } ret = bind(tnode->out_fd, (struct sockaddr *)&sock_in, sockin_size); if (ret == -1) { DBG_ERR("Failed to bind socket (%s)\n", strerror(errno)); - close(tnode->out_fd); - tnode->out_fd = -1; - return; + goto failed; } ret = connect(tnode->out_fd, (struct sockaddr *)&sock_out, sockout_size); if (ret != 0 && errno != EINPROGRESS) { - ctdb_tcp_stop_connection(node); - tnode->connect_te = tevent_add_timer(ctdb->ev, - tnode, - timeval_current_ofs(1, 0), - ctdb_tcp_node_connect, - node); - return; + goto failed; } /* non-blocking connect - wait for write event */ @@ -266,6 +254,16 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te, timeval_current_ofs(1, 0), ctdb_tcp_node_connect, node); + + return; + +failed: + ctdb_tcp_stop_connection(node); + tnode->connect_te = tevent_add_timer(ctdb->ev, + tnode, + timeval_current_ofs(1, 0), + ctdb_tcp_node_connect, + node); } /* |