Date: Tue, 10 May 2005 00:55:01 +0900 From: Hajimu UMEMOTO <ume@FreeBSD.ORG> To: David Schultz <das@FreeBSD.ORG> Cc: Hajimu UMEMOTO <ume@FreeBSD.ORG> Subject: Re: [CFR] correct type of addrinfo.ai_addrlen and netent.n_net Message-ID: <ygemzr4jsx6.wl%ume@mahoroba.org> In-Reply-To: <20050503224409.GA16252@VARK.MIT.EDU> References: <ygemzrcgnej.wl%ume@mahoroba.org> <20050503224409.GA16252@VARK.MIT.EDU>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi, >>>>> On Tue, 3 May 2005 18:44:09 -0400 >>>>> David Schultz <das@FreeBSD.ORG> said: das> - You should use socklen_t instead of uint32_t, as appropriate. Are you mean netent.n_net? If so, it is because of POSIX. das> - It's probably better to use the machine/endian.h macros to test das> endianness instead of hard-coding every architecture. Yes. How about this patch? --- include/netdb.h.orig Thu Apr 28 04:12:56 2005 +++ include/netdb.h Mon May 9 15:45:55 2005 @@ -63,6 +63,8 @@ #include <sys/cdefs.h> #include <sys/_types.h> +#include <machine/_limits.h> +#include <machine/endian.h> #ifndef _SIZE_T_DECLARED typedef __size_t size_t; @@ -74,6 +76,11 @@ #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 @@ -99,14 +106,27 @@ }; /* - * Assumption here is that a network number - * fits in an unsigned long -- probably a poor one. + * Note: n_net used to be an unsigned long integer. + * In XNS5, and subsequently in POSIX-2001 it was changed to an + * uint32_t. + * To accomodate for this while preserving binary compatibility with + * the old interface, we prepend or append 32 bits of padding, + * depending on the (LP64) architecture's endianness. + * + * This should be deleted the next time the libc major number is + * incremented. */ 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 __n_pad0; /* ABI compatibility */ +#endif + uint32_t n_net; /* network # */ +#if __LONG_BIT == 64 && _BYTE_ORDER == _LITTLE_ENDIAN + uint32_t __n_pad0; /* ABI compatibility */ +#endif }; struct servent { @@ -122,12 +142,29 @@ int p_proto; /* protocol # */ }; +/* + * Note: ai_addrlen 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. + * To accomodate for this while preserving binary compatibility with the + * old interface, we prepend or append 32 bits of padding, depending on + * the (LP64) architecture's endianness. + * + * This should be deleted the next time the libc major number is + * incremented. + */ struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ 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 */ +#if __LONG_BIT == 64 && _BYTE_ORDER == _BIG_ENDIAN + uint32_t __ai_pad0; /* ABI compatibility */ +#endif + socklen_t ai_addrlen; /* length of ai_addr */ +#if __LONG_BIT == 64 && _BYTE_ORDER == _LITTLE_ENDIAN + uint32_t __ai_pad0; /* ABI compatibility */ +#endif char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ @@ -225,7 +262,7 @@ 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 *getnetbyaddr(uint32_t, int); struct netent *getnetbyname(const char *); struct netent *getnetent(void); int getnetgrent(char **, char **, char **); das> -#if 1 /* obsolete */ das> +#if __BSD_VISIBLE /* obsolete */ das> #define NI_WITHSCOPEID 0x00000020 das> #endif It reminds me one more issue. I wish to nuke NI_WITHSCOPEID before 6.0-RELEASE. NetBSD and OpenBSD did so already. das> +int getaddrinfo(const char * __restrict, const char * __restrict, das> + const struct addrinfo * __restrict, das> + struct addrinfo ** __restrict); das> +int getnameinfo(const struct sockaddr * __restrict, socklen_t, das> + char * __restrict, __size_t, char * __restrict, das> + __size_t, int); The 4th and 6th arguments are buffer length for return value, and they are size_t in spec. So, they should not be mixuped with others. das> -struct hostent *getipnodebyaddr(const void *, size_t, int, int *); das> +struct hostent *getipnodebyaddr(const void *, __size_t, int, int *); It is thorny issue. I think it is a bug, and it should be int. However, getipnodebyaddr() was defined in RFC 2553, then was deprecated in RFC 3493. So, I think it will never be revised. Sincerely, -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ygemzr4jsx6.wl%ume>