From alfred@FreeBSD.org  Sun Dec 21 12:29:21 2003
Return-Path: <alfred@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 22B3B16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 21 Dec 2003 12:29:21 -0800 (PST)
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 4DDE643D4C
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 21 Dec 2003 12:29:20 -0800 (PST)
	(envelope-from alfred@FreeBSD.org)
Received: from freefall.freebsd.org (alfred@localhost [127.0.0.1])
	by freefall.freebsd.org (8.12.10/8.12.10) with ESMTP id hBLKTKFR059462
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 21 Dec 2003 12:29:20 -0800 (PST)
	(envelope-from alfred@freefall.freebsd.org)
Received: (from alfred@localhost)
	by freefall.freebsd.org (8.12.10/8.12.10/Submit) id hBLKTKjr059461;
	Sun, 21 Dec 2003 12:29:20 -0800 (PST)
	(envelope-from alfred)
Message-Id: <200312212029.hBLKTKjr059461@freefall.freebsd.org>
Date: Sun, 21 Dec 2003 12:29:20 -0800 (PST)
From: Alfred Perlstein <alfred@FreeBSD.org>
Reply-To: Alfred Perlstein <alfred@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: need thread safe gethostent() and getservent()
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         60477
>Category:       kern
>Synopsis:       [libc] [patch] need thread safe gethostent() and getservent()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    ume
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 21 12:30:11 PST 2003
>Closed-Date:    Mon Mar 20 12:49:51 GMT 2006
>Last-Modified:  Mon Mar 20 12:49:51 GMT 2006
>Originator:     Alfred Perlstein
>Release:        FreeBSD 4.9-STABLE i386
>Organization:
RED, Inc.
>Environment:
System: FreeBSD freefall.freebsd.org 4.9-STABLE FreeBSD 4.9-STABLE #10: Wed Dec 10 19:46:23 PST 2003 kensmith@freefall.freebsd.org:/c/src/sys/compile/FREEFALL i386


>Description:
	Hard to write thread safe networking apps without reentrant
	versions of these function.
>How-To-Repeat:
	
>Fix:

	Use thread local storage to make these safe or...

	Implement gethostent_r and getservent_r, perferably from the
	http://publib16.boulder.ibm.com/pseries/en_US/libs/commtrf2/gethostent_r.htm specification, although
	or
	http://www.qnx.com/developer/docs/qnx_6.1_docs/neutrino/lib_ref/g/gethostent_r.html
	I feel that the one that Solaris and glibC offer are technically useless.

	I think that making them thread safe by using thread local data
	might also work reasonably well.

	
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->deischen 
Responsible-Changed-By: bms 
Responsible-Changed-When: Wed Jun 23 06:48:48 GMT 2004 
Responsible-Changed-Why:  
deischen is dealing with TLS 

http://www.freebsd.org/cgi/query-pr.cgi?pr=60477 

From: Michael Spanier <mail@michael-spanier.de>
To: freebsd-gnats-submit@FreeBSD.org, alfred@FreeBSD.org
Cc:  
Subject: Re: bin/60477: need thread safe gethostent() and getservent()
Date: Thu, 5 Aug 2004 18:25:04 +0200

 Hi,
 
 
 here a prelimary idea of the gethostent_r function.
 
 #include <netdb.h>
 
 int gethostent_r (htent, ht_data)
 struct hostent *htent;
 struct hostent_data *ht_data;
 
 struct hostent_data {
          struct in_addr host_addr;               /* host address */
          char    *h_addr_ptrs[_MAXADDRS + 1];    /* list of addresses */
          char    hostaddr[_MAXADDRS];            /* host address */
          char    hostbuf[BUFSIZ+1];              /* host info buffer */
          char    *host_aliases[_MAXALIASES];     /* list of aliases */
          char    *host_addrs[2];                 /* short list of 
 addresses */
          FILE    *hostf;                         /* hosts file */
 };
 
 int
 gethostent_r( struct hostent *host, struct hostent_data *ht_data )
 {
          char *p;
          char *cp, **q;
          int af, len;
 
          if (!ht_data->hostf && !(ht_data->hostf = fopen(_PATH_HOSTS, 
 "r" ))) {
                  return NETDB_INTERNAL;
          }
 
 again:
          if (!(p = fgets(ht_data->hostbuf, sizeof ht_data->hostbuf, 
 ht_data->hostf))) {
                  return HOST_NOT_FOUND;
          }
          if (*p == '#')
                  goto again;
          if (!(cp = strpbrk(p, "#\n")))
                  goto again;
          *cp = '\0';
          if (!(cp = strpbrk(p, " \t")))
                  goto again;
          *cp++ = '\0';
          if (inet_pton(AF_INET6, p, ht_data->host_addr) > 0) {
                  af = AF_INET6;
                  len = IN6ADDRSZ;
          } else if (inet_pton(AF_INET, p, ht_data->host_addr) > 0) {
                  if (_res.options & RES_USE_INET6) {
                          _map_v4v6_address((char*)ht_data->host_addr, 
 (char*)ht_data->host_addr);
                          af = AF_INET6;
                          len = IN6ADDRSZ;
                  } else {
                          af = AF_INET;
                          len = INADDRSZ;
                  }
          } else {
                  goto again;
          }
          ht_data->h_addr_ptrs[0] = (char *) ht_data->host_addr;
          ht_data->h_addr_ptrs[1] = NULL;
          host->h_addr_list = h_addr_ptrs;
          host->h_length = len;
          host->h_addrtype = af;
          while (*cp == ' ' || *cp == '\t')
                  cp++;
          host->h_name = cp;
          q = host->h_aliases = ht_data->host_aliases;
          if ((cp = strpbrk(cp, " \t")) != NULL)
                  *cp++ = '\0';
          while (cp && *cp) {
                  if (*cp == ' ' || *cp == '\t') {
                          cp++;
                          continue;
                  }
                  if (q < &ht_data->host_aliases[MAXALIASES - 1])
                          *q++ = cp;
                  if ((cp = strpbrk(cp, " \t")) != NULL)
                          *cp++ = '\0';
          }
          *q = NULL;
          return NETDB_SUCCESS;
 }
 
 void
 endhostent_r (struct hostent_data *ht_data)
 {
      if (ht_data->hostf)
          fclose(ht_data->hostf);
      free( ht_data );
 }
 

