/*
 * Copyright 2009 Oracle.  All rights reserved.
 *
 * This file is part of nfs-utils.
 *
 * nfs-utils 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.
 *
 * nfs-utils 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 nfs-utils.  If not, see <http://www.gnu.org/licenses/>.
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include "nfslib.h"

#include <netinet/in.h>

#include <sys/socket.h>
#include <sys/resource.h>

#include <rpc/rpc.h>
#include <rpc/svc.h>

#ifdef HAVE_TCP_WRAPPER
#include "tcpwrapper.h"
#endif

#include "sockaddr.h"
#include "rpcmisc.h"
#include "xlog.h"

#ifdef HAVE_LIBTIRPC

#define SVC_CREATE_XPRT_CACHE_SIZE	(8)
static SVCXPRT *svc_create_xprt_cache[SVC_CREATE_XPRT_CACHE_SIZE] = { NULL, };

/*
 * Cache an SVC xprt, in case there are more programs or versions to
 * register against it.
 */
static void
svc_create_cache_xprt(SVCXPRT *xprt)
{
	unsigned int i;

	/* Check if we've already got this one... */
	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
		if (svc_create_xprt_cache[i] == xprt)
			return;

	/* No, we don't.  Cache it. */
	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++)
		if (svc_create_xprt_cache[i] == NULL) {
			svc_create_xprt_cache[i] = xprt;
			return;
		}

	xlog(L_ERROR, "%s: Failed to cache an xprt", __func__);
}

/*
 * Find a previously cached SVC xprt structure with the given bind address
 * and transport semantics.
 *
 * Returns pointer to a cached SVC xprt.
 *
 * If no matching SVC XPRT can be found, NULL is returned.
 */
static SVCXPRT *
svc_create_find_xprt(const struct sockaddr *bindaddr, const struct netconfig *nconf)
{
	unsigned int i;

	for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++) {
		SVCXPRT *xprt = svc_create_xprt_cache[i];
		struct sockaddr *sap;

		if (xprt == NULL)
			continue;
		if (strcmp(nconf->nc_netid, xprt->xp_netid) != 0)
			continue;
		sap = (struct sockaddr *)xprt->xp_ltaddr.buf;
		if (!nfs_compare_sockaddr(bindaddr, sap))
			continue;
		return xprt;
	}
	return NULL;
}

/*
 * Set up an appropriate bind address, given @port and @nconf.
 *
 * Returns getaddrinfo(3) results if successful.  Caller must
 * invoke freeaddrinfo(3) on these results.
 *
 * Otherwise NULL is returned if an error occurs.
 */
__attribute_malloc__
static struct addrinfo *
svc_create_bindaddr(struct netconfig *nconf, const uint16_t port)
{
	struct addrinfo *ai = NULL;
	struct addrinfo hint = {
		.ai_flags	= AI_PASSIVE | AI_NUMERICSERV,
	};
	char buf[8];
	int error;

	if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
		hint.ai_family = AF_INET;
#ifdef IPV6_SUPPORTED
	else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
		hint.ai_family = AF_INET6;
#endif	/* IPV6_SUPPORTED */
	else {
		xlog(D_GENERAL, "Unrecognized bind address family: %s",
			nconf->nc_protofmly);
		return NULL;
	}

	if (strcmp(nconf->nc_proto, NC_UDP) == 0)
		hint.ai_protocol = (int)IPPROTO_UDP;
	else if (strcmp(nconf->nc_proto, NC_TCP) == 0)
		hint.ai_protocol = (int)IPPROTO_TCP;
	else {
		xlog(D_GENERAL, "Unrecognized bind address protocol: %s",
			nconf->nc_proto);
		return NULL;
	}

	(void)snprintf(buf, sizeof(buf), "%u", port);
	error = getaddrinfo(NULL, buf, &hint, &ai);
	if (error != 0) {
		xlog(L_ERROR, "Failed to construct bind address: %s",
			gai_strerror(error));
		return NULL;
	}

	return ai;
}

/*
 * Create a listener socket on a specific bindaddr, and set
 * special socket options to allow it to share the same port
 * as other listeners.
 *
 * Returns an open, bound, and possibly listening network
 * socket on success.
 *
 * Otherwise returns -1 if some error occurs.
 */
static int
svc_create_sock(const struct sockaddr *sap, socklen_t salen,
		struct netconfig *nconf)
{
	int fd, type, protocol;
	int one = 1;

	switch(nconf->nc_semantics) {
	case NC_TPI_CLTS:
		type = SOCK_DGRAM;
		break;
	case NC_TPI_COTS_ORD:
		type = SOCK_STREAM;
		break;
	default:
		xlog(D_GENERAL, "%s: Unrecognized bind address semantics: %u",
			__func__, nconf->nc_semantics);
		return -1;
	}

