[CFR] correct type of addrinfo.ai_addrlen and netent.n_net
David Schultz
das at FreeBSD.ORG
Tue May 3 15:47:26 PDT 2005
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 <sys/cdefs.h>
#include <sys/_types.h>
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
+#include <machine/_limits.h>
+#include <machine/endian.h>
#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_ */
More information about the freebsd-arch
mailing list