/*****************************************************************************\
 *  slurm_protocol_socket.c - slurm socket handling functions
 *****************************************************************************
 *  Copyright (C) 2002-2007 The Regents of the University of California.
 *  Copyright (C) 2008-2010 Lawrence Livermore National Security.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Kevin Tew <tew1@llnl.gov>, et. al.
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#define _GNU_SOURCE

#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <unistd.h>

#include "slurm/slurm_errno.h"
#include "src/common/fd.h"
#include "src/common/log.h"
#include "src/common/net.h"
#include "src/common/read_config.h"
#include "src/common/slurm_protocol_api.h"
#include "src/common/slurm_protocol_socket.h"
#include "src/common/slurm_time.h"
#include "src/common/strlcpy.h"
#include "src/common/util-net.h"
#include "src/common/xmalloc.h"
#include "src/common/xsignal.h"
#include "src/common/xstring.h"

#include "src/interfaces/conn.h"

#define PORT_RETRIES    3
#define MIN_USER_PORT   (IPPORT_RESERVED + 1)
#define MAX_USER_PORT   0xffff
#define RANDOM_USER_PORT ((uint16_t) ((lrand48() % \
		(MAX_USER_PORT - MIN_USER_PORT + 1)) + MIN_USER_PORT))

/* Static functions */
static int _slurm_connect(int __fd, struct sockaddr const * __addr,
			  socklen_t __len);

/****************************************************************
 * MIDDLE LAYER MSG FUNCTIONS
 ****************************************************************/

/*
 * Pick a random port number to use. Use this if the system
 * selected port can't connect. This may indicate that the
 * port/address of both the client and server match a defunct
 * socket record in TIME_WAIT state.
 */
static void _sock_bind_wild(int sockfd)
{
	int rc, retry;
	slurm_addr_t sin;
	socklen_t blen;
	static bool seeded = false;

	if (!seeded) {
		seeded = true;
		srand48((long int) (time(NULL) + getpid()));
	}

	slurm_setup_addr(&sin, RANDOM_USER_PORT);

	for (retry=0; retry < PORT_RETRIES ; retry++) {
		blen = sockaddr_fixlen((struct sockaddr *) &sin,
				       (socklen_t) sizeof(sin));
		rc = bind(sockfd, (struct sockaddr *) &sin, blen);
		if (rc >= 0)
			break;
		slurm_set_port(&sin, RANDOM_USER_PORT);
	}
	return;
}

extern ssize_t slurm_msg_recvfrom_timeout(conn_t *conn, char **pbuf,
					  size_t *lenp, int timeout)
{
	ssize_t  len;
	uint32_t msglen;

	len = slurm_recv_timeout(conn, (char *) &msglen, sizeof(msglen),
				 timeout);

	if (len < ((ssize_t) sizeof(msglen)))
		return SLURM_ERROR;

	msglen = ntohl(msglen);

	if (msglen > MAX_MSG_SIZE)
		slurm_seterrno_ret(SLURM_PROTOCOL_INSANE_MSG_LENGTH);

	/*
	 *  Allocate memory on heap for message
	 */
	if (!(*pbuf = try_xmalloc(msglen)))
		slurm_seterrno_ret(ENOMEM);

	if (slurm_recv_timeout(conn, *pbuf, msglen, timeout) != msglen) {
		xfree(*pbuf);
		*pbuf = NULL;
		return SLURM_ERROR;
	}

	*lenp = msglen;

	return (ssize_t) msglen;
}

