/*
 * Send NSM notify calls to all hosts listed in /var/lib/sm
 *
 * Copyright (C) 2004-2006 Olaf Kirch <okir@suse.de>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <time.h>
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <netdb.h>
#include <errno.h>
#include <grp.h>

#include "sockaddr.h"
#include "xlog.h"
#include "nsm.h"
#include "nfsrpc.h"

/* glibc before 2.3.4 */
#ifndef AI_NUMERICSERV
#define AI_NUMERICSERV	0
#endif

#define NSM_TIMEOUT	2
#define NSM_MAX_TIMEOUT	120	/* don't make this too big */

struct nsm_host {
	struct nsm_host *	next;
	char *			name;
	const char *		mon_name;
	const char *		my_name;
	char *			notify_arg;
	struct addrinfo		*ai;
	time_t			last_used;
	time_t			send_next;
	unsigned int		timeout;
	unsigned int		retries;
	uint32_t		xid;
};

static char		nsm_hostname[SM_MAXSTRLEN + 1];
static int		nsm_state;
static int		nsm_family = AF_INET;
static int		opt_debug = 0;
static _Bool		opt_update_state = true;
static unsigned int	opt_max_retry = 15 * 60;
static char *		opt_srcaddr = NULL;
static char *		opt_srcport = NULL;

static void		notify(const int sock);
static int		notify_host(int, struct nsm_host *);
static void		recv_reply(int);
static void		insert_host(struct nsm_host *);
static struct nsm_host *find_host(uint32_t);
static int		record_pid(void);

static struct nsm_host *	hosts = NULL;

__attribute_malloc__
static struct addrinfo *
smn_lookup(const char *name)
{
	struct addrinfo	*ai = NULL;
	struct addrinfo hint = {
		.ai_family	= (nsm_family == AF_INET ? AF_INET: AF_UNSPEC),
		.ai_protocol	= (int)IPPROTO_UDP,
	};
	int error;

	error = getaddrinfo(name, NULL, &hint, &ai);
	if (error != 0) {
		xlog(D_GENERAL, "getaddrinfo(3): %s", gai_strerror(error));
		return NULL;
	}

	return ai;
}

#ifdef HAVE_GETNAMEINFO
static char *
smn_get_hostname(const struct sockaddr *sap, const socklen_t salen,
		const char *name)
{
	char buf[NI_MAXHOST];
	int error;

	error = getnameinfo(sap, salen, buf, sizeof(buf), NULL, 0, NI_NAMEREQD);
	if (error != 0) {
		xlog(L_ERROR, "my_name '%s' is unusable: %s",
			name, gai_strerror(error));
		return NULL;
	}
	return strdup(buf);
}
#else	/* !HAVE_GETNAMEINFO */
static char *
smn_get_hostname(const struct sockaddr *sap,
		__attribute__ ((unused)) const socklen_t salen,
		const char *name)
{
	const struct sockaddr_in *sin = (const struct sockaddr_in *)(char *)sap;
	const struct in_addr *addr = &sin->sin_addr;
	struct hostent *hp;

	if (sap->sa_family != AF_INET) {
		xlog(L_ERROR, "my_name '%s' is unusable: Bad address family",
			name);
		return NULL;
	}

	hp = gethostbyaddr(addr, (socklen_t)sizeof(addr), AF_INET);
	if (hp == NULL) {
		xlog(L_ERROR, "my_name '%s' is unusable: %s",
			name, hstrerror(h_errno));
		return NULL;
	}
	return strdup(hp->h_name);
}
#endif	/* !HAVE_GETNAMEINFO */

/*
 * Presentation addresses are converted to their canonical hostnames.
 * If the IP address does not map to a hostname, it is an error:
 * we never send a presentation address as the argument of SM_NOTIFY.
 *
 * If "name" is not a presentation address, it is left alone.  This
 * allows the administrator some flexibility if DNS isn't configured
 * exactly how sm-notify prefers it.
 *
 * Returns NUL-terminated C string containing the result, or NULL
 * if the canonical name doesn't exist or cannot be determined.
 * The caller must free the result with free(3).
 */
