zos: track unbound handles and bind before listen
On zOS the listen call does not bind automatically if the socket is unbound. Hence the manual binding to an arbitrary port is required to be done manually. PR-URL: https://github.com/libuv/libuv/pull/949 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
e37f25d776
commit
f4ef897666
@ -132,7 +132,8 @@ enum {
|
||||
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
|
||||
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
|
||||
UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */
|
||||
UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */
|
||||
UV_UDP_PROCESSING = 0x20000, /* Handle is running the send callback queue. */
|
||||
UV_HANDLE_BOUND = 0x40000 /* Handle is bound to an address and port */
|
||||
};
|
||||
|
||||
/* loop flags */
|
||||
|
||||
@ -80,6 +80,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
handle->flags |= UV_HANDLE_BOUND;
|
||||
handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
|
||||
handle->io_watcher.fd = sockfd;
|
||||
return 0;
|
||||
|
||||
@ -604,6 +604,8 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
done:
|
||||
/* Process queued fds */
|
||||
if (server->queued_fds != NULL) {
|
||||
|
||||
@ -134,6 +134,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
|
||||
}
|
||||
tcp->delayed_error = -errno;
|
||||
|
||||
tcp->flags |= UV_HANDLE_BOUND;
|
||||
if (addr->sa_family == AF_INET6)
|
||||
tcp->flags |= UV_HANDLE_IPV6;
|
||||
|
||||
@ -276,10 +277,32 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#ifdef __MVS__
|
||||
/* on zOS the listen call does not bind automatically
|
||||
if the socket is unbound. Hence the manual binding to
|
||||
an arbitrary port is required to be done manually
|
||||
*/
|
||||
|
||||
if (!(tcp->flags & UV_HANDLE_BOUND)) {
|
||||
struct sockaddr_storage saddr;
|
||||
socklen_t slen = sizeof(saddr);
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
|
||||
if (getsockname(tcp->io_watcher.fd, (struct sockaddr*) &saddr, &slen))
|
||||
return -errno;
|
||||
|
||||
if (bind(tcp->io_watcher.fd, (struct sockaddr*) &saddr, slen))
|
||||
return -errno;
|
||||
|
||||
tcp->flags |= UV_HANDLE_BOUND;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (listen(tcp->io_watcher.fd, backlog))
|
||||
return -errno;
|
||||
|
||||
tcp->connection_cb = cb;
|
||||
tcp->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
/* Start listening for connections. */
|
||||
tcp->io_watcher.cb = uv__server_io;
|
||||
|
||||
@ -335,6 +335,8 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
if (addr->sa_family == AF_INET6)
|
||||
handle->flags |= UV_HANDLE_IPV6;
|
||||
|
||||
handle->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user