public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix NIS getservbyproto plus another performance tweak for NULL protocol
@ 2004-03-31  1:46 Jakub Jelinek
  2004-03-31  8:04 ` Ulrich Drepper
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2004-03-31  1:46 UTC (permalink / raw)
  To: Ulrich Drepper, Thorsten Kukuk; +Cc: Glibc hackers

Hi!

POSIX says getservbyproto's first argument is in network byte order.
Unfortunately _nss_nis_getservbyproto_r forget to ntohs it when snprintfing,
so it issued a request for a wrong service with yp_match on little endian
boxes.  If lucky, it would not be a valid service and sequential scanning
was done, if unlucky, wrong service was returned.

Another thing is a performance tweak for protocol == NULL.  "tcp" and "udp"
are the most often used protocols, so libnss_nis.so can first try
*/tcp, then */udp and then fallback to the current sequential scanning.
NIS doesn't comply to POSIX anyway in that it doesn't guarantee that even
during sequential YPPROC_ALL scanning of services.by{,service}name original
first service will be found first, so scanning for tcp and udp first doesn't
make things worse in this regard.

Plus there are 2 small tweaks, one is to use always services.byname map
for sequential scanning (the old code did that and the comment sounded
like there could be NIS servers without services.byservicename but with
services.byname) and the second one is not to allocate excessive 100 chars
for %d integer.

2004-03-30  Jakub Jelinek  <jakub@redhat.com>

	* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r): If protocol
	== NULL, try name/tcp and name/udp first before falling back into
	the sequential scanning.  Use services.byname database for
	sequential scanning.
	(_nss_nis_getservbyport_r): Likewise.  Just allocate sizeof (int) * 3
	chars for integer.

	* nis/nss_nis/nis-service.c (_nss_nis_getservbyport_r): Convert
	proto to host by order for snprintf.

--- libc/nis/nss_nis/nis-service.c.jj	2004-03-30 22:15:38.000000000 +0200
+++ libc/nis/nss_nis/nis-service.c	2004-03-30 23:03:03.899449997 +0200
@@ -268,6 +268,7 @@ _nss_nis_getservbyname_r (const char *na
 {
   enum nss_status status;
   char *domain;
+  const char *proto;
 
   if (name == NULL)
     {
@@ -279,18 +280,21 @@ _nss_nis_getservbyname_r (const char *na
     return NSS_STATUS_UNAVAIL;
 
   /* If the protocol is given, we could try if our NIS server knows
-     about services.byservicename map. If yes, we only need one query */
-  if (protocol != NULL)
+     about services.byservicename map. If yes, we only need one query.
+     If the protocol is not given, try first name/tcp, then name/udp
+     and then fallback to sequential scanning of services.byname map.  */
+  proto = protocol != NULL ? protocol : "tcp";
+  do
     {
-      char key[strlen (name) + strlen (protocol) + 2];
+      char key[strlen (name) + strlen (proto) + 2];
       char *cp, *result;
       size_t keylen, len;
       int int_len;
 
-      /* key is: "name/protocol" */
+      /* key is: "name/proto" */
       cp = stpcpy (key, name);
       *cp++ = '/';
-      stpcpy (cp, protocol);
+      stpcpy (cp, proto);
       keylen = strlen (key);
       status = yperr2nss (yp_match (domain, "services.byservicename", key,
 				    keylen, &result, &int_len));
@@ -329,6 +333,7 @@ _nss_nis_getservbyname_r (const char *na
 	    return NSS_STATUS_SUCCESS;
 	}
     }
+  while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL));
 
   struct ypall_callback ypcb;
   struct search_t req;
@@ -343,7 +348,7 @@ _nss_nis_getservbyname_r (const char *na
   req.buflen = buflen;
   req.errnop = errnop;
   req.status = NSS_STATUS_NOTFOUND;
-  status = yperr2nss (yp_all (domain, "services.byservicename", &ypcb));
+  status = yperr2nss (yp_all (domain, "services.byname", &ypcb));
 
   if (status != NSS_STATUS_SUCCESS)
     return status;
@@ -358,20 +363,24 @@ _nss_nis_getservbyport_r (int port, cons
 {
   enum nss_status status;
   char *domain;
+  const char *proto;
 
   if (yp_get_default_domain (&domain))
     return NSS_STATUS_UNAVAIL;
 
-  /* If the protocol is given, we only need one query */
-  if (protocol != NULL)
+  /* If the protocol is given, we only need one query.
+     Otherwise try first port/tcp, then port/udp and then fallback
+     to sequential scanning of services.byname.  */
+  proto = protocol != NULL ? protocol : "tcp";
+  do
     {
-      char key[100 + strlen (protocol) + 2];
+      char key[sizeof (int) * 3 + strlen (proto) + 2];
       char *result;
       size_t keylen, len;
       int int_len;
 
-      /* key is: "port/protocol" */
-      keylen = snprintf (key, sizeof (key), "%d/%s", port, protocol);
+      /* key is: "port/proto" */
+      keylen = snprintf (key, sizeof (key), "%d/%s", ntohs (port), proto);
       status = yperr2nss (yp_match (domain, "services.byname", key,
 				    keylen, &result, &int_len));
       len = int_len;
@@ -409,6 +418,7 @@ _nss_nis_getservbyport_r (int port, cons
 	    return NSS_STATUS_SUCCESS;
 	}
     }
+  while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL));
 
   if (port == -1)
     return NSS_STATUS_NOTFOUND;

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix NIS getservbyproto plus another performance tweak for NULL protocol
  2004-03-31  1:46 [PATCH] Fix NIS getservbyproto plus another performance tweak for NULL protocol Jakub Jelinek
@ 2004-03-31  8:04 ` Ulrich Drepper
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Drepper @ 2004-03-31  8:04 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Thorsten Kukuk, Glibc hackers

Applied.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-31  0:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-31  1:46 [PATCH] Fix NIS getservbyproto plus another performance tweak for NULL protocol Jakub Jelinek
2004-03-31  8:04 ` Ulrich Drepper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).