Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 02 Aug 2012 01:38:14 +0000
From:      exxo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r240005 - in soc2012/exxo: . patches
Message-ID:  <20120802013814.8537F106566C@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: exxo
Date: Thu Aug  2 01:38:14 2012
New Revision: 240005
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240005

Log:
  Add yp patch and update softnotes

Added:
  soc2012/exxo/patches/yp.patch
Modified:
  soc2012/exxo/softnotes.txt

Added: soc2012/exxo/patches/yp.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2012/exxo/patches/yp.patch	Thu Aug  2 01:38:14 2012	(r240005)
@@ -0,0 +1,2073 @@
+Index: freebsd-head/usr.bin/ypwhich/ypwhich.c
+===================================================================
+--- freebsd-head/usr.bin/ypwhich/ypwhich.c	(revision 239326)
++++ freebsd-head/usr.bin/ypwhich/ypwhich.c	(working copy)
+@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
+ #include <rpc/rpc.h>
+ #include <rpc/xdr.h>
+ #include <rpcsvc/yp_prot.h>
++#include <rpcsvc/yp_utils.h>
+ #include <rpcsvc/ypclnt.h>
+ 
+ #include <netinet/in.h>
+@@ -83,26 +84,68 @@ usage(void)
+ 	exit(ERR_USAGE);
+ }
+ 
++#ifdef INET6
++# define ADDRSTRLEN INET6_ADDRSTRLEN
++#else
++# define ADDRSTRLEN INET_ADDRSTRLEN
++#endif
++
++static void
++print_addr(const union ypbf_resp *ypbr, int version)
++{
++	struct hostent *hent = NULL;
++	char str[ADDRSTRLEN];
++	int family;
++	size_t len;
++	union {
++		struct in_addr	in;
++#ifdef INET6
++		struct in6_addr	in6;
++#endif
++	} ss_addr;
++
++#ifdef YPBIND_COMPAT_V2
++	if (version == YPBINDVERS_2) {
++		family = AF_INET;
++		len = sizeof(ss_addr.in);
++		bcopy(&ypbr->ypbf_raddr_v2, &ss_addr, len);
++	}
++	else /* YPBINDVERS */
++#endif
++	{
++		family = ypbr->ypbf_rfamily;
++#ifdef INET6
++		if (family == AF_INET6)
++			len = sizeof(ss_addr.in6);
++		else /* AF_INET */
++#endif
++			len = sizeof(ss_addr.in);
++		bcopy(&ypbr->ypbf_raddr, &ss_addr, len);
++	}
++	hent = gethostbyaddr((char *)&ss_addr, len, family);
++	if (hent)
++		printf("%s\n", hent->h_name);
++	else
++		printf("%s\n", inet_ntop(family, &ss_addr, str, ADDRSTRLEN));
++}
+ 
+ /*
+  * Like yp_bind except can query a specific host
+  */
+ static int
+-bind_host(char *dom, struct sockaddr_in *lsin)
++bind_host(char *dom, const char *host)
+ {
+-	struct hostent *hent = NULL;
+-	struct ypbind_resp ypbr;
++	union ypbf_resp ypbr;
+ 	struct timeval tv;
+ 	CLIENT *client;
+-	int sock, r;
+-	struct in_addr ss_addr;
++	int r;
++	int version = YPBINDVERS;
+ 
+-	sock = RPC_ANYSOCK;
+ 	tv.tv_sec = 15;
+ 	tv.tv_usec = 0;
+-	client = clntudp_create(lsin, YPBINDPROG, YPBINDVERS, tv, &sock);
++	client = clnt_create_timed(host, YPBINDPROG, version, "udp", &tv);
+ 	if (client == NULL) {
+-		warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND));
++		warnx("can't clnt_create_timed: %s", yperr_string(YPERR_YPBIND));
+ 		return (YPERR_YPBIND);
+ 	}
+ 
+@@ -110,28 +153,31 @@ bind_host(char *dom, struct sockaddr_in 
+ 	tv.tv_usec = 0;
+ 	r = clnt_call(client, YPBINDPROC_DOMAIN,
+ 		(xdrproc_t)xdr_domainname, &dom,
+-		(xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
++		(xdrproc_t)xdr_ypbind_resp, &ypbr.resp, tv);
++#ifdef YPBIND_COMPAT_V2
++	if (r == RPC_PROGVERSMISMATCH) {
++		fprintf(stderr, "Warning: %s, fallback in V2 compatibility mode\n", clnt_sperrno(r));
++		version = YPBINDVERS_2;
++		if (clnt_control(client, CLSET_VERS, &version) == TRUE)
++			r = clnt_call(client, YPBINDPROC_DOMAIN,
++				(xdrproc_t)xdr_domainname, &dom,
++				(xdrproc_t)xdr_ypbind_resp_v2, &ypbr.resp2, tv); /* TODO libc must define YPBIND_COMPAT_V2 */
++	}	    
++#endif
+ 	if (r != RPC_SUCCESS) {
+ 		warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
+ 		clnt_destroy(client);
+ 		return (YPERR_YPBIND);
+ 	} else {
+-		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
++		if (ypbr.ypbf_rstatus != YPBIND_SUCC_VAL) {
+ 			warnx("can't yp_bind: reason: %s",
+-				ypbinderr_string(ypbr.ypbind_respbody.ypbind_error));
++				ypbinderr_string(ypbr.ypbf_rerror));
+ 			clnt_destroy(client);
+ 			return (r);
+ 		}
+ 	}
+ 	clnt_destroy(client);
+-
+-	ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr;
+-	/*printf("%08x\n", ss_addr);*/
+-	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
+-	if (hent)
+-		printf("%s\n", hent->h_name);
+-	else
+-		printf("%s\n", inet_ntoa(ss_addr));
++	print_addr(&ypbr, version);
+ 	return (0);
+ }
+ 
+@@ -141,8 +187,7 @@ main(int argc, char *argv[])
+ 	char *domnam = NULL, *master;
+ 	char *map = NULL;
+ 	struct ypmaplist *ypml, *y;
+-	struct hostent *hent;
+-	struct sockaddr_in lsin;
++	char *host;
+ 	int notrans, mode;
+ 	int c, r;
+ 	u_int i;
+@@ -166,38 +211,20 @@ main(int argc, char *argv[])
+ 			mode++;
+ 			break;
+ 		default:
+-			usage();
++		    usage();
+ 		}
+ 
+ 	if (!domnam)
+ 		yp_get_default_domain(&domnam);
+ 
+ 	if (mode == 0) {
+-		switch (argc-optind) {
+-		case 0:
+-			bzero(&lsin, sizeof lsin);
+-			lsin.sin_family = AF_INET;
+-			lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+-
+-			if (bind_host(domnam, &lsin))
+-				exit(ERR_NOBINDING);
+-			break;
+-		case 1:
+-			bzero(&lsin, sizeof lsin);
+-			lsin.sin_family = AF_INET;
+-			if ((lsin.sin_addr.s_addr = inet_addr(argv[optind])) == INADDR_NONE) {
+-				hent = gethostbyname(argv[optind]);
+-				if (!hent)
+-					errx(ERR_NOSUCHHOST, "host %s unknown", argv[optind]);
+-				bcopy((char *)hent->h_addr_list[0],
+-					(char *)&lsin.sin_addr, sizeof lsin.sin_addr);
+-			}
+-			if (bind_host(domnam, &lsin))
++	    	if (argc-optind == 0 || argc-optind == 1) {
++			host = argc-optind ? argv[optind] : "127.0.0.1";
++			if (bind_host(domnam, host))
+ 				exit(ERR_NOBINDING);
+-			break;
+-		default:
+-			usage();
+ 		}
++		else
++			usage();
+ 		exit(0);
+ 	}
+ 
+Index: freebsd-head/usr.bin/ypwhich/Makefile
+===================================================================
+--- freebsd-head/usr.bin/ypwhich/Makefile	(revision 239326)
++++ freebsd-head/usr.bin/ypwhich/Makefile	(working copy)
+@@ -1,8 +1,15 @@
+ #	from: @(#)Makefile	5.8 (Berkeley) 7/28/90
+ # $FreeBSD$
+ 
++.include <bsd.own.mk>
++
+ PROG=	ypwhich
+ 
+ WARNS?=	2
+ 
++CFLAGS += -DYPBIND_COMPAT_V2
++.if ${MK_INET6_SUPPORT} != "no"
++CFLAGS += -DINET6
++.endif
++
+ .include <bsd.prog.mk>
+Index: freebsd-head/include/rpcsvc/yp_utils.h
+===================================================================
+--- freebsd-head/include/rpcsvc/yp_utils.h	(revision 0)
++++ freebsd-head/include/rpcsvc/yp_utils.h	(revision 240004)
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) TODO
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote
++ *    products derived from this software without specific prior written
++ *    permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * $FreeBSD: soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h 239957 2012-07-31 16:20:04Z exxo $
++ */
++
++#ifndef _RPCSVC_YP_UTILS_H_
++#define _RPCSVC_YP_UTILS_H_
++ 
++/* YPBIND facilities
++ *
++ * This file should be included after <rpcsvc/yp_prot.h> or <rpcsvc/yp.h>
++ * It provides facilities to deal with YPBIND protocols
++ */
++
++#define ypresp_status	ypbind_status
++#define ypsetdom_family ypsetdom_binding.ypbind_binding_family
++
++#ifdef _RPCSVC_YP_PROT_H_ /* if used with yp_prot.h */
++
++# define ypresp_family	ypbind_respbody.ypbind_bindinfo.ypbind_binding_family
++# define ypresp_error	ypbind_respbody.ypbind_error
++# define ypresp_addr	ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr
++# define ypresp_port	ypbind_respbody.ypbind_bindinfo.ypbind_binding_port
++
++#elif defined(_YP_H_RPCGEN) /* if used with yp.h */
++
++# define ypsetdom_addr	ypsetdom_binding.ypbind_binding_addr
++# define ypsetdom_port	ypsetdom_binding.ypbind_binding_port
++
++# define ypresp_family		ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family
++# define ypresp_error		ypbind_resp_u.ypbind_error
++# define ypresp_addr		ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr
++# define ypresp_port		ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port
++# define ypresp_error_v2	ypbind_resp_v2_u.ypbind_error
++# define ypresp_addr_v2		ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr
++# define ypresp_port_v2		ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port
++
++#endif
++
++union ypbf_resp {
++	struct {
++		enum ypbind_resptype status;
++		u_int error;
++	} header;
++	struct ypbind_resp	resp;
++#ifdef YPBIND_COMPAT_V2
++	struct ypbind_resp_v2	resp2;
++#endif
++};
++#define ypbf_rstatus	header.status
++#define ypbf_rerror	header.error
++#define ypbf_rfamily	resp.ypresp_family
++#define ypbf_raddr	resp.ypresp_addr
++#define ypbf_rport	resp.ypresp_port
++#ifdef YPBIND_COMPAT_V2
++# ifdef _RPCSVC_YP_PROT_H_ /* yp_prot.h */
++#  define ypbf_raddr_v2	resp2.ypresp_addr
++#  define ypbf_rport_v2	resp2.ypresp_port
++# elif defined(_YP_H_RPCGEN) /* yp.h */
++#  define ypbf_raddr_v2 resp2.ypresp_addr_v2
++#  define ypbf_rport_v2 resp2.ypresp_port_v2
++# endif
++#endif
++
++union ypbf_setdom {
++	char ypsetdom_domain[YPMAXDOMAIN + 1];
++	struct ypbind_setdom	setdom;
++#ifdef YPBIND_COMPAT_V2
++	struct ypbind_setdom_v2	setdom2;
++#endif
++};
++#define ypbf_sdomain	ypsetdom_domain
++#define ypbf_sfamily	setdom.ypsetdom_family
++#define ypbf_saddr	setdom.ypsetdom_addr
++#define ypbf_sport	setdom.ypsetdom_port
++#define ypbf_svers	setdom.ypsetdom_vers
++#ifdef YPBIND_COMPAT_V2
++# define ypbf_saddr_v2	setdom2.ypsetdom_addr
++# define ypbf_sport_v2	setdom2.ypsetdom_port
++# define ypbf_svers_v2	setdom2.ypsetdom_vers
++#endif
++
++#endif /* _RPCSVC_YP_UTILS_H_ */
+Index: freebsd-head/include/rpcsvc/yp_prot.h
+===================================================================
+--- freebsd-head/include/rpcsvc/yp_prot.h	(revision 239326)
++++ freebsd-head/include/rpcsvc/yp_prot.h	(working copy)
+@@ -199,7 +199,7 @@ struct ypresp_maplist {
+ struct dom_binding {
+ 	struct dom_binding *dom_pnext;
+ 	char dom_domain[YPMAXDOMAIN + 1];
+-	struct sockaddr_in dom_server_addr;
++	struct sockaddr_storage dom_server_addr; /* TODO impact of changing this ? */
+ 	u_short dom_server_port;
+ 	int dom_socket;
+ 	CLIENT *dom_client;
+@@ -222,7 +222,8 @@ struct dom_binding {
+  */
+ 
+ #define YPBINDPROG		((u_long)100007)
+-#define YPBINDVERS		((u_long)2)
++#define YPBINDVERS		((u_long)3)
++#define YPBINDVERS_2		((u_long)2)
+ #define YPBINDVERS_ORIG		((u_long)1)
+ 
+ /* ypbind procedure numbers */
+@@ -238,7 +239,13 @@ enum ypbind_resptype {
+ 
+ /* network order, of course */
+ struct ypbind_binding {
+-	struct in_addr	ypbind_binding_addr;
++    	sa_family_t	ypbind_binding_family;
++	union {
++		struct in_addr	in;
++#ifdef INET6
++		struct in6_addr	in6;
++#endif
++	} ypbind_binding_addr;
+ 	u_short		ypbind_binding_port;
+ };
+ 
+@@ -254,6 +261,7 @@ struct ypbind_resp {
+ #define YPBIND_ERR_ERR		1	/* internal error */
+ #define YPBIND_ERR_NOSERV	2	/* no bound server for passed domain */
+ #define YPBIND_ERR_RESC		3	/* system resource allocation failure */
++#define YPBIND_ERR_FAMILY	4	/* unsupported family */
+ 
+ /*
+  * Request data structure for ypbind "Set domain" procedure.
+@@ -266,6 +274,30 @@ struct ypbind_setdom {
+ #define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
+ #define ypsetdom_port ypsetdom_binding.ypbind_binding_port
+ 
++/* Backward compatibility for YPBIND protocol version 2 */
++#ifdef YPBIND_COMPAT_V2
++
++struct ypbind_binding_v2 {
++	struct in_addr	ypbind_binding_addr;
++	u_short		ypbind_binding_port;
++};
++
++struct ypbind_resp_v2 {
++	enum ypbind_resptype ypbind_status;
++	union {
++		u_int ypbind_error;
++		struct ypbind_binding_v2 ypbind_bindinfo;
++	} ypbind_respbody;
++};
++
++struct ypbind_setdom_v2 {
++	char ypsetdom_domain[YPMAXDOMAIN + 1];
++	struct ypbind_binding_v2 ypsetdom_binding;
++	u_int ypsetdom_vers;
++};
++
++#endif
++
+ /*
+  * YPPUSH PROTOCOL:
+  *
+@@ -317,6 +349,7 @@ bool_t	xdr_ypreq_xfr(XDR *, struct ypreq
+ bool_t	xdr_ypresp_val(XDR *, struct ypresp_val *);
+ bool_t	xdr_ypresp_key_val(XDR *, struct ypresp_key_val *);
+ bool_t	xdr_ypbind_resp(XDR *, struct ypbind_resp *);
++bool_t	xdr_ypbind_resp_v2(XDR *, struct ypbind_resp_v2 *);
+ bool_t	xdr_ypbind_setdom(XDR *, struct ypbind_setdom *);
+ bool_t	xdr_yp_inaddr(XDR *, struct inaddr *);
+ bool_t	xdr_ypmap_parms(XDR *, struct ypmap_parms *);
+Index: freebsd-head/include/rpcsvc/yp.x
+===================================================================
+--- freebsd-head/include/rpcsvc/yp.x	(revision 239326)
++++ freebsd-head/include/rpcsvc/yp.x	(working copy)
+@@ -196,7 +196,8 @@ enum ypbind_resptype {
+ };
+  
+ struct ypbind_binding {
+-    opaque ypbind_binding_addr[4]; /* In network order */
++    unsigned char ypbind_binding_family;
++    opaque ypbind_binding_addr[16]; /* In network order */
+     opaque ypbind_binding_port[2]; /* In network order */
+ };   
+ 
+@@ -207,12 +208,12 @@ case YPBIND_SUCC_VAL:
+         ypbind_binding ypbind_bindinfo;
+ };     
+ 
+-/* Detailed failure reason codes for response field ypbind_error*/
++/* Detailed failure reason codes for response field ypbind_error */
+  
+ const YPBIND_ERR_ERR    = 1;	/* Internal error */
+ const YPBIND_ERR_NOSERV = 2;	/* No bound server for passed domain */
+ const YPBIND_ERR_RESC   = 3;	/* System resource allocation failure */
+- 
++const YPBIND_ERR_FAMILY = 4;	/* Unsupported family */
+  
+ /*
+  * Request data structure for ypbind "Set domain" procedure.
+@@ -223,6 +224,30 @@ struct ypbind_setdom {
+ 	unsigned ypsetdom_vers;
+ };
+ 
++/* Backward compatibility for YPBIND protocol version 2 */
++#ifdef YPBIND_COMPAT_V2
++
++const YPBINDVERS_2 = 2;
++
++struct ypbind_binding_v2 {
++    opaque ypbind_binding_addr[4]; /* In network order */
++    opaque ypbind_binding_port[2]; /* In network order */
++};   
++
++union ypbind_resp_v2 switch (ypbind_resptype ypbind_status) {
++case YPBIND_FAIL_VAL:
++        unsigned ypbind_error;
++case YPBIND_SUCC_VAL:
++        ypbind_binding_v2 ypbind_bindinfo;
++};     
++
++struct ypbind_setdom_v2 {
++	domainname ypsetdom_domain;
++	ypbind_binding_v2 ypsetdom_binding;
++	unsigned ypsetdom_vers;
++};
++
++#endif
+ 
+ /*
+  * NIS v1 support for backwards compatibility
+@@ -371,7 +396,7 @@ program YPBINDPROG {
+ 
+ 		void
+ 		YPBINDPROC_SETDOM(ypbind_setdom) = 2;
+-	} = 2;
++	} = 3;
+ } = 100007;
+ 
+ #endif
+Index: freebsd-head/usr.sbin/ypbind/yp_ping.c
+===================================================================
+--- freebsd-head/usr.sbin/ypbind/yp_ping.c	(revision 239326)
++++ freebsd-head/usr.sbin/ypbind/yp_ping.c	(working copy)
+@@ -103,6 +103,8 @@ __FBSDID("$FreeBSD$");
+  */
+ 
+ 
++#if 0 /* TODO : Does __yp_getport achieve the same result ? */
++
+ static struct timeval timeout = { 1, 0 };
+ static struct timeval tottimeout = { 1, 0 };
+ 
+@@ -145,6 +147,7 @@ __pmap_getport(struct sockaddr_in *addre
+ 	address->sin_port = 0;
+ 	return (port);
+ }
++#endif
+ 
+ /*
+  * Transmit to YPPROC_DOMAIN_NONACK, return immediately.
+@@ -207,104 +210,230 @@ ypproc_domain_nonack_2_recv(domainname *
+  */
+ 
+ struct ping_req {
+-	struct sockaddr_in	sin;
++	struct sockaddr_storage	sst;
+ 	u_int32_t		xid;
+ };
+ 
++struct transport {
++	CLIENT			*clnt;
++	u_int32_t		xid_lookup;
++	struct sockaddr_storage *any;
++	int			sock;
++	struct netbuf		addr;
++};
++#define V4 0
++#define V6 1
++#ifdef INET6
++# define TSP_LEN (V6 + 1)
++#else
++# define TSP_LEN (V4 + 1)
++#endif
++
++u_short
++__rpcb_getport(const char *hostname, const char *netid,
++    const rpcprog_t prognum, const rpcvers_t versnum)
++{
++	struct sockaddr_storage sst;
++	struct netconfig *nconf;
++	struct netbuf svcaddr;
++	u_short port;
++
++	svcaddr.len = 0;
++	svcaddr.maxlen = sizeof(sst);
++	svcaddr.buf = &sst;
++	if ((nconf = getnetconfigent(netid)) == NULL ||
++	    !rpcb_getaddr(prognum, versnum, nconf, &svcaddr, hostname))
++		return (0);
++	switch (svcaddr.len) {
++	case sizeof(struct sockaddr_in) :
++		port = ss_to_sinport(svcaddr.buf);
++		break;
++#ifdef INET6
++	case sizeof(struct sockaddr_in6) :
++		port = ss_to_sin6port(svcaddr.buf);
++		break;
++#endif
++	default :
++		port = 0;
++	}
++	return (port); /* Network byte order */
++}
++
++static u_short
++__yp_getport(const struct sockaddr_storage *host, const char *netid)
++{
++	char str[ADDRSTRLEN];
++	int family;
++	char *ptr;
++
++	if (ss_extract(host, &family, &ptr, 0))
++		return (0);
++	inet_ntop(family, ptr, str, ADDRSTRLEN);
++	return (__rpcb_getport(str, netid, YPPROG, YPVERS));
++}
++
++static int
++rpc_init(struct transport *tsp)
++{
++	static struct timeval timenull;
++	int		async = TRUE;
++	int		dontblock = 1;
++	int		validtransp = 0;
++	int		i;
++
++	for (i = 0; i < TSP_LEN; ++i) {
++		if (tsp[i].any == NULL)
++			continue;
++#ifdef INET6
++		if (i == V6) {
++			tsp[i].sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
++			tsp[i].addr.len = sizeof(struct sockaddr_in6);
++		}
++		else /* V4 */
++#endif
++		{
++			tsp[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
++			tsp[i].addr.len = sizeof(struct sockaddr_in);
++		}
++		if (tsp[i].sock < 0)
++			return (1);
++		tsp[i].addr.buf = tsp[i].any;
++		tsp[i].clnt = clnt_dg_create(tsp[i].sock, &tsp[i].addr, YPPROG, YPVERS, 0, 0);
++		if (tsp[i].clnt == NULL)
++			return (1);
++		tsp[i].clnt->cl_auth = authsys_create_default();
++		clnt_control(tsp[i].clnt, CLSET_TIMEOUT, (char *)&timenull);
++		clnt_control(tsp[i].clnt, CLSET_ASYNC, (char *)&async);
++		ioctl(tsp[i].sock, FIONBIO, &dontblock);
++		++validtransp;
++	}
++	return (!validtransp);
++}
++
++static void
++rpc_destroy(struct transport *tsp)
++{
++	int		i;
++
++	for (i = 0; i < TSP_LEN; ++i) {
++		if (tsp[i].clnt) {
++			auth_destroy(tsp[i].clnt->cl_auth);
++			clnt_destroy(tsp[i].clnt);
++			tsp[i].clnt = NULL;
++		}
++		tsp[i].xid_lookup = 0;
++		tsp[i].any = NULL;
++		close(tsp[i].sock);
++		tsp[i].sock = -1;
++		tsp[i].addr.buf = NULL;
++	}
++}
++
+ int
+-__yp_ping(struct in_addr *restricted_addrs, int cnt, char *dom, short *port)
++__yp_ping(struct sockaddr_storage *restricted_addrs, int cnt, char *dom, u_short *port)
+ {
+-	struct timeval		tv = { 5, 0 };
+ 	struct ping_req		**reqs;
+ 	unsigned long		i;
+-	int			async;
+-	struct sockaddr_in	sin, *any = NULL;
+-	struct netbuf		addr;
++	int			n;
++	struct sockaddr_storage	*req_addr;
+ 	int			winner = -1;
+-	u_int32_t		xid_seed, xid_lookup;
+-	int			sock, dontblock = 1;
+-	CLIENT			*clnt;
++	u_int32_t		xid_seed;
+ 	char			*foo = dom;
+ 	int			validsrvs = 0;
++	u_short			yp_port;
++	struct transport	tsp[TSP_LEN] = {
++#ifdef INET6
++		{NULL, 0, NULL, -1},
++#endif
++		{NULL, 0, NULL, -1}
++	};
+ 
+ 	/* Set up handles. */
+ 	reqs = calloc(1, sizeof(struct ping_req *) * cnt);
+ 	xid_seed = time(NULL) ^ getpid();
+ 
+ 	for (i = 0; i < cnt; i++) {
+-		bzero((char *)&sin, sizeof(sin));
+-		sin.sin_family = AF_INET;
+-		bcopy((char *)&restricted_addrs[i],
+-			(char *)&sin.sin_addr, sizeof(struct in_addr));
+-		sin.sin_port = htons(__pmap_getport(&sin, YPPROG,
+-					YPVERS, IPPROTO_UDP));
+-		if (sin.sin_port == 0)
++		yp_port = __yp_getport(&restricted_addrs[i], CONNLESS_TSP);
++		if (yp_port == 0)
+ 			continue;
+ 		reqs[i] = calloc(1, sizeof(struct ping_req));
+-		bcopy((char *)&sin, (char *)&reqs[i]->sin, sizeof(sin));
+-		any = &reqs[i]->sin;
++		req_addr = &reqs[i]->sst;
++		bcopy((char *)&restricted_addrs[i], (char *)req_addr, sizeof(*req_addr));
++#ifdef INET6
++		if (ss_family(req_addr) == AF_INET6) {
++		    	ss_to_sin6port(req_addr) = yp_port;
++	    		tsp[V6].any = req_addr;
++		}
++		else /* AF_INET */
++#endif
++		{
++			ss_to_sinport(req_addr) = yp_port;
++			tsp[V4].any = req_addr;
++		}
+ 		reqs[i]->xid = xid_seed;
+ 		xid_seed++;
+ 		validsrvs++;
+ 	}
+ 
+ 	/* Make sure at least one server was assigned */
+-	if (!validsrvs) {
+-		free(reqs);
+-		return(-1);
+-	}
++	if (!validsrvs)
++		goto err;
+ 
+-	/* Create RPC handle */
+-	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+-	clnt = clntudp_create(any, YPPROG, YPVERS, tv, &sock);
+-	if (clnt == NULL) {
+-		close(sock);
+-		for (i = 0; i < cnt; i++)
+-			if (reqs[i] != NULL)
+-				free(reqs[i]);
+-		free(reqs);
+-		return(-1);
+-	}
+-	clnt->cl_auth = authunix_create_default();
+-	tv.tv_sec = 0;
+-
+-	clnt_control(clnt, CLSET_TIMEOUT, (char *)&tv);
+-	async = TRUE;
+-	clnt_control(clnt, CLSET_ASYNC, (char *)&async);
+-	ioctl(sock, FIONBIO, &dontblock);
++	/* Create RPC transports
++	 * an inet4 transport for any V4 address existing in `reqs'
++	 * an inet6 transport for any V6 address existing in `reqs'
++	 * otherwise, shutdown
++	 * */
++	if (rpc_init(tsp))
++		goto err;
+ 
+ 	/* Transmit */
+-	for (i = 0; i < cnt; i++) {
++	for (i = 0; i < cnt; i++)
+ 		if (reqs[i] != NULL) {
+-			clnt_control(clnt, CLSET_XID, (char *)&reqs[i]->xid);
+-			addr.len = sizeof(reqs[i]->sin);
+-			addr.buf = (char *) &reqs[i]->sin;
+-			clnt_control(clnt, CLSET_SVC_ADDR, &addr);
+-			ypproc_domain_nonack_2_send(&foo, clnt);
++			req_addr = &reqs[i]->sst;
++			n = (ss_family(req_addr) == AF_INET ? V4 : V6);
++			clnt_control(tsp[n].clnt, CLSET_XID, (char *)&reqs[i]->xid);
++			tsp[n].addr.buf = (char *) req_addr;
++			clnt_control(tsp[n].clnt, CLSET_SVC_ADDR, &tsp[n].addr);
++			ypproc_domain_nonack_2_send(&foo, tsp[n].clnt);
+ 		}
+-	}
+ 
+ 	/* Receive reply */
+-	ypproc_domain_nonack_2_recv(&foo, clnt);
++	for (i = 0; i < TSP_LEN; ++i)
++		if (tsp[i].clnt)
++			ypproc_domain_nonack_2_recv(&foo, tsp[i].clnt);
++
++	/* Get the winner */
++	for (i = 0; i < TSP_LEN; ++i)
++		if (tsp[i].clnt)
++			clnt_control(tsp[i].clnt, CLGET_XID, (char *)&tsp[i].xid_lookup);
+ 
+-	/* Got a winner -- look him up. */
+-	clnt_control(clnt, CLGET_XID, (char *)&xid_lookup);
+-	for (i = 0; i < cnt; i++) {
+-		if (reqs[i] != NULL && reqs[i]->xid == xid_lookup) {
+-			winner = i;
+-			*port = reqs[i]->sin.sin_port;
++	/* Look him up */
++	for (i = 0; i < cnt; i++)
++		if (reqs[i] != NULL) {
++			for (n = 0; n < TSP_LEN; ++n)
++				if (reqs[i]->xid == tsp[n].xid_lookup) {
++#ifdef INET6
++					if (n == V6)
++						*port = ss_to_sin6port(&reqs[i]->sst); /* Network byte order */
++					else /* V4 */
++#endif
++						*port = ss_to_sinport(&reqs[i]->sst);
++					winner = i;
++					break;
++				}
++			if (winner > 0)
++				break;
+ 		}
+-	}
+-
++					
+ 	/* Shut everything down */
+-	auth_destroy(clnt->cl_auth);
+-	clnt_destroy(clnt);
+-	close(sock);
+-
+-	for (i = 0; i < cnt; i++)
+-		if (reqs[i] != NULL)
+-			free(reqs[i]);
++err:
++	rpc_destroy(tsp);
++	if (validsrvs) {
++		for (i = 0; i < cnt; i++)
++			if (reqs[i] != NULL)
++				free(reqs[i]);
++	}
+ 	free(reqs);
+-
+ 	return(winner);
+ }
+Index: freebsd-head/usr.sbin/ypbind/ypbind.c
+===================================================================
+--- freebsd-head/usr.sbin/ypbind/ypbind.c	(revision 239326)
++++ freebsd-head/usr.sbin/ypbind/ypbind.c	(working copy)
+@@ -57,11 +57,13 @@ __FBSDID("$FreeBSD$");
+ #include <net/if.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
++#include <stdarg.h>
+ #include <rpc/pmap_clnt.h>
+ #include <rpc/pmap_prot.h>
+ #include <rpc/pmap_rmt.h>
+ #include <rpc/rpc_com.h>
+ #include <rpcsvc/yp.h>
++#include <rpcsvc/yp_utils.h>
+ #include <rpcsvc/ypclnt.h>
+ #include "yp_ping.h"
+ 
+@@ -69,6 +71,10 @@ __FBSDID("$FreeBSD$");
+ #define BINDINGDIR "/var/yp/binding"
+ #endif
+ 
++#if !defined(BINDINGDIR_V2) && defined(YPBIND_COMPAT_V2)
++#define BINDINGDIR_V2 "/var/yp/binding.2"
++#endif
++
+ #ifndef YPBINDLOCK
+ #define YPBINDLOCK "/var/run/ypbind.lock"
+ #endif
+@@ -76,9 +82,12 @@ __FBSDID("$FreeBSD$");
+ struct _dom_binding {
+ 	struct _dom_binding *dom_pnext;
+ 	char dom_domain[YPMAXDOMAIN + 1];
+-	struct sockaddr_in dom_server_addr;
++	struct sockaddr_storage dom_server_addr;
+ 	long int dom_vers;
+ 	int dom_lockfd;
++#ifdef YPBIND_COMPAT_V2
++	int dom_lockfd_v2;
++#endif
+ 	int dom_alive;
+ 	int dom_broadcast_pid;
+ 	int dom_pipe_fds[2];
+@@ -89,22 +98,26 @@ struct _dom_binding {
+ #define WRITEFD ypdb->dom_pipe_fds[1]
+ #define BROADFD broad_domain->dom_pipe_fds[1]
+ 
+-extern bool_t xdr_domainname(), xdr_ypbind_resp();
++extern bool_t xdr_domainname();
+ extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
+-extern bool_t xdr_ypbind_setdom();
++extern bool_t xdr_ypbind_setdom(), xdr_ypbind_setdom_v2();
++extern bool_t xdr_ypbind_resp(), xdr_ypbind_resp_v2();
+ 
++void	*ypbindproc_null(SVCXPRT *, void *, const rpcvers_t);
++void	*ypbindproc_setdom(SVCXPRT *, const union ypbf_setdom *, const rpcvers_t);
++char	*ypbindproc_domain(SVCXPRT *, domainname *, const rpcvers_t);
++void	ypbindprog(struct svc_req *, register SVCXPRT *);
++void	reaper(int);
++void	terminate(int);
+ void	checkwork(void);
+-void	*ypbindproc_null_2_yp(SVCXPRT *, void *, CLIENT *);
+-void	*ypbindproc_setdom_2_yp(SVCXPRT *, struct ypbind_setdom *, CLIENT *);
+-void	rpc_received(char *, struct sockaddr_in *, int);
++void	handle_children(struct _dom_binding *);
++int	tell_parent(char *, const struct sockaddr_storage *);
++bool_t	broadcast_result(bool_t *, const struct netbuf *, const struct netconfig *);
+ void	broadcast(struct _dom_binding *);
+ int	ping(struct _dom_binding *);
+-int	tell_parent(char *, struct sockaddr_in *);
+-void	handle_children(struct _dom_binding *);
+-void	reaper(int);
+-void	terminate(int);
++void	rpc_received(char *, const struct sockaddr_storage *, int);
++int	verify(const struct sockaddr_storage *);
+ void	yp_restricted_mode(char *);
+-int	verify(struct in_addr);
+ 
+ char *domain_name;
+ struct _dom_binding *ypbindlist;
+@@ -128,7 +141,7 @@ static int not_responding_count = 0;
+ #define RESTRICTED_SERVERS 10
+ int yp_restricted = 0;
+ int yp_manycast = 0;
+-struct in_addr restricted_addrs[RESTRICTED_SERVERS];
++struct sockaddr_storage restricted_addrs[RESTRICTED_SERVERS];
+ 
+ /* No more than MAX_CHILDREN child broadcasters at a time. */
+ #ifndef MAX_CHILDREN
+@@ -154,32 +167,160 @@ int domains = 0;
+ int yplockfd;
+ fd_set fdsr;
+ 
+-SVCXPRT *udptransp, *tcptransp;
++#define CLOSE_LKS	1
++#define FREE_DOMB	2
++
++static int
++create_domb_file(const struct _dom_binding *ypdb, const char *binding_dir)
++{
++	char path[MAXPATHLEN];
++	int fd;
++
++	sprintf(path, "%s/%s.%ld", binding_dir,
++		ypdb->dom_domain, ypdb->dom_vers);
++#ifdef O_SHLOCK
++	if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) {
++		(void)mkdir(binding_dir, 0755);
++		if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1)
++			return (-1);
++	}
++#else
++	if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) {
++		(void)mkdir(binding_dir, 0755);
++		if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1)
++			return (-1);
++	}
++	flock(fd, LOCK_SH);
++#endif
++	return (fd);
++}
++
++static void
++register_domb(struct _dom_binding *ypdb, const struct sockaddr_storage *addr)
++{
++	struct iovec iov[2];
++	struct ypbind_resp ybr;
++	int family;
++	u_short port;
++
++	if (ypdb->dom_lockfd != -1)
++		close(ypdb->dom_lockfd);
++
++	ypdb->dom_lockfd = create_domb_file(ypdb, BINDINGDIR);
++	if (ypdb->dom_lockfd == -1)
++		return;
++
++	port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS);
++	iov[0].iov_base = (char *)&port;
++	iov[0].iov_len = sizeof(port);
++	iov[1].iov_base = (char *)&ybr;
++	iov[1].iov_len = sizeof(ybr);
++	
++	family = ss_family(addr);
++	bzero(&ybr, sizeof(ybr));
++	ybr.ypresp_status = YPBIND_SUCC_VAL;
++	ybr.ypresp_family = family;
++	*(u_short *)&ybr.ypresp_port = *ss_getport(addr);
++#ifdef INET6
++	if (family == AF_INET6)
++		bcopy(ss_to_sin6addr(addr), (char *) ybr.ypresp_addr, sizeof(struct in6_addr));
++	else
++#endif
++		bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr, sizeof(struct in_addr));
++
++	if (writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) {
++		syslog(LOG_WARNING, "write: %m");
++		close(ypdb->dom_lockfd);
++		ypdb->dom_lockfd = -1;
++	}
++}
++
++#ifdef YPBIND_COMPAT_V2
++static void
++register_domb_v2(struct _dom_binding *ypdb, const struct sockaddr_storage *addr)
++{
++	struct iovec iov[2];
++	struct ypbind_resp_v2 ybr;
++	int family;
++	u_short port;
++
++	if (ypdb->dom_lockfd_v2 != -1)
++		close(ypdb->dom_lockfd_v2);
++
++	ypdb->dom_lockfd_v2 = create_domb_file(ypdb, BINDINGDIR_V2);
++	if (ypdb->dom_lockfd_v2 == -1)
++		return;
++
++	port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS_2);
++	iov[0].iov_base = (char *)&port;
++	iov[0].iov_len = sizeof(port);
++	iov[1].iov_base = (char *)&ybr;
++	iov[1].iov_len = sizeof(ybr);
++	
++	family = ss_family(addr);
++	bzero(&ybr, sizeof(ybr));
++	if (family != AF_INET) { /* AF_INET6 is not supported in version 2 */
++		ybr.ypresp_status = YPBIND_FAIL_VAL;
++		ybr.ypresp_error_v2 = YPBIND_ERR_FAMILY;
++	}
++	else {
++		ybr.ypresp_status = YPBIND_SUCC_VAL;
++		bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr_v2, sizeof(struct in_addr));
++		*(u_short *)&ybr.ypresp_port_v2 = ss_to_sinport(addr);
++	}
++
++	if (writev(ypdb->dom_lockfd_v2, iov, 2) != iov[0].iov_len + iov[1].iov_len) {
++		syslog(LOG_WARNING, "write: %m");
++		close(ypdb->dom_lockfd_v2);
++		ypdb->dom_lockfd_v2 = -1;
++	}
++}
++#endif
++
++static void
++unregister_domb(struct _dom_binding *ypdb, unsigned char mode)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120802013814.8537F106566C>