static int _writev_timeout(int fd, conn_t *conn, struct iovec *iov, int iovcnt,
			   int timeout)
{
	int tot_bytes_sent = 0;
	size_t size = 0;
	int fd_flags;
	struct pollfd ufds;
	struct timeval tstart;
	char temp[2];

	if (conn)
		fd = conn_g_get_fd(conn);

	ufds.fd     = fd;
	ufds.events = POLLOUT;

	fd_flags = fcntl(fd, F_GETFL);
	fd_set_nonblocking(fd);

	gettimeofday(&tstart, NULL);

	for (int i = 0; i < iovcnt; i++)
		size += iov[i].iov_len;

	while (true) {
		ssize_t bytes_sent = 0;
		int rc;
		int timeleft = timeout - timeval_tot_wait(&tstart);

		if (conn_g_peek(conn))
			goto ready;

		if (timeleft <= 0) {
			debug("%s at %d of %zu, timeout",
			      __func__, tot_bytes_sent, size);
			errno = SLURM_PROTOCOL_SOCKET_IMPL_TIMEOUT;
			tot_bytes_sent = SLURM_ERROR;
			break;
		}

		if ((rc = poll(&ufds, 1, timeleft)) <= 0) {
			if ((rc == 0) || (errno == EINTR) || (errno == EAGAIN))
 				continue;
			else {
				debug("%s at %d of %zu, poll error: %s",
				      __func__, tot_bytes_sent, size,
				      strerror(errno));
				errno = SLURM_COMMUNICATIONS_SEND_ERROR;
				tot_bytes_sent = SLURM_ERROR;
				break;
			}
		}

		/*
		 * Check here to make sure the socket really is there.
		 * If not then exit out and notify the sender.  This
 		 * is here since a write doesn't always tell you the
		 * socket is gone, but getting 0 back from a
		 * nonblocking read means just that.
		 */
		if (ufds.revents & POLLERR) {
			int e;

			if ((rc = fd_get_socket_error(fd, &e)))
				debug("%s: Socket POLLERR, fd_get_socket_error failed: %s",
				      __func__, slurm_strerror(rc));
			else
				debug("%s: Socket POLLERR: %s",
				      __func__, slurm_strerror(e));

			errno = e;
			tot_bytes_sent = SLURM_ERROR;
			break;
		}
		if ((ufds.revents & POLLHUP) || (ufds.revents & POLLNVAL) ||
		    (recv(fd, &temp, 1, 0) == 0)) {
			int so_err;
			if ((rc = fd_get_socket_error(fd, &so_err)))
				debug2("%s: Socket no longer there, fd_get_socket_error failed: %s",
				       __func__, slurm_strerror(rc));
			else
				debug2("%s: Socket no longer there: %s",
				       __func__, slurm_strerror(so_err));
			errno = so_err;
			tot_bytes_sent = SLURM_ERROR;
			break;
		}
		if ((ufds.revents & POLLOUT) != POLLOUT) {
			error("%s: Poll failure, revents:%d",
			      __func__, ufds.revents);
		}

ready:
		if (conn) {
			bytes_sent = conn_g_sendv(conn, iov, iovcnt);
		} else {
			bytes_sent = writev(fd, iov, iovcnt);
		}

		if (bytes_sent < 0) {
 			if (errno == EINTR)
				continue;

			log_flag(NET, "%s: [fd:%d] writev() sent %zd/%zu bytes failed: %m",
				 __func__, fd, bytes_sent, size);

			if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
				/* poll() lied to us */
				usleep(10000);
				continue;
			}
			errno = SLURM_COMMUNICATIONS_SEND_ERROR;
			tot_bytes_sent = SLURM_ERROR;
			break;
		}
		if (bytes_sent == 0) {
			/*
			 * If driver false reports POLLIN but then does not
			 * provide any output: try poll() again.
			 */
			log_flag(NET, "%s: [fd:%d] writev() sent zero bytes out of %d/%zu",
				 __func__, fd, tot_bytes_sent, size);
			continue;
		}

		tot_bytes_sent += bytes_sent;

		if (tot_bytes_sent >= size) {
			log_flag(NET, "%s: [fd:%d] writev() completed sending %d/%zu bytes",
				 __func__, fd, tot_bytes_sent, size);
			break;
		}

		/* partial write, need to adjust iovec before next call */
		for (int i = 0; i < iovcnt; i++) {
			if (bytes_sent < iov[i].iov_len) {
				iov[i].iov_base += bytes_sent;
				iov[i].iov_len -= bytes_sent;
				break;
			}

			bytes_sent -= iov[i].iov_len;
			iov[i].iov_base = NULL;
			iov[i].iov_len = 0;
		}
	}

	/* Reset fd flags to prior state, preserve errno */
	if (fd_flags != -1) {
		int slurm_err = errno;
		if (fcntl(fd, F_SETFL, fd_flags) < 0)
			error("%s: fcntl(F_SETFL) error: %m", __func__);
		errno = slurm_err;
	}

	return tot_bytes_sent;
}

/*
 * Send slurm message with timeout
 * RET message size (as specified in argument) or SLURM_ERROR on error
 */
