socsvn commit: r240005 - in soc2012/exxo: . patches
exxo at FreeBSD.org
exxo at FreeBSD.org
Thu Aug 2 01:38:16 UTC 2012
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 ***
More information about the svn-soc-all
mailing list