__attribute_malloc__
static char *
smn_verify_my_name(const char *name)
{
	struct addrinfo *ai = NULL;
	struct addrinfo hint = {
#ifdef IPV6_SUPPORTED
		.ai_family	= AF_UNSPEC,
#else	/* !IPV6_SUPPORTED */
		.ai_family	= AF_INET,
#endif	/* !IPV6_SUPPORTED */
		.ai_flags	= AI_NUMERICHOST,
	};
	char *retval;
	int error;

	error = getaddrinfo(name, NULL, &hint, &ai);
	switch (error) {
	case 0:
		/* @name was a presentation address */
		retval = smn_get_hostname(ai->ai_addr, ai->ai_addrlen, name);
		freeaddrinfo(ai);
		if (retval == NULL)
			return NULL;
		break;
	case EAI_NONAME:
		/* @name was not a presentation address */
		retval = strdup(name);
		break;
	default:
		xlog(L_ERROR, "my_name '%s' is unusable: %s",
			name, gai_strerror(error));
		return NULL;
	}

	xlog(D_GENERAL, "Canonical name for my_name '%s': %s",
			name, retval);
	return retval;
}

__attribute_malloc__
static struct nsm_host *
smn_alloc_host(const char *hostname, const char *mon_name,
		const char *my_name, const time_t timestamp)
{
	struct nsm_host	*host;

	host = calloc(1, sizeof(*host));
	if (host == NULL)
		goto out_nomem;

	/*
	 * mon_name and my_name are preserved so sm-notify can
	 * find the right monitor record to remove when it is
	 * done processing this host.
	 */
	host->name = strdup(hostname);
	host->mon_name = (const char *)strdup(mon_name);
	host->my_name = (const char *)strdup(my_name);
	host->notify_arg = strdup(opt_srcaddr != NULL ?
					nsm_hostname : my_name);
	if (host->name == NULL ||
	    host->mon_name == NULL ||
	    host->my_name == NULL ||
	    host->notify_arg == NULL) {
		free(host->notify_arg);
		free((void *)host->my_name);
		free((void *)host->mon_name);
		free(host->name);
		free(host);
		goto out_nomem;
	}

	host->last_used = timestamp;
	host->timeout = NSM_TIMEOUT;
	host->retries = 100;		/* force address retry */

	return host;

out_nomem:
	xlog_warn("Unable to allocate memory");
	return NULL;
}

static void smn_forget_host(struct nsm_host *host)
{
	xlog(D_CALL, "Removing %s (%s, %s) from notify list",
			host->name, host->mon_name, host->my_name);

	nsm_delete_notified_host(host->name, host->mon_name, host->my_name);

	free(host->notify_arg);
	free((void *)host->my_name);
	free((void *)host->mon_name);
	free(host->name);
	if (host->ai)
		freeaddrinfo(host->ai);

	free(host);
}

static unsigned int
smn_get_host(const char *hostname,
		__attribute__ ((unused)) const struct sockaddr *sap,
		const struct mon *m, const time_t timestamp)
{
	struct nsm_host	*host;

	host = smn_alloc_host(hostname,
		m->mon_id.mon_name, m->mon_id.my_id.my_name, timestamp);
	if (host == NULL)
		return 0;

	insert_host(host);
	return 1;
}

#ifdef IPV6_SUPPORTED
static int smn_socket(void)
{
	int sock;

	/*
	 * Use an AF_INET socket if IPv6 is disabled on the
	 * local system.
	 */
	sock = socket(AF_INET6, SOCK_DGRAM, 0);
	if (sock == -1) {
		if (errno != EAFNOSUPPORT) {
			xlog(L_ERROR, "Failed to create RPC socket: %m");
			return -1;
		}
		sock = socket(AF_INET, SOCK_DGRAM, 0);
		if (sock < 0) {
			xlog(L_ERROR, "Failed to create RPC socket: %m");
			return -1;
		}
	} else
		nsm_family = AF_INET6;

	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
		xlog(L_ERROR, "fcntl(3) on RPC socket failed: %m");
		goto out_close;
	}

	/*
	 * TI-RPC over IPv6 (udp6/tcp6) does not handle IPv4.  However,
	 * since sm-notify open-codes all of its RPC support, it can
	 * use a single socket and let the local network stack provide
	 * the correct mapping between address families automatically.
	 * This is the same thing that is done in the kernel.
	 */
	if (nsm_family == AF_INET6) {
		const int zero = 0;
		socklen_t zerolen = (socklen_t)sizeof(zero);

		if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
					(char *)&zero, zerolen) == -1) {
			xlog(L_ERROR, "setsockopt(3) on RPC socket failed: %m");
			goto out_close;
		}
	}

	return sock;

out_close:
	(void)close(sock);
	return -1;
}
#else	/* !IPV6_SUPPORTED */
static int smn_socket(void)
{
	int sock;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1) {
		xlog(L_ERROR, "Failed to create RPC socket: %m");
		return -1;
	}

	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
		xlog(L_ERROR, "fcntl(3) on RPC socket failed: %m");
		(void)close(sock);
		return -1;
	}

	return sock;
}
#endif	/* !IPV6_SUPPORTED */