extern int slurm_send_timeout(conn_t *conn, char *buf, size_t size, int timeout)
{
	struct iovec iov = { .iov_base = buf, .iov_len = size };
	return _writev_timeout(-1, conn, &iov, 1, timeout);
}

extern ssize_t slurm_msg_sendto(conn_t *conn, char *buffer, size_t size)
{
	struct iovec iov[2];
	uint32_t usize;
	int len;
	SigFunc *ohandler;
	int timeout = slurm_conf.msg_timeout * 1000;

	/*
	 *  Ignore SIGPIPE so that send can return a error code if the
	 *    other side closes the socket
	 */
	ohandler = xsignal(SIGPIPE, SIG_IGN);

	iov[0].iov_base = &usize;
	iov[0].iov_len = sizeof(usize);
	iov[1].iov_base = buffer;
	iov[1].iov_len = size;

	usize = htonl(iov[1].iov_len);

	len = _writev_timeout(-1, conn, iov, 2, timeout);

	xsignal(SIGPIPE, ohandler);

	/* Returned size should not include the 4-byte length header. */
	if (len < 0)
		return SLURM_ERROR;
	return size;
}

extern ssize_t slurm_msg_sendto_socket(int fd, char *buffer, size_t size)
{
	struct iovec iov[2];
	uint32_t usize;
	int len;
	SigFunc *ohandler;
	int timeout = slurm_conf.msg_timeout * 1000;

	/*
	 *  Ignore SIGPIPE so that send can return a error code if the
	 *    other side closes the socket
	 */
	ohandler = xsignal(SIGPIPE, SIG_IGN);

	iov[0].iov_base = &usize;
	iov[0].iov_len = sizeof(usize);
	iov[1].iov_base = buffer;
	iov[1].iov_len = size;

	usize = htonl(iov[1].iov_len);

	len = _writev_timeout(fd, NULL, iov, 2, timeout);

	xsignal(SIGPIPE, ohandler);

	/* Returned size should not include the 4-byte length header. */
	if (len < 0)
		return SLURM_ERROR;
	return size;
}

extern ssize_t slurm_bufs_sendto(conn_t *conn, msg_bufs_t *buffers)
{
	struct iovec iov[4];
	int len;
	uint32_t usize;
	SigFunc *ohandler;
	int timeout = slurm_conf.msg_timeout * 1000;

	xassert(buffers);

	/*
	 * Ignore SIGPIPE so that send can return a error code if the other
	 * side closes the socket
	 */
	ohandler = xsignal(SIGPIPE, SIG_IGN);

	/* auth portion is optional. header and body are mandatory. */
	iov[0].iov_base = &usize;
	iov[0].iov_len = sizeof(usize);
	iov[1].iov_base = get_buf_data(buffers->header);
	iov[1].iov_len = get_buf_offset(buffers->header);
	iov[2].iov_base = buffers->auth ? get_buf_data(buffers->auth) : NULL;
	iov[2].iov_len = buffers->auth ? get_buf_offset(buffers->auth) : 0;
	iov[3].iov_base = get_buf_data(buffers->body);
	iov[3].iov_len = get_buf_offset(buffers->body);

	usize = htonl(iov[1].iov_len + iov[2].iov_len + iov[3].iov_len);

	len = _writev_timeout(-1, conn, iov, 4, timeout);

	xsignal(SIGPIPE, ohandler);
	return len;
}

/* Get slurm message with timeout
 * RET message size (as specified in argument) or SLURM_ERROR on error */
