FreeBSD Bugzilla – Attachment 157542 Details for
Bug 200356
dns/mDNSResponder_nss: Build and install nss_mdns
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
The right patch file
patch-mDNSPosix-nss_mdns.c (text/plain), 10.11 KB, created by
sef
on 2015-06-08 19:14:46 UTC
(
hide
)
Description:
The right patch file
Filename:
MIME Type:
Creator:
sef
Created:
2015-06-08 19:14:46 UTC
Size:
10.11 KB
patch
obsolete
>--- mDNSPosix/nss_mdns.c.orig 2012-04-14 23:07:19.000000000 -0700 >+++ mDNSPosix/nss_mdns.c 2015-05-20 13:18:19.000000000 -0700 >@@ -2721,3 +2721,339 @@ > > return -1; > } >+ >+static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_gethostbyname2_r); >+static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_gethostbyaddr_r); >+static NSS_METHOD_PROTOTYPE(__nss_bsdcompat_getaddrinfo); >+ >+static ns_mtab methods[] = { >+ /* database, name, method, mdata */ >+ { NSDB_HOSTS, "gethostbyaddr_r", __nss_bsdcompat_gethostbyaddr_r, NULL }, >+ { NSDB_HOSTS, "gethostbyname2_r", __nss_bsdcompat_gethostbyname2_r, NULL }, >+ { NSDB_HOSTS, "getaddrinfo", __nss_bsdcompat_getaddrinfo, NULL }, >+}; >+ >+/* >+ * The prototype for gethostbyaddr_r is: >+ * int gethostbyaddr_r(const void *addr, socklen_t len, int type, >+ * struct hostent *ret, char *buf, size_t buflen, >+ * struct hostent **result, int *h_errnop); >+ * >+ * nsdispatch calls gethostbyaddr_r as: >+ * rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS, >+ * "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen, >+ * &ret_errno, h_errnop); >+ * which translates into us being (effectively) called as: >+ * rval = func(result, mdata, uaddr, len, type, ret, buf, buflen, &ret_errno, h_errnop) >+ * We turn result into a struct hostent **, set *result to NULL, and then >+ * call _nss_mdns_gethostbyaddr(). >+ */ >+static int >+__nss_bsdcompat_gethostbyaddr_r(void *retval, void *mdata __unused, va_list ap) >+{ >+ const void *addr; >+ socklen_t len; >+ int type; >+ struct hostent *ret; >+ char *buf; >+ size_t buflen; >+ struct hostent **result = (struct hostent**)retval; >+ int *ret_errno; >+ int *h_errnop; >+ enum nss_status status; >+ >+ addr = va_arg(ap, const void*); >+ len = va_arg(ap, int); >+ type = va_arg(ap, int); >+ ret = va_arg(ap, struct hostent *); >+ buf = va_arg(ap, char *); >+ buflen = va_arg(ap, size_t); >+ ret_errno = va_arg(ap, int *); >+ h_errnop = va_arg(ap, int *); >+ >+ *result = NULL; >+ status = _nss_mdns_gethostbyaddr_r(addr, len, type, ret, buf, buflen, ret_errno, h_errnop); >+ status = __nss_compat_result(status, *h_errnop); >+ if (status == NS_SUCCESS) >+ *result = ret; >+ >+ return (status); >+} >+ >+/* >+ * This is a lot of guesswork on my part. >+ * nsdispatch calls getaddrinfo as: >+ * >+ * _nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", >+ * default_dns_files, hostname, pai) >+ * >+ * which translates to us being (effectively) called as: >+ * rval = func(result, mdata, hostname, pai) >+ * The first argument, result, is struct addrinfo **. >+ * >+ */ >+ >+static struct addrinfo * >+get_one_ai(const char *hostname, int af, const struct addrinfo *hints) >+{ >+ nss_status lookup_status; >+ hostent hostent_buf; >+ char buf[1024] = { 0 }; >+ int err1, h_err1; >+ struct addrinfo *retval = NULL; >+ >+ memset(&hostent_buf, 0, sizeof(hostent_buf)); >+ lookup_status = mdns_gethostbyname2(hostname, >+ af, >+ &hostent_buf, >+ buf, >+ sizeof(buf), >+ &err1, >+ &h_err1); >+ lookup_status = __nss_compat_result(lookup_status, h_err1); >+ if (lookup_status == NS_SUCCESS) { >+ // Great, we found it, now what? >+ retval = calloc(1, sizeof(struct addrinfo) + sizeof(struct sockaddr_storage)); >+ if (retval) { >+ // Take advantage of c's scaling >+ retval->ai_addr = (struct sockaddr*)(retval + 1); >+ retval->ai_flags = hints->ai_flags; >+ retval->ai_socktype = hints->ai_socktype; >+ retval->ai_protocol = hints->ai_protocol; >+ retval->ai_family = hostent_buf.h_addrtype; >+ retval->ai_addrlen = hostent_buf.h_length; >+ retval->ai_addr->sa_len = hostent_buf.h_length; >+ retval->ai_addr->sa_family = retval->ai_family; >+ >+ if (retval->ai_family == PF_INET) { >+ struct sockaddr_in *sin = (void*)retval->ai_addr; >+ retval->ai_addrlen = sizeof(*sin); >+ memcpy(&sin->sin_addr, hostent_buf.h_addr, hostent_buf.h_length); >+ } else if (retval->ai_family == PF_INET6) { >+ struct sockaddr_in6 *sin = (void*)retval->ai_addr; >+ retval->ai_addrlen = sizeof(*sin); >+ memcpy(&sin->sin6_addr, hostent_buf.h_addr, hostent_buf.h_length); >+ } else { >+ retval->ai_addrlen = sizeof(struct sockaddr_storage); >+ memcpy(retval->ai_addr->sa_data, >+ hostent_buf.h_addr, >+ hostent_buf.h_length); >+ } >+ retval->ai_canonname = strdup(hostname); >+#ifdef DEBUG >+ fprintf(stderr, "%s: ai_canonname = %s, ai_addrlen = %d\n", __FUNCTION__, retval->ai_canonname, (int)(retval->ai_addrlen)); >+ { >+ char ascii[1024]; >+ void *sin_ptr; >+ >+ if (retval->ai_family == PF_INET) { >+ struct sockaddr_in *sin = (void*)retval->ai_addr; >+ sin_ptr = &sin->sin_addr; >+ } else if (retval->ai_family == PF_INET6) { >+ struct sockaddr_in6 *sin6 = (void*)retval->ai_addr; >+ sin_ptr = &sin6->sin6_addr; >+ } else { >+ sin_ptr = &retval->ai_addr; >+ } >+ if (inet_ntop(retval->ai_family, >+ sin_ptr, >+ ascii, >+ sizeof(ascii))) { >+ fprintf(stderr, "\tip = %s\n", ascii); >+ } else { >+ fprintf(stderr, "\tUnable to convert address to string\n"); >+ } >+ } >+#endif >+ } >+ } >+//#ifdef DEBUG >+ if (retval == NULL) >+ fprintf(stderr, "%s: returning %p, lookup_status = %d\n", __FUNCTION__, retval, lookup_status); >+//#endif >+ return retval; >+} >+ >+#ifdef DEBUG >+static void >+PrintAddrinfo(struct addrinfo *ai) >+{ >+ char buf[1024]; >+ void *sin_ptr; >+ if (ai == NULL) >+ return; >+ buf[0] = 0; >+ if (ai->ai_family == PF_INET) { >+ struct sockaddr_in *sin = (void*)ai->ai_addr; >+ sin_ptr = &sin->sin_addr; >+ } else if (ai->ai_family == PF_INET6) { >+ struct sockaddr_in6 *sin6 = (void*)ai->ai_addr; >+ sin_ptr = &sin6->sin6_addr; >+ } else { >+ sin_ptr = &ai->ai_addr; >+ } >+ inet_ntop(ai->ai_family, sin_ptr, buf, sizeof(buf)); >+ >+ fprintf(stderr, "struct addrinfo {\n"); >+ fprintf(stderr, "\tai_flags = %#x,\n", ai->ai_flags); >+ fprintf(stderr, "\tai_family = %d,\n", ai->ai_family); >+ fprintf(stderr, "\tai_socktype = %d,\n", ai->ai_socktype); >+ fprintf(stderr, "\tai_protocol = %d,\n", ai->ai_protocol); >+ fprintf(stderr, "\tai_addrlen = %d,\n", (int)ai->ai_addrlen); >+ fprintf(stderr, "\tai_addr = %s,\n", buf[0] ? buf : "(unknown?)"); >+ fprintf(stderr, "}\n"); >+ >+} >+#endif >+ >+static int >+__nss_bsdcompat_getaddrinfo(void *result, void *mdata __unused, va_list ap) >+{ >+ const char *hostname; >+ const struct addrinfo *pai; >+ struct addrinfo **retval = (struct addrinfo **)result; >+ >+ hostname = va_arg(ap, const char *); >+ pai = va_arg(ap, const struct addrinfo *); >+ >+ *retval = NULL; >+ // Some quick error checking >+ if (hostname == NULL || pai == NULL) { >+#ifdef DEBUG >+ fprintf(stderr, "%s(%d): Returning NS_UNAVAIL\n", __FUNCTION__, __LINE__); >+#endif >+ return (NS_UNAVAIL); >+ } >+ >+#ifdef DEBUG >+ { >+ fprintf(stderr, >+ "%s: *retval = %p, hostname = %s, pai = { ai_flags = %#x, ai_family = %#x, ai_socktype = %#x, ai_protocol = %#x }\n", >+ __FUNCTION__, *retval, hostname, pai->ai_flags, pai->ai_family, pai->ai_socktype, pai->ai_protocol); >+ } >+#endif >+ >+ /* >+ * We can do three kinds of searches: >+ * PF_UNSPEC: whichever kind we find >+ * PF_INET: An IPv4 address >+ * PF_INET6: An IPv6 address. >+ * We'll use mdns_gethostbyname2_r(), >+ * which will handle PF_INET or PF_INET6. >+ * Buf if we're given PF_UNSPEC we should try each in >+ * succession, I suppose? Or perhaps we're supposed to >+ * return both if we can? >+ */ >+ switch (pai->ai_family) { >+ case PF_INET: >+ case PF_INET6: >+ *retval = get_one_ai(hostname, pai->ai_family, pai); >+#ifdef DEBUG >+ fprintf(stderr, "Only needed one, *retval = %p\n", *retval); >+#endif >+ break; >+ case PF_UNSPEC: >+ { >+ // Do both! >+ struct addrinfo *ipv4, *ipv6; >+ struct addrinfo sentinel, *tmp = &sentinel; >+ memset(&sentinel, 0, sizeof(sentinel)); >+ if ((ipv6 = get_one_ai(hostname, PF_INET6, pai)) != NULL) { >+ tmp->ai_next = ipv6; >+ tmp = ipv6; >+ } >+ if ((ipv4 = get_one_ai(hostname, PF_INET, pai)) != NULL) { >+ tmp->ai_next = ipv4; >+ tmp = ipv4; >+ } >+ *retval = sentinel.ai_next; >+ } >+ break; >+ default: >+#ifdef DEBUG >+ fprintf(stderr, "%s(%d): Returning NS_UNAVAIL\n", __FUNCTION__, __LINE__); >+#endif >+ return (NS_UNAVAIL); >+ } >+ >+ if (*retval == NULL) { >+#ifdef DEBUG >+ fprintf(stderr, "%s(%d): Returning NS_NOTFOUND\n", __FUNCTION__, __LINE__); >+#endif >+ return (NS_NOTFOUND); >+ } >+ >+#ifdef DEBUG >+ { >+ fprintf(stderr, "%s: *retval = %p\n", __FUNCTION__, *retval); >+ } >+ struct addrinfo *tai; >+ for (tai = *retval; tai; tai = tai->ai_next) { >+ PrintAddrinfo(tai); >+ } >+#endif >+ return (NS_SUCCESS); >+} >+ >+/* >+ * The prototype for gethostbyname2_r is >+ * gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer, >+ * size_t buflen, struct hostent **result, int *h_errnop) >+ * >+ * nsdispatch calls gethostbyname2_r as >+ * rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS, >+ * "gethostbyname2_r", default_src, name, af, hp, buf, buflen, >+ * &ret_errno, h_errnop); >+ * which translates into us being (effectively) called as: >+ * rval = func(result, mdata, name, af, hp, buf, buflen, &ret_errno, h_errnop) >+ * We turn result into a struct hostent **, set *result to NULL, and then >+ * call _nss_mdns_gethostbyname2_r() >+ */ >+static int >+__nss_bsdcompat_gethostbyname2_r(void *retval, void *mdata __unused, >+ va_list ap) >+{ >+ char *buf; >+ const char *name; >+ int *h_errnop; >+ struct hostent *hp; >+ struct hostent **resultp = (struct hostent **)retval; >+ int af; >+ size_t buflen; >+ int ret_errno; >+ enum nss_status status; >+ >+ name = va_arg(ap, char *); >+ af = va_arg(ap, int); >+ hp = va_arg(ap, struct hostent *); >+ buf = va_arg(ap, char *); >+ buflen = va_arg(ap, size_t); >+ ret_errno = va_arg(ap, int); >+ h_errnop = va_arg(ap, int *); >+ >+ if (hp == NULL) >+ return (NS_UNAVAIL); >+ >+ *resultp = NULL; >+ status = _nss_mdns_gethostbyname2_r(name, af, hp, buf, buflen, >+ &ret_errno, h_errnop); >+ >+ status = __nss_compat_result(status, *h_errnop); >+ if (status == NS_SUCCESS) >+ *resultp = hp; >+ return (status); >+} >+ >+ns_mtab * >+nss_module_register(const char *source __unused, unsigned int *mtabsize, >+ nss_module_unregister_fn *unreg) >+{ >+#ifdef DEBUG >+ { >+ fprintf(stderr, "%s(%s, %p, %p)\n", __FUNCTION__, source, mtabsize, unreg); >+ } >+#endif >+ *mtabsize = sizeof(methods)/sizeof(methods[0]); >+ *unreg = NULL; >+ return (methods); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 200356
:
156993
|
157538
|
157540
| 157542