	if (strcmp(nconf->nc_proto, NC_UDP) == 0)
		protocol = (int)IPPROTO_UDP;
	else if (strcmp(nconf->nc_proto, NC_TCP) == 0)
		protocol = (int)IPPROTO_TCP;
	else {
		xlog(D_GENERAL, "%s: Unrecognized bind address protocol: %s",
			__func__, nconf->nc_proto);
		return -1;
	}

	fd = socket((int)sap->sa_family, type, protocol);
	if (fd == -1) {
		xlog(L_ERROR, "Could not make a socket: (%d) %m",
			errno);
		return -1;
	}

#ifdef IPV6_SUPPORTED
	if (sap->sa_family == AF_INET6) {
		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
				&one, sizeof(one)) == -1) {
			xlog(L_ERROR, "Failed to set IPV6_V6ONLY: (%d) %m",
				errno);
			(void)close(fd);
			return -1;
		}
	}
#endif	/* IPV6_SUPPORTED */

	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
		       &one, sizeof(one)) == -1) {
		xlog(L_ERROR, "Failed to set SO_REUSEADDR: (%d) %m",
			errno);
		(void)close(fd);
		return -1;
	}

	if (bind(fd, sap, salen) == -1) {
		xlog(L_ERROR, "Could not bind socket: (%d) %m",
			errno);
		(void)close(fd);
		return -1;
	}

	if (nconf->nc_semantics == NC_TPI_COTS_ORD)
		if (listen(fd, SOMAXCONN) == -1) {
			xlog(L_ERROR, "Could not listen on socket: (%d) %m",
				errno);
			(void)close(fd);
			return -1;
		}

	return fd;
}

/*
 * The simple case is allowing the TI-RPC library to create a
 * transport itself, given just the bind address and transport
 * semantics.
 *
 * Our local xprt cache is ignored in this path, since the
 * caller is not interested in sharing listeners or ports, and
 * the library automatically avoids ports already in use.
 *
 * Returns the count of started listeners (one or zero).
 */
static unsigned int
svc_create_nconf_rand_port(const char *name, const rpcprog_t program,
		const rpcvers_t version,
		void (*dispatch)(struct svc_req *, SVCXPRT *),
		struct netconfig *nconf)
{
	struct t_bind bindaddr;
	struct addrinfo *ai;
	SVCXPRT	*xprt;

	ai = svc_create_bindaddr(nconf, 0);
	if (ai == NULL)
		return 0;

	bindaddr.addr.buf = ai->ai_addr;
	bindaddr.qlen = SOMAXCONN;

	xprt = svc_tli_create(RPC_ANYFD, nconf, &bindaddr, 0, 0);
	freeaddrinfo(ai);
	if (xprt == NULL) {
		xlog(D_GENERAL, "Failed to create listener xprt "
			"(%s, %u, %s)", name, version, nconf->nc_netid);
		return 0;
	}

	if (!svc_reg(xprt, program, version, dispatch, nconf)) {
		/* svc_reg(3) destroys @xprt in this case */
		xlog(D_GENERAL, "Failed to register (%s, %u, %s)",
				name, version, nconf->nc_netid);
		return 0;
	}

	return 1;
}

/*
 * If a port is specified on the command line, that port value will be
 * the same for all listeners created here.  Create each listener
 * socket in advance and set SO_REUSEADDR, rather than allowing the
 * RPC library to create the listeners for us on a randomly chosen
 * port via svc_tli_create(RPC_ANYFD).
 *
 * Some callers want to listen for more than one RPC version using the
 * same port number.  For example, mountd could want to listen for MNT
 * version 1, 2, and 3 requests.  This means mountd must use the same
 * set of listener sockets for multiple RPC versions, since, on one
 * system, you can't have two listener sockets with the exact same
 * bind address (and port) and transport protocol.
 *
 * To accomplish this, this function caches xprts as they are created.
 * This cache is checked to see if a previously created xprt can be
 * used, before creating a new xprt for this [program, version].  If
 * there is a cached xprt with the same bindaddr and transport
 * semantics, we simply register the new version with that xprt,
 * rather than creating a fresh xprt for it.
 *
 * The xprt cache implemented here is local to a process.  Two
 * separate RPC daemons can not share a set of listeners.
 *
 * Returns the count of started listeners (one or zero).
 */
static unsigned int
svc_create_nconf_fixed_port(const char *name, const rpcprog_t program,
		const rpcvers_t version,
		void (*dispatch)(struct svc_req *, SVCXPRT *),
		const uint16_t port, struct netconfig *nconf)
{
	struct addrinfo *ai;
	SVCXPRT	*xprt;

	ai = svc_create_bindaddr(nconf, port);
	if (ai == NULL)
		return 0;

	xprt = svc_create_find_xprt(ai->ai_addr, nconf);
	if (xprt == NULL) {
		int fd;

		fd = svc_create_sock(ai->ai_addr, ai->ai_addrlen, nconf);
		if (fd == -1)
			goto out_free;

		xprt = svc_tli_create(fd, nconf, NULL, 0, 0);
		if (xprt == NULL) {
			xlog(D_GENERAL, "Failed to create listener xprt "
				"(%s, %u, %s)", name, version, nconf->nc_netid);
			(void)close(fd);
			goto out_free;
		}
	}

	if (!svc_reg(xprt, program, version, dispatch, nconf)) {
		/* svc_reg(3) destroys @xprt in this case */
		xlog(D_GENERAL, "Failed to register (%s, %u, %s)",
				name, version, nconf->nc_netid);
		goto out_free;
	}

	svc_create_cache_xprt(xprt);

	freeaddrinfo(ai);
	return 1;

out_free:
	freeaddrinfo(ai);
	return 0;
}