extern int slurm_recv_timeout(conn_t *conn, char *buffer, size_t size,
			      int timeout)
{
	int fd = -1;
	int rc;
	int recvlen = 0;
	int fd_flags;
	struct pollfd  ufds;
	struct timeval tstart;
	int timeleft = timeout;

	fd = conn_g_get_fd(conn);

	ufds.fd     = fd;
	ufds.events = POLLIN;

	fd_flags = fcntl(fd, F_GETFL);
	fd_set_nonblocking(fd);

	gettimeofday(&tstart, NULL);

	while (recvlen < size) {
		timeleft = timeout - timeval_tot_wait(&tstart);
		if (timeleft <= 0) {
			debug("%s at %d of %zu, timeout", __func__, recvlen,
			      size);
			errno = SLURM_PROTOCOL_SOCKET_IMPL_TIMEOUT;
			recvlen = SLURM_ERROR;
			goto done;
		}

		if (conn_g_peek(conn))
			goto ready;

		if ((rc = poll(&ufds, 1, timeleft)) <= 0) {
			if ((errno == EINTR) || (errno == EAGAIN) || (rc == 0))
				continue;
			else {
				debug("%s at %d of %zu, poll error: %m",
				      __func__, recvlen, size);
				errno = SLURM_COMMUNICATIONS_RECEIVE_ERROR;
 				recvlen = SLURM_ERROR;
  				goto done;
			}
		}

		if (ufds.revents & POLLERR) {
			int e, rc;

			if ((rc = fd_get_socket_error(fd, &e)))
				debug("%s: Socket POLLERR: fd_get_socket_error failed: %s",
				      __func__, slurm_strerror(rc));
			else
				debug("%s: Socket POLLERR: %s",
				      __func__, slurm_strerror(e));

			errno = e;
			recvlen = SLURM_ERROR;
			goto done;
		}
		if ((ufds.revents & POLLNVAL) ||
		    ((ufds.revents & POLLHUP) &&
		     ((ufds.revents & POLLIN) == 0))) {
			int so_err, rc;
			if ((rc = fd_get_socket_error(fd, &so_err))) {
				debug2("%s: Socket no longer there: fd_get_socket_error failed: %s",
				       __func__, slurm_strerror(rc));
				errno = rc;
			} else {
				debug2("%s: Socket no longer there: %s",
				       __func__, slurm_strerror(so_err));
				errno = so_err;
			}
			recvlen = SLURM_ERROR;
			goto done;
		}
		if ((ufds.revents & POLLIN) != POLLIN) {
			error("%s: Poll failure, revents:%d",
			      __func__, ufds.revents);
			continue;
		}

ready:
		rc = conn_g_recv(conn, &buffer[recvlen], (size - recvlen));

		if (rc < 0)  {
			if ((errno == EINTR) || (errno == EAGAIN)) {
				log_flag(NET, "%s: recv(fd:%d) got %m. retrying.",
					 __func__, fd);
				continue;
			} else {
				debug("%s at %d of %zu, recv error: %m",
				      __func__, recvlen, size);
				errno = SLURM_COMMUNICATIONS_RECEIVE_ERROR;
				recvlen = SLURM_ERROR;
				goto done;
			}
		}
		if (rc == 0) {
			log_flag(NET, "%s: recv(fd:%d)=0 at %d/%zu bytes",
				 __func__, fd, recvlen, size);

			if (recvlen > 0)
				errno = ESLURM_PROTOCOL_INCOMPLETE_PACKET;
			else
				errno = SLURM_PROTOCOL_SOCKET_ZERO_BYTES_SENT;

			recvlen = SLURM_ERROR;
			goto done;
		}
		recvlen += rc;
	}


    done:
	/* Reset fd flags to prior state, preserve errno */
	if (fd_flags != -1) {
		int slurm_err = errno;
		if (fcntl(fd, F_SETFL, fd_flags) < 0)
			error("%s: fcntl(F_SETFL) error: %m", __func__);
		errno = slurm_err;
	}

	return recvlen;
}

extern int slurm_init_msg_engine(slurm_addr_t *addr, bool quiet)
{
	int rc;
	int fd;
	int log_lvl = LOG_LEVEL_ERROR;
	const int one = 1;
	const size_t sz1 = sizeof(one);
	socklen_t bind_len = sockaddr_fixlen((struct sockaddr *) addr,
					     (socklen_t) sizeof(*addr));

#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
/*
 * Fallback: if configure didn't detect any sockaddr length fields,
 * preserve the historical BSD workaround.
 */
#if !defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) && \
	!defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN) && \
	!defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
	if (addr->ss_family == AF_INET)
		((struct sockaddr_in *) addr)->sin_len =
			(uint8_t) sizeof(struct sockaddr_in);
	else if (addr->ss_family == AF_INET6)
		((struct sockaddr_in6 *) addr)->sin6_len =
			(uint8_t) sizeof(struct sockaddr_in6);