From: Michael Spanier <mail@michael-spanier.de>
To: freebsd-gnats-submit@FreeBSD.org, alfred@FreeBSD.org
Cc:  
Subject: Re: bin/60477: need thread safe gethostent() and getservent()
Date: Thu, 5 Aug 2004 23:59:07 +0200

 --Apple-Mail-2--380685334
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain;
 	charset=US-ASCII;
 	format=flowed
 
 Some improvement, now it even compiles.
 
 Source is attached.
 
 --Apple-Mail-2--380685334
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain;
 	x-unix-mode=0644;
 	name="gethostent_r.c"
 Content-Disposition: attachment;
 	filename=gethostent_r.c
 
 #include <sys/cdefs.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdarg.h>
 #include <nsswitch.h>
 #include <arpa/nameser.h>       /* XXX */
 #include <resolv.h>             /* XXX */
 #include <netdb.h>
  
 #define _MAXALIASES	35
 #define _MAXADDRS	35
 
 struct hostent_data {
         struct in_addr host_addr;               /* host address */
         char    *h_addr_ptrs[_MAXADDRS + 1];    /* list of addresses */
         char    hostaddr[_MAXADDRS];            /* host address */
         char    hostbuf[BUFSIZ+1];              /* host info buffer */
         char    *host_aliases[_MAXALIASES];     /* list of aliases */
         char    *host_addrs[2];                 /* short list of addresses */
         FILE    *hostf;                         /* hosts file */
 };
 
 int
 gethostent_r( struct hostent *host, struct hostent_data *ht_data )
 {
         char *p;
         char *cp, **q;
         int af, len;
 
         if (!ht_data->hostf && !(ht_data->hostf = fopen(_PATH_HOSTS, "r" ))) {
                 return NETDB_INTERNAL;
         }
         
 again:
         if (!(p = fgets(ht_data->hostbuf, sizeof ht_data->hostbuf, ht_data->hostf))) {
                 return HOST_NOT_FOUND;
         }
         if (*p == '#')
                 goto again;
         if (!(cp = strpbrk(p, "#\n")))
                 goto again;
         *cp = '\0';
         if (!(cp = strpbrk(p, " \t")))
                 goto again;
         *cp++ = '\0';
         if (inet_pton(AF_INET6, p, &ht_data->host_addr) > 0) {
                 af = AF_INET6;
                 len = IN6ADDRSZ;
         } else if (inet_pton(AF_INET, p, &ht_data->host_addr) > 0) {
                 if (_res.options & RES_USE_INET6) {
                         _map_v4v6_address((char*)&ht_data->host_addr, (char*)&ht_data->host_addr);
                         af = AF_INET6;
                         len = IN6ADDRSZ;
                 } else {
                         af = AF_INET;
                         len = INADDRSZ;
                 }
         } else {
                 goto again;
         }
         ht_data->h_addr_ptrs[0] = (char *) &ht_data->host_addr;
         ht_data->h_addr_ptrs[1] = NULL;
         host->h_addr_list = ht_data->h_addr_ptrs;
         host->h_length = len;
         host->h_addrtype = af;
         while (*cp == ' ' || *cp == '\t')
                 cp++;
         host->h_name = cp;
         q = host->h_aliases = ht_data->host_aliases;
         if ((cp = strpbrk(cp, " \t")) != NULL)
                 *cp++ = '\0';
         while (cp && *cp) {
                 if (*cp == ' ' || *cp == '\t') {
                         cp++;
                         continue;
                 }
                 if (q < &ht_data->host_aliases[_MAXALIASES - 1])
                         *q++ = cp;
                 if ((cp = strpbrk(cp, " \t")) != NULL)
                         *cp++ = '\0';
         }
         *q = NULL;
         return NETDB_SUCCESS;
 }
 
 void
 endhostent_r (struct hostent_data *ht_data)
 {
     if (ht_data->hostf)
         fclose(ht_data->hostf);
 }
 
 --Apple-Mail-2--380685334--
 
State-Changed-From-To: open->closed 
State-Changed-By: ume 
State-Changed-When: Mon Mar 20 12:47:33 UTC 2006 
State-Changed-Why:  
Our netdb functions are thread-safe since 6.0-RELEASE, and it 
was already MFC'ed into RELENG_5.  So, 5.5-RELEASE will have 
thread-safe netdb function. 


Responsible-Changed-From-To: deischen->ume 
Responsible-Changed-By: ume 
Responsible-Changed-When: Mon Mar 20 12:47:33 UTC 2006 
Responsible-Changed-Why:  
I did it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=60477 
>Unformatted:
