From owner-freebsd-arch@FreeBSD.ORG Tue May 3 22:47:26 2005 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B099116A4CE; Tue, 3 May 2005 22:47:26 +0000 (GMT) Received: from VARK.MIT.EDU (VARK.MIT.EDU [18.95.3.179]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0E28E43D5D; Tue, 3 May 2005 22:47:26 +0000 (GMT) (envelope-from das@FreeBSD.ORG) Received: from VARK.MIT.EDU (localhost [127.0.0.1]) by VARK.MIT.EDU (8.13.3/8.13.1) with ESMTP id j43Mi9A3016397; Tue, 3 May 2005 18:44:09 -0400 (EDT) (envelope-from das@FreeBSD.ORG) Received: (from das@localhost) by VARK.MIT.EDU (8.13.3/8.13.1/Submit) id j43Mi99l016396; Tue, 3 May 2005 18:44:09 -0400 (EDT) (envelope-from das@FreeBSD.ORG) Date: Tue, 3 May 2005 18:44:09 -0400 From: David Schultz To: Hajimu UMEMOTO Message-ID: <20050503224409.GA16252@VARK.MIT.EDU> Mail-Followup-To: Hajimu UMEMOTO , arch@FreeBSD.ORG, standards@FreeBSD.ORG References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: cc: arch@FreeBSD.ORG cc: standards@FreeBSD.ORG Subject: Re: [CFR] correct type of addrinfo.ai_addrlen and netent.n_net X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 May 2005 22:47:26 -0000 On Wed, May 04, 2005, Hajimu UMEMOTO wrote: > Hi, > > The ai_addrlen of a struct addrinfo used to be a size_t, per RFC 2553. > In XNS5.2, and subsequently in POSIX-2001 and RFC 3493, it was changed > to a socklen_t. > And, the n_net of a struct netent used to be an unsigned long integer. > In XNS5, and subsequently in POSIX-2001, it was changed to an > uint32_t. > > I made a patch to correct these: > > http://www.imasy.or.jp/~ume/FreeBSD/netdb.h-padding.diff > > To accomodate for this while preserving ABI compatibility with the old > interface, we need to prepend or append 32 bits of padding, depending > on the (LP64) architecture's endianness. I wish to delete these > padding before 6.0-RELEASE. > > Please review it. I have a subset of this (along with some other changes for POSIX) in my tree---see the patch below. My patch only includes the part that can be done without breaking the ABI. (Actually, doesn't your patch *fix* the ABI with respect to FreeBSD 4.X? It just breaks it w.r.t. 5.X, I think.) Assuming that people are willing to accept the ABI breakage (and I'm not sure this is true), the patch looks reasonable. I have two minor comments: - You should use socklen_t instead of uint32_t, as appropriate. - It's probably better to use the machine/endian.h macros to test endianness instead of hard-coding every architecture. Index: netdb.h =================================================================== RCS file: /cvs/src/include/netdb.h,v retrieving revision 1.34 diff -u -r1.34 netdb.h --- netdb.h 14 Feb 2005 11:33:11 -0000 1.34 +++ netdb.h 21 Mar 2005 00:57:54 -0000 @@ -63,17 +63,19 @@ #include #include - -#ifndef _SIZE_T_DECLARED -typedef __size_t size_t; -#define _SIZE_T_DECLARED -#endif +#include +#include #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + #ifndef _PATH_HEQUIV # define _PATH_HEQUIV "/etc/hosts.equiv" #endif @@ -100,13 +102,19 @@ /* * Assumption here is that a network number - * fits in an unsigned long -- probably a poor one. + * fits in 32 bits -- probably a poor one, but required by POSIX. */ struct netent { char *n_name; /* official name of net */ char **n_aliases; /* alias list */ int n_addrtype; /* net address type */ - unsigned long n_net; /* network # */ +#if __LONG_BIT == 64 && _BYTE_ORDER == _BIG_ENDIAN + uint32_t __unused; /* ABI compat */ +#endif + uint32_t n_net; /* network # */ +#if __LONG_BIT == 64 && _BYTE_ORDER == _LITTLE_ENDIAN + uint32_t __unused; /* ABI compat */ +#endif }; struct servent { @@ -127,24 +135,32 @@ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ + /* XXX ai_addrlen should have type socklen_t */ + __size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; +/* Highest reserved port number. Keep in sync with netinet/in.h. */ +#define IPPORT_RESERVED 1024 + /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in h_errno). */ +#if __BSD_VISIBLE #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ +#endif #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ +#if __BSD_VISIBLE #define NO_ADDRESS NO_DATA /* no address, look for MX record */ +#endif /* * Error return codes from getaddrinfo() @@ -166,9 +182,14 @@ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ +#if __BSD_VISIBLE #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 -#define EAI_MAX 14 +#endif +#define EAI_OVERFLOW 14 /* argument buffer overflowed */ +#if __BSD_VISIBLE +#define EAI_MAX 15 +#endif /* * Flag values for getaddrinfo() @@ -177,23 +198,33 @@ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */ #define AI_NUMERICHOST 0x00000004 /* prevent host name resolution */ #define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */ + +#if __BSD_VISIBLE /* valid flags for addrinfo (not a standard def, apps should not use it) */ #define AI_MASK \ (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \ AI_ADDRCONFIG) +#endif #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#if __BSD_VISIBLE #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#endif #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ + +#if __BSD_VISIBLE /* special recommended flags for getipnodebyname */ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) +#endif +#if __BSD_VISIBLE /* * Constants for getnameinfo() */ #define NI_MAXHOST 1025 #define NI_MAXSERV 32 +#endif /* * Flag values for getnameinfo() @@ -203,72 +234,81 @@ #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 -#if 1 /* obsolete */ +#if __BSD_VISIBLE /* obsolete */ #define NI_WITHSCOPEID 0x00000020 #endif +#if __BSD_VISIBLE /* * Scope delimit character */ #define SCOPE_DELIMITER '%' +#endif __BEGIN_DECLS void endhostent(void); void endnetent(void); -void endnetgrent(void); void endprotoent(void); void endservent(void); -void freehostent(struct hostent *); -struct hostent *gethostbyaddr(const char *, int, int); +struct hostent *gethostbyaddr(const void *, int, int); struct hostent *gethostbyname(const char *); -struct hostent *gethostbyname2(const char *, int); struct hostent *gethostent(void); -struct hostent *getipnodebyaddr(const void *, size_t, int, int *); -struct hostent *getipnodebyname(const char *, int, int, int *); struct netent *getnetbyaddr(unsigned long, int); struct netent *getnetbyname(const char *); struct netent *getnetent(void); -int getnetgrent(char **, char **, char **); struct protoent *getprotobyname(const char *); struct protoent *getprotobynumber(int); struct protoent *getprotoent(void); struct servent *getservbyname(const char *, const char *); struct servent *getservbyport(int, const char *); struct servent *getservent(void); -void herror(const char *); -__const char *hstrerror(int); -int innetgr(const char *, const char *, const char *, const char *); + +/* XXX Should replace __size_t with socklen_t below */ void sethostent(int); /* void sethostfile(const char *); */ void setnetent(int); void setprotoent(int); -int getaddrinfo(const char *, const char *, - const struct addrinfo *, struct addrinfo **); -int getnameinfo(const struct sockaddr *, socklen_t, char *, - size_t, char *, size_t, int); +int getaddrinfo(const char * __restrict, const char * __restrict, + const struct addrinfo * __restrict, + struct addrinfo ** __restrict); +int getnameinfo(const struct sockaddr * __restrict, socklen_t, + char * __restrict, __size_t, char * __restrict, + __size_t, int); void freeaddrinfo(struct addrinfo *); const char *gai_strerror(int); -void setnetgrent(const char *); void setservent(int); +#if __BSD_VISIBLE +void endnetgrent(void); +void freehostent(struct hostent *); +struct hostent *gethostbyname2(const char *, int); +struct hostent *getipnodebyaddr(const void *, __size_t, int, int *); +struct hostent *getipnodebyname(const char *, int, int, int *); +int getnetgrent(char **, char **, char **); +void herror(const char *); +__const char *hstrerror(int); +int innetgr(const char *, const char *, const char *, const char *); +void setnetgrent(const char *); +#endif + /* * PRIVATE functions specific to the FreeBSD implementation */ /* DO NOT USE THESE, THEY ARE SUBJECT TO CHANGE AND ARE NOT PORTABLE!!! */ int * __h_error(void); -void _sethosthtent(int); -void _endhosthtent(void); -void _sethostdnsent(int); -void _endhostdnsent(void); -void _setnethtent(int); -void _endnethtent(void); -void _setnetdnsent(int); -void _endnetdnsent(void); -struct hostent * _gethostbynisname(const char *, int); -struct hostent * _gethostbynisaddr(const char *, int, int); -void _map_v4v6_address(const char *, char *); -void _map_v4v6_hostent(struct hostent *, char **, char **); +void __sethosthtent(int); +void __endhosthtent(void); +void __sethostdnsent(int); +void __endhostdnsent(void); +void __setnethtent(int); +void __endnethtent(void); +void __setnetdnsent(int); +void __endnetdnsent(void); +struct hostent * __gethostbynisname(const char *, int); +struct hostent * __gethostbynisaddr(const char *, int, int); +void __map_v4v6_address(const char *, char *); +void __map_v4v6_hostent(struct hostent *, char **, char **); __END_DECLS #endif /* !_NETDB_H_ */