#endif
#endif
	if (quiet)
		log_lvl = LOG_LEVEL_DEBUG;

	if ((fd = socket(addr->ss_family, SOCK_STREAM | SOCK_CLOEXEC,
			 IPPROTO_TCP)) < 0) {
		format_print(log_lvl, "Error creating slurm stream socket: %m");
		return fd;
	}

	rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sz1);
	if (rc < 0) {
		format_print(log_lvl, "setsockopt SO_REUSEADDR failed: %m");
		goto error;
	}

	rc = bind(fd, (struct sockaddr const *) addr, bind_len);
	if (rc < 0) {
		format_print(log_lvl, "Error binding slurm stream socket: %m");
		goto error;
	}

	if (listen(fd, SLURM_DEFAULT_LISTEN_BACKLOG) < 0) {
		format_print(log_lvl,
			     "Error listening on slurm stream socket: %m");
		rc = SLURM_ERROR;
		goto error;
	}

	return fd;

error:
	(void) close(fd);
	return rc;
}

/* Await a connection on socket FD.
 * When a connection arrives, open a new socket to communicate with it,
 * set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
 * peer and *ADDR_LEN to the address's actual length, and return the
 * new socket's descriptor, or -1 for errors.  */
extern int slurm_accept_conn(int fd, slurm_addr_t *addr)
{
	socklen_t len = sizeof(*addr);
	int sock = accept4(fd, (struct sockaddr *) addr, &len, SOCK_CLOEXEC);
	net_set_nodelay(sock, true, NULL);
	return sock;
}

extern void *slurm_accept_msg_conn(int fd, slurm_addr_t *addr)
{
	int sock = -1;
	conn_t *conn = NULL;
	conn_args_t conn_args = {
		.mode = CONN_SERVER,
	};

	do {
		socklen_t len = sizeof(*addr);
		int err = SLURM_COMMUNICATIONS_RECEIVE_ERROR;

		if ((sock = accept4(fd, (struct sockaddr *) addr, &len,
				    SOCK_CLOEXEC)) >= 0) {
			log_flag(NET, "%s: [fd:%d] accept()ed: fd:%d -> %pA",
				 __func__, fd, sock, addr);
			break;
		}

		/* Preserve errno for caller */
		if (errno)
			err = errno;

		if (err == EINTR) {
			log_flag(NET, "%s: [fd:%d] retry accept4() due to interrupt: %s",
				 __func__, fd, slurm_strerror(err));
			continue;
		}

		error("%s: Unable to accept() connection to address %pA: %m",
		      __func__, addr);
		errno = err;
		return NULL;
	} while (true);

	conn_args.input_fd = conn_args.output_fd = sock;
	net_set_nodelay(sock, true, NULL);

	if (!(conn = conn_g_create(&conn_args))) {
		error("%s: Unable to create server TLS connection to address %pA: %m",
		      __func__, addr);
		(void) close(sock);
	}

	return conn;
}

extern int slurm_open_stream(slurm_addr_t *addr, bool retry)
{
	int retry_cnt = 0, ehostunreach_cnt = 0;
	int fd, rc = SLURM_SUCCESS;
	uint32_t sleep_ns = 500 * NSEC_IN_MSEC;
	slurm_addr_t tmp;
	socklen_t alen;

	if ((slurm_addr_is_unspec(addr)) || (slurm_get_port(addr) == 0)) {
		error("Error connecting, bad data: family = %u, port = %u",
		      addr->ss_family, slurm_get_port(addr));
		return SLURM_ERROR;
	}

	while (true) {
		fd = socket(addr->ss_family, SOCK_STREAM | SOCK_CLOEXEC,
			    IPPROTO_TCP);
		if (fd < 0) {
			error("Error creating slurm stream socket: %m");
			return SLURM_ERROR;
		}

		net_set_nodelay(fd, true, NULL);

		if (retry_cnt) {
			if (retry_cnt == 1) {
				debug3("Error connecting, "
				       "picking new stream port");
			}
			_sock_bind_wild(fd);
		}

		tmp = *addr;
		alen = sockaddr_fixlen((struct sockaddr *) &tmp,
				       (socklen_t) sizeof(tmp));
		rc = _slurm_connect(fd, (struct sockaddr const *) &tmp, alen);
		if (!rc) {
			/* success */
			break;
		}
		if (slurm_conf.host_unreach_retry_count &&
		    (rc == EHOSTUNREACH)) {
			if (ehostunreach_cnt >=
			    slurm_conf.host_unreach_retry_count) {
				debug2("Error connecting to %pA (%s), host_unreach_retry_count (%d) reached",
				       addr, strerror(rc),
				       slurm_conf.host_unreach_retry_count);
				goto error;
			}

			ehostunreach_cnt++;
			debug2("Error connecting to %pA (%s), trying again",
			       addr, strerror(rc));
			/*
			 * Assume issue was temporary network outage. Wait for
			 * a bit and hope it comes back.
			 */
			slurm_nanosleep(0, sleep_ns);
		} else if (((rc != ECONNREFUSED) && (rc != ETIMEDOUT)) ||
			   (!retry) || (retry_cnt >= PORT_RETRIES)) {
			goto error;
		} else {
			retry_cnt++;
		}

		(void) close(fd);
	}

	errno = rc;
	return fd;

error:
	debug2("Error connecting slurm stream socket at %pA: %s", addr,
	       strerror(rc));
	(void) close(fd);
	/* Always set errno as upstream callers expect it. */
	errno = rc;
	return SLURM_ERROR;
}

