From owner-freebsd-audit Sun Aug 11 9:32: 5 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CB26637B400; Sun, 11 Aug 2002 09:32:01 -0700 (PDT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id A802143E6E; Sun, 11 Aug 2002 09:32:00 -0700 (PDT) (envelope-from dwmalone@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 11 Aug 2002 17:31:59 +0100 (BST) To: freebsd-gnats-submit@FreeBSD.org, sanewo@ba2.so-net.ne.jp Cc: freebsd-audit@FreeBSD.org Subject: Re: bin/28935: syslogd -u doesn't treat * as "all levels" X-Request-Do: Date: Sun, 11 Aug 2002 17:31:58 +0100 From: David Malone Message-ID: <200208111731.aa70079@salmon.maths.tcd.ie> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG This is a possible patch for: http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/28935 which points out that "*" means completly the wrong thing if you run syslogd -u. It would seem to make more sense to consider "*" as having an explicit set of comparison flags "<=>". This also patch adds a "!" comparison flag which should be compatable with the same flag in the Linux version of syslogd. I'm not sure I find the linux semtics that intuative, but there is little point in being incompatable. David. Index: syslog.conf.5 =================================================================== RCS file: /cvs/FreeBSD-CVS/src/usr.sbin/syslogd/syslog.conf.5,v retrieving revision 1.26 diff -u -r1.26 syslog.conf.5 --- syslog.conf.5 16 May 2002 02:28:39 -0000 1.26 +++ syslog.conf.5 11 Aug 2002 16:20:16 -0000 @@ -85,7 +85,7 @@ a period .Pq Dq \&. , an optional set of comparison flags -.Pq Bq <=> , +.Pq Bo ! Bc Bq <=> , and a .Em level , with no intervening white-space. @@ -123,6 +123,15 @@ level equal or greater than .Em level will be logged. +Comparison flags beginning with +.Do ! Dc +will have their logical sense inverted. +Thus +.Dq !=info +means all levels except info and +.Dq !notice +has the same meaning as +.Dq ; Sun, 11 Aug 2002 09:58:42 -0700 (PDT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 3FCA143E5E for ; Sun, 11 Aug 2002 09:58:41 -0700 (PDT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 11 Aug 2002 17:58:40 +0100 (BST) To: audit@freebsd.org Subject: pw(1) support for pre-encrypted passwords Date: Sun, 11 Aug 2002 17:58:40 +0100 From: Ian Dowse Message-ID: <200208111758.aa74510@salmon.maths.tcd.ie> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The following patch adds support to pw(1) for specifying an encrypted password to be added directly to the password database. It adds a new option, "-H" that works just like the existing "-h" option (the password is read from a user-specified file descriptor) except that pw(1) does not pass the string through crypt(). This is partially based on the patch in PR bin/22033, but is hopefully more consistent with existing features (the proposed patch used "-h -w crypt" instead of "-H fd", but -w and -h used to be mutually exclusive in practice). Index: pw.8 =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw.8,v retrieving revision 1.31 diff -u -r1.31 pw.8 --- pw.8 14 Jul 2002 14:45:10 -0000 1.31 +++ pw.8 11 Aug 2002 00:26:34 -0000 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD: src/usr.sbin/pw/pw.8,v 1.31 2002/07/14 14:45:10 charnier Exp $ .\" -.Dd December 9, 1996 +.Dd August 10, 2002 .Dt PW 8 .Os .Sh NAME @@ -51,7 +51,7 @@ .Op Fl s Ar shell .Op Fl o .Op Fl L Ar class -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -101,7 +101,7 @@ .Op Fl w Ar method .Op Fl s Ar shell .Op Fl L Ar class -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -130,7 +130,7 @@ .Op Fl g Ar gid .Op Fl M Ar members .Op Fl o -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -152,7 +152,7 @@ .Op Fl l Ar name .Op Fl M Ar members .Op Fl m Ar newmembers -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -508,6 +508,12 @@ then the password will be set to .Ql \&* , rendering the account inaccessible via password-based login. +.It Fl H Ar fd +Read an encrypted password string from the specified file descriptor. +This is like +.Fl h , +but the password should be supplied already encrypted in a form +suitable for writing directly to the password database. .El .Pp It is possible to use Index: pw.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw.c,v retrieving revision 1.26 diff -u -r1.26 pw.c --- pw.c 9 Jul 2001 09:24:01 -0000 1.26 +++ pw.c 11 Aug 2002 00:30:30 -0000 @@ -106,18 +106,18 @@ static const char *opts[W_NUM][M_NUM] = { { /* user */ - "V:C:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:Db:NPy:Y", + "V:C:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:H:Db:NPy:Y", "V:C:qn:u:rY", - "V:C:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:FNPY", + "V:C:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:H:FNPY", "V:C:qn:u:FPa7", "V:C:q", "V:C:q", "V:C:q" }, { /* grp */ - "V:C:qn:g:h:M:pNPY", + "V:C:qn:g:h:H:M:pNPY", "V:C:qn:g:Y", - "V:C:qn:g:l:h:FM:m:NPY", + "V:C:qn:g:l:h:H:FM:m:NPY", "V:C:qn:g:FPa", "V:C:q" } @@ -315,6 +315,7 @@ "\t-o duplicate uid ok\n" "\t-L class user class\n" "\t-h fd read password on fd\n" + "\t-H fd read encrypted password on fd\n" "\t-Y update NIS maps\n" "\t-N no update\n" " Setting defaults:\n" @@ -357,6 +358,7 @@ "\t-s shell name of login shell\n" "\t-w method set new password using method\n" "\t-h fd read password on fd\n" + "\t-H fd read encrypted password on fd\n" "\t-Y update NIS maps\n" "\t-N no update\n", "usage: pw usershow [uid|name] [switches]\n" Index: pw_group.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw_group.c,v retrieving revision 1.13 diff -u -r1.13 pw_group.c --- pw_group.c 22 Jun 2000 16:48:41 -0000 1.13 +++ pw_group.c 11 Aug 2002 00:09:53 -0000 @@ -158,11 +158,13 @@ * software. */ - if ((arg = getarg(args, 'h')) != NULL) { + if ((arg = getarg(args, 'h')) != NULL || + (arg = getarg(args, 'H')) != NULL) { if (strcmp(arg->val, "-") == 0) grp->gr_passwd = "*"; /* No access */ else { int fd = atoi(arg->val); + int precrypt = (arg->ch == 'H'); int b; int istty = isatty(fd); struct termios t; @@ -196,7 +198,12 @@ *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", fd); - grp->gr_passwd = pw_pwcrypt(line); + if (precrypt) { + if (strchr(line, ':') != NULL) + return EX_DATAERR; + grp->gr_passwd = line; + } else + grp->gr_passwd = pw_pwcrypt(line); } } Index: pw_user.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw_user.c,v retrieving revision 1.51 diff -u -r1.51 pw_user.c --- pw_user.c 24 Jun 2002 11:33:17 -0000 1.51 +++ pw_user.c 11 Aug 2002 02:39:47 -0000 @@ -86,6 +86,7 @@ * -L class user class * -l name new login name * -h fd password filehandle + * -H fd encrypted password filehandle * -F force print or add * Setting defaults: * -D set user defaults @@ -544,7 +545,8 @@ warnx("WARNING: home `%s' is not a directory", pwd->pw_dir); } - if ((arg = getarg(args, 'w')) != NULL && getarg(args, 'h') == NULL) { + if ((arg = getarg(args, 'w')) != NULL && + getarg(args, 'h') == NULL && getarg(args, 'H') == NULL) { login_cap_t *lc; lc = login_getpwclass(pwd); @@ -602,7 +604,8 @@ } } - if ((arg = getarg(args, 'h')) != NULL) { + if ((arg = getarg(args, 'h')) != NULL || + (arg = getarg(args, 'H')) != NULL) { if (strcmp(arg->val, "-") == 0) { if (!pwd->pw_passwd || *pwd->pw_passwd != '*') { pwd->pw_passwd = "*"; /* No access */ @@ -610,6 +613,7 @@ } } else { int fd = atoi(arg->val); + int precrypt = (arg->ch == 'H'); int b; int istty = isatty(fd); struct termios t; @@ -624,7 +628,10 @@ /* Disable echo */ n.c_lflag &= ~(ECHO); tcsetattr(fd, TCSANOW, &n); - printf("%sassword for user %s:", (mode == M_UPDATE) ? "New p" : "P", pwd->pw_name); + printf("%s%spassword for user %s:", + (mode == M_UPDATE) ? "new " : "", + precrypt ? "encrypted " : "", + pwd->pw_name); fflush(stdout); } } @@ -635,7 +642,8 @@ fflush(stdout); } if (b < 0) { - warn("-h file descriptor"); + warn("-%c file descriptor", precrypt ? 'H' : + 'h'); return EX_IOERR; } line[b] = '\0'; @@ -643,12 +651,18 @@ *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", fd); - lc = login_getpwclass(pwd); - if (lc == NULL || - login_setcryptfmt(lc, "md5", NULL) == NULL) - warn("setting crypt(3) format"); - login_close(lc); - pwd->pw_passwd = pw_pwcrypt(line); + if (precrypt) { + if (strchr(line, ':') != NULL) + return EX_DATAERR; + pwd->pw_passwd = line; + } else { + lc = login_getpwclass(pwd); + if (lc == NULL || + login_setcryptfmt(lc, "md5", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); + pwd->pw_passwd = pw_pwcrypt(line); + } edited = 1; } } @@ -1087,7 +1101,8 @@ /* * We give this information back to the user */ - if (getarg(args, 'h') == NULL && getarg(args, 'N') == NULL) { + if (getarg(args, 'h') == NULL && getarg(args, 'H') == NULL && + getarg(args, 'N') == NULL) { if (isatty(STDOUT_FILENO)) printf("Password for '%s' is: ", user); printf("%s\n", pwbuf); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 3:19:33 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9875C37B400; Mon, 12 Aug 2002 03:15:26 -0700 (PDT) Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id DFECF43E3B; Mon, 12 Aug 2002 03:15:17 -0700 (PDT) (envelope-from sobomax@FreeBSD.org) Received: from relay.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id NAA76768; Mon, 12 Aug 2002 13:14:39 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from vircheck.ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by relay.iptelecom.net.ua (8.12.4/8.12.4) with ESMTP id g7CAEX8Y076679; Mon, 12 Aug 2002 13:14:34 +0300 (EEST) Received: from vega.vega.com (h210.234.dialup.iptcom.net [212.9.234.210]) by vircheck.ipcard.iptcom.net (8.12.3/8.12.3) with ESMTP id g7CAE3oQ057457; Mon, 12 Aug 2002 13:14:06 +0300 (EEST) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.12.5/8.11.3) with ESMTP id g7CAE1F2039450; Mon, 12 Aug 2002 13:14:01 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3D578A99.F0821712@FreeBSD.org> Date: Mon, 12 Aug 2002 13:14:49 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: hackers@FreeBSD.org, audit@FreeBSD.org, Alexander Litvin , Andriy Gapon Subject: Thread-safe resolver [patches for review] Content-Type: multipart/mixed; boundary="------------051496A982500B2DDF1E4FCD" Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG This is a multi-part message in MIME format. --------------051496A982500B2DDF1E4FCD Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Folks, Attched please find two patches based on bin/29581 PR to make FreeBSD resolver thread-safe. They represent two approaches to reach this goal - the first is to introduce reentrant versions of the standard gethostbyXXX(3) APIs, similar to ones existing in other unices, and the second one is to make gethostbyXXX(3) returning data placed into per-thread storage when linked with libc_r. I like the latter approach more, since it doesn't introduce new non-standard APIs. I would like to hear any comments and suggestions on the proposed patches, as well as to opinions about which path to chose. Thanks! -Maxim --------------051496A982500B2DDF1E4FCD Content-Type: text/plain; charset=koi8-r; name="resolv_r-1.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="resolv_r-1.diff" Index: src/include/netdb.h =================================================================== RCS file: /home/ncvs/src/include/netdb.h,v retrieving revision 1.24 diff -d -u -r1.24 netdb.h --- src/include/netdb.h 26 Jun 2002 08:18:42 -0000 1.24 +++ src/include/netdb.h 10 Aug 2002 10:03:43 -0000 @@ -82,7 +82,10 @@ #define _PATH_PROTOCOLS "/etc/protocols" #define _PATH_SERVICES "/etc/services" -extern int h_errno; +__BEGIN_DECLS +int * __h_errno_accessor(void); +__END_DECLS +#define h_errno (* __h_errno_accessor()) /* * Structures returned by network data base library. All addresses are @@ -240,6 +243,15 @@ char *gai_strerror(int); void setnetgrent(const char *); void setservent(int); + +int gethostbyaddr_r(const char *, int, int, struct hostent *, + char *, int, int *); +int gethostbyname_r(const char *, struct hostent *, + char *, int, int *); +int gethostbyname2_r(const char *, int, struct hostent *, + char *, int, int *); +struct hostent *gethostent_r(struct hostent *, char *, int); + /* * PRIVATE functions specific to the FreeBSD implementation Index: src/include/resolv.h =================================================================== RCS file: /home/ncvs/src/include/resolv.h,v retrieving revision 1.21 diff -d -u -r1.21 resolv.h --- src/include/resolv.h 23 Mar 2002 17:24:53 -0000 1.21 +++ src/include/resolv.h 10 Aug 2002 10:03:43 -0000 @@ -90,11 +90,16 @@ #define MAXDFLSRCH 3 /* # default domain levels to try */ #define MAXDNSRCH 6 /* max # domains in search path */ #define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ +#define MAXALIASES 35 /* max # of aliases to return */ +#define MAXADDRS 35 /* max # of addresses to return */ #define RES_TIMEOUT 5 /* min. seconds between retries */ #define MAXRESOLVSORT 10 /* number of net to sort on */ #define RES_MAXNDOTS 15 /* should reflect bit field size */ +#define CAST_ALIGN(ptr, type) \ + (char*)(type)ptr < (char*)ptr ? ((type)ptr) + 1 : (type)ptr + struct __res_state { int retrans; /* retransmition time interval */ int retry; /* number of times to retransmit */ @@ -198,10 +203,6 @@ char * humanname; /* Its fun name, like "mail exchanger" */ }; -extern struct __res_state _res; -/* for INET6 */ -extern struct __res_state_ext _res_ext; - extern const struct res_sym __p_class_syms[]; extern const struct res_sym __p_type_syms[]; @@ -224,6 +225,7 @@ #define fp_query __fp_query #define fp_nquery __fp_nquery #define hostalias __hostalias +#define hostalias_r __hostalias_r #define putlong __putlong #define putshort __putshort #define p_class __p_class @@ -273,6 +275,7 @@ void fp_query(const u_char *, FILE *); void fp_nquery(const u_char *, int, FILE *); const char * hostalias(const char *); +const char * hostalias_r(const char *, char *, int); void putlong(u_int32_t, u_char *); void putshort(u_int16_t, u_char *); const char * p_class(int); @@ -315,5 +318,30 @@ void res_freeupdrec(ns_updrec *); #endif __END_DECLS + +struct __res_data { + int h_errno_res; + int s; /* socket used for communications */ + int connected : 1; /* is the socket connected */ + int vc : 1; /* is the socket a virtual circuit? */ + int af; /* address family of socket */ + res_send_qhook Qhook; + res_send_rhook Rhook; + FILE* hostf; + int stayopen; + struct __res_state *res; + struct __res_state_ext *res_ext; +}; + +__BEGIN_DECLS +u_int16_t _getshort(const u_char *); +u_int32_t _getlong(const u_char *); +struct __res_data * __res_data_accessor(void); +struct __res_state * __res_accessor(void); +__END_DECLS +#define _res_data (* __res_data_accessor()) +#define _res (* __res_accessor()) +/* for INET6 */ +#define _res_ext (* (__res_data_accessor()->res_ext)) #endif /* !_RESOLV_H_ */ Index: src/lib/libc/net/getaddrinfo.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getaddrinfo.c,v retrieving revision 1.28 diff -d -u -r1.28 getaddrinfo.c --- src/lib/libc/net/getaddrinfo.c 2 Aug 2002 11:58:48 -0000 1.28 +++ src/lib/libc/net/getaddrinfo.c 10 Aug 2002 10:03:49 -0000 @@ -1673,7 +1673,6 @@ /* resolver logic */ extern const char *__hostalias(const char *); -extern int h_errno; /* * Formulate a normal query, send, and await answer. Index: src/lib/libc/net/gethostbydns.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbydns.c,v retrieving revision 1.36 diff -d -u -r1.36 gethostbydns.c --- src/lib/libc/net/gethostbydns.c 26 Jun 2002 14:18:36 -0000 1.36 +++ src/lib/libc/net/gethostbydns.c 10 Aug 2002 10:03:49 -0000 @@ -68,6 +68,7 @@ #include #include +#include #include #include #include @@ -82,18 +83,11 @@ #define SPRINTF(x) ((size_t)sprintf x) -#define MAXALIASES 35 -#define MAXADDRS 35 - static const char AskedForGot[] = "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; -static char *h_addr_ptrs[MAXADDRS + 1]; - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[8*1024]; -static u_char host_addr[16]; /* IPv4 or IPv6 */ +static char hostbuf_s[8*1024]; +static u_char host_addr_s[16]; /* IPv4 or IPv6 */ #ifdef RESOLVSORT static void addrsort(char **, int); @@ -119,7 +113,6 @@ char ac; } align; -extern int h_errno; int _dns_ttl_; #ifdef DEBUG @@ -157,11 +150,14 @@ } while (0) static struct hostent * -gethostanswer(answer, anslen, qname, qtype) +gethostanswer(answer, anslen, qname, qtype, host, hostbuf, hostbuflen) const querybuf *answer; int anslen; const char *qname; int qtype; + struct hostent *host; + char *hostbuf; + int hostbuflen; { const HEADER *hp; const u_char *cp; @@ -176,7 +172,7 @@ int (*name_ok)(const char *); tname = qname; - host.h_name = NULL; + host->h_name = NULL; eom = answer->buf + anslen; switch (qtype) { case T_A: @@ -197,7 +193,7 @@ ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; - ep = hostbuf + sizeof hostbuf; + ep = hostbuf + hostbuflen; cp = answer->buf; BOUNDED_INCR(HFIXEDSZ); if (qdcount != 1) { @@ -220,17 +216,15 @@ h_errno = NO_RECOVERY; return (NULL); } - host.h_name = bp; + host->h_name = bp; bp += n; /* The qname can be abbreviated, but h_name is now absolute. */ - qname = host.h_name; + qname = host->h_name; } - ap = host_aliases; + ap = host->h_aliases; *ap = NULL; - host.h_aliases = host_aliases; - hap = h_addr_ptrs; + hap = host->h_addr_list; *hap = NULL; - host.h_addr_list = h_addr_ptrs; haveanswer = 0; had_error = 0; _dns_ttl_ = -1; @@ -259,7 +253,7 @@ continue; /* XXX - had_error++ ? */ } if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { - if (ap >= &host_aliases[MAXALIASES-1]) + if (ap >= &host->h_aliases[MAXALIASES-1]) continue; n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if ((n < 0) || !(*name_ok)(tbuf)) { @@ -286,7 +280,7 @@ continue; } strcpy(bp, tbuf); - host.h_name = bp; + host->h_name = bp; bp += n; continue; } @@ -341,8 +335,8 @@ return (NULL); } if (!haveanswer) - host.h_name = bp; - else if (ap < &host_aliases[MAXALIASES-1]) + host->h_name = bp; + else if (ap < &host->h_aliases[MAXALIASES-1]) *ap++ = bp; else n = -1; @@ -356,7 +350,7 @@ } break; #else - host.h_name = bp; + host->h_name = bp; if (_res.options & RES_USE_INET6) { n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { @@ -364,27 +358,27 @@ break; } bp += n; - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); } h_errno = NETDB_SUCCESS; - return (&host); + return (host); #endif case T_A: case T_AAAA: - if (strcasecmp(host.h_name, bp) != 0) { + if (strcasecmp(host->h_name, bp) != 0) { syslog(LOG_NOTICE|LOG_AUTH, - AskedForGot, host.h_name, bp); + AskedForGot, host->h_name, bp); cp += n; continue; /* XXX - had_error++ ? */ } - if (n != host.h_length) { + if (n != host->h_length) { cp += n; continue; } if (!haveanswer) { int nn; - host.h_name = bp; + host->h_name = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; } @@ -396,7 +390,7 @@ had_error++; continue; } - if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (hap >= &host->h_addr_list[MAXADDRS-1]) { if (!toobig++) dprintf("Too many addresses (%d)\n", MAXADDRS); @@ -430,62 +424,82 @@ * address in that case, not some random one */ if (_res.nsort && haveanswer > 1 && qtype == T_A) - addrsort(h_addr_ptrs, haveanswer); + addrsort(host->h_addr_list, haveanswer); # endif /*RESOLVSORT*/ - if (!host.h_name) { + if (!host->h_name) { n = strlen(qname) + 1; /* for the \0 */ if (n > ep - bp || n >= MAXHOSTNAMELEN) goto no_recovery; strcpy(bp, qname); - host.h_name = bp; + host->h_name = bp; bp += n; } if (_res.options & RES_USE_INET6) - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); h_errno = NETDB_SUCCESS; - return (&host); + return (host); } no_recovery: h_errno = NO_RECOVERY; return (NULL); } -struct hostent * -__dns_getanswer(answer, anslen, qname, qtype) - const char *answer; - int anslen; - const char *qname; - int qtype; -{ - switch(qtype) { - case T_AAAA: - host.h_addrtype = AF_INET6; - host.h_length = IN6ADDRSZ; - break; - case T_A: - default: - host.h_addrtype = AF_INET; - host.h_length = INADDRSZ; - break; - } - - return(gethostanswer((const querybuf *)answer, anslen, qname, qtype)); -} - int _dns_gethostbyname(void *rval, void *cb_data, va_list ap) { const char *name; int af; + struct hostent *host; + char *hostbuf; + int hostbuflen; + u_char *host_addr; querybuf buf; const char *cp; char *bp, *ep; int n, size, type, len; + char abuf[MAXDNAME]; name = va_arg(ap, const char *); af = va_arg(ap, int); + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char *); + hostbuflen = va_arg(ap, int); *(struct hostent **)rval = NULL; + if(hostbuflen != 0 && hostbuf != NULL) { + host->h_aliases = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_aliases + sizeof(char *[MAXALIASES]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host->h_addr_list = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_addr_list + sizeof(char *[MAXADDRS + 1]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host_addr = hostbuf; + bp = (char *)host_addr + sizeof(u_char[16]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < MAXDNAME+1) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + } else { + hostbuf = hostbuf_s; + hostbuflen = sizeof hostbuf_s; + host_addr = host_addr_s; + } + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return NS_UNAVAIL; @@ -506,15 +520,15 @@ return NS_UNAVAIL; } - host.h_addrtype = af; - host.h_length = size; + host->h_addrtype = af; + host->h_length = size; /* * if there aren't any dots, it could be a user-level alias. * this is also done in res_query() since we are not the only * function that looks up host names. */ - if (!strchr(name, '.') && (cp = __hostalias(name))) + if (!strchr(name, '.') && (cp = __hostalias_r(name, abuf, sizeof abuf))) name = cp; /* @@ -538,17 +552,15 @@ strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; - ep = hostbuf + sizeof hostbuf; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; + ep = hostbuf + hostbuflen; + host->h_name = hostbuf; + host->h_aliases[0] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; if (_res.options & RES_USE_INET6) - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; + *(struct hostent **)rval = host; return NS_SUCCESS; } if (!isdigit((unsigned char)*cp) && *cp != '.') @@ -572,15 +584,13 @@ strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; - len = sizeof hostbuf - MAXDNAME; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; + len = hostbuflen - MAXDNAME; + host->h_name = hostbuf; + host->h_aliases[0] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; + *(struct hostent **)rval = host; return NS_SUCCESS; } if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.') @@ -591,7 +601,8 @@ dprintf("res_search failed (%d)\n", n); return NS_UNAVAIL; } - *(struct hostent **)rval = gethostanswer(&buf, n, name, type); + *(struct hostent **)rval = gethostanswer(&buf, n, name, type, + host, hostbuf, hostbuflen); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; } @@ -600,6 +611,10 @@ { const char *addr; /* XXX should have been def'd as u_char! */ int len, af; + struct hostent *host; + char *hostbuf; + int hostbuflen; + char *bp; const u_char *uaddr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; @@ -607,6 +622,7 @@ querybuf buf; struct hostent *hp; char qbuf[MAXDNAME+1], *qp; + u_char *host_addr; #ifdef SUNSECURITY struct hostent *rhp; char **haddr; @@ -618,9 +634,45 @@ uaddr = (const u_char *)addr; len = va_arg(ap, int); af = va_arg(ap, int); - + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char*); + hostbuflen = va_arg(ap, int); *(struct hostent **)rval = NULL; + if(hostbuflen != 0 && hostbuf != NULL) { + host->h_aliases = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_aliases + sizeof(char *[MAXALIASES]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host->h_addr_list = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_addr_list + sizeof(char *[MAXADDRS + 1]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host_addr = hostbuf; + bp = (char *)host_addr + sizeof(u_char[16]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < MAXDNAME+1) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + } else { + hostbuf = hostbuf_s; + hostbuflen = sizeof hostbuf_s; + host_addr = host_addr_s; + } + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return NS_UNAVAIL; @@ -680,7 +732,7 @@ dprintf("static buffer is too small (%d)\n", n); return NS_UNAVAIL; } - if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR))) + if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR, host, hostbuf, hostbuflen))) return NS_NOTFOUND; /* h_errno was set by gethostanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { @@ -717,8 +769,8 @@ hp->h_addrtype = af; hp->h_length = len; bcopy(addr, host_addr, len); - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; if (af == AF_INET && (_res.options & RES_USE_INET6)) { _map_v4v6_address((char*)host_addr, (char*)host_addr); hp->h_addrtype = AF_INET6; Index: src/lib/libc/net/gethostbyht.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbyht.c,v retrieving revision 1.16 diff -d -u -r1.16 gethostbyht.c --- src/lib/libc/net/gethostbyht.c 22 Mar 2002 21:52:29 -0000 1.16 +++ src/lib/libc/net/gethostbyht.c 10 Aug 2002 10:03:52 -0000 @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -70,49 +71,53 @@ #include /* XXX */ #include /* XXX */ -#define MAXALIASES 35 - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[BUFSIZ+1]; -static FILE *hostf = NULL; -static u_int32_t host_addr[4]; /* IPv4 or IPv6 */ static char *h_addr_ptrs[2]; -static int stayopen = 0; +static char *host_aliases[MAXALIASES]; +static struct hostent host_s = { NULL, host_aliases, 0, 0, h_addr_ptrs }; + +static char hostbuf_s[BUFSIZ+1]; +static u_int32_t host_addr_s[4]; /* IPv4 or IPv6 */ void _sethosthtent(f) int f; { - if (!hostf) - hostf = fopen(_PATH_HOSTS, "r" ); + if (!_res_data.hostf) + _res_data.hostf = fopen(_PATH_HOSTS, "r" ); else - rewind(hostf); - stayopen = f; + rewind(_res_data.hostf); + _res_data.stayopen = f; } void _endhosthtent() { - if (hostf && !stayopen) { - (void) fclose(hostf); - hostf = NULL; + if (_res_data.hostf && !_res_data.stayopen) { + (void) fclose(_res_data.hostf); + _res_data.hostf = NULL; } } struct hostent * gethostent() { + + return (gethostent_r(&host_s, hostbuf_s, sizeof hostbuf_s)); +} + +struct hostent * +gethostent_r(struct hostent *host, char *hostbuf, int hostbuflen) +{ char *p; char *cp, **q; int af, len; - if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { + if (!_res_data.hostf && !(_res_data.hostf = fopen(_PATH_HOSTS, "r" ))) { h_errno = NETDB_INTERNAL; return (NULL); } again: - if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + if (!(p = fgets(hostbuf, hostbuflen, _res_data.hostf))) { h_errno = HOST_NOT_FOUND; return (NULL); } @@ -124,12 +129,12 @@ if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; - if (inet_pton(AF_INET6, p, host_addr) > 0) { + if (inet_pton(AF_INET6, p, host->h_addr_list[0]) > 0) { af = AF_INET6; len = IN6ADDRSZ; - } else if (inet_pton(AF_INET, p, host_addr) > 0) { + } else if (inet_pton(AF_INET, p, host->h_addr_list[0]) > 0) { if (_res.options & RES_USE_INET6) { - _map_v4v6_address((char*)host_addr, (char*)host_addr); + _map_v4v6_address(host->h_addr_list[0], host->h_addr_list[0]); af = AF_INET6; len = IN6ADDRSZ; } else { @@ -139,15 +144,12 @@ } else { goto again; } - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; - host.h_length = len; - host.h_addrtype = af; + host->h_length = len; + host->h_addrtype = af; while (*cp == ' ' || *cp == '\t') cp++; - host.h_name = cp; - q = host.h_aliases = host_aliases; + host->h_name = cp; + q = host->h_aliases; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; while (cp && *cp) { @@ -155,14 +157,14 @@ cp++; continue; } - if (q < &host_aliases[MAXALIASES - 1]) + if (q < &host->h_aliases[MAXALIASES - 1]) *q++ = cp; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } *q = NULL; h_errno = NETDB_SUCCESS; - return (&host); + return (host); } int @@ -170,14 +172,58 @@ { const char *name; int af; + struct hostent *host; + char *hostbuf, *bp; + int hostbuflen; + u_int32_t *host_addr; struct hostent *p; char **cp; name = va_arg(ap, const char *); af = va_arg(ap, int); + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char*); + hostbuflen = va_arg(ap, int); + if(hostbuflen != 0 && hostbuf != NULL) { + host->h_aliases = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_aliases + sizeof(char *[MAXALIASES]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host->h_addr_list = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_addr_list + sizeof(char *[2]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host_addr = CAST_ALIGN(hostbuf, u_int32_t *); + bp = (char *)host_addr + sizeof(u_int32_t[4]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < BUFSIZ+1) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + } else { + hostbuf = hostbuf_s; + hostbuflen = sizeof hostbuf_s; + host_addr = host_addr_s; + } + + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; + sethostent(0); - while ((p = gethostent()) != NULL) { + while ((p = gethostent_r(host, hostbuf, hostbuflen)) != NULL) { if (p->h_addrtype != af) continue; if (strcasecmp(p->h_name, name) == 0) @@ -198,14 +244,58 @@ { const char *addr; int len, af; + struct hostent *host; + char *hostbuf, *bp; + int hostbuflen; + u_int32_t *host_addr; struct hostent *p; addr = va_arg(ap, const char *); len = va_arg(ap, int); af = va_arg(ap, int); + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char*); + hostbuflen = va_arg(ap, int); + + if(hostbuflen != 0 && hostbuf != NULL) { + host->h_aliases = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_aliases + sizeof(char *[MAXALIASES]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host->h_addr_list = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_addr_list + sizeof(char *[2]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + host_addr = CAST_ALIGN(hostbuf, u_int32_t *); + bp = (char *)host_addr + sizeof(u_int32_t[4]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < BUFSIZ+1) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NS_UNAVAIL); + } + } else { + hostbuf = hostbuf_s; + hostbuflen = sizeof hostbuf_s; + host_addr = host_addr_s; + } + + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; sethostent(0); - while ((p = gethostent()) != NULL) + while ((p = gethostent_r(host, hostbuf, hostbuflen)) != NULL) if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) break; endhostent(); Index: src/lib/libc/net/gethostbynis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbynis.c,v retrieving revision 1.15 diff -d -u -r1.15 gethostbynis.c --- src/lib/libc/net/gethostbynis.c 22 Mar 2002 21:52:29 -0000 1.15 +++ src/lib/libc/net/gethostbynis.c 10 Aug 2002 10:03:52 -0000 @@ -44,29 +44,63 @@ #include #include #endif - -#define MAXALIASES 35 -#define MAXADDRS 35 - -extern int h_errno; +#include #ifdef YP +static char hostbuf_s[8*1024]; +static u_char host_addr_s[16]; + +static char *h_addr_ptrs[2]; static char *host_aliases[MAXALIASES]; -static char hostaddr[MAXADDRS]; -static char *host_addrs[2]; +static struct hostent host_s = { NULL, host_aliases, 0, 0, h_addr_ptrs }; static struct hostent * -_gethostbynis(name, map, af) +_gethostbynis(name, map, af, host, hostbuf, hostbuflen) const char *name; char *map; int af; + struct hostent *host; + char *hostbuf; + int hostbuflen; { - char *cp, **q; + char *bp, *cp, **q; char *result; int resultlen,size; - static struct hostent h; static char *domain = (char *)NULL; - static char ypbuf[YPMAXRECORD + 2]; + + if(hostbuflen != 0 && hostbuf != NULL) { + host->h_aliases = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_aliases + sizeof(char *[MAXALIASES]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NULL); + } + host->h_addr_list = CAST_ALIGN(hostbuf, char **); + bp = (char *)host->h_addr_list + sizeof(char *[2]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NULL); + } + host->h_addr_list[0] = hostbuf; + bp = (char *)host->h_addr_list[0] + sizeof(u_char[16]); + hostbuflen -= (bp - hostbuf); + hostbuf = bp; + if(hostbuflen < 0) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NULL); + } + } else { + hostbuf = hostbuf_s; + hostbuflen = sizeof hostbuf_s; + host->h_addr_list[0] = host_addr_s; + } switch(af) { case AF_INET: @@ -90,27 +124,29 @@ h_errno = HOST_NOT_FOUND; return ((struct hostent *)NULL); } - - /* avoid potential memory leak */ - bcopy((char *)result, (char *)&ypbuf, resultlen); - ypbuf[resultlen] = '\0'; + if (resultlen > hostbuflen) { + h_errno = NO_RECOVERY; + errno = ERANGE; + return (NULL); + } + result[resultlen] = '\0'; + bcopy((char *)result, hostbuf, resultlen); free(result); - result = (char *)&ypbuf; + result = hostbuf; if ((cp = index(result, '\n'))) *cp = '\0'; cp = strpbrk(result, " \t"); *cp++ = '\0'; - h.h_addr_list = host_addrs; - h.h_addr = hostaddr; - *((u_long *)h.h_addr) = inet_addr(result); - h.h_length = size; - h.h_addrtype = AF_INET; + *((u_long *)host->h_addr_list[0]) = inet_addr(result); + host->h_addr_list[1] = NULL; + host->h_length = size; + host->h_addrtype = AF_INET; while (*cp == ' ' || *cp == '\t') cp++; - h.h_name = cp; - q = h.h_aliases = host_aliases; + host->h_name = cp; + q = host->h_aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; @@ -119,14 +155,14 @@ cp++; continue; } - if (q < &host_aliases[MAXALIASES - 1]) + if (q < &host->h_aliases[MAXALIASES - 1]) *q++ = cp; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; - return (&h); + return (host); } #endif /* YP */ @@ -135,7 +171,7 @@ _gethostbynisname(const char *name, int af) { #ifdef YP - return _gethostbynis(name, "hosts.byname", af); + return _gethostbynis(name, "hosts.byname", af, &host_s, NULL, 0); #else return NULL; #endif @@ -146,7 +182,7 @@ { #ifdef YP return _gethostbynis(inet_ntoa(*(struct in_addr *)addr), - "hosts.byaddr", af); + "hosts.byaddr", af, &host_s, NULL, 0); #else return NULL; #endif @@ -159,11 +195,18 @@ #ifdef YP const char *name; int af; + struct hostent *host; + char *hostbuf; + int hostbuflen; name = va_arg(ap, const char *); af = va_arg(ap, int); + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char *); + hostbuflen = va_arg(ap, int); - *(struct hostent **)rval = _gethostbynis(name, "hosts.byname", af); + *(struct hostent **)rval = _gethostbynis(name, "hosts.byname", af, + host, hostbuf, hostbuflen); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; #else return NS_UNAVAIL; @@ -177,12 +220,19 @@ const char *addr; int len; int af; + struct hostent *host; + char *hostbuf; + int hostbuflen; addr = va_arg(ap, const char *); len = va_arg(ap, int); af = va_arg(ap, int); - - *(struct hostent **)rval =_gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af); + host = va_arg(ap, struct hostent *); + hostbuf = va_arg(ap, char *); + hostbuflen = va_arg(ap, int); + + *(struct hostent **)rval =_gethostbynis(inet_ntoa(*(struct in_addr *)addr), + "hosts.byaddr", af, host, hostbuf, hostbuflen); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; #else return NS_UNAVAIL; Index: src/lib/libc/net/gethostnamadr.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostnamadr.c,v retrieving revision 1.20 diff -d -u -r1.20 gethostnamadr.c --- src/lib/libc/net/gethostnamadr.c 22 Mar 2002 21:52:29 -0000 1.20 +++ src/lib/libc/net/gethostnamadr.c 10 Aug 2002 10:03:52 -0000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,10 @@ extern int _dns_gethostbyaddr(void *, void *, va_list); extern int _nis_gethostbyaddr(void *, void *, va_list); +static char *h_addr_ptrs[MAXADDRS + 1]; +static char *host_aliases[MAXALIASES]; +static struct hostent host_s = { NULL, host_aliases, 0, 0, h_addr_ptrs }; + /* Host lookup order if nsswitch.conf is broken or nonexistant */ static const ns_src default_src[] = { { NSSRC_FILES, NS_SUCCESS }, @@ -53,25 +58,38 @@ { 0 } }; -struct hostent * -gethostbyname(const char *name) +int +gethostbyname_r(const char *name, struct hostent *resp, + char *buffer, int buflen, int *h_errnop) { - struct hostent *hp; + int rval; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (NULL); + *h_errnop = NO_RECOVERY; + return (NETDB_INTERNAL); } if (_res.options & RES_USE_INET6) { /* XXX */ - hp = gethostbyname2(name, AF_INET6); /* XXX */ - if (hp) /* XXX */ - return (hp); /* XXX */ + rval = gethostbyname2_r(name, AF_INET6, resp, + buffer, buflen, h_errnop); /* XXX */ + if (rval == 0) /* XXX */ + return (0); /* XXX */ } /* XXX */ - return (gethostbyname2(name, AF_INET)); + return (gethostbyname2_r(name, AF_INET, resp, + buffer, buflen, h_errnop)); } struct hostent * -gethostbyname2(const char *name, int type) +gethostbyname(const char *name) +{ + int rval; + + rval = gethostbyname_r(name, &host_s, NULL, 0, &h_errno); + return (rval == 0 ? &host_s : NULL); +} + +int +gethostbyname2_r(const char *name, int type, struct hostent *resp, + char *buffer, int buflen, int *h_errnop) { struct hostent *hp = 0; int rval; @@ -82,18 +100,29 @@ NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ { 0 } }; - + rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname", - default_src, name, type); + default_src, name, type, resp, buffer, buflen); + *h_errnop = h_errno; if (rval != NS_SUCCESS) - return NULL; + return ((errno == 0) ? -1 : errno); /* Be paranoid */ else - return hp; + return (0); } struct hostent * -gethostbyaddr(const char *addr, int len, int type) +gethostbyname2(const char *name, int type) +{ + int rval; + + rval = gethostbyname2_r(name, type, &host_s, NULL, 0, &h_errno); + return (rval == 0 ? &host_s : NULL); +} + +int +gethostbyaddr_r(const char *addr, int len, int type, struct hostent *resp, + char *buffer, int buflen, int *h_errnop) { struct hostent *hp = 0; int rval; @@ -106,37 +135,28 @@ }; rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyaddr", - default_src, addr, len, type); + default_src, addr, len, type, resp, buffer, buflen); + *h_errnop = h_errno; if (rval != NS_SUCCESS) - return NULL; + return ((errno == 0) ? -1 : errno); /* Be paranoid */ else - return hp; + return (0); } -struct hostent_data; - -/* - * Temporary function (not thread safe) - */ -int gethostbyaddr_r(const char *addr, int len, int type, - struct hostent *result, struct hostent_data *buffer) +struct hostent * +gethostbyaddr(const char *addr, int len, int type) { - struct hostent *hp; - int ret; - if ((hp = gethostbyaddr(addr, len, type)) == NULL) { - ret = -1; - } else { - memcpy(result, hp, sizeof(struct hostent)); - ret = 0; - } - return(ret); + int rval; + + rval = gethostbyaddr_r(addr, len, type, NULL, NULL, 0, &h_errno); + return (rval == 0 ? &host_s : NULL); } void -sethostent(stayopen) - int stayopen; +sethostent(int stayopen) { + _sethosthtent(stayopen); _sethostdnsent(stayopen); } @@ -144,6 +164,7 @@ void endhostent() { + _endhosthtent(); _endhostdnsent(); } Index: src/lib/libc/net/getnetbydns.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbydns.c,v retrieving revision 1.21 diff -d -u -r1.21 getnetbydns.c --- src/lib/libc/net/getnetbydns.c 26 Jun 2002 14:18:36 -0000 1.21 +++ src/lib/libc/net/getnetbydns.c 10 Aug 2002 10:03:52 -0000 @@ -82,11 +82,8 @@ #include "res_config.h" -extern int h_errno; - #define BYADDR 0 #define BYNAME 1 -#define MAXALIASES 35 #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ Index: src/lib/libc/net/getnetbyht.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbyht.c,v retrieving revision 1.10 diff -d -u -r1.10 getnetbyht.c --- src/lib/libc/net/getnetbyht.c 22 Mar 2002 21:52:29 -0000 1.10 +++ src/lib/libc/net/getnetbyht.c 10 Aug 2002 10:03:52 -0000 @@ -58,8 +58,7 @@ #include #include #include - -#define MAXALIASES 35 +#include static FILE *netf; static char line[BUFSIZ+1]; Index: src/lib/libc/net/getnetbynis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbynis.c,v retrieving revision 1.15 diff -d -u -r1.15 getnetbynis.c --- src/lib/libc/net/getnetbynis.c 22 Mar 2002 21:52:29 -0000 1.15 +++ src/lib/libc/net/getnetbynis.c 10 Aug 2002 10:03:52 -0000 @@ -44,9 +44,7 @@ #include #include #endif - -#define MAXALIASES 35 -#define MAXADDRS 35 +#include #ifdef YP static char *host_aliases[MAXALIASES]; Index: src/lib/libc/net/herror.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/herror.c,v retrieving revision 1.11 diff -d -u -r1.11 herror.c --- src/lib/libc/net/herror.c 22 Mar 2002 21:52:29 -0000 1.11 +++ src/lib/libc/net/herror.c 10 Aug 2002 10:03:52 -0000 @@ -71,8 +71,6 @@ }; int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; -int h_errno; - /* * herror -- * print the error indicated by the h_errno value. @@ -110,3 +108,19 @@ return (h_errlist[err]); return ("Unknown resolver error"); } + +#undef h_errno +int h_errno; + +/* + * Declare a weak reference in case the application is not linked + * with libpthread. + */ +__weak_reference(__h_errno_accessor_unthreaded, __h_errno_accessor); + +int * +__h_errno_accessor_unthreaded() +{ + return &h_errno; +} + Index: src/lib/libc/net/res_init.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_init.c,v retrieving revision 1.29 diff -d -u -r1.29 res_init.c --- src/lib/libc/net/res_init.c 22 Mar 2002 21:52:30 -0000 1.29 +++ src/lib/libc/net/res_init.c 10 Aug 2002 10:03:55 -0000 @@ -104,17 +104,6 @@ # define isascii(c) (!(c & 0200)) #endif -/* - * Resolver state default settings. - */ - -struct __res_state _res -# if defined(__BIND_RES_TEXT) - = { RES_TIMEOUT, } /* Motorola, et al. */ -# endif - ; - -struct __res_state_ext _res_ext; /* * Set up default settings. If the configuration file exist, the values @@ -154,6 +143,9 @@ #ifndef RFC1535 int dots; #endif + + if(&_res_data==NULL) + return -1; /* * These three fields used to be statically initialized. This made @@ -582,3 +574,43 @@ */ #undef res_init __weak_reference(__res_init, res_init); + +/* + * Resolver state default settings. + */ + +#undef _res +#undef _res_ext +#undef _res_data + +struct __res_state _res +# if defined(__BIND_RES_TEXT) + = { RES_TIMEOUT, } /* Motorola, et al. */ +# endif + ; + +struct __res_state_ext _res_ext; + +struct __res_data _res_data = { 0, -1, 0, 0, 0, NULL, NULL, NULL, 0, &_res, + &_res_ext }; + +/* + * Declare a weak reference in case the application is not linked + * with libpthread. + */ +__weak_reference(__res_data_accessor_unthreaded, __res_data_accessor); +__weak_reference(__res_accessor_unthreaded, __res_accessor); + +struct __res_data * +__res_data_accessor_unthreaded() +{ + + return &_res_data; +} + +struct __res_state * +__res_accessor_unthreaded() +{ + + return _res_data.res; +} Index: src/lib/libc/net/res_query.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_query.c,v retrieving revision 1.23 diff -d -u -r1.23 res_query.c --- src/lib/libc/net/res_query.c 7 Jul 2002 11:28:28 -0000 1.23 +++ src/lib/libc/net/res_query.c 10 Aug 2002 10:03:55 -0000 @@ -87,6 +87,7 @@ #include #include #include +#include #include "res_config.h" @@ -374,11 +375,20 @@ hostalias(name) const char *name; { + static char abuf[MAXDNAME]; + return (hostalias_r(name, abuf, sizeof abuf)); +} + +const char * +hostalias_r(name, abuf, len) + const char *name; + char *abuf; + int len; +{ char *cp1, *cp2; FILE *fp; char *file; char buf[BUFSIZ]; - static char abuf[MAXDNAME]; if (_res.options & RES_NOALIASES) return (NULL); @@ -402,8 +412,8 @@ break; for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2) ; - abuf[sizeof(abuf) - 1] = *cp2 = '\0'; - strncpy(abuf, cp1, sizeof(abuf) - 1); + abuf[len - 1] = *cp2 = '\0'; + strncpy(abuf, cp1, len - 1); fclose(fp); return (abuf); } Index: src/lib/libc/net/res_send.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_send.c,v retrieving revision 1.45 diff -d -u -r1.45 res_send.c --- src/lib/libc/net/res_send.c 1 Apr 2002 16:09:45 -0000 1.45 +++ src/lib/libc/net/res_send.c 10 Aug 2002 10:03:56 -0000 @@ -102,13 +102,6 @@ #include "res_config.h" -static int s = -1; /* socket used for communications */ -static int connected = 0; /* is the socket connected */ -static int vc = 0; /* is the socket a virtual circuit? */ -static int af = 0; /* address family of socket */ -static res_send_qhook Qhook = NULL; -static res_send_rhook Rhook = NULL; - #define CAN_RECONNECT 1 @@ -170,7 +163,7 @@ res_send_qhook hook; { - Qhook = hook; + _res_data.Qhook = hook; } void @@ -178,7 +171,7 @@ res_send_rhook hook; { - Rhook = hook; + _res_data.Rhook = hook; } static struct sockaddr * get_nsaddr(size_t); @@ -406,13 +399,13 @@ goto next_ns; } - if (Qhook) { + if (_res_data.Qhook) { int done = 0, loops = 0; do { res_sendhookact act; - act = (*Qhook)((struct sockaddr_in **)&nsap, + act = (*_res_data.Qhook)((struct sockaddr_in **)&nsap, &buf, &buflen, ans, anssiz, &resplen); switch (act) { @@ -457,14 +450,14 @@ */ try = _res.retry; truncated = 0; - if (s < 0 || !vc || hp->opcode == ns_o_update || - af != nsap->sa_family) { - if (s >= 0) + if (_res_data.s < 0 || !_res_data.vc || hp->opcode == ns_o_update || + _res_data.af != nsap->sa_family) { + if (_res_data.s >= 0) res_close(); - af = nsap->sa_family; - s = _socket(af, SOCK_STREAM, 0); - if (s < 0) { + _res_data.af = nsap->sa_family; + _res_data.s = _socket(_res_data.af, SOCK_STREAM, 0); + if (_res_data.s < 0) { terrno = errno; Perror(stderr, "socket(vc)", errno); badns |= (1 << ns); @@ -472,7 +465,7 @@ goto next_ns; } errno = 0; - if (_connect(s, nsap, salen) < 0) { + if (_connect(_res_data.s, nsap, salen) < 0) { terrno = errno; Aerror(stderr, "connect/vc", errno, nsap); @@ -480,7 +473,7 @@ res_close(); goto next_ns; } - vc = 1; + _res_data.vc = 1; } /* * Send length & message @@ -490,7 +483,7 @@ iov[0].iov_len = INT16SZ; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = buflen; - if (_writev(s, iov, 2) != (INT16SZ + buflen)) { + if (_writev(_res_data.s, iov, 2) != (INT16SZ + buflen)) { terrno = errno; Perror(stderr, "write failed", errno); badns |= (1 << ns); @@ -503,7 +496,7 @@ read_len: cp = ans; len = INT16SZ; - while ((n = _read(s, (char *)cp, (int)len)) > 0) { + while ((n = _read(_res_data.s, (char *)cp, (int)len)) > 0) { cp += n; if ((len -= n) <= 0) break; @@ -551,7 +544,7 @@ } cp = ans; while (len != 0 && - (n = _read(s, (char *)cp, (int)len)) > 0) { + (n = _read(_res_data.s, (char *)cp, (int)len)) > 0) { cp += n; len -= n; } @@ -574,7 +567,7 @@ n = (len > sizeof(junk) ? sizeof(junk) : len); - if ((n = _read(s, junk, n)) > 0) + if ((n = _read(_res_data.s, junk, n)) > 0) len -= n; else break; @@ -604,12 +597,13 @@ struct sockaddr_storage from; int fromlen; - if (s < 0 || vc || af != nsap->sa_family) { - if (vc) + if (_res_data.s < 0 || _res_data.vc || + _res_data.af != nsap->sa_family) { + if (_res_data.vc) res_close(); - af = nsap->sa_family; - s = _socket(af, SOCK_DGRAM, 0); - if (s < 0) { + _res_data.af = nsap->sa_family; + _res_data.s = _socket(_res_data.af, SOCK_DGRAM, 0); + if (_res_data.s < 0) { #ifndef CAN_RECONNECT bad_dg_sock: #endif @@ -619,7 +613,7 @@ res_close(); goto next_ns; } - connected = 0; + _res_data.connected = 0; } #ifndef CANNOT_CONNECT_DGRAM /* @@ -650,8 +644,8 @@ * Connect only if we are sure we won't * receive a response from another server. */ - if (!connected) { - if (_connect(s, nsap, salen) < 0) { + if (!_res_data.connected) { + if (_connect(_res_data.s, nsap, salen) < 0) { Aerror(stderr, "connect(dg)", errno, nsap); @@ -659,9 +653,9 @@ res_close(); goto next_ns; } - connected = 1; + _res_data.connected = 1; } - if (send(s, (char*)buf, buflen, 0) != buflen) { + if (send(_res_data.s, (char*)buf, buflen, 0) != buflen) { Perror(stderr, "send", errno); badns |= (1 << ns); res_close(); @@ -672,7 +666,7 @@ * Disconnect if we want to listen * for responses from more than one server. */ - if (connected) { + if (_res_data.connected) { #ifdef CAN_RECONNECT /* XXX: any errornous address */ struct sockaddr_in no_addr; @@ -680,24 +674,24 @@ no_addr.sin_family = AF_INET; no_addr.sin_addr.s_addr = INADDR_ANY; no_addr.sin_port = 0; - (void) _connect(s, + (void) _connect(_res_data.s, (struct sockaddr *) &no_addr, sizeof no_addr); #else - int s1 = _socket(af, SOCK_DGRAM,0); + int s1 = _socket(_res_data.af, SOCK_DGRAM,0); if (s1 < 0) goto bad_dg_sock; - (void)_dup2(s1, s); + (void)_dup2(s1, _res_data.s); (void)_close(s1); Dprint(_res.options & RES_DEBUG, (stdout, ";; new DG socket\n")) #endif /* CAN_RECONNECT */ - connected = 0; + _res_data.connected = 0; errno = 0; } #endif /* !CANNOT_CONNECT_DGRAM */ - if (_sendto(s, (char*)buf, buflen, 0, + if (_sendto(_res_data.s, (char*)buf, buflen, 0, nsap, salen) != buflen) { Aerror(stderr, "sendto", errno, nsap); badns |= (1 << ns); @@ -722,13 +716,13 @@ (void) gettimeofday(&ctv, NULL); timeradd(&timeout, &ctv, &timeout); wait: - if (s < 0) { + if (_res_data.s < 0) { Perror(stderr, "s out-of-bounds", EMFILE); res_close(); goto next_ns; } - EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0); + EV_SET(&kv, _res_data.s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0); n = _kevent(kq, &kv, 1, &kv, 1, &ts); if (n < 0) { @@ -757,7 +751,7 @@ } errno = 0; fromlen = sizeof(from); - resplen = _recvfrom(s, (char*)ans, anssiz, 0, + resplen = _recvfrom(_res_data.s, (char*)ans, anssiz, 0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { Perror(stderr, "recvfrom", errno); @@ -862,13 +856,13 @@ !(_res.options & RES_STAYOPEN)) { res_close(); } - if (Rhook) { + if (_res_data.Rhook) { int done = 0, loops = 0; do { res_sendhookact act; - act = (*Rhook)((struct sockaddr_in *)nsap, + act = (*_res_data.Rhook)((struct sockaddr_in *)nsap, buf, buflen, ans, anssiz, &resplen); switch (act) { @@ -920,12 +914,12 @@ void res_close() { - if (s >= 0) { - (void)_close(s); - s = -1; - connected = 0; - vc = 0; - af = 0; + if (_res_data.s >= 0) { + (void)_close(_res_data.s); + _res_data.s = -1; + _res_data.connected = 0; + _res_data.vc = 0; + _res_data.af = 0; } } Index: src/lib/libc_r/sys/Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc_r/sys/Makefile.inc,v retrieving revision 1.10 diff -d -u -r1.10 Makefile.inc --- src/lib/libc_r/sys/Makefile.inc 28 Aug 1999 00:03:13 -0000 1.10 +++ src/lib/libc_r/sys/Makefile.inc 10 Aug 2002 10:03:56 -0000 @@ -2,5 +2,5 @@ .PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH} -SRCS+= uthread_error.c _atomic_lock.S +SRCS+= uthread_error.c uthread_resolv.c _atomic_lock.S Index: src/lib/libc_r/sys/uthread_resolv.c =================================================================== RCS file: src/lib/libc_r/sys/uthread_resolv.c diff -N src/lib/libc_r/sys/uthread_resolv.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/lib/libc_r/sys/uthread_resolv.c 10 Aug 2002 10:03:56 -0000 @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2001 Alexandr Litvin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include "pthread_private.h" + +#undef h_errno +#undef _res +#undef _res_ext +#undef _res_data + +extern int h_errno; +extern struct __res_data _res_data; + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static pthread_key_t key; + + +static void +__res_data_destroy(void *p) +{ + struct __res_data *_res_datap = (struct __res_data *)p; + + if(_res_datap->res) + free(_res_datap->res); + if(_res_datap->res_ext) + free(_res_datap->res_ext); + if(_res_datap->s >= 0) + close(_res_datap->s); + if(_res_datap->hostf) + fclose(_res_datap->hostf); + free(_res_datap); +} + +static void +__res_data_init() +{ + + pthread_key_create(&key, __res_data_destroy); +} + +struct __res_data * +__res_data_accessor() +{ + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + _res_datap = &_res_data; + } else { + pthread_once(&once, __res_data_init); + _res_datap = (struct __res_data *)pthread_getspecific(key); + if(_res_datap==NULL) { + _res_datap = malloc(sizeof(struct __res_data)); + if(_res_datap==NULL) + return (NULL); + bzero(_res_datap, sizeof(struct __res_data)); + _res_datap->res = malloc(sizeof(struct __res_state)); + if(_res_datap->res == NULL) { + free(_res_datap); + return (NULL); + } + bzero(_res_datap->res, sizeof(struct __res_state)); + _res_datap->res_ext = + malloc(sizeof(struct __res_state_ext)); + if(_res_datap->res_ext == NULL) { + free(_res_datap->res); + free(_res_datap); + return (NULL); + } + bzero(_res_datap->res_ext, + sizeof(struct __res_state_ext)); + _res_datap->s = -1; + pthread_setspecific(key, _res_datap); + } + } + return (_res_datap); +} + +static struct __res_state dummy_res; +static int dummy_h_errno; + +struct __res_state * +__res_accessor() +{ + struct __res_state *resp; + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + resp = _res_data.res; + } else { + _res_datap = __res_data_accessor(); + if(_res_datap) { + resp = _res_datap->res; + } else { + dummy_res.options = RES_DEFAULT; + resp = &dummy_res; + } + } + return (resp); +} + +int * +__h_errno_accessor() +{ + int *h_errnop; + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + h_errnop = &h_errno; + } else { + _res_datap = __res_data_accessor(); + if(_res_datap) { + h_errnop = &_res_datap->h_errno_res; + } else { + dummy_h_errno = NETDB_INTERNAL; + h_errnop = &dummy_h_errno; + } + } + return (h_errnop); +} --------------051496A982500B2DDF1E4FCD Content-Type: text/plain; charset=koi8-r; name="resolv_r-2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="resolv_r-2.diff" Index: src/include/netdb.h =================================================================== RCS file: /home/ncvs/src/include/netdb.h,v retrieving revision 1.24 diff -d -u -r1.24 netdb.h --- src/include/netdb.h 26 Jun 2002 08:18:42 -0000 1.24 +++ src/include/netdb.h 12 Aug 2002 09:48:11 -0000 @@ -82,7 +82,10 @@ #define _PATH_PROTOCOLS "/etc/protocols" #define _PATH_SERVICES "/etc/services" -extern int h_errno; +__BEGIN_DECLS +int * __h_errno_accessor(void); +__END_DECLS +#define h_errno (* __h_errno_accessor()) /* * Structures returned by network data base library. All addresses are Index: src/include/resolv.h =================================================================== RCS file: /home/ncvs/src/include/resolv.h,v retrieving revision 1.21 diff -d -u -r1.21 resolv.h --- src/include/resolv.h 23 Mar 2002 17:24:53 -0000 1.21 +++ src/include/resolv.h 12 Aug 2002 09:48:11 -0000 @@ -62,6 +62,7 @@ #include #include #include +#include /* * Revision information. This is the release date in YYYYMMDD format. @@ -90,6 +91,8 @@ #define MAXDFLSRCH 3 /* # default domain levels to try */ #define MAXDNSRCH 6 /* max # domains in search path */ #define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ +#define MAXALIASES 35 /* max # of aliases to return */ +#define MAXADDRS 35 /* max # of addresses to return */ #define RES_TIMEOUT 5 /* min. seconds between retries */ #define MAXRESOLVSORT 10 /* number of net to sort on */ @@ -198,10 +201,6 @@ char * humanname; /* Its fun name, like "mail exchanger" */ }; -extern struct __res_state _res; -/* for INET6 */ -extern struct __res_state_ext _res_ext; - extern const struct res_sym __p_class_syms[]; extern const struct res_sym __p_type_syms[]; @@ -224,6 +223,7 @@ #define fp_query __fp_query #define fp_nquery __fp_nquery #define hostalias __hostalias +#define hostalias_r __hostalias_r #define putlong __putlong #define putshort __putshort #define p_class __p_class @@ -273,6 +273,7 @@ void fp_query(const u_char *, FILE *); void fp_nquery(const u_char *, int, FILE *); const char * hostalias(const char *); +const char * hostalias_r(const char *, char *, int); void putlong(u_int32_t, u_char *); void putshort(u_int16_t, u_char *); const char * p_class(int); @@ -315,5 +316,35 @@ void res_freeupdrec(ns_updrec *); #endif __END_DECLS + +struct __res_data { + int h_errno_res; + int s; /* socket used for communications */ + int connected : 1; /* is the socket connected */ + int vc : 1; /* is the socket a virtual circuit? */ + int af; /* address family of socket */ + res_send_qhook Qhook; + res_send_rhook Rhook; + FILE* hostf; + int stayopen; + struct hostent host; + char *hostbuf; + int hostbuflen; + u_char *host_addr; + int host_addrlen; + struct __res_state *res; + struct __res_state_ext *res_ext; +}; + +__BEGIN_DECLS +u_int16_t _getshort(const u_char *); +u_int32_t _getlong(const u_char *); +struct __res_data * __res_data_accessor(void); +struct __res_state * __res_accessor(void); +__END_DECLS +#define _res_data (* __res_data_accessor()) +#define _res (* __res_accessor()) +/* for INET6 */ +#define _res_ext (* (__res_data_accessor()->res_ext)) #endif /* !_RESOLV_H_ */ Index: src/lib/libc/net/getaddrinfo.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getaddrinfo.c,v retrieving revision 1.28 diff -d -u -r1.28 getaddrinfo.c --- src/lib/libc/net/getaddrinfo.c 2 Aug 2002 11:58:48 -0000 1.28 +++ src/lib/libc/net/getaddrinfo.c 12 Aug 2002 09:48:17 -0000 @@ -1673,7 +1673,6 @@ /* resolver logic */ extern const char *__hostalias(const char *); -extern int h_errno; /* * Formulate a normal query, send, and await answer. Index: src/lib/libc/net/gethostbydns.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbydns.c,v retrieving revision 1.36 diff -d -u -r1.36 gethostbydns.c --- src/lib/libc/net/gethostbydns.c 26 Jun 2002 14:18:36 -0000 1.36 +++ src/lib/libc/net/gethostbydns.c 12 Aug 2002 09:48:17 -0000 @@ -68,6 +68,7 @@ #include #include +#include #include #include #include @@ -82,19 +83,9 @@ #define SPRINTF(x) ((size_t)sprintf x) -#define MAXALIASES 35 -#define MAXADDRS 35 - static const char AskedForGot[] = "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; -static char *h_addr_ptrs[MAXADDRS + 1]; - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[8*1024]; -static u_char host_addr[16]; /* IPv4 or IPv6 */ - #ifdef RESOLVSORT static void addrsort(char **, int); #endif @@ -119,7 +110,6 @@ char ac; } align; -extern int h_errno; int _dns_ttl_; #ifdef DEBUG @@ -157,11 +147,14 @@ } while (0) static struct hostent * -gethostanswer(answer, anslen, qname, qtype) +gethostanswer(answer, anslen, qname, qtype, host, hostbuf, hostbuflen) const querybuf *answer; int anslen; const char *qname; int qtype; + struct hostent *host; + char *hostbuf; + int hostbuflen; { const HEADER *hp; const u_char *cp; @@ -176,7 +169,7 @@ int (*name_ok)(const char *); tname = qname; - host.h_name = NULL; + host->h_name = NULL; eom = answer->buf + anslen; switch (qtype) { case T_A: @@ -197,7 +190,7 @@ ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; - ep = hostbuf + sizeof hostbuf; + ep = hostbuf + hostbuflen; cp = answer->buf; BOUNDED_INCR(HFIXEDSZ); if (qdcount != 1) { @@ -220,17 +213,15 @@ h_errno = NO_RECOVERY; return (NULL); } - host.h_name = bp; + host->h_name = bp; bp += n; /* The qname can be abbreviated, but h_name is now absolute. */ - qname = host.h_name; + qname = host->h_name; } - ap = host_aliases; + ap = host->h_aliases; *ap = NULL; - host.h_aliases = host_aliases; - hap = h_addr_ptrs; + hap = host->h_addr_list; *hap = NULL; - host.h_addr_list = h_addr_ptrs; haveanswer = 0; had_error = 0; _dns_ttl_ = -1; @@ -259,7 +250,7 @@ continue; /* XXX - had_error++ ? */ } if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { - if (ap >= &host_aliases[MAXALIASES-1]) + if (ap >= &host->h_aliases[MAXALIASES-1]) continue; n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if ((n < 0) || !(*name_ok)(tbuf)) { @@ -286,7 +277,7 @@ continue; } strcpy(bp, tbuf); - host.h_name = bp; + host->h_name = bp; bp += n; continue; } @@ -341,8 +332,8 @@ return (NULL); } if (!haveanswer) - host.h_name = bp; - else if (ap < &host_aliases[MAXALIASES-1]) + host->h_name = bp; + else if (ap < &host->h_aliases[MAXALIASES-1]) *ap++ = bp; else n = -1; @@ -356,7 +347,7 @@ } break; #else - host.h_name = bp; + host->h_name = bp; if (_res.options & RES_USE_INET6) { n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { @@ -364,27 +355,27 @@ break; } bp += n; - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); } h_errno = NETDB_SUCCESS; - return (&host); + return (host); #endif case T_A: case T_AAAA: - if (strcasecmp(host.h_name, bp) != 0) { + if (strcasecmp(host->h_name, bp) != 0) { syslog(LOG_NOTICE|LOG_AUTH, - AskedForGot, host.h_name, bp); + AskedForGot, host->h_name, bp); cp += n; continue; /* XXX - had_error++ ? */ } - if (n != host.h_length) { + if (n != host->h_length) { cp += n; continue; } if (!haveanswer) { int nn; - host.h_name = bp; + host->h_name = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; } @@ -396,7 +387,7 @@ had_error++; continue; } - if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (hap >= &host->h_addr_list[MAXADDRS-1]) { if (!toobig++) dprintf("Too many addresses (%d)\n", MAXADDRS); @@ -430,57 +421,40 @@ * address in that case, not some random one */ if (_res.nsort && haveanswer > 1 && qtype == T_A) - addrsort(h_addr_ptrs, haveanswer); + addrsort(host->h_addr_list, haveanswer); # endif /*RESOLVSORT*/ - if (!host.h_name) { + if (!host->h_name) { n = strlen(qname) + 1; /* for the \0 */ if (n > ep - bp || n >= MAXHOSTNAMELEN) goto no_recovery; strcpy(bp, qname); - host.h_name = bp; + host->h_name = bp; bp += n; } if (_res.options & RES_USE_INET6) - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); h_errno = NETDB_SUCCESS; - return (&host); + return (host); } no_recovery: h_errno = NO_RECOVERY; return (NULL); } -struct hostent * -__dns_getanswer(answer, anslen, qname, qtype) - const char *answer; - int anslen; - const char *qname; - int qtype; -{ - switch(qtype) { - case T_AAAA: - host.h_addrtype = AF_INET6; - host.h_length = IN6ADDRSZ; - break; - case T_A: - default: - host.h_addrtype = AF_INET; - host.h_length = INADDRSZ; - break; - } - - return(gethostanswer((const querybuf *)answer, anslen, qname, qtype)); -} - int _dns_gethostbyname(void *rval, void *cb_data, va_list ap) { const char *name; int af; + struct hostent *host; + char *hostbuf; + int hostbuflen; + u_char *host_addr; querybuf buf; const char *cp; char *bp, *ep; int n, size, type, len; + char abuf[MAXDNAME]; name = va_arg(ap, const char *); af = va_arg(ap, int); @@ -491,6 +465,11 @@ return NS_UNAVAIL; } + host = &_res_data.host; + hostbuf = _res_data.hostbuf; + hostbuflen = _res_data.hostbuflen; + host_addr = _res_data.host_addr; + switch (af) { case AF_INET: size = INADDRSZ; @@ -506,15 +485,15 @@ return NS_UNAVAIL; } - host.h_addrtype = af; - host.h_length = size; + host->h_addrtype = af; + host->h_length = size; /* * if there aren't any dots, it could be a user-level alias. * this is also done in res_query() since we are not the only * function that looks up host names. */ - if (!strchr(name, '.') && (cp = __hostalias(name))) + if (!strchr(name, '.') && (cp = __hostalias_r(name, abuf, sizeof abuf))) name = cp; /* @@ -538,17 +517,15 @@ strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; - ep = hostbuf + sizeof hostbuf; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; + ep = hostbuf + hostbuflen; + host->h_name = hostbuf; + host->h_aliases[0] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; if (_res.options & RES_USE_INET6) - _map_v4v6_hostent(&host, &bp, &ep); + _map_v4v6_hostent(host, &bp, &ep); h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; + *(struct hostent **)rval = host; return NS_SUCCESS; } if (!isdigit((unsigned char)*cp) && *cp != '.') @@ -572,15 +549,13 @@ strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; - len = sizeof hostbuf - MAXDNAME; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; + len = hostbuflen - MAXDNAME; + host->h_name = hostbuf; + host->h_aliases[0] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; + *(struct hostent **)rval = host; return NS_SUCCESS; } if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.') @@ -591,7 +566,8 @@ dprintf("res_search failed (%d)\n", n); return NS_UNAVAIL; } - *(struct hostent **)rval = gethostanswer(&buf, n, name, type); + *(struct hostent **)rval = gethostanswer(&buf, n, name, type, + host, hostbuf, hostbuflen); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; } @@ -600,6 +576,9 @@ { const char *addr; /* XXX should have been def'd as u_char! */ int len, af; + struct hostent *host; + char *hostbuf; + int hostbuflen; const u_char *uaddr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; @@ -607,6 +586,7 @@ querybuf buf; struct hostent *hp; char qbuf[MAXDNAME+1], *qp; + u_char *host_addr; #ifdef SUNSECURITY struct hostent *rhp; char **haddr; @@ -618,13 +598,19 @@ uaddr = (const u_char *)addr; len = va_arg(ap, int); af = va_arg(ap, int); - + *(struct hostent **)rval = NULL; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return NS_UNAVAIL; } + + host = &_res_data.host; + hostbuf = _res_data.hostbuf; + hostbuflen = _res_data.hostbuflen; + host_addr = _res_data.host_addr; + if (af == AF_INET6 && len == IN6ADDRSZ && (!bcmp(uaddr, mapped, sizeof mapped) || !bcmp(uaddr, tunnelled, sizeof tunnelled))) { @@ -680,7 +666,8 @@ dprintf("static buffer is too small (%d)\n", n); return NS_UNAVAIL; } - if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR))) + if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR, host, hostbuf, + hostbuflen))) return NS_NOTFOUND; /* h_errno was set by gethostanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { @@ -717,8 +704,8 @@ hp->h_addrtype = af; hp->h_length = len; bcopy(addr, host_addr, len); - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; + host->h_addr_list[0] = (char *)host_addr; + host->h_addr_list[1] = NULL; if (af == AF_INET && (_res.options & RES_USE_INET6)) { _map_v4v6_address((char*)host_addr, (char*)host_addr); hp->h_addrtype = AF_INET6; Index: src/lib/libc/net/gethostbyht.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbyht.c,v retrieving revision 1.16 diff -d -u -r1.16 gethostbyht.c --- src/lib/libc/net/gethostbyht.c 22 Mar 2002 21:52:29 -0000 1.16 +++ src/lib/libc/net/gethostbyht.c 12 Aug 2002 09:48:20 -0000 @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -70,33 +71,35 @@ #include /* XXX */ #include /* XXX */ -#define MAXALIASES 35 - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[BUFSIZ+1]; -static FILE *hostf = NULL; -static u_int32_t host_addr[4]; /* IPv4 or IPv6 */ -static char *h_addr_ptrs[2]; -static int stayopen = 0; - void _sethosthtent(f) int f; { - if (!hostf) - hostf = fopen(_PATH_HOSTS, "r" ); + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return; + } + + if (!_res_data.hostf) + _res_data.hostf = fopen(_PATH_HOSTS, "r" ); else - rewind(hostf); - stayopen = f; + rewind(_res_data.hostf); + _res_data.stayopen = f; } void _endhosthtent() { - if (hostf && !stayopen) { - (void) fclose(hostf); - hostf = NULL; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return; + } + + if (_res_data.hostf && !_res_data.stayopen) { + (void) fclose(_res_data.hostf); + _res_data.hostf = NULL; } } @@ -106,13 +109,27 @@ char *p; char *cp, **q; int af, len; + struct hostent *host; + char *hostbuf; + int hostbuflen; - if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NULL; + } + + host = &_res_data.host; + hostbuf = _res_data.hostbuf; + hostbuflen = _res_data.hostbuflen; + host->h_addr_list[0] = _res_data.host_addr; + host->h_addr_list[1] = NULL; + + if (!_res_data.hostf && !(_res_data.hostf = fopen(_PATH_HOSTS, "r" ))) { h_errno = NETDB_INTERNAL; return (NULL); } again: - if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + if (!(p = fgets(hostbuf, hostbuflen, _res_data.hostf))) { h_errno = HOST_NOT_FOUND; return (NULL); } @@ -124,12 +141,12 @@ if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; - if (inet_pton(AF_INET6, p, host_addr) > 0) { + if (inet_pton(AF_INET6, p, host->h_addr_list[0]) > 0) { af = AF_INET6; len = IN6ADDRSZ; - } else if (inet_pton(AF_INET, p, host_addr) > 0) { + } else if (inet_pton(AF_INET, p, host->h_addr_list[0]) > 0) { if (_res.options & RES_USE_INET6) { - _map_v4v6_address((char*)host_addr, (char*)host_addr); + _map_v4v6_address(host->h_addr_list[0], host->h_addr_list[0]); af = AF_INET6; len = IN6ADDRSZ; } else { @@ -139,15 +156,12 @@ } else { goto again; } - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; - host.h_length = len; - host.h_addrtype = af; + host->h_length = len; + host->h_addrtype = af; while (*cp == ' ' || *cp == '\t') cp++; - host.h_name = cp; - q = host.h_aliases = host_aliases; + host->h_name = cp; + q = host->h_aliases; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; while (cp && *cp) { @@ -155,14 +169,14 @@ cp++; continue; } - if (q < &host_aliases[MAXALIASES - 1]) + if (q < &host->h_aliases[MAXALIASES - 1]) *q++ = cp; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } *q = NULL; h_errno = NETDB_SUCCESS; - return (&host); + return (host); } int @@ -175,7 +189,7 @@ name = va_arg(ap, const char *); af = va_arg(ap, int); - + sethostent(0); while ((p = gethostent()) != NULL) { if (p->h_addrtype != af) Index: src/lib/libc/net/gethostbynis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostbynis.c,v retrieving revision 1.15 diff -d -u -r1.15 gethostbynis.c --- src/lib/libc/net/gethostbynis.c 22 Mar 2002 21:52:29 -0000 1.15 +++ src/lib/libc/net/gethostbynis.c 12 Aug 2002 09:48:20 -0000 @@ -44,16 +44,9 @@ #include #include #endif - -#define MAXALIASES 35 -#define MAXADDRS 35 - -extern int h_errno; +#include #ifdef YP -static char *host_aliases[MAXALIASES]; -static char hostaddr[MAXADDRS]; -static char *host_addrs[2]; static struct hostent * _gethostbynis(name, map, af) @@ -64,9 +57,20 @@ char *cp, **q; char *result; int resultlen,size; - static struct hostent h; static char *domain = (char *)NULL; - static char ypbuf[YPMAXRECORD + 2]; + struct hostent *host; + char *hostbuf; + int hostbuflen; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NULL; + } + + host = &_res_data.host; + hostbuf = _res_data.hostbuf; + hostbuflen = _res_data.hostbuflen; + host->h_addr_list[0] = _res_data.host_addr; switch(af) { case AF_INET: @@ -90,27 +94,29 @@ h_errno = HOST_NOT_FOUND; return ((struct hostent *)NULL); } - - /* avoid potential memory leak */ - bcopy((char *)result, (char *)&ypbuf, resultlen); - ypbuf[resultlen] = '\0'; + if (resultlen > hostbuflen) { + h_errno = NETDB_INTERNAL; + errno = ERANGE; + return (NULL); + } + result[resultlen] = '\0'; + bcopy((char *)result, hostbuf, resultlen); free(result); - result = (char *)&ypbuf; + result = hostbuf; if ((cp = index(result, '\n'))) *cp = '\0'; cp = strpbrk(result, " \t"); *cp++ = '\0'; - h.h_addr_list = host_addrs; - h.h_addr = hostaddr; - *((u_long *)h.h_addr) = inet_addr(result); - h.h_length = size; - h.h_addrtype = AF_INET; + *((u_long *)host->h_addr_list[0]) = inet_addr(result); + host->h_addr_list[1] = NULL; + host->h_length = size; + host->h_addrtype = AF_INET; while (*cp == ' ' || *cp == '\t') cp++; - h.h_name = cp; - q = h.h_aliases = host_aliases; + host->h_name = cp; + q = host->h_aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; @@ -119,14 +125,14 @@ cp++; continue; } - if (q < &host_aliases[MAXALIASES - 1]) + if (q < &host->h_aliases[MAXALIASES - 1]) *q++ = cp; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; - return (&h); + return (host); } #endif /* YP */ @@ -163,6 +169,11 @@ name = va_arg(ap, const char *); af = va_arg(ap, int); + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NS_UNAVAIL; + } + *(struct hostent **)rval = _gethostbynis(name, "hosts.byname", af); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; #else @@ -181,8 +192,14 @@ addr = va_arg(ap, const char *); len = va_arg(ap, int); af = va_arg(ap, int); - - *(struct hostent **)rval =_gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af); + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NS_UNAVAIL; + } + + *(struct hostent **)rval = _gethostbynis( + inet_ntoa(*(struct in_addr *)addr), "hosts.byaddr", af); return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND; #else return NS_UNAVAIL; Index: src/lib/libc/net/gethostnamadr.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/gethostnamadr.c,v retrieving revision 1.20 diff -d -u -r1.20 gethostnamadr.c --- src/lib/libc/net/gethostnamadr.c 22 Mar 2002 21:52:29 -0000 1.20 +++ src/lib/libc/net/gethostnamadr.c 12 Aug 2002 09:48:20 -0000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,7 @@ NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ { 0 } }; - + rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname", default_src, name, type); @@ -114,29 +115,10 @@ return hp; } -struct hostent_data; - -/* - * Temporary function (not thread safe) - */ -int gethostbyaddr_r(const char *addr, int len, int type, - struct hostent *result, struct hostent_data *buffer) -{ - struct hostent *hp; - int ret; - if ((hp = gethostbyaddr(addr, len, type)) == NULL) { - ret = -1; - } else { - memcpy(result, hp, sizeof(struct hostent)); - ret = 0; - } - return(ret); -} - void -sethostent(stayopen) - int stayopen; +sethostent(int stayopen) { + _sethosthtent(stayopen); _sethostdnsent(stayopen); } @@ -144,6 +126,7 @@ void endhostent() { + _endhosthtent(); _endhostdnsent(); } Index: src/lib/libc/net/getnetbydns.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbydns.c,v retrieving revision 1.21 diff -d -u -r1.21 getnetbydns.c --- src/lib/libc/net/getnetbydns.c 26 Jun 2002 14:18:36 -0000 1.21 +++ src/lib/libc/net/getnetbydns.c 12 Aug 2002 09:48:20 -0000 @@ -82,11 +82,8 @@ #include "res_config.h" -extern int h_errno; - #define BYADDR 0 #define BYNAME 1 -#define MAXALIASES 35 #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ Index: src/lib/libc/net/getnetbyht.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbyht.c,v retrieving revision 1.10 diff -d -u -r1.10 getnetbyht.c --- src/lib/libc/net/getnetbyht.c 22 Mar 2002 21:52:29 -0000 1.10 +++ src/lib/libc/net/getnetbyht.c 12 Aug 2002 09:48:20 -0000 @@ -58,8 +58,7 @@ #include #include #include - -#define MAXALIASES 35 +#include static FILE *netf; static char line[BUFSIZ+1]; Index: src/lib/libc/net/getnetbynis.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/getnetbynis.c,v retrieving revision 1.15 diff -d -u -r1.15 getnetbynis.c --- src/lib/libc/net/getnetbynis.c 22 Mar 2002 21:52:29 -0000 1.15 +++ src/lib/libc/net/getnetbynis.c 12 Aug 2002 09:48:20 -0000 @@ -44,9 +44,7 @@ #include #include #endif - -#define MAXALIASES 35 -#define MAXADDRS 35 +#include #ifdef YP static char *host_aliases[MAXALIASES]; Index: src/lib/libc/net/herror.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/herror.c,v retrieving revision 1.11 diff -d -u -r1.11 herror.c --- src/lib/libc/net/herror.c 22 Mar 2002 21:52:29 -0000 1.11 +++ src/lib/libc/net/herror.c 12 Aug 2002 09:48:20 -0000 @@ -71,8 +71,6 @@ }; int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; -int h_errno; - /* * herror -- * print the error indicated by the h_errno value. @@ -104,9 +102,26 @@ hstrerror(err) int err; { + if (err < 0) return ("Resolver internal error"); else if (err < h_nerr) return (h_errlist[err]); return ("Unknown resolver error"); +} + +#undef h_errno +int h_errno; + +/* + * Declare a weak reference in case the application is not linked + * with libpthread. + */ +__weak_reference(__h_errno_accessor_unthreaded, __h_errno_accessor); + +int * +__h_errno_accessor_unthreaded() +{ + + return &h_errno; } Index: src/lib/libc/net/res_init.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_init.c,v retrieving revision 1.29 diff -d -u -r1.29 res_init.c --- src/lib/libc/net/res_init.c 22 Mar 2002 21:52:30 -0000 1.29 +++ src/lib/libc/net/res_init.c 12 Aug 2002 09:48:22 -0000 @@ -83,12 +83,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include "res_config.h" @@ -104,17 +104,6 @@ # define isascii(c) (!(c & 0200)) #endif -/* - * Resolver state default settings. - */ - -struct __res_state _res -# if defined(__BIND_RES_TEXT) - = { RES_TIMEOUT, } /* Motorola, et al. */ -# endif - ; - -struct __res_state_ext _res_ext; /* * Set up default settings. If the configuration file exist, the values @@ -154,6 +143,10 @@ #ifndef RFC1535 int dots; #endif + + /* Ensure that _res_data is inited in the threaded case */ + if(&_res_data == NULL) + return -1; /* * These three fields used to be statically initialized. This made @@ -582,3 +575,49 @@ */ #undef res_init __weak_reference(__res_init, res_init); + +/* + * Resolver state default settings. + */ + +#undef _res +#undef _res_ext +#undef _res_data + +struct __res_state _res +# if defined(__BIND_RES_TEXT) + = { RES_TIMEOUT, } /* Motorola, et al. */ +# endif + ; + +struct __res_state_ext _res_ext; + +static char *host_aliases[MAXALIASES]; +static char *h_addr_ptrs[MAXADDRS + 1]; +static char hostbuf[8*1024]; +static u_char host_addr[16]; + +struct __res_data _res_data = { 0, -1, 0, 0, 0, NULL, NULL, NULL, 0, + { NULL, host_aliases, 0, 0, h_addr_ptrs }, hostbuf, sizeof hostbuf, + host_addr, sizeof host_addr, &_res, &_res_ext }; + +/* + * Declare a weak reference in case the application is not linked + * with libpthread. + */ +__weak_reference(__res_data_accessor_unthreaded, __res_data_accessor); +__weak_reference(__res_accessor_unthreaded, __res_accessor); + +struct __res_data * +__res_data_accessor_unthreaded() +{ + + return &_res_data; +} + +struct __res_state * +__res_accessor_unthreaded() +{ + + return _res_data.res; +} Index: src/lib/libc/net/res_query.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_query.c,v retrieving revision 1.23 diff -d -u -r1.23 res_query.c --- src/lib/libc/net/res_query.c 7 Jul 2002 11:28:28 -0000 1.23 +++ src/lib/libc/net/res_query.c 12 Aug 2002 09:48:22 -0000 @@ -87,6 +87,7 @@ #include #include #include +#include #include "res_config.h" @@ -374,11 +375,21 @@ hostalias(name) const char *name; { + static char abuf[MAXDNAME]; + + return (hostalias_r(name, abuf, sizeof abuf)); +} + +const char * +hostalias_r(name, abuf, len) + const char *name; + char *abuf; + int len; +{ char *cp1, *cp2; FILE *fp; char *file; char buf[BUFSIZ]; - static char abuf[MAXDNAME]; if (_res.options & RES_NOALIASES) return (NULL); @@ -402,8 +413,8 @@ break; for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2) ; - abuf[sizeof(abuf) - 1] = *cp2 = '\0'; - strncpy(abuf, cp1, sizeof(abuf) - 1); + abuf[len - 1] = *cp2 = '\0'; + strncpy(abuf, cp1, len - 1); fclose(fp); return (abuf); } Index: src/lib/libc/net/res_send.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/res_send.c,v retrieving revision 1.45 diff -d -u -r1.45 res_send.c --- src/lib/libc/net/res_send.c 1 Apr 2002 16:09:45 -0000 1.45 +++ src/lib/libc/net/res_send.c 12 Aug 2002 09:48:23 -0000 @@ -102,13 +102,6 @@ #include "res_config.h" -static int s = -1; /* socket used for communications */ -static int connected = 0; /* is the socket connected */ -static int vc = 0; /* is the socket a virtual circuit? */ -static int af = 0; /* address family of socket */ -static res_send_qhook Qhook = NULL; -static res_send_rhook Rhook = NULL; - #define CAN_RECONNECT 1 @@ -170,7 +163,7 @@ res_send_qhook hook; { - Qhook = hook; + _res_data.Qhook = hook; } void @@ -178,7 +171,7 @@ res_send_rhook hook; { - Rhook = hook; + _res_data.Rhook = hook; } static struct sockaddr * get_nsaddr(size_t); @@ -406,13 +399,13 @@ goto next_ns; } - if (Qhook) { + if (_res_data.Qhook) { int done = 0, loops = 0; do { res_sendhookact act; - act = (*Qhook)((struct sockaddr_in **)&nsap, + act = (*_res_data.Qhook)((struct sockaddr_in **)&nsap, &buf, &buflen, ans, anssiz, &resplen); switch (act) { @@ -457,14 +450,16 @@ */ try = _res.retry; truncated = 0; - if (s < 0 || !vc || hp->opcode == ns_o_update || - af != nsap->sa_family) { - if (s >= 0) + if (_res_data.s < 0 || !_res_data.vc || + hp->opcode == ns_o_update || + _res_data.af != nsap->sa_family) { + if (_res_data.s >= 0) res_close(); - af = nsap->sa_family; - s = _socket(af, SOCK_STREAM, 0); - if (s < 0) { + _res_data.af = nsap->sa_family; + _res_data.s = _socket(_res_data.af, SOCK_STREAM, + 0); + if (_res_data.s < 0) { terrno = errno; Perror(stderr, "socket(vc)", errno); badns |= (1 << ns); @@ -472,7 +467,7 @@ goto next_ns; } errno = 0; - if (_connect(s, nsap, salen) < 0) { + if (_connect(_res_data.s, nsap, salen) < 0) { terrno = errno; Aerror(stderr, "connect/vc", errno, nsap); @@ -480,7 +475,7 @@ res_close(); goto next_ns; } - vc = 1; + _res_data.vc = 1; } /* * Send length & message @@ -490,7 +485,7 @@ iov[0].iov_len = INT16SZ; iov[1].iov_base = (caddr_t)buf; iov[1].iov_len = buflen; - if (_writev(s, iov, 2) != (INT16SZ + buflen)) { + if (_writev(_res_data.s, iov, 2) != (INT16SZ + buflen)) { terrno = errno; Perror(stderr, "write failed", errno); badns |= (1 << ns); @@ -503,7 +498,7 @@ read_len: cp = ans; len = INT16SZ; - while ((n = _read(s, (char *)cp, (int)len)) > 0) { + while ((n = _read(_res_data.s, (char *)cp, (int)len)) > 0) { cp += n; if ((len -= n) <= 0) break; @@ -551,7 +546,7 @@ } cp = ans; while (len != 0 && - (n = _read(s, (char *)cp, (int)len)) > 0) { + (n = _read(_res_data.s, (char *)cp, (int)len)) > 0) { cp += n; len -= n; } @@ -574,7 +569,7 @@ n = (len > sizeof(junk) ? sizeof(junk) : len); - if ((n = _read(s, junk, n)) > 0) + if ((n = _read(_res_data.s, junk, n)) > 0) len -= n; else break; @@ -604,12 +599,14 @@ struct sockaddr_storage from; int fromlen; - if (s < 0 || vc || af != nsap->sa_family) { - if (vc) + if (_res_data.s < 0 || _res_data.vc || + _res_data.af != nsap->sa_family) { + if (_res_data.vc) res_close(); - af = nsap->sa_family; - s = _socket(af, SOCK_DGRAM, 0); - if (s < 0) { + _res_data.af = nsap->sa_family; + _res_data.s = _socket(_res_data.af, SOCK_DGRAM, + 0); + if (_res_data.s < 0) { #ifndef CAN_RECONNECT bad_dg_sock: #endif @@ -619,7 +616,7 @@ res_close(); goto next_ns; } - connected = 0; + _res_data.connected = 0; } #ifndef CANNOT_CONNECT_DGRAM /* @@ -650,8 +647,9 @@ * Connect only if we are sure we won't * receive a response from another server. */ - if (!connected) { - if (_connect(s, nsap, salen) < 0) { + if (!_res_data.connected) { + if (_connect(_res_data.s, nsap, salen) < + 0) { Aerror(stderr, "connect(dg)", errno, nsap); @@ -659,9 +657,10 @@ res_close(); goto next_ns; } - connected = 1; + _res_data.connected = 1; } - if (send(s, (char*)buf, buflen, 0) != buflen) { + if (send(_res_data.s, (char*)buf, buflen, 0) != + buflen) { Perror(stderr, "send", errno); badns |= (1 << ns); res_close(); @@ -672,7 +671,7 @@ * Disconnect if we want to listen * for responses from more than one server. */ - if (connected) { + if (_res_data.connected) { #ifdef CAN_RECONNECT /* XXX: any errornous address */ struct sockaddr_in no_addr; @@ -680,24 +679,25 @@ no_addr.sin_family = AF_INET; no_addr.sin_addr.s_addr = INADDR_ANY; no_addr.sin_port = 0; - (void) _connect(s, + (void) _connect(_res_data.s, (struct sockaddr *) &no_addr, sizeof no_addr); #else - int s1 = _socket(af, SOCK_DGRAM,0); + int s1 = _socket(_res_data.af, + SOCK_DGRAM,0); if (s1 < 0) goto bad_dg_sock; - (void)_dup2(s1, s); + (void)_dup2(s1, _res_data.s); (void)_close(s1); Dprint(_res.options & RES_DEBUG, (stdout, ";; new DG socket\n")) #endif /* CAN_RECONNECT */ - connected = 0; + _res_data.connected = 0; errno = 0; } #endif /* !CANNOT_CONNECT_DGRAM */ - if (_sendto(s, (char*)buf, buflen, 0, + if (_sendto(_res_data.s, (char*)buf, buflen, 0, nsap, salen) != buflen) { Aerror(stderr, "sendto", errno, nsap); badns |= (1 << ns); @@ -722,13 +722,14 @@ (void) gettimeofday(&ctv, NULL); timeradd(&timeout, &ctv, &timeout); wait: - if (s < 0) { + if (_res_data.s < 0) { Perror(stderr, "s out-of-bounds", EMFILE); res_close(); goto next_ns; } - EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0); + EV_SET(&kv, _res_data.s, EVFILT_READ, + EV_ADD | EV_ONESHOT, 0,0,0); n = _kevent(kq, &kv, 1, &kv, 1, &ts); if (n < 0) { @@ -757,7 +758,7 @@ } errno = 0; fromlen = sizeof(from); - resplen = _recvfrom(s, (char*)ans, anssiz, 0, + resplen = _recvfrom(_res_data.s, (char*)ans, anssiz, 0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { Perror(stderr, "recvfrom", errno); @@ -862,15 +863,15 @@ !(_res.options & RES_STAYOPEN)) { res_close(); } - if (Rhook) { + if (_res_data.Rhook) { int done = 0, loops = 0; do { res_sendhookact act; - act = (*Rhook)((struct sockaddr_in *)nsap, - buf, buflen, - ans, anssiz, &resplen); + act = (*_res_data.Rhook)( + (struct sockaddr_in *)nsap, buf, buflen, + ans, anssiz, &resplen); switch (act) { case res_goahead: case res_done: @@ -920,12 +921,12 @@ void res_close() { - if (s >= 0) { - (void)_close(s); - s = -1; - connected = 0; - vc = 0; - af = 0; + if (_res_data.s >= 0) { + (void)_close(_res_data.s); + _res_data.s = -1; + _res_data.connected = 0; + _res_data.vc = 0; + _res_data.af = 0; } } Index: src/lib/libc_r/sys/Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc_r/sys/Makefile.inc,v retrieving revision 1.10 diff -d -u -r1.10 Makefile.inc --- src/lib/libc_r/sys/Makefile.inc 28 Aug 1999 00:03:13 -0000 1.10 +++ src/lib/libc_r/sys/Makefile.inc 12 Aug 2002 09:48:23 -0000 @@ -2,5 +2,5 @@ .PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH} -SRCS+= uthread_error.c _atomic_lock.S +SRCS+= uthread_error.c uthread_resolv.c _atomic_lock.S Index: src/lib/libc_r/sys/uthread_resolv.c =================================================================== RCS file: src/lib/libc_r/sys/uthread_resolv.c diff -N src/lib/libc_r/sys/uthread_resolv.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/lib/libc_r/sys/uthread_resolv.c 12 Aug 2002 09:48:23 -0000 @@ -0,0 +1,186 @@ +/*- + * Copyright (c) 2001 Alexandr Litvin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pthread_private.h" + +#undef h_errno +#undef _res +#undef _res_ext +#undef _res_data + +extern int h_errno; +extern struct __res_data _res_data; + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static pthread_key_t key; + + +static void +__res_data_destroy(void *p) +{ + struct __res_data *_res_datap = (struct __res_data *)p; + + if(_res_datap->res) + free(_res_datap->res); + if(_res_datap->res_ext) + free(_res_datap->res_ext); + if (_res_datap->host.h_aliases) + free(_res_datap->host.h_aliases); + if (_res_datap->host.h_addr_list) + free(_res_datap->host.h_addr_list); + if (_res_datap->hostbuf) + free(_res_datap->hostbuf); + if (_res_datap->host_addr) + free(_res_datap->host_addr); + if(_res_datap->s >= 0) + close(_res_datap->s); + if(_res_datap->hostf) + fclose(_res_datap->hostf); + free(_res_datap); +} + +static void +__res_data_init() +{ + + pthread_key_create(&key, __res_data_destroy); +} + +struct __res_data * +__res_data_accessor() +{ + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + _res_datap = &_res_data; + } else { + pthread_once(&once, __res_data_init); + _res_datap = (struct __res_data *)pthread_getspecific(key); + if(_res_datap==NULL) { + _res_datap = malloc(sizeof(struct __res_data)); + if(_res_datap==NULL) + return (NULL); + bzero(_res_datap, sizeof(struct __res_data)); + _res_datap->res = malloc(sizeof(struct __res_state)); + if(_res_datap->res == NULL) + goto e1; + bzero(_res_datap->res, sizeof(struct __res_state)); + _res_datap->res_ext = + malloc(sizeof(struct __res_state_ext)); + if(_res_datap->res_ext == NULL) + goto e2; + bzero(_res_datap->res_ext, + sizeof(struct __res_state_ext)); + _res_datap->s = -1; + _res_datap->host.h_name = NULL; + _res_datap->host.h_aliases = + malloc(sizeof(char *[MAXALIASES])); + if (_res_datap->host.h_aliases == NULL) + goto e3; + _res_datap->host.h_addrtype = 0; + _res_datap->host.h_length = 0; + _res_datap->host.h_addr_list = + malloc(sizeof(char *[MAXADDRS + 1])); + if (_res_datap->host.h_addr_list == NULL) + goto e4; + _res_datap->hostbuflen = sizeof(*_res_datap->hostbuf) * + 8 * 1024; + _res_datap->hostbuf = malloc(_res_datap->hostbuflen); + if (_res_datap->hostbuf == NULL) + goto e5; + _res_datap->host_addrlen = + sizeof(*_res_datap->host_addr) * 16; + _res_datap->host_addr = + malloc(_res_datap->host_addrlen); + if (_res_datap->host_addr == NULL) + goto e6; + pthread_setspecific(key, _res_datap); + } + } + return (_res_datap); + +e6: free(_res_datap->hostbuf); +e5: free(_res_datap->host.h_addr_list); +e4: free(_res_datap->host.h_aliases); +e3: free(_res_datap->res_ext); +e2: free(_res_datap->res); +e1: free(_res_datap); + return (NULL); +} + +static struct __res_state dummy_res; +static int dummy_h_errno; + +struct __res_state * +__res_accessor() +{ + struct __res_state *resp; + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + resp = _res_data.res; + } else { + _res_datap = __res_data_accessor(); + if(_res_datap) { + resp = _res_datap->res; + } else { + dummy_res.options = RES_DEFAULT; + resp = &dummy_res; + } + } + return (resp); +} + +int * +__h_errno_accessor() +{ + int *h_errnop; + struct __res_data *_res_datap; + + if (_thread_run == _thread_initial) { + h_errnop = &h_errno; + } else { + _res_datap = __res_data_accessor(); + if(_res_datap) { + h_errnop = &_res_datap->h_errno_res; + } else { + dummy_h_errno = NETDB_INTERNAL; + h_errnop = &dummy_h_errno; + } + } + return (h_errnop); +} --------------051496A982500B2DDF1E4FCD-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 3:53:30 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F221637B400; Mon, 12 Aug 2002 03:53:25 -0700 (PDT) Received: from gull.mail.pas.earthlink.net (gull.mail.pas.earthlink.net [207.217.120.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id 93E4943E72; Mon, 12 Aug 2002 03:53:25 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0085.cvx21-bradley.dialup.earthlink.net ([209.179.192.85] helo=mindspring.com) by gull.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17eCp9-0005Q5-00; Mon, 12 Aug 2002 03:53:24 -0700 Message-ID: <3D5792CD.497C80F0@mindspring.com> Date: Mon, 12 Aug 2002 03:49:49 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Maxim Sobolev Cc: hackers@FreeBSD.org, audit@FreeBSD.org, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <3D578A99.F0821712@FreeBSD.org> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Maxim Sobolev wrote: > Attched please find two patches based on bin/29581 PR to make FreeBSD > resolver thread-safe. They represent two approaches to reach this goal > - the first is to introduce reentrant versions of the standard > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > the second one is to make gethostbyXXX(3) returning data placed into > per-thread storage when linked with libc_r. I like the latter approach > more, since it doesn't introduce new non-standard APIs. > > I would like to hear any comments and suggestions on the proposed > patches, as well as to opinions about which path to chose. 1) Allocate the per thread storage as a single blob, and set the pointers into it, instead of using seperate allocations. This will have the side effect of letting you free it, all at once, and will tend to make it faster on each first use per thread, anyway. You can do this by making a meta structure containing the list of structures to be allocated, and then setting the pointers to the addresses of the structure subelements. 2) Note somewhere in the man page that this makes it so you can not pass the results off to another thread by reference, unless you copy them once there (i.e. you are not allowed persistant references accross threads). It seems to me the most likely use would be to permit a seperate thread (or threads) to be used to resolve concurrently, and/or with other operations. The upshot of this is that holding a reference would mean that you could not initiate another lookup on the lookup worker thread(s) until the reference was freed. You may also want to consider the use of a .init and .fini section for the code, to permit the creation of an initial lookup context chunk; this is kind of a tradeoff, but it will mean that a server will not have to do the recheck each time. The .fini section would aloow auto-cleanup. This may be a necessity for a long running program that uses a shared object to perform the thread creation and lookup (you could leak memory, otherwise). -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 5:23:58 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A2E1937B400; Mon, 12 Aug 2002 05:23:54 -0700 (PDT) Received: from mail.pcnet.com (pcnet1.pcnet.com [204.213.232.3]) by mx1.FreeBSD.org (Postfix) with ESMTP id CFC4243E86; Mon, 12 Aug 2002 05:23:53 -0700 (PDT) (envelope-from eischen@pcnet1.pcnet.com) Received: from localhost (eischen@localhost) by mail.pcnet.com (8.12.3/8.12.1) with ESMTP id g7CCNmo9021178; Mon, 12 Aug 2002 08:23:48 -0400 (EDT) Date: Mon, 12 Aug 2002 08:23:48 -0400 (EDT) From: Daniel Eischen To: Maxim Sobolev Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] In-Reply-To: <3D578A99.F0821712@FreeBSD.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 12 Aug 2002, Maxim Sobolev wrote: > Folks, > > Attched please find two patches based on bin/29581 PR to make FreeBSD > resolver thread-safe. They represent two approaches to reach this goal > - the first is to introduce reentrant versions of the standard > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > the second one is to make gethostbyXXX(3) returning data placed into > per-thread storage when linked with libc_r. I like the latter approach > more, since it doesn't introduce new non-standard APIs. > > I would like to hear any comments and suggestions on the proposed > patches, as well as to opinions about which path to chose. Why do you need uthread_resolv.c? You should be able to thread calls by checking __isthreaded. Just keep everything in libc. If there are missing stubs for some pthread_* routines (I think everything you need is in -current's libc), then add them. -- Dan Eischen To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 5:28: 1 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8F9B937B400; Mon, 12 Aug 2002 05:27:55 -0700 (PDT) Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id E533743E8A; Mon, 12 Aug 2002 05:27:50 -0700 (PDT) (envelope-from sobomax@FreeBSD.org) Received: from relay.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id PAA20856; Mon, 12 Aug 2002 15:27:27 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from vircheck.ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by relay.iptelecom.net.ua (8.12.4/8.12.4) with ESMTP id g7CCRO8Y020796; Mon, 12 Aug 2002 15:27:24 +0300 (EEST) Received: from vega.vega.com (h210.234.dialup.iptcom.net [212.9.234.210]) by vircheck.ipcard.iptcom.net (8.12.3/8.12.3) with ESMTP id g7CCRIoQ021025; Mon, 12 Aug 2002 15:27:21 +0300 (EEST) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.12.5/8.11.3) with ESMTP id g7CCRHF2039805; Mon, 12 Aug 2002 15:27:17 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3D57A9D4.DAA043EF@FreeBSD.org> Date: Mon, 12 Aug 2002 15:28:04 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: Terry Lambert Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <3D578A99.F0821712@FreeBSD.org> <3D5792CD.497C80F0@mindspring.com> Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Terry Lambert wrote: > > Maxim Sobolev wrote: > > Attched please find two patches based on bin/29581 PR to make FreeBSD > > resolver thread-safe. They represent two approaches to reach this goal > > - the first is to introduce reentrant versions of the standard > > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > > the second one is to make gethostbyXXX(3) returning data placed into > > per-thread storage when linked with libc_r. I like the latter approach > > more, since it doesn't introduce new non-standard APIs. > > > > I would like to hear any comments and suggestions on the proposed > > patches, as well as to opinions about which path to chose. > > 1) Allocate the per thread storage as a single blob, and > set the pointers into it, instead of using seperate > allocations. This will have the side effect of letting > you free it, all at once, and will tend to make it > faster on each first use per thread, anyway. You can > do this by making a meta structure containing the list > of structures to be allocated, and then setting the > pointers to the addresses of the structure subelements. Ok, I'll do it. > 2) Note somewhere in the man page that this makes it so > you can not pass the results off to another thread by > reference, unless you copy them once there (i.e. you > are not allowed persistant references accross threads). > It seems to me the most likely use would be to permit > a seperate thread (or threads) to be used to resolve > concurrently, and/or with other operations. The upshot > of this is that holding a reference would mean that you > could not initiate another lookup on the lookup worker > thread(s) until the reference was freed. Yuip, I'll do it as well. > You may also want to consider the use of a .init and .fini > section for the code, to permit the creation of an initial > lookup context chunk; this is kind of a tradeoff, but it will > mean that a server will not have to do the recheck each time. > The .fini section would aloow auto-cleanup. This may be a > necessity for a long running program that uses a shared object > to perform the thread creation and lookup (you could leak > memory, otherwise). Could you please elaborate how exactly memory could be leaked in this case, if the program does correctly shut down all its threads? I also would like to hear from you whether or not you think that we need all those gethostbyXXX_r(3) functions. -Maxim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 5:33:53 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F283E37B400; Mon, 12 Aug 2002 05:33:50 -0700 (PDT) Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id 52BD243E3B; Mon, 12 Aug 2002 05:33:46 -0700 (PDT) (envelope-from sobomax@FreeBSD.org) Received: from relay.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id PAA29342; Mon, 12 Aug 2002 15:33:26 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from vircheck.ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by relay.iptelecom.net.ua (8.12.4/8.12.4) with ESMTP id g7CCXM8Y029267; Mon, 12 Aug 2002 15:33:23 +0300 (EEST) Received: from vega.vega.com (h210.234.dialup.iptcom.net [212.9.234.210]) by vircheck.ipcard.iptcom.net (8.12.3/8.12.3) with ESMTP id g7CCXIoQ023526; Mon, 12 Aug 2002 15:33:19 +0300 (EEST) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.12.5/8.11.3) with ESMTP id g7CCXIF2039813; Mon, 12 Aug 2002 15:33:18 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3D57AB3D.17737AD7@FreeBSD.org> Date: Mon, 12 Aug 2002 15:34:05 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: Daniel Eischen Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Daniel Eischen wrote: > > On Mon, 12 Aug 2002, Maxim Sobolev wrote: > > Folks, > > > > Attched please find two patches based on bin/29581 PR to make FreeBSD > > resolver thread-safe. They represent two approaches to reach this goal > > - the first is to introduce reentrant versions of the standard > > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > > the second one is to make gethostbyXXX(3) returning data placed into > > per-thread storage when linked with libc_r. I like the latter approach > > more, since it doesn't introduce new non-standard APIs. > > > > I would like to hear any comments and suggestions on the proposed > > patches, as well as to opinions about which path to chose. > > Why do you need uthread_resolv.c? You should be able to thread > calls by checking __isthreaded. Just keep everything in libc. > If there are missing stubs for some pthread_* routines (I think > everything you need is in -current's libc), then add them. Why do we have uthread_error.c then? Also it will add penalty to every access to _res_data structure even in non-threaded case. -Maxim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 6:10:29 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 78B1737B406; Mon, 12 Aug 2002 06:10:22 -0700 (PDT) Received: from mail.pcnet.com (pcnet1.pcnet.com [204.213.232.3]) by mx1.FreeBSD.org (Postfix) with ESMTP id EAC7E43E4A; Mon, 12 Aug 2002 06:10:21 -0700 (PDT) (envelope-from eischen@pcnet1.pcnet.com) Received: from localhost (eischen@localhost) by mail.pcnet.com (8.12.3/8.12.1) with ESMTP id g7CDAKhh027052; Mon, 12 Aug 2002 09:10:20 -0400 (EDT) Date: Mon, 12 Aug 2002 09:10:20 -0400 (EDT) From: Daniel Eischen To: Maxim Sobolev Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] In-Reply-To: <3D57AB3D.17737AD7@FreeBSD.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 12 Aug 2002, Maxim Sobolev wrote: > Daniel Eischen wrote: > > > > On Mon, 12 Aug 2002, Maxim Sobolev wrote: > > > Folks, > > > > > > Attched please find two patches based on bin/29581 PR to make FreeBSD > > > resolver thread-safe. They represent two approaches to reach this goal > > > - the first is to introduce reentrant versions of the standard > > > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > > > the second one is to make gethostbyXXX(3) returning data placed into > > > per-thread storage when linked with libc_r. I like the latter approach > > > more, since it doesn't introduce new non-standard APIs. > > > > > > I would like to hear any comments and suggestions on the proposed > > > patches, as well as to opinions about which path to chose. > > > > Why do you need uthread_resolv.c? You should be able to thread > > calls by checking __isthreaded. Just keep everything in libc. > > If there are missing stubs for some pthread_* routines (I think > > everything you need is in -current's libc), then add them. > > Why do we have uthread_error.c then? Also it will add penalty to every > access to _res_data structure even in non-threaded case. Take a look at everything else in libc. What about malloc? It does the same thing and checks __isthreaded. -- Dan Eischen To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 8: 9:32 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0359D37B400; Mon, 12 Aug 2002 08:09:26 -0700 (PDT) Received: from snipe.mail.pas.earthlink.net (snipe.mail.pas.earthlink.net [207.217.120.62]) by mx1.FreeBSD.org (Postfix) with ESMTP id 94B7843E65; Mon, 12 Aug 2002 08:09:25 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0043.cvx22-bradley.dialup.earthlink.net ([209.179.198.43] helo=mindspring.com) by snipe.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17eGou-0000Cs-00; Mon, 12 Aug 2002 08:09:24 -0700 Message-ID: <3D57CF6D.2982CE8@mindspring.com> Date: Mon, 12 Aug 2002 08:08:29 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Maxim Sobolev Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <3D578A99.F0821712@FreeBSD.org> <3D5792CD.497C80F0@mindspring.com> <3D57A9D4.DAA043EF@FreeBSD.org> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Maxim Sobolev wrote: > > You may also want to consider the use of a .init and .fini > > section for the code, to permit the creation of an initial > > lookup context chunk; this is kind of a tradeoff, but it will > > mean that a server will not have to do the recheck each time. > > The .fini section would aloow auto-cleanup. This may be a > > necessity for a long running program that uses a shared object > > to perform the thread creation and lookup (you could leak > > memory, otherwise). > > Could you please elaborate how exactly memory could be leaked in this > case, if the program does correctly shut down all its threads? Create PIC object foo.so. Link PIC object foo.so against libc.so. Call dlopen to load module foo.so into program "bob". Call function in foo.so from program "bob". Function in foo.so creates two threads, one for IPv4 lookup, another for IPv6 lookup to cause lookups to proceed concurrently. Lookup completes. Unload module foo.so. -> leak memory in libc.so image The assumption (which is potentially wrong) is that the program will correctly shut down all its threads, when in fact it was a module not under the programs control that created and used the threads. The leak depends on: 1) A pool of worker threads being created and left around or the purpose of simultaneous resolution 2) The parent shutting down the module without explicitly dealing with the threads (basically, code which would need to live in ".fini" of the foo.so, and could not be automatically triggered on unload of foo.so any other way). I think that parallel IPv6/IPv4 resolution presented as a single serial interface is a high probability implementation with the support for threaded access to the resolver, particularly with the Mozilla code acting the way it does. > I also would like to hear from you whether or not you think that we > need all those gethostbyXXX_r(3) functions. No. I don't think any of the _r functions are needed, so long as the results are not cached by pointer instead of a copy, before passing them from one thread to another. It's a risk on the clobber case of a call with a cached reference outstanding but not processed by another thread which is not an issue with the _r functions, which require that you pass the storage down. Of course, if you pass down per thread storage, you could have the same problem if you didn't copy rather than reference the results before passing to another thread by address. Given that, per thread allocations ("thread local storage") makes more sense than allocate/free fights between threads based on who's responsible for owning the memory after an inter-thread call. 8-). -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 12:22:55 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2774B37B400; Mon, 12 Aug 2002 12:22:51 -0700 (PDT) Received: from canning.wemm.org (canning.wemm.org [192.203.228.65]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6C4CC43E3B; Mon, 12 Aug 2002 12:22:50 -0700 (PDT) (envelope-from peter@wemm.org) Received: from wemm.org (localhost [127.0.0.1]) by canning.wemm.org (Postfix) with ESMTP id 4B81B2A7D6; Mon, 12 Aug 2002 12:22:50 -0700 (PDT) (envelope-from peter@wemm.org) X-Mailer: exmh version 2.5 07/13/2001 with nmh-1.0.4 To: Maxim Sobolev Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] In-Reply-To: <3D57A9D4.DAA043EF@FreeBSD.org> Date: Mon, 12 Aug 2002 12:22:50 -0700 From: Peter Wemm Message-Id: <20020812192250.4B81B2A7D6@canning.wemm.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Maxim Sobolev wrote: > I also would like to hear from you whether or not you think that we > need all those gethostbyXXX_r(3) functions. Yes. Because autoconf looks for them and will assume non-reentrancy if they are not present. Also, for source compatability with linux and solaris and just about everything else that implements this stuff. The expectation is that gethostbyXXX is non-safe and that gethostbyXXX_r is safe. If you can make the non_r versions safe then that is a bonus I guess. Cheers, -Peter -- Peter Wemm - peter@wemm.org; peter@FreeBSD.org; peter@yahoo-inc.com "All of this is for nothing if we don't go to the stars" - JMS/B5 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 15:18: 6 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 451B637B400; Mon, 12 Aug 2002 15:18:03 -0700 (PDT) Received: from mta5.snfc21.pbi.net (mta5.snfc21.pbi.net [206.13.28.241]) by mx1.FreeBSD.org (Postfix) with ESMTP id F023043E6E; Mon, 12 Aug 2002 15:18:02 -0700 (PDT) (envelope-from mbsd@pacbell.net) Received: from atlas ([64.160.45.209]) by mta5.snfc21.pbi.net (iPlanet Messaging Server 5.1 (built May 7 2001)) with ESMTP id <0H0R00JSX4M2LN@mta5.snfc21.pbi.net>; Mon, 12 Aug 2002 15:18:02 -0700 (PDT) Date: Mon, 12 Aug 2002 15:18:02 -0700 (PDT) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= Subject: Re: Thread-safe resolver [patches for review] In-reply-to: <20020812192250.4B81B2A7D6@canning.wemm.org> X-X-Sender: mikko@atlas.home To: Peter Wemm Cc: Maxim Sobolev , hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Message-id: <20020812150652.Q38018-100000@atlas.home> MIME-version: 1.0 Content-type: TEXT/PLAIN; charset=ISO-8859-1 Content-transfer-encoding: 8BIT Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 12 Aug 2002, Peter Wemm wrote: > Maxim Sobolev wrote: > > I also would like to hear from you whether or not you think that we > > need all those gethostbyXXX_r(3) functions. > > Yes. Because autoconf looks for them and will assume non-reentrancy if > they are not present. Also, for source compatability with linux and > solaris and just about everything else that implements this stuff. The > expectation is that gethostbyXXX is non-safe and that gethostbyXXX_r is > safe. If you can make the non_r versions safe then that is a bonus I guess. You are aware that Solaris's version of gethostbyname_r() has a different interface than Linux's (glibc 2.whatever) variant, and that both differ from AIX's gethostbyname_r()... right? Also, some systems (HP-UX 11 and Irix [not sure, though]) have a reentrant gethostbyname(), possibly alongside a _r version marked "obsolete". So, even though I agree that having _r versions might be useful, neither autoconf (which has to be smarter than just looking for a "_r" version), nor source compatibility should be considered the main reasons, IMHO. $.02, /Mikko Mikko Työläjärvi_______________________________________mikko@rsasecurity.com RSA Security To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 16:59:30 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 029A837B400 for ; Mon, 12 Aug 2002 16:59:26 -0700 (PDT) Received: from web20908.mail.yahoo.com (web20908.mail.yahoo.com [216.136.226.230]) by mx1.FreeBSD.org (Postfix) with SMTP id 37E5943E42 for ; Mon, 12 Aug 2002 16:59:25 -0700 (PDT) (envelope-from bsddiy@yahoo.com) Message-ID: <20020812235925.98910.qmail@web20908.mail.yahoo.com> Received: from [210.83.128.34] by web20908.mail.yahoo.com via HTTP; Mon, 12 Aug 2002 16:59:25 PDT Date: Mon, 12 Aug 2002 16:59:25 -0700 (PDT) From: David Xu Subject: Re: Thread-safe resolver [patches for review] To: Terry Lambert , Maxim Sobolev Cc: "hackers@FreeBSD.ORG " , "audit@FreeBSD.ORG" , Alexander Litvin , Andriy Gapon MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > > No. I don't think any of the _r functions are needed, so long > as the results are not cached by pointer instead of a copy, > before passing them from one thread to another. It's a risk on > the clobber case of a call with a cached reference outstanding > but not processed by another thread which is not an issue with > the _r functions, which require that you pass the storage down. > > Of course, if you pass down per thread storage, you could have > the same problem if you didn't copy rather than reference the > results before passing to another thread by address. > > Given that, per thread allocations ("thread local storage") > makes more sense than allocate/free fights between threads > based on who's responsible for owning the memory after an > inter-thread call. 8-). > > -- Terry localtime() etc. are candidate to make them use per thread storage. David Xu __________________________________________________ Do You Yahoo!? HotJobs - Search Thousands of New Jobs http://www.hotjobs.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 17: 3:55 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 32FEF37B400; Mon, 12 Aug 2002 17:03:53 -0700 (PDT) Received: from falcon.mail.pas.earthlink.net (falcon.mail.pas.earthlink.net [207.217.120.74]) by mx1.FreeBSD.org (Postfix) with ESMTP id CA71643E42; Mon, 12 Aug 2002 17:03:52 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0130.cvx21-bradley.dialup.earthlink.net ([209.179.192.130] helo=mindspring.com) by falcon.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17ePA1-0002cc-00; Mon, 12 Aug 2002 17:03:45 -0700 Message-ID: <3D584CAB.1BD6D8E8@mindspring.com> Date: Mon, 12 Aug 2002 17:02:51 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: David Xu Cc: Maxim Sobolev , "hackers@FreeBSD.ORG" , "audit@FreeBSD.ORG" , Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <20020812235925.98910.qmail@web20908.mail.yahoo.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG David Xu wrote: > localtime() etc. are candidate to make them use per thread > storage. Any call that returns a pointer to a statically allocated data area is a candidate, by definition, I think. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Mon Aug 12 17: 5:17 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E033937B400; Mon, 12 Aug 2002 17:05:13 -0700 (PDT) Received: from falcon.mail.pas.earthlink.net (falcon.mail.pas.earthlink.net [207.217.120.74]) by mx1.FreeBSD.org (Postfix) with ESMTP id 63A6343E75; Mon, 12 Aug 2002 17:05:13 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0130.cvx21-bradley.dialup.earthlink.net ([209.179.192.130] helo=mindspring.com) by falcon.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17ePBA-0004E1-00; Mon, 12 Aug 2002 17:04:57 -0700 Message-ID: <3D584CF2.D5306D8B@mindspring.com> Date: Mon, 12 Aug 2002 17:04:02 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Peter Wemm Cc: Maxim Sobolev , hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <20020812192250.4B81B2A7D6@canning.wemm.org> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Peter Wemm wrote: > Maxim Sobolev wrote: > > I also would like to hear from you whether or not you think that we > > need all those gethostbyXXX_r(3) functions. > > Yes. Because autoconf looks for them and will assume non-reentrancy if > they are not present. Also, for source compatability with linux and > solaris and just about everything else that implements this stuff. The > expectation is that gethostbyXXX is non-safe and that gethostbyXXX_r is > safe. If you can make the non_r versions safe then that is a bonus I guess. Autoconf is evil pure and simple, from the 8th dimension. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue Aug 13 1:14:36 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7917437B400; Tue, 13 Aug 2002 01:14:17 -0700 (PDT) Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id 76EC243E65; Tue, 13 Aug 2002 01:14:13 -0700 (PDT) (envelope-from sobomax@FreeBSD.org) Received: from relay.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id LAA47364; Tue, 13 Aug 2002 11:13:51 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from vircheck.ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by relay.iptelecom.net.ua (8.12.4/8.12.4) with ESMTP id g7D8Dl8c047320; Tue, 13 Aug 2002 11:13:48 +0300 (EEST) Received: from vega.vega.com (h81.234.dialup.iptcom.net [212.9.234.81]) by vircheck.ipcard.iptcom.net (8.12.3/8.12.3) with ESMTP id g7D8DgoQ023263; Tue, 13 Aug 2002 11:13:44 +0300 (EEST) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.12.5/8.11.3) with ESMTP id g7D8DfF2042236; Tue, 13 Aug 2002 11:13:41 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3D58BFE8.9281433@FreeBSD.org> Date: Tue, 13 Aug 2002 11:14:32 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: Terry Lambert Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <3D578A99.F0821712@FreeBSD.org> <3D5792CD.497C80F0@mindspring.com> <3D57A9D4.DAA043EF@FreeBSD.org> <3D57CF6D.2982CE8@mindspring.com> Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Terry Lambert wrote: > > Maxim Sobolev wrote: > > > You may also want to consider the use of a .init and .fini > > > section for the code, to permit the creation of an initial > > > lookup context chunk; this is kind of a tradeoff, but it will > > > mean that a server will not have to do the recheck each time. > > > The .fini section would aloow auto-cleanup. This may be a > > > necessity for a long running program that uses a shared object > > > to perform the thread creation and lookup (you could leak > > > memory, otherwise). > > > > Could you please elaborate how exactly memory could be leaked in this > > case, if the program does correctly shut down all its threads? > > Create PIC object foo.so. > Link PIC object foo.so against libc.so. > Call dlopen to load module foo.so into program "bob". > Call function in foo.so from program "bob". > Function in foo.so creates two threads, one for IPv4 lookup, > another for IPv6 lookup to cause lookups to proceed > concurrently. > Lookup completes. > Unload module foo.so. > -> leak memory in libc.so image This scenario doesn't look as a legitimate way to do things for me. Let's inspect what will happen when you are unloading a PIC module, which has one or more threads running. There are two possibilities: either thread scheduler (libc_r) was linked with the program itself and therefore loaded with it, or it was linked with PIC module and loaded along with that module. In the first case, after you have dlclose'd the PIC module, dynamic linker will unmap module's code from memory, but the thread scheduler will remain running and on the next attempt to pass control to the thread in your PIC module will probably get SIGBUS due to the fact that code is no longer mapped. In the second case, you'll unload module along with thread scheduler, but thread-scheduling signals setup will remain in place, so that shortly you will get the same SIGBUS, when the kernel will be trying to delivery signal to no longer mapper region. In either case, you will get the problem much more serious than memory leak. > The assumption (which is potentially wrong) is that the program > will correctly shut down all its threads, when in fact it was a > module not under the programs control that created and used the > threads. I do not quite agree. In such case, the module should probably have destructor function, either placed into the fini section, or to be explicitly called by the program before dlclose(). > The leak depends on: > > 1) A pool of worker threads being created and left around > or the purpose of simultaneous resolution > > 2) The parent shutting down the module without explicitly > dealing with the threads (basically, code which would > need to live in ".fini" of the foo.so, and could not be > automatically triggered on unload of foo.so any other way). > > I think that parallel IPv6/IPv4 resolution presented as a single > serial interface is a high probability implementation with the > support for threaded access to the resolver, particularly with > the Mozilla code acting the way it does. > > > I also would like to hear from you whether or not you think that we > > need all those gethostbyXXX_r(3) functions. > > No. I don't think any of the _r functions are needed, so long > as the results are not cached by pointer instead of a copy, > before passing them from one thread to another. It's a risk on > the clobber case of a call with a cached reference outstanding > but not processed by another thread which is not an issue with > the _r functions, which require that you pass the storage down. > > Of course, if you pass down per thread storage, you could have > the same problem if you didn't copy rather than reference the > results before passing to another thread by address. > > Given that, per thread allocations ("thread local storage") > makes more sense than allocate/free fights between threads > based on who's responsible for owning the memory after an > inter-thread call. 8-). Thank you for the explanation! -Maxim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue Aug 13 1:31:52 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5E0A037B400; Tue, 13 Aug 2002 01:31:40 -0700 (PDT) Received: from avocet.mail.pas.earthlink.net (avocet.mail.pas.earthlink.net [207.217.120.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id EB97643E42; Tue, 13 Aug 2002 01:31:39 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0012.cvx21-bradley.dialup.earthlink.net ([209.179.192.12] helo=mindspring.com) by avocet.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17eX5R-0006a4-00; Tue, 13 Aug 2002 01:31:33 -0700 Message-ID: <3D58C359.A5F7B1AA@mindspring.com> Date: Tue, 13 Aug 2002 01:29:13 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Maxim Sobolev Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: <3D578A99.F0821712@FreeBSD.org> <3D5792CD.497C80F0@mindspring.com> <3D57A9D4.DAA043EF@FreeBSD.org> <3D57CF6D.2982CE8@mindspring.com> <3D58BFE8.9281433@FreeBSD.org> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Maxim Sobolev wrote: > This scenario doesn't look as a legitimate way to do things for me. > Let's inspect what will happen when you are unloading a PIC module, > which has one or more threads running. There are two possibilities: > either thread scheduler (libc_r) was linked with the program itself > and therefore loaded with it, or it was linked with PIC module and > loaded along with that module. In the first case, after you have > dlclose'd the PIC module, dynamic linker will unmap module's code from > memory, but the thread scheduler will remain running and on the next > attempt to pass control to the thread in your PIC module will probably > get SIGBUS due to the fact that code is no longer mapped. In the > second case, you'll unload module along with thread scheduler, but > thread-scheduling signals setup will remain in place, so that shortly > you will get the same SIGBUS, when the kernel will be trying to > delivery signal to no longer mapper region. Unless you have a single exported API from the .so that takes a single request, and does simultaneous lookups. The result will be two inactive threads hanging on a condition variable which will never come true, because the function which makes it true in order to trigger the parallel lookup has been unloaded. Basically, a sleep is a sleep, and it doesn't matter if the code that caused it is there any more or not, if you never get a wakeup. To use an analogy, it doesn't matter if the SIGHUP handler will cause a core dump, if you never get a SIGHUP, does it? > In either case, you will get the problem much more serious than memory > leak. Assuming, incorrectly, that you are talking to the threads directly, rather than to a proxy function. The calling program need not be threaded or support threads. > > The assumption (which is potentially wrong) is that the program > > will correctly shut down all its threads, when in fact it was a > > module not under the programs control that created and used the > > threads. > > I do not quite agree. In such case, the module should probably have > destructor function, either placed into the fini section, or to be > explicitly called by the program before dlclose(). Uh, that's exactly the argument I was making: use a .fini section to clean up the per thread memory allocations. 8-). -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Tue Aug 13 3:14:50 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6969037B400; Tue, 13 Aug 2002 03:14:47 -0700 (PDT) Received: from alcatraz.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1053443E3B; Tue, 13 Aug 2002 03:14:43 -0700 (PDT) (envelope-from sobomax@FreeBSD.org) Received: from relay.iptelecom.net.ua (alcatraz.iptelecom.net.ua [212.9.224.15]) by alcatraz.iptelecom.net.ua (8.9.3/8.9.3) with ESMTP id NAA76900; Tue, 13 Aug 2002 13:14:23 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from vircheck.ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by relay.iptelecom.net.ua (8.12.4/8.12.4) with ESMTP id g7DAEJ8c076830; Tue, 13 Aug 2002 13:14:20 +0300 (EEST) Received: from vega.vega.com (h124.234.dialup.iptcom.net [212.9.234.124]) by vircheck.ipcard.iptcom.net (8.12.3/8.12.3) with ESMTP id g7DADvoQ081252; Tue, 13 Aug 2002 13:14:16 +0300 (EEST) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.12.5/8.11.3) with ESMTP id g7DADuF2042460; Tue, 13 Aug 2002 13:13:56 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3D58DC16.5AB834BF@FreeBSD.org> Date: Tue, 13 Aug 2002 13:14:46 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.79 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: Daniel Eischen Cc: hackers@FreeBSD.ORG, audit@FreeBSD.ORG, Alexander Litvin , Andriy Gapon Subject: Re: Thread-safe resolver [patches for review] References: Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Daniel Eischen wrote: > > On Mon, 12 Aug 2002, Maxim Sobolev wrote: > > Folks, > > > > Attched please find two patches based on bin/29581 PR to make FreeBSD > > resolver thread-safe. They represent two approaches to reach this goal > > - the first is to introduce reentrant versions of the standard > > gethostbyXXX(3) APIs, similar to ones existing in other unices, and > > the second one is to make gethostbyXXX(3) returning data placed into > > per-thread storage when linked with libc_r. I like the latter approach > > more, since it doesn't introduce new non-standard APIs. > > > > I would like to hear any comments and suggestions on the proposed > > patches, as well as to opinions about which path to chose. > > Why do you need uthread_resolv.c? You should be able to thread > calls by checking __isthreaded. Just keep everything in libc. > If there are missing stubs for some pthread_* routines (I think > everything you need is in -current's libc), then add them. I did that, but I can't fugure out correct way to get _thread_run and _thread_initial symbols into libc from libc_r. Any ideas? -Maxim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat Aug 17 2:15: 4 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 047C637B400 for ; Sat, 17 Aug 2002 02:14:59 -0700 (PDT) Received: from mail.tgd.net (mail.tgd.net [209.81.25.10]) by mx1.FreeBSD.org (Postfix) with ESMTP id BBA2743E4A for ; Sat, 17 Aug 2002 02:14:58 -0700 (PDT) (envelope-from sean@mail.tgd.net) Received: by mail.tgd.net (Postfix, from userid 1001) id 40E9420F05; Fri, 16 Aug 2002 11:36:44 -0700 (PDT) Date: Fri, 16 Aug 2002 11:36:44 -0700 From: Sean Chittenden To: audit@FreeBSD.org Subject: [sean@chittenden.org: w/uptime warning inappropriately under xdm/kdm [patch]...] Message-ID: <20020816183644.GL15682@ninja1.internal> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nhYGnrYv1PEJ5gA2" Content-Disposition: inline User-Agent: Mutt/1.4i X-PGP-Key: finger seanc@FreeBSD.org X-PGP-Fingerprint: 6CEB 1B06 BFD3 70F6 95BE 7E4D 8E85 2E0A 5F5B 3ECB X-Web-Homepage: http://sean.chittenden.org/ Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --nhYGnrYv1PEJ5gA2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline [This is a repost from a current@ posting] When logging into a system via xdm/kdm, the wtmp/utmp entries aren't being set correctly. As a result, when you call w(1), you get a nice pair of warnings: $ w w: /dev/:0: No such file or directory w: /dev/:0: No such file or directory 11:33AM up 5 days, 17:02, 0 users, load averages: 0.08, 0.07, 0.08 USER TTY FROM LOGIN@ IDLE WHAT The attached (tiny) patch suppresses the warning and deals with it in the same way that who(1) does. -sc -- Sean Chittenden --nhYGnrYv1PEJ5gA2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I've switched one of my desktops to using kdm and I've noticed that w(1) creates suprious warnings because it can't find the tty entry. $ w w: /dev/:0: No such file or directory w: /dev/:0: No such file or directory 2:41AM up 49 mins, 0 users, load averages: 0.05, 0.04, 0.04 USER TTY FROM LOGIN@ IDLE WHAT $ I've included a patch that quiets this. The attached patch is inline with the behavior from who(1). Are there any objections to it? What should be the correct behaviour when loggin in via xdm/kdm? Is there a better way to detect that you're logged in via xdm/kdm? Should w(1) iterate through utmp/wtmp to get user info? -sc -- Sean Chittenden --nhYGnrYv1PEJ5gA2 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch Index: w.c =================================================================== RCS file: /home/ncvs/src/usr.bin/w/w.c,v retrieving revision 1.54 diff -u -r1.54 w.c --- w.c 2002/06/07 01:41:54 1.54 +++ w.c 2002/08/09 09:57:17 @@ -491,11 +491,10 @@ char ttybuf[MAXPATHLEN]; (void)snprintf(ttybuf, sizeof(ttybuf), "%s%.*s", _PATH_DEV, sz, line); - if (stat(ttybuf, &sb)) { - warn("%s", ttybuf); + if (stat(ttybuf, &sb) == 0) { + return (&sb); + } else return (NULL); - } - return (&sb); } static void --nhYGnrYv1PEJ5gA2-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message