Example #1
0
/*
 * Called to set up service over a particular transport.
 */
void
do_one(char *provider, NETSELDECL(proto), struct protob *protobp0,
	int (*svc)(int, struct netbuf, struct netconfig *))
{
	register int sock;
	struct protob *protobp;
	struct netbuf *retaddr;
	struct netconfig *retnconf;
	struct netbuf addrmask;
	int vers;
	int err;
	int l;

	if (provider)
		sock = bind_to_provider(provider, protobp0->serv, &retaddr,
		    &retnconf);
	else
		sock = bind_to_proto(proto, protobp0->serv, &retaddr,
		    &retnconf);

	if (sock == -1) {
		(void) syslog(LOG_ERR,
	"Cannot establish %s service over %s: transport setup problem.",
		    protobp0->serv, provider ? provider : proto);
		return;
	}

	if (set_addrmask(sock, retnconf, &addrmask) < 0) {
		(void) syslog(LOG_ERR,
		    "Cannot set address mask for %s", retnconf->nc_netid);
		return;
	}

	/*
	 * Register all versions of the programs in the protocol block list.
	 */
	l = strlen(NC_UDP);
	for (protobp = protobp0; protobp; protobp = protobp->next) {
		for (vers = protobp->versmin; vers <= protobp->versmax;
		    vers++) {
			if ((protobp->program == NFS_PROGRAM ||
			    protobp->program == NFS_ACL_PROGRAM) &&
			    vers == NFS_V4 &&
			    strncasecmp(retnconf->nc_proto, NC_UDP, l) == 0)
				continue;

			(void) rpcb_unset(protobp->program, vers, retnconf);
			(void) rpcb_set(protobp->program, vers, retnconf,
			    retaddr);
		}
	}

	/*
	 * Register services with CLTS semantics right now.
	 * Note: services with COTS/COTS_ORD semantics will be
	 * registered later from cots_listen_event function.
	 */
	if (retnconf->nc_semantics == NC_TPI_CLTS) {
		/* Don't drop core if supporting module(s) aren't loaded. */
		(void) signal(SIGSYS, SIG_IGN);

		/*
		 * svc() doesn't block, it returns success or failure.
		 */

		if (svc == NULL && Mysvc4 != NULL)
			err = (*Mysvc4)(sock, &addrmask, retnconf,
			    NFS4_SETPORT|NFS4_KRPC_START, retaddr);
		else
			err = (*svc)(sock, addrmask, retnconf);

		if (err < 0) {
			(void) syslog(LOG_ERR,
			    "Cannot establish %s service over <file desc."
			    " %d, protocol %s> : %m. Exiting",
			    protobp0->serv, sock, retnconf->nc_proto);
			exit(1);
		}
	}
	free(addrmask.buf);

	/*
	 * We successfully set up the server over this transport.
	 * Add this descriptor to the one being polled on.
	 */
	add_to_poll_list(sock, retnconf);
}
Example #2
0
/*
 * Called to set up service over a particular transport.
 */
void
do_one(char *provider, NETSELDECL(proto), struct protob *protobp0,
	int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap)
{
	register int sock;
	struct protob *protobp;
	struct netbuf *retaddr;
	struct netconfig *retnconf;
	struct netbuf addrmask;
	int vers;
	int err;
	int l;

	if (provider)
		sock = bind_to_provider(provider, protobp0->serv, &retaddr,
		    &retnconf);
	else
		sock = bind_to_proto(proto, protobp0->serv, &retaddr,
		    &retnconf);

	if (sock == -1) {
		(void) syslog(LOG_ERR,
	"Cannot establish %s service over %s: transport setup problem.",
		    protobp0->serv, provider ? provider : proto);
		return;
	}

	if (set_addrmask(sock, retnconf, &addrmask) < 0) {
		(void) syslog(LOG_ERR,
		    "Cannot set address mask for %s", retnconf->nc_netid);
		return;
	}

	/*
	 * Register all versions of the programs in the protocol block list.
	 */
	l = strlen(NC_UDP);
	for (protobp = protobp0; protobp; protobp = protobp->next) {
		for (vers = protobp->versmin; vers <= protobp->versmax;
		    vers++) {
			if ((protobp->program == NFS_PROGRAM ||
			    protobp->program == NFS_ACL_PROGRAM) &&
			    vers == NFS_V4 &&
			    strncasecmp(retnconf->nc_proto, NC_UDP, l) == 0)
				continue;

			if (protobp->flags & PROTOB_NO_REGISTER)
				continue;

			if (use_pmap) {
				/*
				 * Note that if we're using a portmapper
				 * instead of rpcbind then we can't do an
				 * unregister operation here.
				 *
				 * The reason is that the portmapper unset
				 * operation removes all the entries for a
				 * given program/version regardelss of
				 * transport protocol.
				 *
				 * The caller of this routine needs to ensure
				 * that __pmap_unset() has been called for all
				 * program/version service pairs they plan
				 * to support before they start registering
				 * each program/version/protocol triplet.
				 */
				(void) __pmap_set(protobp->program, vers,
				    retnconf, retaddr);
			} else {
				(void) rpcb_unset(protobp->program, vers,
				    retnconf);
				(void) rpcb_set(protobp->program, vers,
				    retnconf, retaddr);
			}
		}
	}

	if (retnconf->nc_semantics == NC_TPI_CLTS) {
		/* Don't drop core if supporting module(s) aren't loaded. */
		(void) signal(SIGSYS, SIG_IGN);

		/*
		 * svc() doesn't block, it returns success or failure.
		 */

		if (svc == NULL && Mysvc4 != NULL)
			err = (*Mysvc4)(sock, &addrmask, retnconf,
			    NFS4_SETPORT|NFS4_KRPC_START, retaddr);
		else
			err = (*svc)(sock, addrmask, retnconf);

		if (err < 0) {
			(void) syslog(LOG_ERR,
			    "Cannot establish %s service over <file desc."
			    " %d, protocol %s> : %m. Exiting",
			    protobp0->serv, sock, retnconf->nc_proto);
			exit(1);
		}
	}

	/*
	 * We successfully set up the server over this transport.
	 * Add this descriptor to the one being polled on.
	 */
	add_to_poll_list(sock, retnconf);
}