extern int slurm_open_unix_stream(char *addr_name, int sock_flags, int *fd)
{
	struct sockaddr_un sa;
	socklen_t slen;
	int rc;

	xassert(addr_name);

	if (strlen(addr_name) >= sizeof(sa.sun_path)) {
		rc = ESLURMD_INVALID_SOCKET_NAME_LEN;
		error("%s: [%s]: %s", __func__, addr_name, slurm_strerror(rc));
		return rc;
	}

	if ((*fd = socket(AF_UNIX, SOCK_STREAM | sock_flags, 0)) < 0) {
		rc = errno;
		error("%s: [%s]: socket() failed: %m", __func__, addr_name);
		return rc;
	}

	memset(&sa, 0, sizeof(sa));
	sa.sun_family = AF_UNIX;
	strcpy(sa.sun_path, addr_name);
	slen = sockaddr_fixlen((struct sockaddr *) &sa, (socklen_t) sizeof(sa));

	while ((rc = connect(*fd, (struct sockaddr *) &sa, slen)) &&
	       (errno == EINTR))
		; /* empty loop */

	if (rc < 0) {
		rc = errno;
		debug2("%s: [%s]: connect() failed: %m", __func__, addr_name);
		fd_close(fd);
	}
	return rc;
}

/* Put the local address of FD into *ADDR and its length in *LEN.  */
extern int slurm_get_stream_addr(int fd, slurm_addr_t *addr )
{
	socklen_t size = sizeof(*addr);
	return getsockname(fd, (struct sockaddr *) addr, &size);
}

/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
 * For connectionless socket types, just set the default address to send to
 * and the only address from which to accept transmissions.
 * Return SLURM_SUCCESS or error  */
static int _slurm_connect (int __fd, struct sockaddr const * __addr,
			   socklen_t __len)
{
	/* From "man connect": Note that for IP sockets the timeout
	 * may be very long when syncookies are enabled on the server.
	 *
	 * Timeouts in excess of 3 minutes have been observed, resulting
	 * in serious problems for slurmctld. Making the connect call
	 * non-blocking and polling seems to fix the problem. */
	int rc, flags, flags_save;
	struct pollfd ufds;

	flags = fcntl(__fd, F_GETFL);
	flags_save = flags;
	if (flags == -1) {
		error("%s: fcntl(F_GETFL) error: %m", __func__);
		flags = 0;
	}
	if (fcntl(__fd, F_SETFL, flags | O_NONBLOCK) < 0)
		error("%s: fcntl(F_SETFL) error: %m", __func__);

	rc = connect(__fd , __addr , __len);
	if ((rc < 0) && (errno != EINPROGRESS))
		return errno;
	if (rc == 0)
		goto done;  /* connect completed immediately */

	ufds.fd = __fd;
	ufds.events = POLLIN | POLLOUT;
	ufds.revents = 0;

again:
	rc = poll(&ufds, 1, slurm_conf.tcp_timeout * 1000);
	if (rc == -1) {
		int lerrno = errno;

		/* poll failed */
		if (lerrno == EINTR) {
			/* NOTE: connect() is non-interruptible in Linux */
			debug2("%s: poll() failed for %pA: %s",
			      __func__, __addr, slurm_strerror(lerrno));
			goto again;
		}

		error("%s: poll() failed for %pA: %s",
		      __func__, __addr, slurm_strerror(lerrno));
		return lerrno;
	} else if (rc == 0) {
		/* poll timed out before any socket events */
		debug2("%s: connect to %pA in %us: %s",
		      __func__, __addr, slurm_conf.tcp_timeout,
		      slurm_strerror(ETIMEDOUT));
		return ETIMEDOUT;
	} else if (ufds.revents & POLLERR) {
		int err;

		/* poll saw some event on the socket
		 * We need to check if the connection succeeded by
		 * using getsockopt.  The revent is not necessarily
		 * POLLERR when the connection fails! */
		if ((rc = fd_get_socket_error(__fd, &err)))
			return rc;

		/* NOTE: Connection refused is typically reported for
		 * non-responsived nodes plus attempts to communicate
		 * with terminated srun commands. */
		debug2("%s: failed to connect to %pA: %s",
		       __func__, __addr, slurm_strerror(err));
		return err;
	}

done:
	if (flags_save != -1) {
		if (fcntl(__fd, F_SETFL, flags_save) < 0)
			error("%s: fcntl(F_SETFL) error: %m", __func__);
	}

	return SLURM_SUCCESS;
}