/*
 * If admin specified a source address or srcport, then convert those
 * to a sockaddr and return it.   Otherwise, return an ANYADDR address.
 */
__attribute_malloc__
static struct addrinfo *
smn_bind_address(const char *srcaddr, const char *srcport)
{
	struct addrinfo *ai = NULL;
	struct addrinfo hint = {
		.ai_flags	= AI_NUMERICSERV | AI_V4MAPPED,
		.ai_family	= nsm_family,
		.ai_protocol	= (int)IPPROTO_UDP,
	};
	int error;

	if (srcaddr == NULL)
		hint.ai_flags |= AI_PASSIVE;

	/* Do not allow "node" and "service" parameters both to be NULL */
	if (srcport == NULL)
		error = getaddrinfo(srcaddr, "", &hint, &ai);
	else
		error = getaddrinfo(srcaddr, srcport, &hint, &ai);
	if (error != 0) {
		xlog(L_ERROR,
			"Invalid bind address or port for RPC socket: %s",
				gai_strerror(error));
		return NULL;
	}

	return ai;
}

#ifdef HAVE_LIBTIRPC
static int
smn_bindresvport(int sock, struct sockaddr *sap)
{
	return bindresvport_sa(sock, sap);
}

#else	/* !HAVE_LIBTIRPC */
static int
smn_bindresvport(int sock, struct sockaddr *sap)
{
	if (sap->sa_family != AF_INET) {
		errno = EAFNOSUPPORT;
		return -1;
	}

	return bindresvport(sock, (struct sockaddr_in *)(char *)sap);
}
#endif	/* !HAVE_LIBTIRPC */

/*
 * Prepare a socket for sending RPC requests
 *
 * Returns a bound datagram socket file descriptor, or -1 if
 * an error occurs.
 */
static int
smn_create_socket(const char *srcaddr, const char *srcport)
{
	int sock, retry_cnt = 0;
	struct addrinfo *ai;

retry:
	sock = smn_socket();
	if (sock == -1)
		return -1;

	ai = smn_bind_address(srcaddr, srcport);
	if (ai == NULL) {
		(void)close(sock);
		return -1;
	}

	/* Use source port if provided on the command line,
	 * otherwise use bindresvport */
	if (srcport) {
		if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
			xlog(L_ERROR, "Failed to bind RPC socket: %m");
			freeaddrinfo(ai);
			(void)close(sock);
			return -1;
		}
	} else {
		struct servent *se;

		if (smn_bindresvport(sock, ai->ai_addr) == -1) {
			xlog(L_ERROR,
				"bindresvport on RPC socket failed: %m");
			freeaddrinfo(ai);
			(void)close(sock);
			return -1;
		}

		/* try to avoid known ports */
		se = getservbyport((int)nfs_get_port(ai->ai_addr), "udp");
		if (se != NULL && retry_cnt < 100) {
			retry_cnt++;
			freeaddrinfo(ai);
			(void)close(sock);
			goto retry;
		}
	}

	freeaddrinfo(ai);
	return sock;
}