static unsigned int
svc_create_nconf(const char *name, const rpcprog_t program,
		const rpcvers_t version,
		void (*dispatch)(struct svc_req *, SVCXPRT *),
		const uint16_t port, struct netconfig *nconf)
{
	if (port != 0)
		return svc_create_nconf_fixed_port(name, program,
			version, dispatch, port, nconf);

	return svc_create_nconf_rand_port(name, program,
			version, dispatch, nconf);
}

/**
 * nfs_svc_create - start up RPC svc listeners
 * @name: C string containing name of new service
 * @program: RPC program number to register
 * @version: RPC version number to register
 * @dispatch: address of function that handles incoming RPC requests
 * @port: if not zero, transport listens on this port
 *
 * Sets up network transports for receiving RPC requests, and starts
 * the RPC dispatcher.  Returns the number of started network transports.
 */
unsigned int
nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
		void (*dispatch)(struct svc_req *, SVCXPRT *),
		const uint16_t port)
{
	const struct sigaction create_sigaction = {
		.sa_handler	= SIG_IGN,
	};
	unsigned int visible, up, servport;
	struct netconfig *nconf;
	void *handlep;

	/*
	 * Ignore SIGPIPE to avoid exiting sideways when peers
	 * close their TCP connection while we're trying to reply
	 * to them.
	 */
	(void)sigaction(SIGPIPE, &create_sigaction, NULL);

	handlep = setnetconfig();
	if (handlep == NULL) {
		xlog(L_ERROR, "Failed to access local netconfig database: %s",
			nc_sperror());
		return 0;
	}

	visible = 0;
	up = 0;
	while ((nconf = getnetconfig(handlep)) != NULL) {
		if (!(nconf->nc_flag & NC_VISIBLE))
			continue;
		visible++;

		if (!strcmp(nconf->nc_proto, NC_UDP) && !NFSCTL_UDPISSET(_rpcprotobits))
			continue;

		if (!strcmp(nconf->nc_proto, NC_TCP) && !NFSCTL_TCPISSET(_rpcprotobits))
			continue;

		if (port == 0)
			servport = getservport(program, nconf->nc_proto);
		else
			servport = port;

		up += svc_create_nconf(name, program, version, dispatch,
						servport, nconf);
	}

	if (visible == 0)
		xlog(L_ERROR, "Failed to find any visible netconfig entries");

	if (endnetconfig(handlep) == -1)
		xlog(L_ERROR, "Failed to close local netconfig database: %s",
			nc_sperror());

	return up;
}

/**
 * nfs_svc_unregister - remove service registrations from local rpcbind database
 * @program: RPC program number to unregister
 * @version: RPC version number to unregister
 *
 * Removes all registrations for [ @program, @version ] .
 */
void
nfs_svc_unregister(const rpcprog_t program, const rpcvers_t version)
{
	if (rpcb_unset(program, version, NULL) == FALSE)
		xlog(D_GENERAL, "Failed to unregister program %lu, version %lu",
			(unsigned long)program, (unsigned long)version);
}

#else	/* !HAVE_LIBTIRPC */

/**
 * nfs_svc_create - start up RPC svc listeners
 * @name: C string containing name of new service
 * @program: RPC program number to register
 * @version: RPC version number to register
 * @dispatch: address of function that handles incoming RPC requests
 * @port: if not zero, transport listens on this port
 *
 * Sets up network transports for receiving RPC requests, and starts
 * the RPC dispatcher.  Returns the number of started network transports.
 */
unsigned int
nfs_svc_create(char *name, const rpcprog_t program, const rpcvers_t version,
		void (*dispatch)(struct svc_req *, SVCXPRT *),
		const uint16_t port)
{
	rpc_init(name, (int)program, (int)version, dispatch, (int)port);
	return 1;
}

/**
 * nfs_svc_unregister - remove service registrations from local rpcbind database
 * @program: RPC program number to unregister
 * @version: RPC version number to unregister
 *
 * Removes all registrations for [ @program, @version ] .
 */
void
nfs_svc_unregister(const rpcprog_t program, const rpcvers_t version)
{
	if (pmap_unset((unsigned long)program, (unsigned long)version) == FALSE)
		xlog(D_GENERAL, "Failed to unregister program %lu, version %lu",
			(unsigned long)program, (unsigned long)version);
}

#endif	/* !HAVE_LIBTIRPC */