extern void slurm_set_addr(slurm_addr_t *addr, uint16_t port, char *host)
{
	struct addrinfo *ai_ptr, *ai_start;

	log_flag(NET, "%s: called with port='%u' host='%s'",
		__func__, port, host);

	/*
	 * xgetaddrinfo uses hints from our config to determine what address
	 * families to return
	 */
	ai_start = xgetaddrinfo_port(host, port);

	if (!ai_start) {
		error_in_daemon("%s: Unable to resolve \"%s\"", __func__, host);
		addr->ss_family = AF_UNSPEC;
		return;
	}

	/*
	 * When host is null, assume we are trying to bind here.
	 * Make sure we return the v6 wildcard address first (when applicable)
	 * since we want v6 to be the default.
	 */
	if (host || !(slurm_conf.conf_flags & CONF_FLAG_IPV6_ENABLED)) {
		ai_ptr = ai_start;
	} else {
		for (ai_ptr = ai_start; ai_ptr; ai_ptr = ai_ptr->ai_next) {
			if (ai_ptr->ai_family == AF_INET6)
				break;
		}
		/* fall back to whatever was available */
		if (!ai_ptr)
			ai_ptr = ai_start;
	}

	memcpy(addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
	log_flag(NET, "%s: update addr. addr='%pA'", __func__, addr);
	freeaddrinfo(ai_start);
}

extern void slurm_pack_addr(slurm_addr_t *addr, buf_t *buffer)
{
	pack16(addr->ss_family, buffer);

	if (addr->ss_family == AF_INET6) {
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) addr;
		packmem(in6->sin6_addr.s6_addr, 16, buffer);
		pack16(in6->sin6_port, buffer);
	} else if (addr->ss_family == AF_INET) {
		struct sockaddr_in *in = (struct sockaddr_in *) addr;
		pack32(in->sin_addr.s_addr, buffer);
		pack16(in->sin_port, buffer);
	}
}

extern int slurm_unpack_addr_no_alloc(slurm_addr_t *addr, buf_t *buffer)
{
	uint16_t tmp_uint16 = 0;

	/* ss_family is only uint8_t on BSD. */
	safe_unpack16(&tmp_uint16, buffer);
	addr->ss_family = tmp_uint16;

	if (addr->ss_family == AF_INET6) {
		uint32_t size;
		char *buffer_addr;
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) addr;

		safe_unpackmem_ptr(&buffer_addr, &size, buffer);
		if (size != 16)
			goto unpack_error;
		memcpy(&in6->sin6_addr.s6_addr, buffer_addr, 16);

		safe_unpack16(&in6->sin6_port, buffer);
	} else if (addr->ss_family == AF_INET) {
		struct sockaddr_in *in = (struct sockaddr_in *) addr;

		safe_unpack32(&in->sin_addr.s_addr, buffer);
		safe_unpack16(&in->sin_port, buffer);
	} else {
		memset(addr, 0, sizeof(*addr));
	}
	return SLURM_SUCCESS;

unpack_error:
	return SLURM_ERROR;
}