int
main(int argc, char **argv)
{
	int	c, sock, force = 0;
	char *	progname;

	progname = strrchr(argv[0], '/');
	if (progname != NULL)
		progname++;
	else
		progname = argv[0];

	while ((c = getopt(argc, argv, "dm:np:v:P:f")) != -1) {
		switch (c) {
		case 'f':
			force = 1;
			break;
		case 'd':
			opt_debug++;
			break;
		case 'm':
			opt_max_retry = atoi(optarg) * 60;
			break;
		case 'n':
			opt_update_state = false;
			break;
		case 'p':
			opt_srcport = optarg;
			break;
		case 'v':
			opt_srcaddr = optarg;
			break;
		case 'P':
			if (!nsm_setup_pathnames(argv[0], optarg))
				exit(1);
			break;

		default:
			goto usage;
		}
	}

	if (optind < argc) {
usage:		fprintf(stderr,
			"Usage: %s -notify [-dfq] [-m max-retry-minutes] [-p srcport]\n"
			"            [-P /path/to/state/directory] [-v my_host_name]\n",
			progname);
		exit(1);
	}

	if (opt_debug) {
		xlog_syslog(0);
		xlog_stderr(1);
		xlog_config(D_ALL, 1);
	} else {
		xlog_syslog(1);
		xlog_stderr(0);
	}

	xlog_open(progname);
	xlog(L_NOTICE, "Version " VERSION " starting");

	if (nsm_is_default_parentdir()) {
		if (record_pid() == 0 && force == 0 && opt_update_state) {
			/* already run, don't try again */
			xlog(L_NOTICE, "Already notifying clients; Exiting!");
			exit(0);
		}
	}

	if (opt_srcaddr != NULL) {
		char *name;

		name = smn_verify_my_name(opt_srcaddr);
		if (name == NULL)
			exit(1);

		strncpy(nsm_hostname, name, sizeof(nsm_hostname));
		free(name);
	}

	(void)nsm_retire_monitored_hosts();
	if (nsm_load_notify_list(smn_get_host) == 0) {
		xlog(D_GENERAL, "No hosts to notify; exiting");
		return 0;
	}

	nsm_state = nsm_get_state(opt_update_state);
	if (nsm_state == 0)
		exit(1);
	nsm_update_kernel_state(nsm_state);

	if (!opt_debug) {
		xlog(L_NOTICE, "Backgrounding to notify hosts...\n");

		if (daemon(0, 0) < 0) {
			xlog(L_ERROR, "unable to background: %m");
			exit(1);
		}

		close(0);
		close(1);
		close(2);
	}

	sock = smn_create_socket(opt_srcaddr, opt_srcport);
	if (sock == -1)
		exit(1);

	if (!nsm_drop_privileges(-1))
		exit(1);

	notify(sock);

	if (hosts) {
		struct nsm_host	*hp;

		while ((hp = hosts) != 0) {
			hosts = hp->next;
			xlog(L_NOTICE, "Unable to notify %s, giving up",
				hp->name);
		}
		exit(1);
	}

	exit(0);
}

/*
 * Notify hosts
 */
static void
notify(const int sock)
{
	time_t	failtime = 0;

	if (opt_max_retry)
		failtime = time(NULL) + opt_max_retry;

	while (hosts) {
		struct pollfd	pfd;
		time_t		now = time(NULL);
		unsigned int	sent = 0;
		struct nsm_host	*hp;
		long		wait;

		if (failtime && now >= failtime)
			break;

		while (hosts && ((wait = hosts->send_next - now) <= 0)) {
			/* Never send more than 10 packets at once */
			if (sent++ >= 10)
				break;

			/* Remove queue head */
			hp = hosts;
			hosts = hp->next;

			if (notify_host(sock, hp))
				continue;

			/* Set the timeout for this call, using an
			   exponential timeout strategy */
			wait = hp->timeout;
			if ((hp->timeout <<= 1) > NSM_MAX_TIMEOUT)
				hp->timeout = NSM_MAX_TIMEOUT;
			hp->send_next = now + wait;
			hp->retries++;

			insert_host(hp);
		}
		if (hosts == NULL)
			return;

		xlog(D_GENERAL, "Host %s due in %ld seconds",
				hosts->name, wait);

		pfd.fd = sock;
		pfd.events = POLLIN;

		wait *= 1000;
		if (wait < 100)
			wait = 100;
		if (poll(&pfd, 1, wait) != 1)
			continue;

		recv_reply(sock);
	}
}

/*
 * Send notification to a single host
 */
static int
notify_host(int sock, struct nsm_host *host)
{
	struct sockaddr *sap;
	socklen_t salen;

	if (host->ai == NULL) {
		host->ai = smn_lookup(host->name);
		if (host->ai == NULL) {
			xlog_warn("DNS resolution of %s failed; "
				"retrying later", host->name);
			return 0;
		}
	}

	/* If we retransmitted 4 times, reset the port to force
	 * a new portmap lookup (in case statd was restarted).
	 * We also rotate through multiple IP addresses at this
	 * point.
	 */
	if (host->retries >= 4) {
		/* don't rotate if there is only one addrinfo */
		if (host->ai->ai_next != NULL) {
			struct addrinfo *first = host->ai;
			struct addrinfo **next = &host->ai;

			/* remove the first entry from the list */
			host->ai = first->ai_next;
			first->ai_next = NULL;
			/* find the end of the list */
			next = &first->ai_next;
			while ( *next )
				next = & (*next)->ai_next;
			/* put first entry at end */
			*next = first;
		}

		nfs_set_port(host->ai->ai_addr, 0);
		host->retries = 0;
	}

	sap = host->ai->ai_addr;
	salen = host->ai->ai_addrlen;

	if (nfs_get_port(sap) == 0)
		host->xid = nsm_xmit_rpcbind(sock, sap, SM_PROG, SM_VERS);
	else
		host->xid = nsm_xmit_notify(sock, sap, salen,
					SM_PROG, host->notify_arg, nsm_state);

	return 0;
}

static void
smn_defer(struct nsm_host *host)
{
	host->xid = 0;
	host->send_next = time(NULL) + NSM_MAX_TIMEOUT;
	host->timeout = NSM_MAX_TIMEOUT;
	insert_host(host);
}

static void
smn_schedule(struct nsm_host *host)
{
	host->retries = 0;
	host->xid = 0;
	host->send_next = time(NULL);
	host->timeout = NSM_TIMEOUT;
	insert_host(host);
}

/*
 * Extract the returned port number and set up the SM_NOTIFY call.
 */
static void
recv_rpcbind_reply(struct sockaddr *sap, struct nsm_host *host, XDR *xdr)
{
	uint16_t port = nsm_recv_rpcbind(sap->sa_family, xdr);

	if (port == 0) {
		/* No binding for statd... */
		xlog(D_GENERAL, "No statd on host %s", host->name);
		smn_defer(host);
	} else {
		xlog(D_GENERAL, "Processing rpcbind reply for %s (port %u)",
			host->name, port);
		nfs_set_port(sap, port);
		smn_schedule(host);
	}
}

/*
 * Successful NOTIFY call. Server returns void.
 *
 * Try sending another SM_NOTIFY with an unqualified "my_name"
 * argument.  Reuse the port number.  If "my_name" is already
 * unqualified, we're done.
 */
static void
recv_notify_reply(struct nsm_host *host)
{
	char *dot = strchr(host->notify_arg, '.');

	if (dot != NULL) {
		*dot = '\0';
		smn_schedule(host);
	} else {
		xlog(D_GENERAL, "Host %s notified successfully", host->name);
		smn_forget_host(host);
	}
}

/*
 * Receive reply from remote host
 */
static void
recv_reply(int sock)
{
	struct nsm_host	*hp;
	struct sockaddr *sap;
	char msgbuf[NSM_MAXMSGSIZE];
	uint32_t	xid;
	ssize_t		msglen;
	XDR		xdr;

	memset(msgbuf, 0 , sizeof(msgbuf));
	msglen = recv(sock, msgbuf, sizeof(msgbuf), 0);
	if (msglen < 0)
		return;

	xlog(D_GENERAL, "Received packet...");

	memset(&xdr, 0, sizeof(xdr));
	xdrmem_create(&xdr, msgbuf, (unsigned int)msglen, XDR_DECODE);
	xid = nsm_parse_reply(&xdr);
	if (xid == 0)
		goto out;

	/* Before we look at the data, find the host struct for
	   this reply */
	if ((hp = find_host(xid)) == NULL)
		goto out;

	sap = hp->ai->ai_addr;
	if (nfs_get_port(sap) == 0)
		recv_rpcbind_reply(sap, hp, &xdr);
	else
		recv_notify_reply(hp);

out:
	xdr_destroy(&xdr);
}

/*
 * Insert host into notification list, sorted by next send time
 */
static void
insert_host(struct nsm_host *host)
{
	struct nsm_host	**where, *p;

	where = &hosts;
	while ((p = *where) != 0) {
		/* Sort in ascending order of timeout */
		if (host->send_next < p->send_next)
			break;
		/* If we have the same timeout, put the
		 * most recently used host first.
		 * This makes sure that "recent" hosts
		 * get notified first.
		 */
		if (host->send_next == p->send_next
		 && host->last_used > p->last_used)
			break;
		where = &p->next;
	}

	host->next = *where;
	*where = host;
	xlog(D_GENERAL, "Added host %s to notify list", host->name);
}

/*
 * Find host given the XID
 */
static struct nsm_host *
find_host(uint32_t xid)
{
	struct nsm_host	**where, *p;

	where = &hosts;
	while ((p = *where) != 0) {
		if (p->xid == xid) {
			*where = p->next;
			return p;
		}
		where = &p->next;
	}
	return NULL;
}

/*
 * Record pid in /var/run/sm-notify.pid
 * This file should remain until a reboot, even if the
 * program exits.
 * If file already exists, fail.
 */
static int record_pid(void)
{
	char pid[20];
	ssize_t len;
	int fd;

	(void)snprintf(pid, sizeof(pid), "%d\n", (int)getpid());
	fd = open("/var/run/sm-notify.pid", O_CREAT|O_EXCL|O_WRONLY, 0600);
	if (fd < 0)
		return 0;

	len = write(fd, pid, strlen(pid));
	if ((len < 0) || ((size_t)len != strlen(pid))) {
		xlog_warn("Writing to pid file failed: errno %d (%m)",
				errno);
	}

	(void)close(fd);
	return 1;
}
