From 6815a33d53164e7f1a3b87cec905c17c7a14a007 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 21 Sep 2016 16:30:27 +0200 Subject: resolv: Remove unsupported hook functions from the API [BZ #20016] --- include/resolv.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/resolv.h') diff --git a/include/resolv.h b/include/resolv.h index 4c614760a8..d7c98dc807 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -33,8 +33,6 @@ extern u_int32_t _getlong (const u_char *__src); extern u_int16_t _getshort (const u_char *__src); extern void res_pquery (const res_state __statp, const u_char *__msg, int __len, FILE *__file); -extern void res_send_setqhook (res_send_qhook __hook); -extern void res_send_setrhook (res_send_rhook __hook); extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); extern void __res_iclose (res_state statp, bool free_addr); -- cgit v1.2.3 From 11160cb76f56e0a711686e34881a4eaf1ad2fa0e Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Sun, 21 Aug 2016 15:38:41 -0400 Subject: Installed-header hygiene (BZ#20366): obsolete BSD u_* types. The types u_char, u_short, u_int, u_long, ushort, uint, ulong, u_int8_t, u_int16_t, u_int32_t, u_int64_t, quad_t, and u_quad_t are BSDisms that have never been standardized. While glibc should continue to *provide* these types for compatibility's sake, its public headers should not use them. The meat of this change was mechanically generated by the following shell command: perl -pi~ -e ' s/\b(__)?u_char\b/unsigned char/g; s/\b(__)?u_?short\b/unsigned short/g; s/\b(__)?u_?int\b/unsigned int/g; s/\b(__)?u_?long\b/unsigned long/g; s/\b(__)?u_int8_t\b/uint8_t/g; s/\b(__)?u_int16_t\b/uint16_t/g; s/\b(__)?u_int32_t\b/uint32_t/g; s/\b(__)?u_int64_t\b/uint64_t/g; s/\b(__)?u_quad_t\b/uint64_t/g; s/\b(__)?quad_t\b/uint64_t/g; ' $(grep -lE -e '\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>' \ $(grep -LE '\<(_(SYS|BITS)_TYPES_H|rpc/(rpc|rpc_msg|types|xdr)\.h)\>' \ $(find . \( -false $(sed 's/^/-o -name /' all-installed-headers) \ \) -printf '%P\n' | sort -u))) where 'all-installed-headers' was a list of the basenames of all installed header files, manually extracted from the Makefiles. Non-installed wrapper headers in include/ are also adjusted, for consistency. I then manually fixed up indentation and line-wrapping. sys/types.h and bits/types.h are excluded because they must continue to define the u_* types (under __USE_MISC) for compatibility with applications. They do not use these types themselves. All headers that (transitively) include rpc/types.h are also excluded, for three reasons. First, the u_* types are defined by rpc/types.h, unconditionally (not just under __USE_MISC) so they are logically part of the SunRPC API. Second, many of those headers appear to be machine-generated. Third, it's my understanding that we are getting rid of as much of SunRPC as possible in the near future. (The one file under sunrpc/ that's touched, sunrpc/rpc/rpc_des.h, does *not* include rpc/types.h. This may itself be a bug.) After changing from u_intNN_t to uintNN_t, a number of headers now need to include stdint.h to pick up those types. It might be more hygenic, namespace-wise, to use __uintNN_t instead, but none of these headers are bound by ISO or POSIX to do so, and it's unlikely that anyone using them will be bothered. (The two files that were using __-prefixed versions of the u_types, sysdeps/mach/hurd/net/route.h and sysdeps/unix/sysv/linux/net/route.h, both already also contained uses of the unprefixed versions.) Some of these files directly included features.h and/or sys/cdefs.h, which I removed, as the style generally seems to be to let sys/types.h do that for us. (This does not change the set of definitions exposed by any header; sys/types.h unconditionally includes both features.h and sys/cdefs.h.) One file included asm/types.h unnecessarily. * bits/in.h, gmon/sys/gmon.h, inet/netinet/igmp.h * inet/protocols/routed.h, inet/protocols/talkd.h * inet/protocols/timed.h, io/fts.h, nptl_db/thread_db.h * resolv/arpa/nameser.h, resolv/resolv.h, sunrpc/rpc/rpc_des.h * sysdeps/generic/netinet/if_ether.h * sysdeps/generic/netinet/in_systm.h * sysdeps/generic/netinet/ip.h, sysdeps/generic/netinet/tcp.h * sysdeps/gnu/netinet/ip_icmp.h, sysdeps/gnu/netinet/tcp.h * sysdeps/gnu/netinet/udp.h, sysdeps/mach/hurd/net/ethernet.h * sysdeps/mach/hurd/net/if_arp.h * sysdeps/mach/hurd/net/if_ppp.h * sysdeps/mach/hurd/net/route.h, sysdeps/mach/sys/reboot.h * sysdeps/unix/sysv/linux/bits/in.h * sysdeps/unix/sysv/linux/net/ethernet.h * sysdeps/unix/sysv/linux/net/if_arp.h * sysdeps/unix/sysv/linux/net/if_ppp.h * sysdeps/unix/sysv/linux/net/if_shaper.h * sysdeps/unix/sysv/linux/net/route.h * sysdeps/unix/sysv/linux/netinet/if_ether.h * sysdeps/unix/sysv/linux/netinet/if_fddi.h * sysdeps/unix/sysv/linux/netinet/if_tr.h * sysdeps/unix/sysv/linux/netipx/ipx.h * sysdeps/unix/sysv/linux/sys/acct.h * include/arpa/nameser.h, include/resolv.h: Change all uses of u_char to unsigned char, u_short and ushort to unsigned short, u_int and uint to unsigned int, u_long and ulong to unsigned long, u_int8_t to uint8_t, u_int16_t to uint16_t, u_int32_t to uint32_t, quad_t to int64_t, and u_int64_t and u_quad_t to uint64_t. * mach/sys/reboot.h: Remove two casts of integer literals to the types they already have. * bits/in.h: Correct error in description of IP_MULTICAST_LOOP. * sysdeps/unix/sysv/linux/bits/in.h: Likewise. * sysdeps/unix/sysv/linux/netinet/if_ether.h: Change a comment from referring to 'unsigned char' to 'uint8_t' for consistency with the macro definition below. * gmon/sys/gmon.h, inet/netinet/igmp.h, inet/protocols/talkd.h * io/fts.h, resolv/arpa/nameser.h, resolv/resolv.h * sunrpc/rpc/rpc_des.h, sysdeps/generic/netinet/ip.h * sysdeps/gnu/netinet/tcp.h, sysdeps/gnu/netinet/udp.h * sysdeps/mach/hurd/net/if_ppp.h, sysdeps/unix/sysv/linux/net/if_ppp.h * sysdeps/unix/sysv/linux/sys/acct.h * include/arpa/nameser.h, include/resolv.h: Fix indentation disrupted by mechanical edits. * inet/protocols/talkd.h, resolv/arpa/nameser.h * sysdeps/generic/netinet/in_systm.h * sysdeps/gnu/netinet/ip_icmp.h, sysdeps/gnu/netinet/tcp.h * sysdeps/gnu/netinet/udp.h * sysdeps/unix/sysv/linux/net/ethernet.h * sysdeps/unix/sysv/linux/net/if_arp.h * sysdeps/unix/sysv/linux/net/if_ppp.h * sysdeps/unix/sysv/linux/net/if_shaper.h * sysdeps/unix/sysv/linux/netinet/if_fddi.h * sysdeps/unix/sysv/linux/netinet/if_tr.h * sysdeps/unix/sysv/linux/netipx/ipx.h * sysdeps/unix/sysv/linux/sys/acct.h Include stdint.h for uintNN_t definitions. Don't include sys/cdefs.h, features.h, or asm/types.h directly. --- ChangeLog | 65 +++++++++++ bits/in.h | 4 +- gmon/sys/gmon.h | 30 +++--- include/arpa/nameser.h | 4 +- include/resolv.h | 24 +++-- inet/netinet/igmp.h | 8 +- inet/protocols/routed.h | 6 +- inet/protocols/talkd.h | 21 ++-- inet/protocols/timed.h | 6 +- io/fts.h | 20 ++-- nptl_db/thread_db.h | 2 +- resolv/arpa/nameser.h | 120 +++++++++++---------- resolv/resolv.h | 117 +++++++++++--------- sunrpc/rpc/rpc_des.h | 8 +- sysdeps/generic/netinet/if_ether.h | 2 +- sysdeps/generic/netinet/in_systm.h | 8 +- sysdeps/generic/netinet/ip.h | 46 ++++---- sysdeps/generic/netinet/tcp.h | 34 +++--- sysdeps/gnu/netinet/ip_icmp.h | 56 +++++----- sysdeps/gnu/netinet/tcp.h | 167 +++++++++++++++-------------- sysdeps/gnu/netinet/udp.h | 19 ++-- sysdeps/mach/hurd/net/ethernet.h | 8 +- sysdeps/mach/hurd/net/if_arp.h | 2 +- sysdeps/mach/hurd/net/if_ppp.h | 4 +- sysdeps/mach/hurd/net/route.h | 12 +-- sysdeps/mach/sys/reboot.h | 6 +- sysdeps/unix/sysv/linux/bits/in.h | 4 +- sysdeps/unix/sysv/linux/net/ethernet.h | 11 +- sysdeps/unix/sysv/linux/net/if_arp.h | 5 +- sysdeps/unix/sysv/linux/net/if_ppp.h | 9 +- sysdeps/unix/sysv/linux/net/if_shaper.h | 6 +- sysdeps/unix/sysv/linux/net/route.h | 12 +-- sysdeps/unix/sysv/linux/netinet/if_ether.h | 16 +-- sysdeps/unix/sysv/linux/netinet/if_fddi.h | 10 +- sysdeps/unix/sysv/linux/netinet/if_tr.h | 36 +++---- sysdeps/unix/sysv/linux/netipx/ipx.h | 9 +- sysdeps/unix/sysv/linux/sys/acct.h | 31 +++--- 37 files changed, 517 insertions(+), 431 deletions(-) (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index f4ea6f17a4..81456f80d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,68 @@ +2016-09-23 Zack Weinberg + + * bits/in.h, gmon/sys/gmon.h, inet/netinet/igmp.h + * inet/protocols/routed.h, inet/protocols/talkd.h + * inet/protocols/timed.h, io/fts.h, nptl_db/thread_db.h + * resolv/arpa/nameser.h, resolv/resolv.h, sunrpc/rpc/rpc_des.h + * sysdeps/generic/netinet/if_ether.h + * sysdeps/generic/netinet/in_systm.h + * sysdeps/generic/netinet/ip.h, sysdeps/generic/netinet/tcp.h + * sysdeps/gnu/netinet/ip_icmp.h, sysdeps/gnu/netinet/tcp.h + * sysdeps/gnu/netinet/udp.h, sysdeps/mach/hurd/net/ethernet.h + * sysdeps/mach/hurd/net/if_arp.h + * sysdeps/mach/hurd/net/if_ppp.h + * sysdeps/mach/hurd/net/route.h, sysdeps/mach/sys/reboot.h + * sysdeps/unix/sysv/linux/bits/in.h + * sysdeps/unix/sysv/linux/net/ethernet.h + * sysdeps/unix/sysv/linux/net/if_arp.h + * sysdeps/unix/sysv/linux/net/if_ppp.h + * sysdeps/unix/sysv/linux/net/if_shaper.h + * sysdeps/unix/sysv/linux/net/route.h + * sysdeps/unix/sysv/linux/netinet/if_ether.h + * sysdeps/unix/sysv/linux/netinet/if_fddi.h + * sysdeps/unix/sysv/linux/netinet/if_tr.h + * sysdeps/unix/sysv/linux/netipx/ipx.h + * sysdeps/unix/sysv/linux/sys/acct.h + * include/arpa/nameser.h, include/resolv.h: + Change all uses of u_char to unsigned char, + u_short and ushort to unsigned short, u_int and uint to unsigned int, + u_long and ulong to unsigned long, u_int8_t to uint8_t, + u_int16_t to uint16_t, u_int32_t to uint32_t, quad_t to int64_t, + and u_int64_t and u_quad_t to uint64_t. + + * mach/sys/reboot.h: Remove two casts of integer literals + to the types they already have. + + * bits/in.h: Correct error in description of IP_MULTICAST_LOOP. + * sysdeps/unix/sysv/linux/bits/in.h: Likewise. + * sysdeps/unix/sysv/linux/netinet/if_ether.h: Change a comment + from referring to 'unsigned char' to 'uint8_t' for consistency with + the macro definition below. + + * gmon/sys/gmon.h, inet/netinet/igmp.h, inet/protocols/talkd.h + * io/fts.h, resolv/arpa/nameser.h, resolv/resolv.h + * sunrpc/rpc/rpc_des.h, sysdeps/generic/netinet/ip.h + * sysdeps/gnu/netinet/tcp.h, sysdeps/gnu/netinet/udp.h + * sysdeps/mach/hurd/net/if_ppp.h, sysdeps/unix/sysv/linux/net/if_ppp.h + * sysdeps/unix/sysv/linux/sys/acct.h + * include/arpa/nameser.h, include/resolv.h: + Fix indentation disrupted by mechanical edits. + + * inet/protocols/talkd.h, resolv/arpa/nameser.h + * sysdeps/generic/netinet/in_systm.h + * sysdeps/gnu/netinet/ip_icmp.h, sysdeps/gnu/netinet/tcp.h + * sysdeps/gnu/netinet/udp.h + * sysdeps/unix/sysv/linux/net/ethernet.h + * sysdeps/unix/sysv/linux/net/if_arp.h + * sysdeps/unix/sysv/linux/net/if_ppp.h + * sysdeps/unix/sysv/linux/net/if_shaper.h + * sysdeps/unix/sysv/linux/netinet/if_fddi.h + * sysdeps/unix/sysv/linux/netinet/if_tr.h + * sysdeps/unix/sysv/linux/netipx/ipx.h + * sysdeps/unix/sysv/linux/sys/acct.h + Include stdint.h for uintNN_t definitions. + Don't include sys/cdefs.h, features.h, or asm/types.h directly. + 2016-09-23 Zack Weinberg * rpcsvc/nislib.h: Include rpcsvc/nis.h. diff --git a/bits/in.h b/bits/in.h index 7dc93c192f..8063a753e6 100644 --- a/bits/in.h +++ b/bits/in.h @@ -39,8 +39,8 @@ #define IP_RECVDSTADDR 7 /* bool; Receive IP dst addr w/datagram. */ #define IP_RETOPTS 8 /* ip_opts; Set/get IP per-packet options. */ #define IP_MULTICAST_IF 9 /* in_addr; set/get IP multicast i/f */ -#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */ -#define IP_MULTICAST_LOOP 11 /* i_char; set/get IP multicast loopback */ +#define IP_MULTICAST_TTL 10 /* unsigned char; set/get IP multicast ttl */ +#define IP_MULTICAST_LOOP 11 /* bool; set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */ #define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */ diff --git a/gmon/sys/gmon.h b/gmon/sys/gmon.h index 5b430abc3e..b4cc3b043a 100644 --- a/gmon/sys/gmon.h +++ b/gmon/sys/gmon.h @@ -117,7 +117,7 @@ extern struct __bb *__bb_head; /* * The type used to represent indices into gmonparam.tos[]. */ -#define ARCINDEX u_long +#define ARCINDEX unsigned long /* * Maximum number of arcs we want to allow. @@ -130,7 +130,7 @@ extern struct __bb *__bb_head; #define MAXARCS (1 << 20) struct tostruct { - u_long selfpc; + unsigned long selfpc; long count; ARCINDEX link; }; @@ -140,9 +140,9 @@ struct tostruct { * the called site and a count. */ struct rawarc { - u_long raw_frompc; - u_long raw_selfpc; - long raw_count; + unsigned long raw_frompc; + unsigned long raw_selfpc; + long raw_count; }; /* @@ -156,17 +156,17 @@ struct rawarc { */ struct gmonparam { long int state; - u_short *kcount; - u_long kcountsize; + unsigned short *kcount; + unsigned long kcountsize; ARCINDEX *froms; - u_long fromssize; + unsigned long fromssize; struct tostruct *tos; - u_long tossize; + unsigned long tossize; long tolimit; - u_long lowpc; - u_long highpc; - u_long textsize; - u_long hashfraction; + unsigned long lowpc; + unsigned long highpc; + unsigned long textsize; + unsigned long hashfraction; long log_hashfraction; }; @@ -190,8 +190,8 @@ struct gmonparam { __BEGIN_DECLS /* Set up data structures and start profiling. */ -extern void __monstartup (u_long __lowpc, u_long __highpc) __THROW; -extern void monstartup (u_long __lowpc, u_long __highpc) __THROW; +extern void __monstartup (unsigned long __lowpc, unsigned long __highpc) __THROW; +extern void monstartup (unsigned long __lowpc, unsigned long __highpc) __THROW; /* Clean up profiling and write out gmon.out. */ extern void _mcleanup (void) __THROW; diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h index 57f7457848..ce6f0238ed 100644 --- a/include/arpa/nameser.h +++ b/include/arpa/nameser.h @@ -47,8 +47,8 @@ extern const struct _ns_flagdata _ns_flagdata[] attribute_hidden; #endif -extern u_int __ns_get16 (const u_char *) __THROW; -extern u_long __ns_get32 (const u_char *) __THROW; +extern unsigned int __ns_get16 (const unsigned char *) __THROW; +extern unsigned long __ns_get32 (const unsigned char *) __THROW; #define ns_msg_getflag(handle, flag) \ (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) diff --git a/include/resolv.h b/include/resolv.h index d7c98dc807..52ac218666 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -29,14 +29,14 @@ extern struct hostent *_gethtent (void); extern struct hostent *_gethtbyname (const char *__name); extern struct hostent *_gethtbyname2 (const char *__name, int __af); struct hostent *_gethtbyaddr (const char *addr, size_t __len, int __af); -extern u_int32_t _getlong (const u_char *__src); -extern u_int16_t _getshort (const u_char *__src); -extern void res_pquery (const res_state __statp, const u_char *__msg, +extern uint32_t _getlong (const unsigned char *__src); +extern uint16_t _getshort (const unsigned char *__src); +extern void res_pquery (const res_state __statp, const unsigned char *__msg, int __len, FILE *__file); extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); extern void __res_iclose (res_state statp, bool free_addr); -extern int __res_nopt(res_state statp, int n0, u_char *buf, int buflen, +extern int __res_nopt(res_state statp, int n0, unsigned char *buf, int buflen, int anslen); libc_hidden_proto (__res_ninit) libc_hidden_proto (__res_maybe_init) @@ -45,12 +45,16 @@ libc_hidden_proto (__res_iclose) libc_hidden_proto (__res_randomid) libc_hidden_proto (__res_state) -int __libc_res_nquery (res_state, const char *, int, int, u_char *, int, - u_char **, u_char **, int *, int *, int *); -int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int, - u_char **, u_char **, int *, int *, int *); -int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int, - u_char *, int, u_char **, u_char **, int *, int *, int *) +int __libc_res_nquery (res_state, const char *, int, int, + unsigned char *, int, unsigned char **, + unsigned char **, int *, int *, int *); +int __libc_res_nsearch (res_state, const char *, int, int, + unsigned char *, int, unsigned char **, + unsigned char **, int *, int *, int *); +int __libc_res_nsend (res_state, const unsigned char *, int, + const unsigned char *, int, unsigned char *, + int, unsigned char **, unsigned char **, + int *, int *, int *) attribute_hidden; libresolv_hidden_proto (_sethtent) diff --git a/inet/netinet/igmp.h b/inet/netinet/igmp.h index fc7599e5e8..ffbebc7caf 100644 --- a/inet/netinet/igmp.h +++ b/inet/netinet/igmp.h @@ -64,10 +64,10 @@ __BEGIN_DECLS */ struct igmp { - u_int8_t igmp_type; /* IGMP type */ - u_int8_t igmp_code; /* routing code */ - u_int16_t igmp_cksum; /* checksum */ - struct in_addr igmp_group; /* group address */ + uint8_t igmp_type; /* IGMP type */ + uint8_t igmp_code; /* routing code */ + uint16_t igmp_cksum; /* checksum */ + struct in_addr igmp_group; /* group address */ }; #define IGMP_MINLEN 8 diff --git a/inet/protocols/routed.h b/inet/protocols/routed.h index befd8654d7..adb1767dca 100644 --- a/inet/protocols/routed.h +++ b/inet/protocols/routed.h @@ -48,9 +48,9 @@ struct netinfo { }; struct rip { - u_char rip_cmd; /* request/response */ - u_char rip_vers; /* protocol version # */ - u_char rip_res1[2]; /* pad to 32-bit boundary */ + unsigned char rip_cmd; /* request/response */ + unsigned char rip_vers; /* protocol version # */ + unsigned char rip_res1[2]; /* pad to 32-bit boundary */ union { struct netinfo ru_nets[1]; /* variable length... */ char ru_tracefile[1]; /* ditto ... */ diff --git a/inet/protocols/talkd.h b/inet/protocols/talkd.h index a8f33b1bab..34e2654cfc 100644 --- a/inet/protocols/talkd.h +++ b/inet/protocols/talkd.h @@ -52,16 +52,17 @@ #include #include +#include /* * Client->server request message format. */ typedef struct { - u_char vers; /* protocol version */ - u_char type; /* request type, see below */ - u_char answer; /* not used */ - u_char pad; - u_int32_t id_num; /* message id */ + unsigned char vers; /* protocol version */ + unsigned char type; /* request type, see below */ + unsigned char answer; /* not used */ + unsigned char pad; + uint32_t id_num; /* message id */ struct osockaddr addr; /* old (4.3) style */ struct osockaddr ctl_addr; /* old (4.3) style */ int32_t pid; /* caller's process id */ @@ -76,11 +77,11 @@ typedef struct { * Server->client response message format. */ typedef struct { - u_char vers; /* protocol version */ - u_char type; /* type of request message, see below */ - u_char answer; /* response to request message, see below */ - u_char pad; - u_int32_t id_num; /* message id */ + unsigned char vers; /* protocol version */ + unsigned char type; /* type of request message, see below */ + unsigned char answer; /* response to request message, see below */ + unsigned char pad; + uint32_t id_num; /* message id */ struct osockaddr addr; /* address for establishing conversation */ } CTL_RESPONSE; diff --git a/inet/protocols/timed.h b/inet/protocols/timed.h index b5d4702ff3..cabdce44a6 100644 --- a/inet/protocols/timed.h +++ b/inet/protocols/timed.h @@ -44,9 +44,9 @@ #define MAXHOSTNAMELEN 64 struct tsp { - u_char tsp_type; - u_char tsp_vers; - u_short tsp_seq; + unsigned char tsp_type; + unsigned char tsp_vers; + unsigned short tsp_seq; union { struct timeval tspu_time; char tspu_hopcnt; diff --git a/io/fts.h b/io/fts.h index 127a0d2721..607e8b12d6 100644 --- a/io/fts.h +++ b/io/fts.h @@ -105,8 +105,8 @@ typedef struct _ftsent { char *fts_path; /* root path */ int fts_errno; /* errno for this node */ int fts_symfd; /* fd for symlink */ - u_short fts_pathlen; /* strlen(fts_path) */ - u_short fts_namelen; /* strlen(fts_name) */ + unsigned short fts_pathlen; /* strlen(fts_path) */ + unsigned short fts_namelen; /* strlen(fts_name) */ ino_t fts_ino; /* inode */ dev_t fts_dev; /* device */ @@ -130,17 +130,17 @@ typedef struct _ftsent { #define FTS_SL 12 /* symbolic link */ #define FTS_SLNONE 13 /* symbolic link without target */ #define FTS_W 14 /* whiteout object */ - u_short fts_info; /* user flags for FTSENT structure */ + unsigned short fts_info; /* user flags for FTSENT structure */ #define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ #define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ - u_short fts_flags; /* private flags for FTSENT structure */ + unsigned short fts_flags; /* private flags for FTSENT structure */ #define FTS_AGAIN 1 /* read node again */ #define FTS_FOLLOW 2 /* follow symbolic link */ #define FTS_NOINSTR 3 /* no instructions */ #define FTS_SKIP 4 /* discard node */ - u_short fts_instr; /* fts_set() instructions */ + unsigned short fts_instr; /* fts_set() instructions */ struct stat *fts_statp; /* stat(2) information */ char fts_name[1]; /* file name */ @@ -157,8 +157,8 @@ typedef struct _ftsent64 { char *fts_path; /* root path */ int fts_errno; /* errno for this node */ int fts_symfd; /* fd for symlink */ - u_short fts_pathlen; /* strlen(fts_path) */ - u_short fts_namelen; /* strlen(fts_name) */ + unsigned short fts_pathlen; /* strlen(fts_path) */ + unsigned short fts_namelen; /* strlen(fts_name) */ ino64_t fts_ino; /* inode */ dev_t fts_dev; /* device */ @@ -166,11 +166,11 @@ typedef struct _ftsent64 { short fts_level; /* depth (-1 to N) */ - u_short fts_info; /* user flags for FTSENT structure */ + unsigned short fts_info; /* user flags for FTSENT structure */ - u_short fts_flags; /* private flags for FTSENT structure */ + unsigned short fts_flags; /* private flags for FTSENT structure */ - u_short fts_instr; /* fts_set() instructions */ + unsigned short fts_instr; /* fts_set() instructions */ struct stat64 *fts_statp; /* stat(2) information */ char fts_name[1]; /* file name */ diff --git a/nptl_db/thread_db.h b/nptl_db/thread_db.h index abb95df3fb..540c318872 100644 --- a/nptl_db/thread_db.h +++ b/nptl_db/thread_db.h @@ -108,7 +108,7 @@ struct link_map; #define TD_EVENTSIZE 2 #define BT_UISHIFT 5 /* log base 2 of BT_NBIPUI, to extract word index */ -#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per uint */ +#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per unsigned int */ #define BT_UIMASK (BT_NBIPUI - 1) /* to extract bit index */ /* Bitmask of enabled events. */ diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h index a866ce8973..80d5cdf951 100644 --- a/resolv/arpa/nameser.h +++ b/resolv/arpa/nameser.h @@ -50,7 +50,7 @@ #include #include -#include +#include /* * Define constants based on RFC 883, RFC 1034, RFC 1035 @@ -63,9 +63,9 @@ #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ -#define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ -#define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ -#define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ +#define NS_INT32SZ 4 /*%< #/bytes of data in a uint32_t */ +#define NS_INT16SZ 2 /*%< #/bytes of data in a uint16_t */ +#define NS_INT8SZ 1 /*%< #/bytes of data in a uint8_t */ #define NS_INADDRSZ 4 /*%< IPv4 T_A */ #define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ #define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ @@ -91,12 +91,12 @@ typedef enum __ns_sect { * leading _'s on the member names. Use the accessor functions, not the _'s. */ typedef struct __ns_msg { - const u_char *_msg, *_eom; - u_int16_t _id, _flags, _counts[ns_s_max]; - const u_char *_sections[ns_s_max]; - ns_sect _sect; - int _rrnum; - const u_char *_msg_ptr; + const unsigned char *_msg, *_eom; + uint16_t _id, _flags, _counts[ns_s_max]; + const unsigned char *_sections[ns_s_max]; + ns_sect _sect; + int _rrnum; + const unsigned char *_msg_ptr; } ns_msg; /* Private data structure - do not use from outside library. */ @@ -115,12 +115,12 @@ extern const struct _ns_flagdata _ns_flagdata[]; * This is a parsed record. It is caller allocated and has no dynamic data. */ typedef struct __ns_rr { - char name[NS_MAXDNAME]; - u_int16_t type; - u_int16_t rr_class; - u_int32_t ttl; - u_int16_t rdlength; - const u_char * rdata; + char name[NS_MAXDNAME]; + uint16_t type; + uint16_t rr_class; + uint32_t ttl; + uint16_t rdlength; + const unsigned char * rdata; } ns_rr; /* Accessor macros - this is part of the public interface. */ @@ -317,34 +317,34 @@ typedef enum __ns_cert_types { * Inline versions of get/put short/long. Pointer is advanced. */ #define NS_GET16(s, cp) do { \ - const u_char *t_cp = (const u_char *)(cp); \ - (s) = ((u_int16_t)t_cp[0] << 8) \ - | ((u_int16_t)t_cp[1]) \ + const unsigned char *t_cp = (const unsigned char *)(cp); \ + (s) = ((uint16_t)t_cp[0] << 8) \ + | ((uint16_t)t_cp[1]) \ ; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_GET32(l, cp) do { \ - const u_char *t_cp = (const u_char *)(cp); \ - (l) = ((u_int32_t)t_cp[0] << 24) \ - | ((u_int32_t)t_cp[1] << 16) \ - | ((u_int32_t)t_cp[2] << 8) \ - | ((u_int32_t)t_cp[3]) \ + const unsigned char *t_cp = (const unsigned char *)(cp); \ + (l) = ((uint32_t)t_cp[0] << 24) \ + | ((uint32_t)t_cp[1] << 16) \ + | ((uint32_t)t_cp[2] << 8) \ + | ((uint32_t)t_cp[3]) \ ; \ (cp) += NS_INT32SZ; \ } while (0) #define NS_PUT16(s, cp) do { \ - u_int16_t t_s = (u_int16_t)(s); \ - u_char *t_cp = (u_char *)(cp); \ + uint16_t t_s = (uint16_t)(s); \ + unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_PUT32(l, cp) do { \ - u_int32_t t_l = (u_int32_t)(l); \ - u_char *t_cp = (u_char *)(cp); \ + uint32_t t_l = (uint32_t)(l); \ + unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ @@ -354,38 +354,46 @@ typedef enum __ns_cert_types { __BEGIN_DECLS int ns_msg_getflag (ns_msg, int) __THROW; -u_int ns_get16 (const u_char *) __THROW; -u_long ns_get32 (const u_char *) __THROW; -void ns_put16 (u_int, u_char *) __THROW; -void ns_put32 (u_long, u_char *) __THROW; -int ns_initparse (const u_char *, int, ns_msg *) __THROW; -int ns_skiprr (const u_char *, const u_char *, ns_sect, int) - __THROW; +unsigned int ns_get16 (const unsigned char *) __THROW; +unsigned long ns_get32 (const unsigned char *) __THROW; +void ns_put16 (unsigned int, unsigned char *) __THROW; +void ns_put32 (unsigned long, unsigned char *) __THROW; +int ns_initparse (const unsigned char *, int, ns_msg *) __THROW; +int ns_skiprr (const unsigned char *, const unsigned char *, + ns_sect, int) __THROW; int ns_parserr (ns_msg *, ns_sect, int, ns_rr *) __THROW; int ns_sprintrr (const ns_msg *, const ns_rr *, const char *, const char *, char *, size_t) __THROW; -int ns_sprintrrf (const u_char *, size_t, const char *, - ns_class, ns_type, u_long, const u_char *, - size_t, const char *, const char *, - char *, size_t) __THROW; -int ns_format_ttl (u_long, char *, size_t) __THROW; -int ns_parse_ttl (const char *, u_long *) __THROW; -u_int32_t ns_datetosecs (const char *, int *) __THROW; -int ns_name_ntol (const u_char *, u_char *, size_t) __THROW; -int ns_name_ntop (const u_char *, char *, size_t) __THROW; -int ns_name_pton (const char *, u_char *, size_t) __THROW; -int ns_name_unpack (const u_char *, const u_char *, - const u_char *, u_char *, size_t) __THROW; -int ns_name_pack (const u_char *, u_char *, int, - const u_char **, const u_char **) __THROW; -int ns_name_uncompress (const u_char *, const u_char *, - const u_char *, char *, size_t) __THROW; -int ns_name_compress (const char *, u_char *, size_t, - const u_char **, const u_char **) __THROW; -int ns_name_skip (const u_char **, const u_char *) __THROW; -void ns_name_rollback (const u_char *, const u_char **, - const u_char **) __THROW; +int ns_sprintrrf (const unsigned char *, size_t, const char *, + ns_class, ns_type, unsigned long, + const unsigned char *, size_t, const char *, + const char *, char *, size_t) __THROW; +int ns_format_ttl (unsigned long, char *, size_t) __THROW; +int ns_parse_ttl (const char *, unsigned long *) __THROW; +uint32_t ns_datetosecs (const char *, int *) __THROW; +int ns_name_ntol (const unsigned char *, unsigned char *, size_t) + __THROW; +int ns_name_ntop (const unsigned char *, char *, size_t) __THROW; +int ns_name_pton (const char *, unsigned char *, size_t) __THROW; +int ns_name_unpack (const unsigned char *, const unsigned char *, + const unsigned char *, unsigned char *, size_t) + __THROW; +int ns_name_pack (const unsigned char *, unsigned char *, int, + const unsigned char **, const unsigned char **) + __THROW; +int ns_name_uncompress (const unsigned char *, + const unsigned char *, + const unsigned char *, + char *, size_t) __THROW; +int ns_name_compress (const char *, unsigned char *, size_t, + const unsigned char **, + const unsigned char **) __THROW; +int ns_name_skip (const unsigned char **, const unsigned char *) + __THROW; +void ns_name_rollback (const unsigned char *, + const unsigned char **, + const unsigned char **) __THROW; int ns_samedomain (const char *, const char *) __THROW; int ns_subdomain (const char *, const char *) __THROW; int ns_makecanon (const char *, char *, size_t) __THROW; diff --git a/resolv/resolv.h b/resolv/resolv.h index a6f4dadf12..58c3c38743 100644 --- a/resolv/resolv.h +++ b/resolv/resolv.h @@ -87,39 +87,39 @@ struct __res_state { int retrans; /* retransmition time interval */ int retry; /* number of times to retransmit */ - u_long options; /* option flags - see below. */ + unsigned long options; /* option flags - see below. */ int nscount; /* number of name servers */ struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */ # define nsaddr nsaddr_list[0] /* for backward compatibility */ - u_short id; /* current message id */ + unsigned short id; /* current message id */ /* 2 byte hole here. */ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ char defdname[256]; /* default domain (deprecated) */ - u_long pfcode; /* RES_PRF_ flags - see below. */ + unsigned long pfcode; /* RES_PRF_ flags - see below. */ unsigned ndots:4; /* threshold for initial abs. query */ unsigned nsort:4; /* number of elements in sort_list[] */ unsigned ipv6_unavail:1; /* connecting to IPv6 server failed */ unsigned unused:23; struct { struct in_addr addr; - u_int32_t mask; + uint32_t mask; } sort_list[MAXRESOLVSORT]; /* 4 byte hole here on 64-bit architectures. */ void * __glibc_unused_qhook; void * __glibc_unused_rhook; int res_h_errno; /* last one set for this context */ int _vcsock; /* PRIVATE: for res_send VC i/o */ - u_int _flags; /* PRIVATE: see below */ + unsigned int _flags; /* PRIVATE: see below */ /* 4 byte hole here on 64-bit architectures. */ union { char pad[52]; /* On an i386 this means 512b total. */ struct { - u_int16_t nscount; - u_int16_t nsmap[MAXNS]; + uint16_t nscount; + uint16_t nsmap[MAXNS]; int nssocks[MAXNS]; - u_int16_t nscount6; - u_int16_t nsinit; + uint16_t nscount6; + uint16_t nsinit; struct sockaddr_in6 *nsaddrs[MAXNS]; #ifdef _LIBC unsigned long long int initstamp @@ -247,20 +247,24 @@ __END_DECLS #define res_send __res_send __BEGIN_DECLS -void fp_nquery (const u_char *, int, FILE *) __THROW; -void fp_query (const u_char *, FILE *) __THROW; +void fp_nquery (const unsigned char *, int, FILE *) __THROW; +void fp_query (const unsigned char *, FILE *) __THROW; const char * hostalias (const char *) __THROW; -void p_query (const u_char *) __THROW; +void p_query (const unsigned char *) __THROW; void res_close (void) __THROW; int res_init (void) __THROW; int res_isourserver (const struct sockaddr_in *) __THROW; -int res_mkquery (int, const char *, int, int, const u_char *, - int, const u_char *, u_char *, int) __THROW; -int res_query (const char *, int, int, u_char *, int) __THROW; +int res_mkquery (int, const char *, int, int, + const unsigned char *, int, const unsigned char *, + unsigned char *, int) __THROW; +int res_query (const char *, int, int, unsigned char *, int) + __THROW; int res_querydomain (const char *, const char *, int, int, - u_char *, int) __THROW; -int res_search (const char *, int, int, u_char *, int) __THROW; -int res_send (const u_char *, int, u_char *, int) __THROW; + unsigned char *, int) __THROW; +int res_search (const char *, int, int, unsigned char *, int) + __THROW; +int res_send (const unsigned char *, int, unsigned char *, int) + __THROW; __END_DECLS #define b64_ntop __b64_ntop @@ -313,56 +317,65 @@ int res_dnok (const char *) __THROW; int sym_ston (const struct res_sym *, const char *, int *) __THROW; const char * sym_ntos (const struct res_sym *, int, int *) __THROW; const char * sym_ntop (const struct res_sym *, int, int *) __THROW; -int b64_ntop (u_char const *, size_t, char *, size_t) __THROW; -int b64_pton (char const *, u_char *, size_t) __THROW; -int loc_aton (const char *__ascii, u_char *__binary) __THROW; -const char * loc_ntoa (const u_char *__binary, char *__ascii) __THROW; -int dn_skipname (const u_char *, const u_char *) __THROW; -void putlong (u_int32_t, u_char *) __THROW; -void putshort (u_int16_t, u_char *) __THROW; +int b64_ntop (const unsigned char *, size_t, char *, size_t) + __THROW; +int b64_pton (char const *, unsigned char *, size_t) __THROW; +int loc_aton (const char *__ascii, unsigned char *__binary) __THROW; +const char * loc_ntoa (const unsigned char *__binary, char *__ascii) __THROW; +int dn_skipname (const unsigned char *, const unsigned char *) + __THROW; +void putlong (uint32_t, unsigned char *) __THROW; +void putshort (uint16_t, unsigned char *) __THROW; const char * p_class (int) __THROW; -const char * p_time (u_int32_t) __THROW; +const char * p_time (uint32_t) __THROW; const char * p_type (int) __THROW; const char * p_rcode (int) __THROW; -const u_char * p_cdnname (const u_char *, const u_char *, int, FILE *) - __THROW; -const u_char * p_cdname (const u_char *, const u_char *, FILE *) __THROW; -const u_char * p_fqnname (const u_char *__cp, const u_char *__msg, - int, char *, int) __THROW; -const u_char * p_fqname (const u_char *, const u_char *, FILE *) __THROW; -const char * p_option (u_long __option) __THROW; -char * p_secstodate (u_long) __THROW; +const unsigned char * p_cdnname (const unsigned char *, + const unsigned char *, int, FILE *) __THROW; +const unsigned char * p_cdname (const unsigned char *, const unsigned char *, + FILE *) __THROW; +const unsigned char * p_fqnname (const unsigned char *__cp, + const unsigned char *__msg, + int, char *, int) __THROW; +const unsigned char * p_fqname (const unsigned char *, + const unsigned char *, FILE *) __THROW; +const char * p_option (unsigned long __option) __THROW; +char * p_secstodate (unsigned long) __THROW; int dn_count_labels (const char *) __THROW; -int dn_comp (const char *, u_char *, int, u_char **, u_char **) - __THROW; -int dn_expand (const u_char *, const u_char *, const u_char *, - char *, int) __THROW; -u_int res_randomid (void) __THROW; +int dn_comp (const char *, unsigned char *, int, unsigned char **, + unsigned char **) __THROW; +int dn_expand (const unsigned char *, const unsigned char *, + const unsigned char *, char *, int) __THROW; +unsigned int res_randomid (void) __THROW; int res_nameinquery (const char *, int, int, - const u_char *, const u_char *) __THROW; -int res_queriesmatch (const u_char *, const u_char *, - const u_char *, const u_char *) __THROW; + const unsigned char *, + const unsigned char *) __THROW; +int res_queriesmatch (const unsigned char *, + const unsigned char *, + const unsigned char *, + const unsigned char *) __THROW; const char * p_section (int __section, int __opcode) __THROW; /* Things involving a resolver context. */ int res_ninit (res_state) __THROW; int res_nisourserver (const res_state, const struct sockaddr_in *) __THROW; void fp_resstat (const res_state, FILE *) __THROW; -void res_npquery (const res_state, const u_char *, int, FILE *) - __THROW; +void res_npquery (const res_state, const unsigned char *, int, + FILE *) __THROW; const char * res_hostalias (const res_state, const char *, char *, size_t) __THROW; -int res_nquery (res_state, const char *, int, int, u_char *, int) - __THROW; -int res_nsearch (res_state, const char *, int, int, u_char *, int) - __THROW; +int res_nquery (res_state, const char *, int, int, + unsigned char *, int) __THROW; +int res_nsearch (res_state, const char *, int, int, + unsigned char *, int) __THROW; int res_nquerydomain (res_state, const char *, const char *, int, - int, u_char *, int) __THROW; + int, unsigned char *, int) __THROW; int res_nmkquery (res_state, int, const char *, int, int, - const u_char *, int, const u_char *, u_char *, - int) __THROW; -int res_nsend (res_state, const u_char *, int, u_char *, int) + const unsigned char *, int, + const unsigned char *, unsigned char *, int) __THROW; +int res_nsend (res_state, const unsigned char *, int, + unsigned char *, int) __THROW; void res_nclose (res_state) __THROW; __END_DECLS #endif diff --git a/sunrpc/rpc/rpc_des.h b/sunrpc/rpc/rpc_des.h index 4b3c426c62..2091f52414 100644 --- a/sunrpc/rpc/rpc_des.h +++ b/sunrpc/rpc/rpc_des.h @@ -53,15 +53,15 @@ enum desmode */ struct desparams { - u_char des_key[8]; /* key (with low bit parity) */ + unsigned char des_key[8]; /* key (with low bit parity) */ enum desdir des_dir; /* direction */ enum desmode des_mode; /* mode */ - u_char des_ivec[8]; /* input vector */ + unsigned char des_ivec[8]; /* input vector */ unsigned des_len; /* number of bytes to crypt */ union { - u_char UDES_data[DES_QUICKLEN]; - u_char *UDES_buf; + unsigned char UDES_data[DES_QUICKLEN]; + unsigned char *UDES_buf; } UDES; #define des_data UDES.UDES_data /* direct data here if quick */ diff --git a/sysdeps/generic/netinet/if_ether.h b/sysdeps/generic/netinet/if_ether.h index c106a41c82..6d02536bd4 100644 --- a/sysdeps/generic/netinet/if_ether.h +++ b/sysdeps/generic/netinet/if_ether.h @@ -26,7 +26,7 @@ systems. */ struct ether_addr { - u_int8_t ether_addr_octet[ETH_ALEN]; + uint8_t ether_addr_octet[ETH_ALEN]; } __attribute__ ((__packed__)); #endif /* netinet/if_ether.h */ diff --git a/sysdeps/generic/netinet/in_systm.h b/sysdeps/generic/netinet/in_systm.h index 41704ee40a..7b9a92be41 100644 --- a/sysdeps/generic/netinet/in_systm.h +++ b/sysdeps/generic/netinet/in_systm.h @@ -19,8 +19,8 @@ #ifndef _NETINET_IN_SYSTM_H #define _NETINET_IN_SYSTM_H 1 -#include #include +#include __BEGIN_DECLS @@ -31,9 +31,9 @@ __BEGIN_DECLS * may not reflect the actual size of the native data types. */ -typedef u_int16_t n_short; /* short as received from the net */ -typedef u_int32_t n_long; /* long as received from the net */ -typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */ +typedef uint16_t n_short; /* short as received from the net */ +typedef uint32_t n_long; /* long as received from the net */ +typedef uint32_t n_time; /* ms since 00:00 GMT, byte rev */ __END_DECLS diff --git a/sysdeps/generic/netinet/ip.h b/sysdeps/generic/netinet/ip.h index 557a460d71..5f16c9a2bd 100644 --- a/sysdeps/generic/netinet/ip.h +++ b/sysdeps/generic/netinet/ip.h @@ -27,8 +27,8 @@ __BEGIN_DECLS struct timestamp { - u_int8_t len; - u_int8_t ptr; + uint8_t len; + uint8_t ptr; #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int flags:4; unsigned int overflow:4; @@ -38,7 +38,7 @@ struct timestamp #else # error "Please fix " #endif - u_int32_t data[9]; + uint32_t data[9]; }; struct iphdr @@ -52,15 +52,15 @@ struct iphdr #else # error "Please fix " #endif - u_int8_t tos; - u_int16_t tot_len; - u_int16_t id; - u_int16_t frag_off; - u_int8_t ttl; - u_int8_t protocol; - u_int16_t check; - u_int32_t saddr; - u_int32_t daddr; + uint8_t tos; + uint16_t tot_len; + uint16_t id; + uint16_t frag_off; + uint8_t ttl; + uint8_t protocol; + uint16_t check; + uint32_t saddr; + uint32_t daddr; /*The options start here. */ }; @@ -114,17 +114,17 @@ struct ip unsigned int ip_v:4; /* version */ unsigned int ip_hl:4; /* header length */ #endif - u_int8_t ip_tos; /* type of service */ - u_short ip_len; /* total length */ - u_short ip_id; /* identification */ - u_short ip_off; /* fragment offset field */ + uint8_t ip_tos; /* type of service */ + unsigned short ip_len; /* total length */ + unsigned short ip_id; /* identification */ + unsigned short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_int8_t ip_ttl; /* time to live */ - u_int8_t ip_p; /* protocol */ - u_short ip_sum; /* checksum */ + uint8_t ip_ttl; /* time to live */ + uint8_t ip_p; /* protocol */ + unsigned short ip_sum; /* checksum */ struct in_addr ip_src, ip_dst; /* source and dest address */ }; @@ -133,9 +133,9 @@ struct ip */ struct ip_timestamp { - u_int8_t ipt_code; /* IPOPT_TS */ - u_int8_t ipt_len; /* size of structure (variable) */ - u_int8_t ipt_ptr; /* index of current entry */ + uint8_t ipt_code; /* IPOPT_TS */ + uint8_t ipt_len; /* size of structure (variable) */ + uint8_t ipt_ptr; /* index of current entry */ #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ipt_flg:4; /* flags, see below */ unsigned int ipt_oflw:4; /* overflow counter */ @@ -144,7 +144,7 @@ struct ip_timestamp unsigned int ipt_oflw:4; /* overflow counter */ unsigned int ipt_flg:4; /* flags, see below */ #endif - u_int32_t data[9]; + uint32_t data[9]; }; #endif /* __USE_MISC */ diff --git a/sysdeps/generic/netinet/tcp.h b/sysdeps/generic/netinet/tcp.h index 0d71903309..49f1bfbc26 100644 --- a/sysdeps/generic/netinet/tcp.h +++ b/sysdeps/generic/netinet/tcp.h @@ -43,42 +43,42 @@ typedef unsigned int tcp_seq; * Per RFC 793, September, 1981. */ struct tcphdr { - u_short th_sport; /* source port */ - u_short th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ + unsigned short th_sport; /* source port */ + unsigned short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ #if __BYTE_ORDER == __LITTLE_ENDIAN - u_char th_x2:4, /* (unused) */ - th_off:4; /* data offset */ + unsigned char th_x2:4, /* (unused) */ + th_off:4; /* data offset */ #endif #if __BYTE_ORDER == __BIG_ENDIAN - u_char th_off:4, /* data offset */ - th_x2:4; /* (unused) */ + unsigned char th_off:4, /* data offset */ + th_x2:4; /* (unused) */ #endif - u_char th_flags; + unsigned char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 - u_short th_win; /* window */ - u_short th_sum; /* checksum */ - u_short th_urp; /* urgent pointer */ + unsigned short th_win; /* window */ + unsigned short th_sum; /* checksum */ + unsigned short th_urp; /* urgent pointer */ }; #define TCPOPT_EOL 0 #define TCPOPT_NOP 1 #define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 +#define TCPOLEN_MAXSEG 4 #define TCPOPT_WINDOW 3 -#define TCPOLEN_WINDOW 3 +#define TCPOLEN_WINDOW 3 #define TCPOPT_SACK_PERMITTED 4 /* Experimental */ -#define TCPOLEN_SACK_PERMITTED 2 +#define TCPOLEN_SACK_PERMITTED 2 #define TCPOPT_SACK 5 /* Experimental */ #define TCPOPT_TIMESTAMP 8 -#define TCPOLEN_TIMESTAMP 10 -#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) diff --git a/sysdeps/gnu/netinet/ip_icmp.h b/sysdeps/gnu/netinet/ip_icmp.h index 4f7c1b1b60..542e789e2a 100644 --- a/sysdeps/gnu/netinet/ip_icmp.h +++ b/sysdeps/gnu/netinet/ip_icmp.h @@ -18,28 +18,28 @@ #ifndef __NETINET_IP_ICMP_H #define __NETINET_IP_ICMP_H 1 -#include #include +#include __BEGIN_DECLS struct icmphdr { - u_int8_t type; /* message type */ - u_int8_t code; /* type sub-code */ - u_int16_t checksum; + uint8_t type; /* message type */ + uint8_t code; /* type sub-code */ + uint16_t checksum; union { struct { - u_int16_t id; - u_int16_t sequence; + uint16_t id; + uint16_t sequence; } echo; /* echo datagram */ - u_int32_t gateway; /* gateway address */ + uint32_t gateway; /* gateway address */ struct { - u_int16_t __glibc_reserved; - u_int16_t mtu; + uint16_t __glibc_reserved; + uint16_t mtu; } frag; /* path mtu discovery */ } un; }; @@ -130,38 +130,38 @@ struct icmphdr */ struct icmp_ra_addr { - u_int32_t ira_addr; - u_int32_t ira_preference; + uint32_t ira_addr; + uint32_t ira_preference; }; struct icmp { - u_int8_t icmp_type; /* type of message, see below */ - u_int8_t icmp_code; /* type sub code */ - u_int16_t icmp_cksum; /* ones complement checksum of struct */ + uint8_t icmp_type; /* type of message, see below */ + uint8_t icmp_code; /* type sub code */ + uint16_t icmp_cksum; /* ones complement checksum of struct */ union { - u_char ih_pptr; /* ICMP_PARAMPROB */ + unsigned char ih_pptr; /* ICMP_PARAMPROB */ struct in_addr ih_gwaddr; /* gateway address */ struct ih_idseq /* echo datagram */ { - u_int16_t icd_id; - u_int16_t icd_seq; + uint16_t icd_id; + uint16_t icd_seq; } ih_idseq; - u_int32_t ih_void; + uint32_t ih_void; /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { - u_int16_t ipm_void; - u_int16_t ipm_nextmtu; + uint16_t ipm_void; + uint16_t ipm_nextmtu; } ih_pmtu; struct ih_rtradv { - u_int8_t irt_num_addrs; - u_int8_t irt_wpa; - u_int16_t irt_lifetime; + uint8_t irt_num_addrs; + uint8_t irt_wpa; + uint16_t irt_lifetime; } ih_rtradv; } icmp_hun; #define icmp_pptr icmp_hun.ih_pptr @@ -178,9 +178,9 @@ struct icmp { struct { - u_int32_t its_otime; - u_int32_t its_rtime; - u_int32_t its_ttime; + uint32_t its_otime; + uint32_t its_rtime; + uint32_t its_ttime; } id_ts; struct { @@ -188,8 +188,8 @@ struct icmp /* options and then 64 bits of data */ } id_ip; struct icmp_ra_addr id_radv; - u_int32_t id_mask; - u_int8_t id_data[1]; + uint32_t id_mask; + uint8_t id_data[1]; } icmp_dun; #define icmp_otime icmp_dun.id_ts.its_otime #define icmp_rtime icmp_dun.id_ts.its_rtime diff --git a/sysdeps/gnu/netinet/tcp.h b/sysdeps/gnu/netinet/tcp.h index 3918bcac4f..3fbea54daf 100644 --- a/sysdeps/gnu/netinet/tcp.h +++ b/sysdeps/gnu/netinet/tcp.h @@ -73,8 +73,9 @@ #ifdef __USE_MISC # include # include +# include -typedef u_int32_t tcp_seq; +typedef uint32_t tcp_seq; /* * TCP header. * Per RFC 793, September, 1981. @@ -85,61 +86,61 @@ struct tcphdr { struct { - u_int16_t th_sport; /* source port */ - u_int16_t th_dport; /* destination port */ + uint16_t th_sport; /* source port */ + uint16_t th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ # if __BYTE_ORDER == __LITTLE_ENDIAN - u_int8_t th_x2:4; /* (unused) */ - u_int8_t th_off:4; /* data offset */ + uint8_t th_x2:4; /* (unused) */ + uint8_t th_off:4; /* data offset */ # endif # if __BYTE_ORDER == __BIG_ENDIAN - u_int8_t th_off:4; /* data offset */ - u_int8_t th_x2:4; /* (unused) */ + uint8_t th_off:4; /* data offset */ + uint8_t th_x2:4; /* (unused) */ # endif - u_int8_t th_flags; + uint8_t th_flags; # define TH_FIN 0x01 # define TH_SYN 0x02 # define TH_RST 0x04 # define TH_PUSH 0x08 # define TH_ACK 0x10 # define TH_URG 0x20 - u_int16_t th_win; /* window */ - u_int16_t th_sum; /* checksum */ - u_int16_t th_urp; /* urgent pointer */ + uint16_t th_win; /* window */ + uint16_t th_sum; /* checksum */ + uint16_t th_urp; /* urgent pointer */ }; struct { - u_int16_t source; - u_int16_t dest; - u_int32_t seq; - u_int32_t ack_seq; + uint16_t source; + uint16_t dest; + uint32_t seq; + uint32_t ack_seq; # if __BYTE_ORDER == __LITTLE_ENDIAN - u_int16_t res1:4; - u_int16_t doff:4; - u_int16_t fin:1; - u_int16_t syn:1; - u_int16_t rst:1; - u_int16_t psh:1; - u_int16_t ack:1; - u_int16_t urg:1; - u_int16_t res2:2; + uint16_t res1:4; + uint16_t doff:4; + uint16_t fin:1; + uint16_t syn:1; + uint16_t rst:1; + uint16_t psh:1; + uint16_t ack:1; + uint16_t urg:1; + uint16_t res2:2; # elif __BYTE_ORDER == __BIG_ENDIAN - u_int16_t doff:4; - u_int16_t res1:4; - u_int16_t res2:2; - u_int16_t urg:1; - u_int16_t ack:1; - u_int16_t psh:1; - u_int16_t rst:1; - u_int16_t syn:1; - u_int16_t fin:1; + uint16_t doff:4; + uint16_t res1:4; + uint16_t res2:2; + uint16_t urg:1; + uint16_t ack:1; + uint16_t psh:1; + uint16_t rst:1; + uint16_t syn:1; + uint16_t fin:1; # else # error "Adjust your defines" # endif - u_int16_t window; - u_int16_t check; - u_int16_t urg_ptr; + uint16_t window; + uint16_t check; + uint16_t urg_ptr; }; }; }; @@ -209,45 +210,45 @@ enum tcp_ca_state struct tcp_info { - u_int8_t tcpi_state; - u_int8_t tcpi_ca_state; - u_int8_t tcpi_retransmits; - u_int8_t tcpi_probes; - u_int8_t tcpi_backoff; - u_int8_t tcpi_options; - u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; - - u_int32_t tcpi_rto; - u_int32_t tcpi_ato; - u_int32_t tcpi_snd_mss; - u_int32_t tcpi_rcv_mss; - - u_int32_t tcpi_unacked; - u_int32_t tcpi_sacked; - u_int32_t tcpi_lost; - u_int32_t tcpi_retrans; - u_int32_t tcpi_fackets; + uint8_t tcpi_state; + uint8_t tcpi_ca_state; + uint8_t tcpi_retransmits; + uint8_t tcpi_probes; + uint8_t tcpi_backoff; + uint8_t tcpi_options; + uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + + uint32_t tcpi_rto; + uint32_t tcpi_ato; + uint32_t tcpi_snd_mss; + uint32_t tcpi_rcv_mss; + + uint32_t tcpi_unacked; + uint32_t tcpi_sacked; + uint32_t tcpi_lost; + uint32_t tcpi_retrans; + uint32_t tcpi_fackets; /* Times. */ - u_int32_t tcpi_last_data_sent; - u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ - u_int32_t tcpi_last_data_recv; - u_int32_t tcpi_last_ack_recv; + uint32_t tcpi_last_data_sent; + uint32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ + uint32_t tcpi_last_data_recv; + uint32_t tcpi_last_ack_recv; /* Metrics. */ - u_int32_t tcpi_pmtu; - u_int32_t tcpi_rcv_ssthresh; - u_int32_t tcpi_rtt; - u_int32_t tcpi_rttvar; - u_int32_t tcpi_snd_ssthresh; - u_int32_t tcpi_snd_cwnd; - u_int32_t tcpi_advmss; - u_int32_t tcpi_reordering; - - u_int32_t tcpi_rcv_rtt; - u_int32_t tcpi_rcv_space; - - u_int32_t tcpi_total_retrans; + uint32_t tcpi_pmtu; + uint32_t tcpi_rcv_ssthresh; + uint32_t tcpi_rtt; + uint32_t tcpi_rttvar; + uint32_t tcpi_snd_ssthresh; + uint32_t tcpi_snd_cwnd; + uint32_t tcpi_advmss; + uint32_t tcpi_reordering; + + uint32_t tcpi_rcv_rtt; + uint32_t tcpi_rcv_space; + + uint32_t tcpi_total_retrans; }; @@ -257,17 +258,17 @@ struct tcp_info struct tcp_md5sig { struct sockaddr_storage tcpm_addr; /* Address associated. */ - u_int16_t __tcpm_pad1; /* Zero. */ - u_int16_t tcpm_keylen; /* Key length. */ - u_int32_t __tcpm_pad2; /* Zero. */ - u_int8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* Key (binary). */ + uint16_t __tcpm_pad1; /* Zero. */ + uint16_t tcpm_keylen; /* Key length. */ + uint32_t __tcpm_pad2; /* Zero. */ + uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* Key (binary). */ }; /* For socket repair options. */ struct tcp_repair_opt { - u_int32_t opt_code; - u_int32_t opt_val; + uint32_t opt_code; + uint32_t opt_val; }; /* Queue to repair, for TCP_REPAIR_QUEUE. */ @@ -298,12 +299,12 @@ enum struct tcp_cookie_transactions { - u_int16_t tcpct_flags; - u_int8_t __tcpct_pad1; - u_int8_t tcpct_cookie_desired; - u_int16_t tcpct_s_data_desired; - u_int16_t tcpct_used; - u_int8_t tcpct_value[TCP_MSS_DEFAULT]; + uint16_t tcpct_flags; + uint8_t __tcpct_pad1; + uint8_t tcpct_cookie_desired; + uint16_t tcpct_s_data_desired; + uint16_t tcpct_used; + uint8_t tcpct_value[TCP_MSS_DEFAULT]; }; #endif /* Misc. */ diff --git a/sysdeps/gnu/netinet/udp.h b/sysdeps/gnu/netinet/udp.h index e3d4492c8a..d5f60e499c 100644 --- a/sysdeps/gnu/netinet/udp.h +++ b/sysdeps/gnu/netinet/udp.h @@ -47,9 +47,8 @@ #ifndef __NETINET_UDP_H #define __NETINET_UDP_H 1 -#include #include - +#include /* UDP header as specified by RFC 768, August 1980. */ @@ -59,17 +58,17 @@ struct udphdr { struct { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - u_int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ + uint16_t uh_sport; /* source port */ + uint16_t uh_dport; /* destination port */ + uint16_t uh_ulen; /* udp length */ + uint16_t uh_sum; /* udp checksum */ }; struct { - u_int16_t source; - u_int16_t dest; - u_int16_t len; - u_int16_t check; + uint16_t source; + uint16_t dest; + uint16_t len; + uint16_t check; }; }; }; diff --git a/sysdeps/mach/hurd/net/ethernet.h b/sysdeps/mach/hurd/net/ethernet.h index 404311e7a2..ddac67800c 100644 --- a/sysdeps/mach/hurd/net/ethernet.h +++ b/sysdeps/mach/hurd/net/ethernet.h @@ -31,15 +31,15 @@ __BEGIN_DECLS systems. */ struct ether_addr { - u_int8_t ether_addr_octet[ETH_ALEN]; + uint8_t ether_addr_octet[ETH_ALEN]; }; /* 10Mb/s ethernet header */ struct ether_header { - u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ - u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */ - u_int16_t ether_type; /* packet type ID field */ + uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ + uint8_t ether_shost[ETH_ALEN]; /* source ether addr */ + uint16_t ether_type; /* packet type ID field */ }; /* Ethernet protocol ID's */ diff --git a/sysdeps/mach/hurd/net/if_arp.h b/sysdeps/mach/hurd/net/if_arp.h index 7ed5550a73..90d389df29 100644 --- a/sysdeps/mach/hurd/net/if_arp.h +++ b/sysdeps/mach/hurd/net/if_arp.h @@ -132,7 +132,7 @@ struct arpreq struct arpd_request { unsigned short int req; /* Request type. */ - u_int32_t ip; /* IP address of entry. */ + uint32_t ip; /* IP address of entry. */ unsigned long int dev; /* Device entry is tied to. */ unsigned long int stamp; unsigned long int updated; diff --git a/sysdeps/mach/hurd/net/if_ppp.h b/sysdeps/mach/hurd/net/if_ppp.h index 1b1c3ea6eb..b210d7fd06 100644 --- a/sysdeps/mach/hurd/net/if_ppp.h +++ b/sysdeps/mach/hurd/net/if_ppp.h @@ -114,8 +114,8 @@ struct npioctl { /* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ struct ppp_option_data { - u_int8_t *ptr; - u_int32_t length; + uint8_t *ptr; + uint32_t length; int transmit; }; diff --git a/sysdeps/mach/hurd/net/route.h b/sysdeps/mach/hurd/net/route.h index a596ce18e3..d974950172 100644 --- a/sysdeps/mach/hurd/net/route.h +++ b/sysdeps/mach/hurd/net/route.h @@ -55,12 +55,12 @@ struct in6_rtmsg struct in6_addr rtmsg_dst; struct in6_addr rtmsg_src; struct in6_addr rtmsg_gateway; - u_int32_t rtmsg_type; - u_int16_t rtmsg_dst_len; - u_int16_t rtmsg_src_len; - u_int32_t rtmsg_metric; + uint32_t rtmsg_type; + uint16_t rtmsg_dst_len; + uint16_t rtmsg_src_len; + uint32_t rtmsg_metric; unsigned long int rtmsg_info; - u_int32_t rtmsg_flags; + uint32_t rtmsg_flags; int rtmsg_ifindex; }; @@ -109,7 +109,7 @@ struct in6_rtmsg #define RTF_NAT 0x08000000 #define RTF_ADDRCLASSMASK 0xF8000000 -#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) +#define RT_ADDRCLASS(flags) ((uint32_t) flags >> 23) #define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) diff --git a/sysdeps/mach/sys/reboot.h b/sysdeps/mach/sys/reboot.h index fc7308929b..9beb8aef72 100644 --- a/sysdeps/mach/sys/reboot.h +++ b/sysdeps/mach/sys/reboot.h @@ -27,7 +27,7 @@ * (pre-GNU) HISTORY * * Revision 2.8 93/03/11 13:46:40 danner - * u_long -> u_int. + * unsigned long -> unsigned int. * [93/03/09 danner] * * Revision 2.7 92/05/21 17:25:11 jfriedl @@ -145,8 +145,8 @@ #define B_TYPEMASK 0xff #define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK) -#define B_MAGICMASK ((u_int)0xf0000000U) -#define B_DEVMAGIC ((u_int)0xa0000000U) +#define B_MAGICMASK 0xf0000000U +#define B_DEVMAGIC 0xa0000000U #define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \ (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \ diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h index 4d70a6baba..f2824bb55b 100644 --- a/sysdeps/unix/sysv/linux/bits/in.h +++ b/sysdeps/unix/sysv/linux/bits/in.h @@ -53,8 +53,8 @@ #define IP_RECVRETOPTS IP_RETOPTS /* bool; Receive IP options for response. */ #define IP_RETOPTS 7 /* ip_opts; Set/get IP per-packet options. */ #define IP_MULTICAST_IF 32 /* in_addr; set/get IP multicast i/f */ -#define IP_MULTICAST_TTL 33 /* u_char; set/get IP multicast ttl */ -#define IP_MULTICAST_LOOP 34 /* i_char; set/get IP multicast loopback */ +#define IP_MULTICAST_TTL 33 /* unsigned char; set/get IP multicast ttl */ +#define IP_MULTICAST_LOOP 34 /* bool; set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 35 /* ip_mreq; add an IP group membership */ #define IP_DROP_MEMBERSHIP 36 /* ip_mreq; drop an IP group membership */ #define IP_UNBLOCK_SOURCE 37 /* ip_mreq_source: unblock data from source */ diff --git a/sysdeps/unix/sysv/linux/net/ethernet.h b/sysdeps/unix/sysv/linux/net/ethernet.h index 3160e9341b..833473e41d 100644 --- a/sysdeps/unix/sysv/linux/net/ethernet.h +++ b/sysdeps/unix/sysv/linux/net/ethernet.h @@ -21,8 +21,9 @@ #ifndef __NET_ETHERNET_H #define __NET_ETHERNET_H 1 -#include #include +#include + #include /* IEEE 802.3 Ethernet constants */ __BEGIN_DECLS @@ -31,15 +32,15 @@ __BEGIN_DECLS systems. */ struct ether_addr { - u_int8_t ether_addr_octet[ETH_ALEN]; + uint8_t ether_addr_octet[ETH_ALEN]; } __attribute__ ((__packed__)); /* 10Mb/s ethernet header */ struct ether_header { - u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ - u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */ - u_int16_t ether_type; /* packet type ID field */ + uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ + uint8_t ether_shost[ETH_ALEN]; /* source ether addr */ + uint16_t ether_type; /* packet type ID field */ } __attribute__ ((__packed__)); /* Ethernet protocol ID's */ diff --git a/sysdeps/unix/sysv/linux/net/if_arp.h b/sysdeps/unix/sysv/linux/net/if_arp.h index 1b3f1d3820..9a20c8358f 100644 --- a/sysdeps/unix/sysv/linux/net/if_arp.h +++ b/sysdeps/unix/sysv/linux/net/if_arp.h @@ -20,12 +20,11 @@ /* Based on the 4.4BSD and Linux version of this file. */ #ifndef _NET_IF_ARP_H - #define _NET_IF_ARP_H 1 -#include #include #include +#include __BEGIN_DECLS @@ -171,7 +170,7 @@ struct arpreq_old struct arpd_request { unsigned short int req; /* Request type. */ - u_int32_t ip; /* IP address of entry. */ + uint32_t ip; /* IP address of entry. */ unsigned long int dev; /* Device entry is tied to. */ unsigned long int stamp; unsigned long int updated; diff --git a/sysdeps/unix/sysv/linux/net/if_ppp.h b/sysdeps/unix/sysv/linux/net/if_ppp.h index 1b1c3ea6eb..9994982fc0 100644 --- a/sysdeps/unix/sysv/linux/net/if_ppp.h +++ b/sysdeps/unix/sysv/linux/net/if_ppp.h @@ -49,8 +49,7 @@ #define __NET_IF_PPP_H 1 #include -#include - +#include #include #include #include @@ -114,9 +113,9 @@ struct npioctl { /* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ struct ppp_option_data { - u_int8_t *ptr; - u_int32_t length; - int transmit; + uint8_t *ptr; + uint32_t length; + int transmit; }; struct ifpppstatsreq { diff --git a/sysdeps/unix/sysv/linux/net/if_shaper.h b/sysdeps/unix/sysv/linux/net/if_shaper.h index 956ad62c9b..e318794e0f 100644 --- a/sysdeps/unix/sysv/linux/net/if_shaper.h +++ b/sysdeps/unix/sysv/linux/net/if_shaper.h @@ -18,8 +18,8 @@ #ifndef _NET_IF_SHAPER_H #define _NET_IF_SHAPER_H 1 -#include #include +#include #include #include @@ -43,11 +43,11 @@ __BEGIN_DECLS struct shaperconf { - u_int16_t ss_cmd; + uint16_t ss_cmd; union { char ssu_name[14]; - u_int32_t ssu_speed; + uint32_t ssu_speed; } ss_u; #define ss_speed ss_u.ssu_speed #define ss_name ss_u.ssu_name diff --git a/sysdeps/unix/sysv/linux/net/route.h b/sysdeps/unix/sysv/linux/net/route.h index 11d21c6cf1..ea785ab04a 100644 --- a/sysdeps/unix/sysv/linux/net/route.h +++ b/sysdeps/unix/sysv/linux/net/route.h @@ -59,12 +59,12 @@ struct in6_rtmsg struct in6_addr rtmsg_dst; struct in6_addr rtmsg_src; struct in6_addr rtmsg_gateway; - u_int32_t rtmsg_type; - u_int16_t rtmsg_dst_len; - u_int16_t rtmsg_src_len; - u_int32_t rtmsg_metric; + uint32_t rtmsg_type; + uint16_t rtmsg_dst_len; + uint16_t rtmsg_src_len; + uint32_t rtmsg_metric; unsigned long int rtmsg_info; - u_int32_t rtmsg_flags; + uint32_t rtmsg_flags; int rtmsg_ifindex; }; @@ -113,7 +113,7 @@ struct in6_rtmsg #define RTF_NAT 0x08000000 #define RTF_ADDRCLASSMASK 0xF8000000 -#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) +#define RT_ADDRCLASS(flags) ((uint32_t) flags >> 23) #define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) diff --git a/sysdeps/unix/sysv/linux/netinet/if_ether.h b/sysdeps/unix/sysv/linux/netinet/if_ether.h index e9ed13774f..ccd8cebbaf 100644 --- a/sysdeps/unix/sysv/linux/netinet/if_ether.h +++ b/sysdeps/unix/sysv/linux/netinet/if_ether.h @@ -70,10 +70,10 @@ __BEGIN_DECLS */ struct ether_arp { struct arphdr ea_hdr; /* fixed-size header */ - u_int8_t arp_sha[ETH_ALEN]; /* sender hardware address */ - u_int8_t arp_spa[4]; /* sender protocol address */ - u_int8_t arp_tha[ETH_ALEN]; /* target hardware address */ - u_int8_t arp_tpa[4]; /* target protocol address */ + uint8_t arp_sha[ETH_ALEN]; /* sender hardware address */ + uint8_t arp_spa[4]; /* sender protocol address */ + uint8_t arp_tha[ETH_ALEN]; /* target hardware address */ + uint8_t arp_tpa[4]; /* target protocol address */ }; #define arp_hrd ea_hdr.ar_hrd #define arp_pro ea_hdr.ar_pro @@ -88,14 +88,14 @@ struct ether_arp { */ #define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \ /* struct in_addr *ipaddr; */ \ - /* u_char enaddr[ETH_ALEN]; */ \ + /* uint8_t enaddr[ETH_ALEN]; */ \ { \ (enaddr)[0] = 0x01; \ (enaddr)[1] = 0x00; \ (enaddr)[2] = 0x5e; \ - (enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f; \ - (enaddr)[4] = ((u_int8_t *)ipaddr)[2]; \ - (enaddr)[5] = ((u_int8_t *)ipaddr)[3]; \ + (enaddr)[3] = ((uint8_t *)ipaddr)[1] & 0x7f; \ + (enaddr)[4] = ((uint8_t *)ipaddr)[2]; \ + (enaddr)[5] = ((uint8_t *)ipaddr)[3]; \ } __END_DECLS diff --git a/sysdeps/unix/sysv/linux/netinet/if_fddi.h b/sysdeps/unix/sysv/linux/netinet/if_fddi.h index 6e0ab370de..675801418f 100644 --- a/sysdeps/unix/sysv/linux/netinet/if_fddi.h +++ b/sysdeps/unix/sysv/linux/netinet/if_fddi.h @@ -18,18 +18,16 @@ #ifndef _NETINET_IF_FDDI_H #define _NETINET_IF_FDDI_H 1 -#include #include -#include - +#include #include #ifdef __USE_MISC struct fddi_header { - u_int8_t fddi_fc; /* Frame Control (FC) value */ - u_int8_t fddi_dhost[FDDI_K_ALEN]; /* Destination host */ - u_int8_t fddi_shost[FDDI_K_ALEN]; /* Source host */ + uint8_t fddi_fc; /* Frame Control (FC) value */ + uint8_t fddi_dhost[FDDI_K_ALEN]; /* Destination host */ + uint8_t fddi_shost[FDDI_K_ALEN]; /* Source host */ }; #endif diff --git a/sysdeps/unix/sysv/linux/netinet/if_tr.h b/sysdeps/unix/sysv/linux/netinet/if_tr.h index c203d11be1..814a35d5da 100644 --- a/sysdeps/unix/sysv/linux/netinet/if_tr.h +++ b/sysdeps/unix/sysv/linux/netinet/if_tr.h @@ -18,8 +18,8 @@ #ifndef _NETINET_IF_TR_H #define _NETINET_IF_TR_H 1 -#include #include +#include /* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble and FCS/CRC (frame check sequence). */ @@ -35,22 +35,22 @@ /* This is an Token-Ring frame header. */ struct trh_hdr { - u_int8_t ac; /* access control field */ - u_int8_t fc; /* frame control field */ - u_int8_t daddr[TR_ALEN]; /* destination address */ - u_int8_t saddr[TR_ALEN]; /* source address */ - u_int16_t rcf; /* route control field */ - u_int16_t rseg[8]; /* routing registers */ + uint8_t ac; /* access control field */ + uint8_t fc; /* frame control field */ + uint8_t daddr[TR_ALEN]; /* destination address */ + uint8_t saddr[TR_ALEN]; /* source address */ + uint16_t rcf; /* route control field */ + uint16_t rseg[8]; /* routing registers */ }; /* This is an Token-Ring LLC structure */ struct trllc { - u_int8_t dsap; /* destination SAP */ - u_int8_t ssap; /* source SAP */ - u_int8_t llc; /* LLC control field */ - u_int8_t protid[3]; /* protocol id */ - u_int16_t ethertype; /* ether type field */ + uint8_t dsap; /* destination SAP */ + uint8_t ssap; /* source SAP */ + uint8_t llc; /* LLC control field */ + uint8_t protid[3]; /* protocol id */ + uint16_t ethertype; /* ether type field */ }; /* Token-Ring statistics collection data. */ @@ -97,12 +97,12 @@ struct tr_statistics struct trn_hdr { - u_int8_t trn_ac; /* access control field */ - u_int8_t trn_fc; /* field control field */ - u_int8_t trn_dhost[TR_ALEN]; /* destination host */ - u_int8_t trn_shost[TR_ALEN]; /* source host */ - u_int16_t trn_rcf; /* route control field */ - u_int16_t trn_rseg[8]; /* routing registers */ + uint8_t trn_ac; /* access control field */ + uint8_t trn_fc; /* field control field */ + uint8_t trn_dhost[TR_ALEN]; /* destination host */ + uint8_t trn_shost[TR_ALEN]; /* source host */ + uint16_t trn_rcf; /* route control field */ + uint16_t trn_rseg[8]; /* routing registers */ }; #endif diff --git a/sysdeps/unix/sysv/linux/netipx/ipx.h b/sysdeps/unix/sysv/linux/netipx/ipx.h index 855ab9903d..338aab5095 100644 --- a/sysdeps/unix/sysv/linux/netipx/ipx.h +++ b/sysdeps/unix/sysv/linux/netipx/ipx.h @@ -18,9 +18,8 @@ #ifndef __NETIPX_IPX_H #define __NETIPX_IPX_H 1 -#include - #include +#include #include __BEGIN_DECLS @@ -34,10 +33,10 @@ __BEGIN_DECLS struct sockaddr_ipx { sa_family_t sipx_family; - u_int16_t sipx_port; - u_int32_t sipx_network; + uint16_t sipx_port; + uint32_t sipx_network; unsigned char sipx_node[IPX_NODE_LEN]; - u_int8_t sipx_type; + uint8_t sipx_type; unsigned char sipx_zero; /* 16 byte fill */ }; diff --git a/sysdeps/unix/sysv/linux/sys/acct.h b/sysdeps/unix/sysv/linux/sys/acct.h index ea0e7fde23..d24c2a7267 100644 --- a/sysdeps/unix/sysv/linux/sys/acct.h +++ b/sysdeps/unix/sysv/linux/sys/acct.h @@ -18,12 +18,11 @@ #ifndef _SYS_ACCT_H #define _SYS_ACCT_H 1 -#include - +#include +#include #include #define __need_time_t #include -#include __BEGIN_DECLS @@ -35,15 +34,15 @@ __BEGIN_DECLS specific encoding system used. */ -typedef u_int16_t comp_t; +typedef uint16_t comp_t; struct acct { char ac_flag; /* Flags. */ - u_int16_t ac_uid; /* Real user ID. */ - u_int16_t ac_gid; /* Real group ID. */ - u_int16_t ac_tty; /* Controlling terminal. */ - u_int32_t ac_btime; /* Beginning time. */ + uint16_t ac_uid; /* Real user ID. */ + uint16_t ac_gid; /* Real group ID. */ + uint16_t ac_tty; /* Controlling terminal. */ + uint32_t ac_btime; /* Beginning time. */ comp_t ac_utime; /* User time. */ comp_t ac_stime; /* System time. */ comp_t ac_etime; /* Elapsed time. */ @@ -53,7 +52,7 @@ struct acct comp_t ac_minflt; /* Minor pagefaults. */ comp_t ac_majflt; /* Major pagefaults. */ comp_t ac_swaps; /* Number of swaps. */ - u_int32_t ac_exitcode; /* Process exitcode. */ + uint32_t ac_exitcode; /* Process exitcode. */ char ac_comm[ACCT_COMM+1]; /* Command name. */ char ac_pad[10]; /* Padding bytes. */ }; @@ -63,13 +62,13 @@ struct acct_v3 { char ac_flag; /* Flags */ char ac_version; /* Always set to ACCT_VERSION */ - u_int16_t ac_tty; /* Control Terminal */ - u_int32_t ac_exitcode; /* Exitcode */ - u_int32_t ac_uid; /* Real User ID */ - u_int32_t ac_gid; /* Real Group ID */ - u_int32_t ac_pid; /* Process ID */ - u_int32_t ac_ppid; /* Parent Process ID */ - u_int32_t ac_btime; /* Process Creation Time */ + uint16_t ac_tty; /* Control Terminal */ + uint32_t ac_exitcode; /* Exitcode */ + uint32_t ac_uid; /* Real User ID */ + uint32_t ac_gid; /* Real Group ID */ + uint32_t ac_pid; /* Process ID */ + uint32_t ac_ppid; /* Parent Process ID */ + uint32_t ac_btime; /* Process Creation Time */ float ac_etime; /* Elapsed Time */ comp_t ac_utime; /* User Time */ comp_t ac_stime; /* System Time */ -- cgit v1.2.3 From 4775578486c8ee2aa09b402eb272eb932e7e0691 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Tue, 23 Aug 2016 21:19:17 -0400 Subject: Installed header hygiene (BZ#20366): Test of installed headers. This adds a test to ensure that the problems fixed in the last several patches do not recur. Each directory checks the headers that it installs for two properties: first, each header must be compilable in isolation, as both C and C++, under a representative combination of language and library conformance levels; second, there is a blacklist of identifiers that may not appear in any installed header, currently consisting of the legacy BSD typedefs. (There is an exemption for the headers that define those typedefs, and for the RPC headers. It may be necessary to make this more sophisticated if we add more stuff to the blacklist in the future.) In order for this test to work correctly, every wrapper header that actually defines something must guard those definitions with #ifndef _ISOMAC. This is the existing mechanism used by the conform/ tests to tell wrapper headers not to define anything that the public header wouldn't, and not to use anything from libc-symbols.h. conform/ only cares for headers that we need to check for standards conformance, whereas this test applies to *every* header. (Headers in include/ that are either installed directly, or are internal-use-only and do *not* correspond to any installed header, are not affected.) * scripts/check-installed-headers.sh: New script. * Rules: In each directory that defines header files to be installed, run check-installed-headers.sh on them as a special test. * Makefile: Likewise for the headers installed at top level. * include/aliases.h, include/alloca.h, include/argz.h * include/arpa/nameser.h, include/arpa/nameser_compat.h * include/elf.h, include/envz.h, include/err.h * include/execinfo.h, include/fpu_control.h, include/getopt.h * include/gshadow.h, include/ifaddrs.h, include/libintl.h * include/link.h, include/malloc.h, include/mcheck.h * include/mntent.h, include/netinet/ether.h * include/nss.h, include/obstack.h, include/printf.h * include/pty.h, include/resolv.h, include/rpc/auth.h * include/rpc/auth_des.h, include/rpc/auth_unix.h * include/rpc/clnt.h, include/rpc/des_crypt.h * include/rpc/key_prot.h, include/rpc/netdb.h * include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h * include/rpc/pmap_rmt.h, include/rpc/rpc.h * include/rpc/rpc_msg.h, include/rpc/svc.h * include/rpc/svc_auth.h, include/rpc/xdr.h * include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h * include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h * include/rpcsvc/ypupd.h, include/shadow.h * include/stdio_ext.h, include/sys/epoll.h * include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h * include/sys/prctl.h, include/sys/profil.h * include/sys/statfs.h, include/sys/sysctl.h * include/sys/sysinfo.h, include/ttyent.h, include/utmp.h * sysdeps/arm/nacl/include/bits/setjmp.h * sysdeps/mips/include/sys/asm.h * sysdeps/unix/sysv/linux/include/sys/sysinfo.h * sysdeps/unix/sysv/linux/include/sys/timex.h * sysdeps/x86/fpu/include/bits/fenv.h: Add #ifndef _ISOMAC guard around internal declarations. Add multiple-inclusion guard if not already present. --- ChangeLog | 39 +++++++ Makefile | 23 ++++ Rules | 23 ++++ include/aliases.h | 3 + include/alloca.h | 4 + include/argz.h | 3 + include/arpa/nameser.h | 3 + include/arpa/nameser_compat.h | 3 + include/elf.h | 9 +- include/envz.h | 3 + include/err.h | 6 ++ include/execinfo.h | 3 + include/fpu_control.h | 6 ++ include/getopt.h | 5 +- include/gshadow.h | 3 + include/ifaddrs.h | 4 + include/libintl.h | 4 + include/link.h | 11 +- include/malloc.h | 2 + include/mcheck.h | 3 + include/mntent.h | 3 + include/netinet/ether.h | 3 + include/nss.h | 3 + include/obstack.h | 6 ++ include/printf.h | 4 + include/pty.h | 3 + include/resolv.h | 11 +- include/rpc/auth.h | 3 + include/rpc/auth_des.h | 3 + include/rpc/auth_unix.h | 6 ++ include/rpc/clnt.h | 3 + include/rpc/des_crypt.h | 3 + include/rpc/key_prot.h | 6 ++ include/rpc/netdb.h | 3 + include/rpc/pmap_clnt.h | 7 +- include/rpc/pmap_prot.h | 6 ++ include/rpc/pmap_rmt.h | 6 ++ include/rpc/rpc.h | 4 + include/rpc/rpc_msg.h | 3 + include/rpc/svc.h | 3 + include/rpc/svc_auth.h | 3 + include/rpc/xdr.h | 6 ++ include/rpcsvc/nis_callback.h | 3 + include/rpcsvc/nislib.h | 3 + include/rpcsvc/yp.h | 3 + include/rpcsvc/ypclnt.h | 3 + include/rpcsvc/ypupd.h | 3 + include/shadow.h | 3 + include/stdio_ext.h | 7 +- include/sys/epoll.h | 3 + include/sys/file.h | 4 + include/sys/gmon.h | 4 + include/sys/ioctl.h | 4 + include/sys/prctl.h | 3 + include/sys/profil.h | 3 + include/sys/statfs.h | 4 + include/sys/sysctl.h | 3 + include/sys/sysinfo.h | 3 + include/ttyent.h | 7 +- include/utmp.h | 3 + scripts/check-installed-headers.sh | 146 ++++++++++++++++++++++++++ sysdeps/arm/nacl/include/bits/setjmp.h | 3 + sysdeps/mips/include/sys/asm.h | 6 +- sysdeps/unix/sysv/linux/include/sys/sysinfo.h | 3 + sysdeps/unix/sysv/linux/include/sys/timex.h | 3 + sysdeps/x86/fpu/include/bits/fenv.h | 6 ++ 66 files changed, 470 insertions(+), 21 deletions(-) create mode 100644 scripts/check-installed-headers.sh (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index 47ea83666f..fa6d945ed1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2016-09-23 Zack Weinberg + + * scripts/check-installed-headers.sh: New script. + * Rules: In each directory that defines header files to be installed, + run check-installed-headers.sh on them as a special test. + * Makefile: Likewise for the headers installed at top level. + + * include/aliases.h, include/alloca.h, include/argz.h + * include/arpa/nameser.h, include/arpa/nameser_compat.h + * include/elf.h, include/envz.h, include/err.h + * include/execinfo.h, include/fpu_control.h, include/getopt.h + * include/gshadow.h, include/ifaddrs.h, include/libintl.h + * include/link.h, include/malloc.h, include/mcheck.h + * include/mntent.h, include/netinet/ether.h + * include/nss.h, include/obstack.h, include/printf.h + * include/pty.h, include/resolv.h, include/rpc/auth.h + * include/rpc/auth_des.h, include/rpc/auth_unix.h + * include/rpc/clnt.h, include/rpc/des_crypt.h + * include/rpc/key_prot.h, include/rpc/netdb.h + * include/rpc/pmap_clnt.h, include/rpc/pmap_prot.h + * include/rpc/pmap_rmt.h, include/rpc/rpc.h + * include/rpc/rpc_msg.h, include/rpc/svc.h + * include/rpc/svc_auth.h, include/rpc/xdr.h + * include/rpcsvc/nis_callback.h, include/rpcsvc/nislib.h + * include/rpcsvc/yp.h, include/rpcsvc/ypclnt.h + * include/rpcsvc/ypupd.h, include/shadow.h + * include/stdio_ext.h, include/sys/epoll.h + * include/sys/file.h, include/sys/gmon.h, include/sys/ioctl.h + * include/sys/prctl.h, include/sys/profil.h + * include/sys/statfs.h, include/sys/sysctl.h + * include/sys/sysinfo.h, include/ttyent.h, include/utmp.h + * sysdeps/arm/nacl/include/bits/setjmp.h + * sysdeps/mips/include/sys/asm.h + * sysdeps/unix/sysv/linux/include/sys/sysinfo.h + * sysdeps/unix/sysv/linux/include/sys/timex.h + * sysdeps/x86/fpu/include/bits/fenv.h: + Add #ifndef _ISOMAC guard around internal declarations. + Add multiple-inclusion guard if not already present. + 2016-09-23 Zack Weinberg * sysdeps/generic/sys/ucontext.h diff --git a/Makefile b/Makefile index 4478c97126..1ae3281184 100644 --- a/Makefile +++ b/Makefile @@ -318,6 +318,29 @@ $(objpfx)begin-end-check.out: scripts/begin-end-check.pl $(evaluate-test) endif +ifneq "$(headers)" "" +# Special test of all the installed headers in this directory. +tests-special += $(objpfx)check-installed-headers-c.out +libof-check-installed-headers-c := nonlib +$(objpfx)check-installed-headers-c.out: \ + scripts/check-installed-headers.sh $(headers) + $(SHELL) $(..)scripts/check-installed-headers.sh c \ + "$(CC) $(filter-out -std=%,$(CFLAGS)) -D_ISOMAC $(+includes)" \ + $(headers) > $@; \ + $(evaluate-test) + +ifneq "$(CXX)" "" +tests-special += $(objpfx)check-installed-headers-cxx.out +libof-check-installed-headers-cxx := nonlib +$(objpfx)check-installed-headers-cxx.out: \ + scripts/check-installed-headers.sh $(headers) + $(SHELL) $(..)scripts/check-installed-headers.sh c++ \ + "$(CXX) $(filter-out -std=%,$(CXXFLAGS)) -D_ISOMAC $(+includes)" \ + $(headers) > $@; \ + $(evaluate-test) +endif +endif + define summarize-tests @egrep -v '^(PASS|XFAIL):' $(objpfx)$1 || true @echo "Summary of test results$2:" diff --git a/Rules b/Rules index 8306d36a07..342d659408 100644 --- a/Rules +++ b/Rules @@ -80,6 +80,29 @@ $(common-objpfx)dummy.c: (echo 'extern void __dummy__ (void);'; \ echo 'void __dummy__ (void) { }') > $@ common-generated += dummy.o dummy.c + +ifneq "$(headers)" "" +# Special test of all the installed headers in this directory. +tests-special += $(objpfx)check-installed-headers-c.out +libof-check-installed-headers-c := nonlib +$(objpfx)check-installed-headers-c.out: \ + $(..)scripts/check-installed-headers.sh $(headers) + $(SHELL) $(..)scripts/check-installed-headers.sh c \ + "$(CC) $(filter-out -std=%,$(CFLAGS)) -D_ISOMAC $(+includes)" \ + $(headers) > $@; \ + $(evaluate-test) + +ifneq "$(CXX)" "" +tests-special += $(objpfx)check-installed-headers-cxx.out +libof-check-installed-headers-cxx := nonlib +$(objpfx)check-installed-headers-cxx.out: \ + $(..)scripts/check-installed-headers.sh $(headers) + $(SHELL) $(..)scripts/check-installed-headers.sh c++ \ + "$(CXX) $(filter-out -std=%,$(CXXFLAGS)) -D_ISOMAC $(+includes)" \ + $(headers) > $@; \ + $(evaluate-test) +endif +endif # This makes all the auxiliary and test programs. diff --git a/include/aliases.h b/include/aliases.h index f7cfafcd6c..ece69ebe43 100644 --- a/include/aliases.h +++ b/include/aliases.h @@ -1,6 +1,8 @@ #ifndef _ALIASES_H #include +# ifndef _ISOMAC + extern int __getaliasent_r (struct aliasent *__restrict __result_buf, char *__restrict __buffer, size_t __buflen, struct aliasent **__restrict __result) @@ -34,4 +36,5 @@ DECLARE_NSS_PROTOTYPES (nis) DECLARE_NSS_PROTOTYPES (nisplus) #undef DECLARE_NSS_PROTOTYPES +# endif /* !_ISOMAC */ #endif diff --git a/include/alloca.h b/include/alloca.h index 01500259b8..fd90664f0a 100644 --- a/include/alloca.h +++ b/include/alloca.h @@ -1,6 +1,9 @@ #ifndef _ALLOCA_H #include + +# ifndef _ISOMAC + #include #undef __alloca @@ -73,4 +76,5 @@ libc_hidden_proto (__libc_alloca_cutoff) extend_alloca (buf, len, s__); }) #endif +# endif /* !_ISOMAC */ #endif diff --git a/include/argz.h b/include/argz.h index 4eab0b680b..0388c23277 100644 --- a/include/argz.h +++ b/include/argz.h @@ -2,8 +2,11 @@ #include +# ifndef _ISOMAC + libc_hidden_proto (argz_delete) libc_hidden_proto (__argz_count) libc_hidden_proto (__argz_stringify) +# endif /* !_ISOMAC */ #endif diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h index ce6f0238ed..cd7ab6e925 100644 --- a/include/arpa/nameser.h +++ b/include/arpa/nameser.h @@ -2,6 +2,8 @@ #include +# ifndef _ISOMAC + /* If the machine allows unaligned access we can do better than using the NS_GET16, NS_GET32, NS_PUT16, and NS_PUT32 macros from the installed header. */ @@ -74,4 +76,5 @@ libresolv_hidden_proto (ns_samename) libresolv_hidden_proto (ns_makecanon) libresolv_hidden_proto (ns_format_ttl) +# endif /* !_ISOMAC */ #endif diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h index 2e735ede4c..69280009b5 100644 --- a/include/arpa/nameser_compat.h +++ b/include/arpa/nameser_compat.h @@ -1,8 +1,11 @@ #ifndef _ARPA_NAMESER_COMPAT_ #include +# ifndef _ISOMAC + /* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e., T_A and T_AAAA). */ #define T_UNSPEC 62321 +# endif /* !_ISOMAC */ #endif diff --git a/include/elf.h b/include/elf.h index 60658c617c..f06a33f256 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1,5 +1,8 @@ #ifndef _ELF_H -# include +#include + +# ifndef _ISOMAC + /* Some information which is not meant for the public and therefore not in . */ # include @@ -9,4 +12,6 @@ # define DT_1_SUPPORTED_MASK \ (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \ | DF_1_ORIGIN | DF_1_NODEFLIB) -#endif + +# endif /* !_ISOMAC */ +#endif /* elf.h */ diff --git a/include/envz.h b/include/envz.h index 8cfd9b57e9..633fcc6f40 100644 --- a/include/envz.h +++ b/include/envz.h @@ -2,7 +2,10 @@ #include +# ifndef _ISOMAC + libc_hidden_proto (envz_entry) libc_hidden_proto (envz_remove) +# endif /* !_ISOMAC */ #endif diff --git a/include/err.h b/include/err.h index 737dfc1b6f..382855938e 100644 --- a/include/err.h +++ b/include/err.h @@ -1,8 +1,14 @@ +#ifndef _ERR_H #include +# ifndef _ISOMAC + libc_hidden_proto (warn) libc_hidden_proto (warnx) libc_hidden_proto (vwarn) libc_hidden_proto (vwarnx) libc_hidden_proto (verr) libc_hidden_proto (verrx) + +# endif /* !_ISOMAC */ +#endif /* err.h */ diff --git a/include/execinfo.h b/include/execinfo.h index c929821e8c..0b132b089f 100644 --- a/include/execinfo.h +++ b/include/execinfo.h @@ -1,6 +1,8 @@ #ifndef _EXECINFO_H #include +# ifndef _ISOMAC + extern int __backtrace (void **__array, int __size); libc_hidden_proto (__backtrace) @@ -10,4 +12,5 @@ extern void __backtrace_symbols_fd (void *const *__array, int __size, int __fd); libc_hidden_proto (__backtrace_symbols_fd) +# endif /* !_ISOMAC */ #endif diff --git a/include/fpu_control.h b/include/fpu_control.h index d0b5e9c0d1..4498a83b87 100644 --- a/include/fpu_control.h +++ b/include/fpu_control.h @@ -1,4 +1,10 @@ +#ifndef _FPU_CONTROL_H #include_next +# ifndef _ISOMAC + /* Called at startup. It can be used to manipulate fpu control register. */ extern void __setfpucw (fpu_control_t); + +# endif /* !_ISOMAC */ +#endif /* fpu_control.h */ diff --git a/include/getopt.h b/include/getopt.h index 6f2693d21b..c094972c97 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -3,11 +3,10 @@ #include /* Get __GNU_LIBRARY__ defined now. */ #include -# ifdef _GETOPT_H +# if defined _GETOPT_H && !defined _ISOMAC /* Now define the internal interfaces. */ extern void __getopt_clean_environment (char **__env); -# endif - +# endif /* _GETOPT_H && !_ISOMAC */ #endif diff --git a/include/gshadow.h b/include/gshadow.h index 8a981f688a..532801afd0 100644 --- a/include/gshadow.h +++ b/include/gshadow.h @@ -1,6 +1,8 @@ #ifndef _GSHADOW_H #include +# ifndef _ISOMAC + extern int __fgetsgent_r (FILE *stream, struct sgrp *resbuf, char *buffer, size_t buflen, struct sgrp **result); extern int __sgetsgent_r (const char *string, struct sgrp *resbuf, @@ -12,4 +14,5 @@ extern int _nss_files_parse_sgent (char *line, struct sgrp *result, size_t datalen, int *errnop); libc_hidden_proto (_nss_files_parse_sgent) +# endif /* !_ISOMAC */ #endif diff --git a/include/ifaddrs.h b/include/ifaddrs.h index 2787f21115..54f4b7a3ce 100644 --- a/include/ifaddrs.h +++ b/include/ifaddrs.h @@ -1,5 +1,8 @@ #ifndef _IFADDRS_H #include + +# ifndef _ISOMAC + #include #include @@ -30,4 +33,5 @@ extern void __check_native (uint32_t a1_index, int *a1_native, extern uint32_t __bump_nl_timestamp (void) attribute_hidden; #endif +# endif /* !_ISOMAC */ #endif /* ifaddrs.h */ diff --git a/include/libintl.h b/include/libintl.h index 0551a04084..9a11367ec6 100644 --- a/include/libintl.h +++ b/include/libintl.h @@ -1,5 +1,8 @@ #ifndef _LIBINTL_H #include + +# ifndef _ISOMAC + #include /* Now define the internal interfaces. */ @@ -46,4 +49,5 @@ libc_hidden_proto (_libc_intl_domainname) # define _(msgid) \ __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) +# endif /* !_ISOMAC */ #endif diff --git a/include/link.h b/include/link.h index 32a7392f38..055844285c 100644 --- a/include/link.h +++ b/include/link.h @@ -24,12 +24,18 @@ # error this should be impossible #endif +# ifndef _ISOMAC /* Get most of the contents from the public header, but we define a different `struct link_map' type for private use. The la_objopen prototype uses the type, so we have to declare it separately. */ -#define link_map link_map_public -#define la_objopen la_objopen_wrongproto +# define link_map link_map_public +# define la_objopen la_objopen_wrongproto +# endif + #include + +# ifndef _ISOMAC + #undef link_map #undef la_objopen @@ -341,4 +347,5 @@ extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, `ELF64_R_TYPE'. */ #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) +# endif /* !_ISOMAC */ #endif /* include/link.h */ diff --git a/include/malloc.h b/include/malloc.h index 42fc8ed696..70d32c7c84 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -1,6 +1,7 @@ #ifndef _MALLOC_H #include +# ifndef _ISOMAC /* In the GNU libc we rename the global variable `__malloc_initialized' to `__libc_malloc_initialized'. */ @@ -11,4 +12,5 @@ extern int __malloc_initialized attribute_hidden; struct malloc_state; typedef struct malloc_state *mstate; +# endif /* !_ISOMAC */ #endif diff --git a/include/mcheck.h b/include/mcheck.h index b0037a7107..8883c3d53e 100644 --- a/include/mcheck.h +++ b/include/mcheck.h @@ -2,7 +2,10 @@ #include +# ifndef _ISOMAC + libc_hidden_proto (mcheck) libc_hidden_proto (mcheck_check_all) +# endif /* !_ISOMAC */ #endif diff --git a/include/mntent.h b/include/mntent.h index b34674aa3e..169210fc66 100644 --- a/include/mntent.h +++ b/include/mntent.h @@ -1,6 +1,8 @@ #ifndef _MNTENT_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern FILE *__setmntent (const char *__file, const char *__mode); extern struct mntent *__getmntent_r (FILE *__stream, @@ -14,4 +16,5 @@ libc_hidden_proto (__setmntent) libc_hidden_proto (__getmntent_r) libc_hidden_proto (__endmntent) +# endif /* !_ISOMAC */ #endif diff --git a/include/netinet/ether.h b/include/netinet/ether.h index 2efe4c04e4..8bfe7e03ad 100644 --- a/include/netinet/ether.h +++ b/include/netinet/ether.h @@ -1,6 +1,8 @@ #ifndef _NETINET_ETHER_H #include +# ifndef _ISOMAC + libc_hidden_proto (ether_aton_r) libc_hidden_proto (ether_ntoa_r) @@ -39,4 +41,5 @@ DECLARE_NSS_PROTOTYPES (nisplus) #undef DECLARE_NSS_PROTOTYPES +# endif /* !_ISOMAC */ #endif diff --git a/include/nss.h b/include/nss.h index 1e8cc3910d..6358a10fd3 100644 --- a/include/nss.h +++ b/include/nss.h @@ -1,6 +1,8 @@ #ifndef _NSS_H #include +# ifndef _ISOMAC + #define NSS_INVALID_FIELD_CHARACTERS ":\n" extern const char __nss_invalid_field_characters[] attribute_hidden; @@ -11,4 +13,5 @@ _Bool __nss_valid_list_field (char **list) const char *__nss_rewrite_field (const char *value, char **to_be_freed) attribute_hidden internal_function; +# endif /* !_ISOMAC */ #endif /* _NSS_H */ diff --git a/include/obstack.h b/include/obstack.h index 349d59bb03..fe2e595381 100644 --- a/include/obstack.h +++ b/include/obstack.h @@ -1,3 +1,9 @@ +#ifndef _OBSTACK_H #include +# ifndef _ISOMAC + libc_hidden_proto (_obstack_newchunk) + +# endif /* !_ISOMAC */ +#endif /* obstack.h */ diff --git a/include/printf.h b/include/printf.h index b12b5dc971..984f263167 100644 --- a/include/printf.h +++ b/include/printf.h @@ -1,6 +1,9 @@ #ifndef _PRINTF_H #include + +# ifndef _ISOMAC + #include /* Now define the internal interfaces. */ @@ -13,4 +16,5 @@ extern int __printf_fp_l (FILE *, locale_t, const struct printf_info *, const void *const *); libc_hidden_proto (__printf_fp_l) +# endif /* !_ISOMAC */ #endif diff --git a/include/pty.h b/include/pty.h index a91be80852..4979bb765f 100644 --- a/include/pty.h +++ b/include/pty.h @@ -1,6 +1,9 @@ #ifndef _PTY_H #include +# ifndef _ISOMAC + libutil_hidden_proto (openpty) +# endif /* !_ISOMAC */ #endif diff --git a/include/resolv.h b/include/resolv.h index 52ac218666..699cc81569 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -1,17 +1,19 @@ #ifndef _RESOLV_H_ -#define RES_SET_H_ERRNO(r,x) \ +# ifndef _ISOMAC +# include +# define RES_SET_H_ERRNO(r,x) \ do \ { \ (r)->res_h_errno = x; \ __set_h_errno(x); \ } \ while (0) +# endif -#include #include -#ifdef _RESOLV_H_ +# if defined _RESOLV_H_ && !defined _ISOMAC # if IS_IN (libc) # define __resp __libc_resp @@ -97,6 +99,5 @@ libresolv_hidden_proto (__p_secstodate) extern const char *_res_opcodes[]; libresolv_hidden_proto (_res_opcodes) -#endif - +# endif /* _RESOLV_H_ && !_ISOMAC */ #endif diff --git a/include/rpc/auth.h b/include/rpc/auth.h index 0219fd9316..2e55cce11d 100644 --- a/include/rpc/auth.h +++ b/include/rpc/auth.h @@ -1,6 +1,8 @@ #ifndef _RPC_AUTH_H #include +# ifndef _ISOMAC + libc_hidden_proto (getnetname) libc_hidden_proto (netname2user) libc_hidden_proto (host2netname) @@ -41,4 +43,5 @@ libc_hidden_proto (key_setnet) libc_hidden_proto (key_setsecret) libc_hidden_proto (netname2host) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/auth_des.h b/include/rpc/auth_des.h index 0e9db1a226..6afed56b71 100644 --- a/include/rpc/auth_des.h +++ b/include/rpc/auth_des.h @@ -2,6 +2,8 @@ #include +# ifndef _ISOMAC + libc_hidden_proto (getpublickey) libc_hidden_proto (getsecretkey) libc_hidden_proto (rtime) @@ -32,4 +34,5 @@ libc_hidden_proto (authdes_getucred) libc_hidden_proto (xdr_authdes_cred) libc_hidden_proto (xdr_authdes_verf) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/auth_unix.h b/include/rpc/auth_unix.h index 07031c9bd9..019efa275a 100644 --- a/include/rpc/auth_unix.h +++ b/include/rpc/auth_unix.h @@ -1,3 +1,9 @@ +#ifndef _RPC_AUTH_UNIX_H #include +# ifndef _ISOMAC + libc_hidden_proto (xdr_authunix_parms) + +# endif /* !_ISOMAC */ +#endif /* rpc/auth_unix.h */ diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h index d79a6a7b5b..a397023a93 100644 --- a/include/rpc/clnt.h +++ b/include/rpc/clnt.h @@ -1,6 +1,8 @@ #ifndef _RPC_CLNT_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int _openchild (const char *command, FILE **fto, FILE **ffrom); @@ -27,4 +29,5 @@ libc_hidden_proto (get_myaddress) libc_hidden_proto (clntunix_create) libc_hidden_proto (__libc_clntudp_bufcreate) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/des_crypt.h b/include/rpc/des_crypt.h index 44f7e669b0..7a34957df8 100644 --- a/include/rpc/des_crypt.h +++ b/include/rpc/des_crypt.h @@ -1,6 +1,8 @@ #ifndef __DES_CRYPT_H__ #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int xencrypt (char *secret, char *passwd); @@ -12,4 +14,5 @@ libc_hidden_proto (cbc_crypt) libc_hidden_proto (xencrypt) libc_hidden_proto (xdecrypt) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/key_prot.h b/include/rpc/key_prot.h index 29d14cc8a0..4711a94edf 100644 --- a/include/rpc/key_prot.h +++ b/include/rpc/key_prot.h @@ -1,5 +1,8 @@ +#ifndef _KEY_PROT_H_RPCGEN #include +# ifndef _ISOMAC + libc_hidden_proto (xdr_cryptkeyarg) libc_hidden_proto (xdr_cryptkeyarg2) libc_hidden_proto (xdr_cryptkeyres) @@ -10,3 +13,6 @@ libc_hidden_proto (xdr_keystatus) libc_hidden_proto (xdr_getcredres) libc_hidden_proto (xdr_netnamestr) libc_hidden_proto (xdr_unixcred) + +# endif /* !_ISOMAC */ +#endif /* rpc/key_prot.h */ diff --git a/include/rpc/netdb.h b/include/rpc/netdb.h index 65af237e50..9b84668be7 100644 --- a/include/rpc/netdb.h +++ b/include/rpc/netdb.h @@ -1,6 +1,8 @@ #ifndef _RPC_NETDB_H #include +# ifndef _ISOMAC + extern int __getrpcbyname_r (const char *__name, struct rpcent *__result_buf, char *__buffer, size_t __buflen, struct rpcent **__result); @@ -48,4 +50,5 @@ DECLARE_NSS_PROTOTYPES (nisplus) #undef DECLARE_NSS_PROTOTYPES +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h index 67628e0589..ec907c28cc 100644 --- a/include/rpc/pmap_clnt.h +++ b/include/rpc/pmap_clnt.h @@ -1,5 +1,7 @@ #ifndef _RPC_PMAP_CLNT_H -# include +#include + +# ifndef _ISOMAC libc_hidden_proto (pmap_getport) libc_hidden_proto (pmap_set) @@ -18,4 +20,5 @@ libc_hidden_proto (clnt_broadcast) libc_hidden_proto (pmap_getmaps) libc_hidden_proto (pmap_rmtcall) -#endif +# endif /* !_ISOMAC */ +#endif /* rpc/pmap_clnt.h */ diff --git a/include/rpc/pmap_prot.h b/include/rpc/pmap_prot.h index 2e9076ee3d..a2573d106f 100644 --- a/include/rpc/pmap_prot.h +++ b/include/rpc/pmap_prot.h @@ -1,4 +1,10 @@ +#ifndef _RPC_PMAP_PROT_H #include +# ifndef _ISOMAC + libc_hidden_proto (xdr_pmap) libc_hidden_proto (xdr_pmaplist) + +# endif /* !_ISOMAC */ +#endif /* rpc/pmap_prot.h */ diff --git a/include/rpc/pmap_rmt.h b/include/rpc/pmap_rmt.h index e8822dabe9..ae53a02652 100644 --- a/include/rpc/pmap_rmt.h +++ b/include/rpc/pmap_rmt.h @@ -1,4 +1,10 @@ +#ifndef _RPC_PMAP_RMT_H #include +# ifndef _ISOMAC + libc_hidden_proto (xdr_rmtcall_args) libc_hidden_proto (xdr_rmtcallres) + +# endif /* !_ISOMAC */ +#endif /* rpc/pmap_rmt.h */ diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h index 58bdef3cc9..4c9ee82617 100644 --- a/include/rpc/rpc.h +++ b/include/rpc/rpc.h @@ -1,5 +1,8 @@ #ifndef _RPC_RPC_H #include + +# ifndef _ISOMAC + #include /* Now define the internal interfaces. */ @@ -56,4 +59,5 @@ libc_hidden_proto (__rpc_thread_createerr) #endif /* _RPC_THREAD_SAFE_ */ +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/rpc_msg.h b/include/rpc/rpc_msg.h index be1f4838c9..93c5ab8764 100644 --- a/include/rpc/rpc_msg.h +++ b/include/rpc/rpc_msg.h @@ -1,6 +1,8 @@ #ifndef _RPC_MSG_H #include +# ifndef _ISOMAC + libc_hidden_proto (_seterr_reply) /* Now define the internal interfaces. */ @@ -14,4 +16,5 @@ libc_hidden_proto (xdr_callmsg) libc_hidden_proto (xdr_rejected_reply) libc_hidden_proto (xdr_replymsg) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/svc.h b/include/rpc/svc.h index 61a8ab3503..465bf4427d 100644 --- a/include/rpc/svc.h +++ b/include/rpc/svc.h @@ -1,6 +1,8 @@ #ifndef _RPC_SVC_H #include +# ifndef _ISOMAC + libc_hidden_proto (xprt_register) libc_hidden_proto (xprt_unregister) libc_hidden_proto (svc_register) @@ -37,4 +39,5 @@ libc_hidden_proto (svc_getreq_poll) extern void __svc_accept_failed (void) attribute_hidden; +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/svc_auth.h b/include/rpc/svc_auth.h index 582bb31aea..2609d19544 100644 --- a/include/rpc/svc_auth.h +++ b/include/rpc/svc_auth.h @@ -1,6 +1,8 @@ #ifndef _RPC_SVC_AUTH_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern enum auth_stat _svcauth_unix (struct svc_req *rqst, struct rpc_msg *msg); @@ -9,4 +11,5 @@ extern enum auth_stat _svcauth_short (struct svc_req *rqst, libc_hidden_proto (_authenticate) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h index 57971d0758..e1bff1cd1c 100644 --- a/include/rpc/xdr.h +++ b/include/rpc/xdr.h @@ -1,5 +1,8 @@ +#ifndef _RPC_XDR_H #include +# ifndef _ISOMAC + libc_hidden_proto (xdrstdio_create) libc_hidden_proto (xdr_array) libc_hidden_proto (xdr_bool) @@ -45,3 +48,6 @@ libc_hidden_proto (xdr_int64_t) libc_hidden_proto (xdr_uint64_t) libc_hidden_proto (xdr_quad_t) libc_hidden_proto (xdr_u_quad_t) + +# endif /* !_ISOMAC */ +#endif /* rpc/xdr.h */ diff --git a/include/rpcsvc/nis_callback.h b/include/rpcsvc/nis_callback.h index dfa9cd3ef7..0515d07887 100644 --- a/include/rpcsvc/nis_callback.h +++ b/include/rpcsvc/nis_callback.h @@ -1,7 +1,10 @@ #ifndef _RPCSVC_NIS_CALLBACK_H #include +# ifndef _ISOMAC + libnsl_hidden_proto (xdr_obj_p) libnsl_hidden_proto (xdr_cback_data) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpcsvc/nislib.h b/include/rpcsvc/nislib.h index 635c513e4d..05b19877e7 100644 --- a/include/rpcsvc/nislib.h +++ b/include/rpcsvc/nislib.h @@ -1,6 +1,8 @@ #ifndef __RPCSVC_NISLIB_H__ #include +# ifndef _ISOMAC + libnsl_hidden_proto (nis_leaf_of_r) libnsl_hidden_proto (nis_name_of_r) libnsl_hidden_proto (nis_getnames) @@ -44,4 +46,5 @@ libnsl_hidden_proto (nis_clone_object) extern const_nis_name __nis_domain_of (const_nis_name) __THROW; +# endif /* !_ISOMAC */ #endif diff --git a/include/rpcsvc/yp.h b/include/rpcsvc/yp.h index 04a973eae7..b6d7c15f62 100644 --- a/include/rpcsvc/yp.h +++ b/include/rpcsvc/yp.h @@ -1,6 +1,8 @@ #ifndef __RPCSVC_YP_H__ #include +# ifndef _ISOMAC + libnsl_hidden_proto (xdr_ypstat) libnsl_hidden_proto (xdr_ypxfrstat) libnsl_hidden_proto (xdr_domainname) @@ -23,4 +25,5 @@ libnsl_hidden_proto (xdr_ypresp_order) libnsl_hidden_proto (xdr_ypbind_resp) libnsl_hidden_proto (xdr_ypresp_master) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpcsvc/ypclnt.h b/include/rpcsvc/ypclnt.h index b38dc6bb4c..1b4e2f215c 100644 --- a/include/rpcsvc/ypclnt.h +++ b/include/rpcsvc/ypclnt.h @@ -1,10 +1,13 @@ #ifndef __RPCSVC_YPCLNT_H__ #include +# ifndef _ISOMAC + libnsl_hidden_proto (ypbinderr_string) libnsl_hidden_proto (yp_bind) libnsl_hidden_proto (yp_get_default_domain) libnsl_hidden_proto (ypprot_err) libnsl_hidden_proto (yp_master) +# endif /* !_ISOMAC */ #endif diff --git a/include/rpcsvc/ypupd.h b/include/rpcsvc/ypupd.h index 7601971512..6d179dd306 100644 --- a/include/rpcsvc/ypupd.h +++ b/include/rpcsvc/ypupd.h @@ -1,8 +1,11 @@ #ifndef __RPCSVC_YPUPD_H__ #include +# ifndef _ISOMAC + libnsl_hidden_proto (xdr_yp_buf) libnsl_hidden_proto (xdr_ypdelete_args) libnsl_hidden_proto (xdr_ypupdate_args) +# endif /* !_ISOMAC */ #endif diff --git a/include/shadow.h b/include/shadow.h index a3f897cba1..124a1ab50a 100644 --- a/include/shadow.h +++ b/include/shadow.h @@ -1,6 +1,8 @@ #ifndef _SHADOW_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int __getspent_r (struct spwd *__result_buf, char *__buffer, size_t __buflen, struct spwd **__result) @@ -47,4 +49,5 @@ DECLARE_NSS_PROTOTYPES (nisplus) #undef DECLARE_NSS_PROTOTYPES +# endif /* !_ISOMAC */ #endif diff --git a/include/stdio_ext.h b/include/stdio_ext.h index 354146f8e8..29c6e68cdb 100644 --- a/include/stdio_ext.h +++ b/include/stdio_ext.h @@ -1,6 +1,7 @@ #ifndef _STDIO_EXT_H +#include -# include +# ifndef _ISOMAC libc_hidden_proto (__fsetlocking) @@ -18,5 +19,5 @@ libc_hidden_proto (__fsetlocking) __result; \ }) - -#endif +# endif /* !_ISOMAC */ +#endif /* stdio_ext.h */ diff --git a/include/sys/epoll.h b/include/sys/epoll.h index ce1c2e26d5..86e0a54e62 100644 --- a/include/sys/epoll.h +++ b/include/sys/epoll.h @@ -1,6 +1,9 @@ #ifndef _SYS_EPOLL_H #include_next +# ifndef _ISOMAC + libc_hidden_proto (epoll_pwait) +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/file.h b/include/sys/file.h index e73a4d1c94..d0cd1f9e15 100644 --- a/include/sys/file.h +++ b/include/sys/file.h @@ -1,6 +1,10 @@ #ifndef _SYS_FILE_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int __flock (int __fd, int __operation); + +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/gmon.h b/include/sys/gmon.h index 55739cf00c..30889d8bc3 100644 --- a/include/sys/gmon.h +++ b/include/sys/gmon.h @@ -1,6 +1,8 @@ #ifndef _SYS_GMON_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ /* Write current profiling data to file. */ @@ -12,4 +14,6 @@ extern void __bb_init_func (struct __bb *bb); extern void __bb_exit_func (void); extern struct gmonparam _gmonparam attribute_hidden; + +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index ebadd526b9..bfc6909dbc 100644 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -1,6 +1,10 @@ #ifndef _SYS_IOCTL_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int __ioctl (int __fd, unsigned long int __request, ...); + +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/prctl.h b/include/sys/prctl.h index 316f454c1c..0920ed642b 100644 --- a/include/sys/prctl.h +++ b/include/sys/prctl.h @@ -1,6 +1,9 @@ #ifndef _SYS_PRCTL_H #include_next +# ifndef _ISOMAC + extern int __prctl (int __option, ...); +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/profil.h b/include/sys/profil.h index 7bf17003ad..2b1133073e 100644 --- a/include/sys/profil.h +++ b/include/sys/profil.h @@ -1,9 +1,12 @@ #ifndef _PROFIL_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int __sprofil (struct prof *__profp, int __profcnt, struct timeval *__tvp, unsigned int __flags); +# endif /* !_ISOMAC */ #endif /* _PROFIL_H */ diff --git a/include/sys/statfs.h b/include/sys/statfs.h index e34ad02965..3fac4a3490 100644 --- a/include/sys/statfs.h +++ b/include/sys/statfs.h @@ -1,10 +1,14 @@ #ifndef _SYS_STATFS_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern int __statfs (const char *__file, struct statfs *__buf); libc_hidden_proto (__statfs) extern int __fstatfs (int __fildes, struct statfs *__buf); extern int __statfs64 (const char *__file, struct statfs64 *__buf); extern int __fstatfs64 (int __fildes, struct statfs64 *__buf); + +# endif /* !_ISOMAC */ #endif diff --git a/include/sys/sysctl.h b/include/sys/sysctl.h index 4fffb4ff49..2a15e91354 100644 --- a/include/sys/sysctl.h +++ b/include/sys/sysctl.h @@ -1,10 +1,13 @@ #ifndef _SYS_SYSCTL_H #include_next +# ifndef _ISOMAC + /* Read or write system parameters (Linux, FreeBSD specific). */ extern int __sysctl (int *__name, int __nlen, void *__oldval, size_t *__oldlenp, void *__newval, size_t __newlen); libc_hidden_proto (__sysctl) +# endif /* !_ISOMAC */ #endif /* _SYS_SYSCTL_H */ diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h index d33055a2b3..c33eae2883 100644 --- a/include/sys/sysinfo.h +++ b/include/sys/sysinfo.h @@ -1,6 +1,8 @@ #ifndef _SYS_SYSINFO_H #include_next +# ifndef _ISOMAC + /* Now we define the internal interface. */ /* Return number of configured processors. */ @@ -18,4 +20,5 @@ extern long int __get_avphys_pages (void); /* Return maximum number of processes this real user ID can have. */ extern long int __get_child_max (void); +# endif /* !_ISOMAC */ #endif /* sys/sysinfo.h */ diff --git a/include/ttyent.h b/include/ttyent.h index 81e52116e5..53a66681d2 100644 --- a/include/ttyent.h +++ b/include/ttyent.h @@ -1,5 +1,7 @@ #ifndef _TTYENT_H -# include +#include + +# ifndef _ISOMAC extern __typeof (getttyent) __getttyent __THROW; libc_hidden_proto (__getttyent) @@ -8,4 +10,5 @@ libc_hidden_proto (__setttyent) extern __typeof (endttyent) __endttyent __THROW; libc_hidden_proto (__endttyent) -#endif +# endif /* !_ISOMAC */ +#endif /* ttyent.h */ diff --git a/include/utmp.h b/include/utmp.h index 28207d1282..6b2e262362 100644 --- a/include/utmp.h +++ b/include/utmp.h @@ -1,6 +1,8 @@ #ifndef _UTMP_H #include +# ifndef _ISOMAC + /* Now define the internal interfaces. */ extern void __updwtmp (const char *__wtmp_file, const struct utmp *__utmp); extern int __utmpname (const char *__file); @@ -18,4 +20,5 @@ extern int __getutline_r (const struct utmp *__line, libutil_hidden_proto (login_tty) +# endif /* !_ISOMAC */ #endif diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh new file mode 100644 index 0000000000..7fbc725c0f --- /dev/null +++ b/scripts/check-installed-headers.sh @@ -0,0 +1,146 @@ +#! /bin/sh +# Copyright (C) 2016 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# . + +# Check installed headers for cleanliness. For each header, confirm +# that it's possible to compile a file that includes that header and +# does nothing else, in several different compilation modes. Also, +# scan the header for a set of obsolete typedefs that should no longer +# appear. + +# These compilation switches assume GCC or compatible, which is probably +# fine since we also assume that when _building_ glibc. +c_modes="-std=c89 -std=gnu89 -std=c11 -std=gnu11" +cxx_modes="-std=c++98 -std=gnu++98 -std=c++11 -std=gnu++11" + +# An exhaustive test of feature selection macros would take far too long. +# These are probably the most commonly used three. +lib_modes="-D_DEFAULT_SOURCE=1 -D_GNU_SOURCE=1 -D_XOPEN_SOURCE=700" + +# sys/types.h+bits/types.h have to define the obsolete types. +# rpc(svc)/* have the obsolete types too deeply embedded in their API +# to remove. +skip_obsolete_type_check='*/sys/types.h|*/bits/types.h|*/rpc/*|*/rpcsvc/*' +obsolete_type_re=\ +'\<((__)?(quad_t|u(short|int|long|_(char|short|int([0-9]+_t)?|long|quad_t))))\>' + +if [ $# -lt 3 ]; then + echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 + exit 2 +fi +case "$1" in + (c) + lang_modes="$c_modes" + cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.c) + already="$skip_obsolete_type_check" + ;; + (c++) + lang_modes="$cxx_modes" + cih_test_c=$(mktemp ${TMPDIR-/tmp}/cih_test_XXXXXX.cc) + # The obsolete-type check can be skipped for C++; it is + # sufficient to do it for C. + already="*" + ;; + (*) + echo "usage: $0 c|c++ \"compile command\" header header header..." >&2 + exit 2;; +esac +shift +cc_cmd="$1" +shift +trap "rm -f '$cih_test_c'" 0 + +failed=0 +is_x86_64=unknown +for header in "$@"; do + # Skip various headers for which this test gets a false failure. + case "$header" in + # bits/* are not meant to be included directly and usually #error + # out if you try it. + # regexp.h is a stub containing only an #error. + # Sun RPC's .x files are traditionally installed in + # $prefix/include/rpcsvc, but they are not C header files. + (bits/* | regexp.h | rpcsvc/*.x) + continue;; + + # sys/elf.h and sys/vm86.h are "unsupported on x86-64" and + # #error out on that target. + (sys/elf.h | sys/vm86.h) + case "$is_x86_64" in + (yes) continue;; + (no) ;; + (unknown) + cat >"$cih_test_c" < /dev/null 2>&1 + then + is_x86_64=no + else + is_x86_64=yes + continue + fi + ;; + esac + esac + + echo :: "$header" + for lang_mode in "" $lang_modes; do + for lib_mode in "" $lib_modes; do + echo :::: $lang_mode $lib_mode + if [ -z "$lib_mode" ]; then + expanded_lib_mode='/* default library mode */' + else + expanded_lib_mode=$(echo : $lib_mode | \ + sed 's/^: -D/#define /; s/=/ /') + fi + cat >"$cih_test_c" < +int avoid_empty_translation_unit; +EOF + if $cc_cmd -fsyntax-only $lang_mode "$cih_test_c" 2>&1 + then + includes=$($cc_cmd -fsyntax-only -H $lang_mode \ + "$cih_test_c" 2>&1 | sed -ne 's/^[.][.]* //p') + for h in $includes; do + # Don't repeat work. + eval 'case "$h" in ('"$already"') continue;; esac' + + if grep -qE "$obsolete_type_re" "$h"; then + echo "*** Obsolete types detected:" + grep -HE "$obsolete_type_re" "$h" + failed=1 + fi + already="$already|$h" + done + else + failed=1 + fi + done + done +done +exit $failed diff --git a/sysdeps/arm/nacl/include/bits/setjmp.h b/sysdeps/arm/nacl/include/bits/setjmp.h index 6b6a235871..e1fe5059a3 100644 --- a/sysdeps/arm/nacl/include/bits/setjmp.h +++ b/sysdeps/arm/nacl/include/bits/setjmp.h @@ -24,6 +24,8 @@ # include #endif +# ifndef _ISOMAC + /* Register list for a ldm/stm instruction to load/store the general registers from a __jmp_buf. @@ -35,4 +37,5 @@ /* Index of __jmp_buf where the sp register resides. */ #define __JMP_BUF_SP 0 +# endif /* _ISOMAC */ #endif /* include/bits/setjmp.h */ diff --git a/sysdeps/mips/include/sys/asm.h b/sysdeps/mips/include/sys/asm.h index 7e288df117..67acf74dc0 100644 --- a/sysdeps/mips/include/sys/asm.h +++ b/sysdeps/mips/include/sys/asm.h @@ -16,8 +16,9 @@ . */ #ifndef _SYS_ASM_H +#include_next -# include_next +# ifndef _ISOMAC # undef __mips_cfi_startproc # define __mips_cfi_startproc cfi_startproc @@ -50,4 +51,5 @@ cfi_restore (gp) # endif -#endif +# endif /* _ISOMAC */ +#endif /* sys/asm.h */ diff --git a/sysdeps/unix/sysv/linux/include/sys/sysinfo.h b/sysdeps/unix/sysv/linux/include/sys/sysinfo.h index 50077fb08c..b76f7e0d09 100644 --- a/sysdeps/unix/sysv/linux/include/sys/sysinfo.h +++ b/sysdeps/unix/sysv/linux/include/sys/sysinfo.h @@ -21,6 +21,9 @@ #include_next +# ifndef _ISOMAC + extern __typeof (sysinfo) __sysinfo __THROW; +# endif /* _ISOMAC */ #endif /* sys/sysinfo.h */ diff --git a/sysdeps/unix/sysv/linux/include/sys/timex.h b/sysdeps/unix/sysv/linux/include/sys/timex.h index ace90ee033..4b4ff88895 100644 --- a/sysdeps/unix/sysv/linux/include/sys/timex.h +++ b/sysdeps/unix/sysv/linux/include/sys/timex.h @@ -21,6 +21,9 @@ #include_next +# ifndef _ISOMAC + libc_hidden_proto (__adjtimex) +# endif /* _ISOMAC */ #endif /* sys/timex.h */ diff --git a/sysdeps/x86/fpu/include/bits/fenv.h b/sysdeps/x86/fpu/include/bits/fenv.h index 6e8b733f33..a410ed00d0 100644 --- a/sysdeps/x86/fpu/include/bits/fenv.h +++ b/sysdeps/x86/fpu/include/bits/fenv.h @@ -16,8 +16,11 @@ License along with the GNU C Library; if not, see . */ +#ifndef _BITS_FENV_H #include_next +# ifndef _ISOMAC + /* Ensure __feraiseexcept calls in glibc are optimized the same as feraiseexcept calls. */ @@ -40,3 +43,6 @@ __NTH (__feraiseexcept (int __excepts)) __END_DECLS #endif + +# endif /* _ISOMAC */ +#endif /* bits/fenv.h */ -- cgit v1.2.3 From e7eceec0bc34b520a66c688dc81a0b0d4e36610f Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 30 Dec 2016 18:43:04 +0100 Subject: resolv: Turn historic name lookup functions into compat symbols This change also removes the preprocessor-based function renaming. It also applied to tests in resolv/, which ended up running against the historic functions. _endhtent was not part of the ABI because it is not listed in the resolv/Versions file. --- ChangeLog | 18 + include/resolv.h | 1 - resolv/Makefile | 11 +- resolv/compat-gethnamaddr.c | 903 ++++++++++++++++++++++++++++++++++++++++++++ resolv/gethnamaddr.c | 890 ------------------------------------------- 5 files changed, 924 insertions(+), 899 deletions(-) create mode 100644 resolv/compat-gethnamaddr.c delete mode 100644 resolv/gethnamaddr.c (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index abb3696b44..233997cbe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2016-12-30 Florian Weimer + + * resolv/Makefile (libresolv-routines): Rename gethnamaddr to + compat-gethnamaddr. + (CPPFLAGS): Remove. + * resolv/gethnamaddr.c: Rename ... + * resolv/compat-gethnamaddr.c: ... to this file. + (_endhtent): Make static. + (res_gethostbyname): Renamed from gethostbyname. Turn into compat + symbol. + (res_gethostbyname2): Renamed from gethostbyname2. Turn into + compat symbol. + (res_gethostbyaddr): Renamed from gethostbyaddr. Turn into compat + symbol. + (_sethtent, _gethtent, _gethtbyname, gethtbyname2, _gethtbyaddr): + Turn into compat symbol. + * include/resolv.h (_endhtent): Remove declaration. + 2016-12-30 Joseph Myers * bits/types.h (__intmax_t): New typedef. diff --git a/include/resolv.h b/include/resolv.h index 699cc81569..95dcd3ca37 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -26,7 +26,6 @@ extern __thread struct __res_state *__resp attribute_tls_model_ie; extern int __res_vinit (res_state, int); extern int __res_maybe_init (res_state, int); extern void _sethtent (int); -extern void _endhtent (void); extern struct hostent *_gethtent (void); extern struct hostent *_gethtbyname (const char *__name); extern struct hostent *_gethtbyname2 (const char *__name, int __af); diff --git a/resolv/Makefile b/resolv/Makefile index 06329e1f5c..bd086e0e7d 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -42,11 +42,12 @@ routines += gai_sigqueue tests += tst-res_hconf_reorder endif extra-libs-others = $(extra-libs) -libresolv-routines := gethnamaddr res_comp res_debug \ +libresolv-routines := res_comp res_debug \ res_data res_mkquery res_query res_send \ inet_net_ntop inet_net_pton inet_neta base64 \ ns_parse ns_name ns_netint ns_ttl ns_print \ - ns_samedomain ns_date compat-hooks + ns_samedomain ns_date \ + compat-hooks compat-gethnamaddr libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ getaddrinfo_a @@ -84,12 +85,6 @@ generated += mtrace-tst-leaks.out tst-leaks.mtrace \ include ../Rules -CPPFLAGS += -Dgethostbyname=res_gethostbyname \ - -Dgethostbyname2=res_gethostbyname2 \ - -Dgethostbyaddr=res_gethostbyaddr \ - -Dgetnetbyname=res_getnetbyname \ - -Dgetnetbyaddr=res_getnetbyaddr - CFLAGS-res_hconf.c = -fexceptions # The DNS NSS modules needs the resolver. diff --git a/resolv/compat-gethnamaddr.c b/resolv/compat-gethnamaddr.c new file mode 100644 index 0000000000..6d2292b4cd --- /dev/null +++ b/resolv/compat-gethnamaddr.c @@ -0,0 +1,903 @@ +/* + * ++Copyright++ 1985, 1988, 1993 + * - + * Copyright (c) 1985, 1988, 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/* XXX This file is not used by any of the resolver functions implemented by + glibc (i.e. get*info and gethostby*). It cannot be removed however because + it exports symbols in the libresolv ABI. The file is not maintained any + more, nor are these functions. */ + +#include +#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_25) + +# include +# include +# include +# include +# include +# include + +# include +# include +# include +# include +# include +# include +# include + +# define MAXALIASES 35 +# define MAXADDRS 35 + +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 FILE *hostf = NULL; +static int stayopen = 0; + +static void map_v4v6_address (const char *src, char *dst) __THROW; +static void map_v4v6_hostent (struct hostent *hp, char **bp, int *len) __THROW; + +extern void addrsort (char **, int) __THROW; + +# if PACKETSZ > 65536 +# define MAXPACKET PACKETSZ +# else +# define MAXPACKET 65536 +# endif + +/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */ +# ifdef MAXHOSTNAMELEN +# undef MAXHOSTNAMELEN +# endif +# define MAXHOSTNAMELEN 256 + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + int32_t al; + char ac; +} align; + +# ifndef h_errno +extern int h_errno; +# endif + +# ifdef DEBUG +static void +Dprintf (char *msg, int num) +{ + if (_res.options & RES_DEBUG) { + int save = errno; + + printf(msg, num); + __set_errno (save); + } +} +# else +# define Dprintf(msg, num) /*nada*/ +# endif + +# define BOUNDED_INCR(x) \ + do { \ + cp += x; \ + if (cp > eom) { \ + __set_h_errno (NO_RECOVERY); \ + return (NULL); \ + } \ + } while (0) + +# define BOUNDS_CHECK(ptr, count) \ + do { \ + if ((ptr) + (count) > eom) { \ + __set_h_errno (NO_RECOVERY); \ + return (NULL); \ + } \ + } while (0) + + +static struct hostent * +getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) +{ + const HEADER *hp; + const u_char *cp; + int n; + const u_char *eom, *erdata; + char *bp, **ap, **hap; + int type, class, buflen, ancount, qdcount; + int haveanswer, had_error; + int toobig = 0; + char tbuf[MAXDNAME]; + const char *tname; + int (*name_ok) (const char *); + + tname = qname; + host.h_name = NULL; + eom = answer->buf + anslen; + switch (qtype) { + case T_A: + case T_AAAA: + name_ok = res_hnok; + break; + case T_PTR: + name_ok = res_dnok; + break; + default: + return (NULL); /* XXX should be abort(); */ + } + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = hostbuf; + buflen = sizeof hostbuf; + cp = answer->buf; + BOUNDED_INCR(HFIXEDSZ); + if (qdcount != 1) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !(*name_ok)(bp)) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + BOUNDED_INCR(n + QFIXEDSZ); + if (qtype == T_A || qtype == T_AAAA) { + /* res_send() has already verified that the query name is the + * same as the one we sent; this just gets the expanded name + * (i.e., with the succeeding search-domain tacked on). + */ + n = strlen(bp) + 1; /* for the \0 */ + if (n >= MAXHOSTNAMELEN) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + host.h_name = bp; + bp += n; + buflen -= n; + /* The qname can be abbreviated, but h_name is now absolute. */ + qname = host.h_name; + } + ap = host_aliases; + *ap = NULL; + host.h_aliases = host_aliases; + hap = h_addr_ptrs; + *hap = NULL; + host.h_addr_list = h_addr_ptrs; + haveanswer = 0; + had_error = 0; + while (ancount-- > 0 && cp < eom && !had_error) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !(*name_ok)(bp)) { + had_error++; + continue; + } + cp += n; /* name */ + BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); + type = ns_get16(cp); + cp += INT16SZ; /* type */ + class = ns_get16(cp); + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = ns_get16(cp); + cp += INT16SZ; /* len */ + BOUNDS_CHECK(cp, n); + erdata = cp + n; + if (class != C_IN) { + /* XXX - debug? syslog? */ + cp += n; + continue; /* XXX - had_error++ ? */ + } + if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { + if (ap >= &host_aliases[MAXALIASES-1]) + continue; + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if ((n < 0) || !(*name_ok)(tbuf)) { + had_error++; + continue; + } + cp += n; + if (cp != erdata) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + /* Store alias. */ + *ap++ = bp; + n = strlen(bp) + 1; /* for the \0 */ + if (n >= MAXHOSTNAMELEN) { + had_error++; + continue; + } + bp += n; + buflen -= n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen || n >= MAXHOSTNAMELEN) { + had_error++; + continue; + } + strcpy(bp, tbuf); + host.h_name = bp; + bp += n; + buflen -= n; + continue; + } + if (qtype == T_PTR && type == T_CNAME) { + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if (n < 0 || !res_dnok(tbuf)) { + had_error++; + continue; + } + cp += n; + if (cp != erdata) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen || n >= MAXHOSTNAMELEN) { + had_error++; + continue; + } + strcpy(bp, tbuf); + tname = bp; + bp += n; + buflen -= n; + continue; + } + if (type != qtype) { + /* Log a low priority message if we get an unexpected + * record, but skip it if we are using DNSSEC since it + * uses many different types in responses that do not + * match QTYPE. + */ + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(tname, bp) != 0) { + cp += n; + continue; /* XXX - had_error++ ? */ + } + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !res_hnok(bp)) { + had_error++; + break; + } + cp += n; + if (cp != erdata) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + if (!haveanswer) + host.h_name = bp; + else if (ap < &host_aliases[MAXALIASES-1]) + *ap++ = bp; + else + n = -1; + if (n != -1) { + n = strlen(bp) + 1; /* for the \0 */ + if (n >= MAXHOSTNAMELEN) { + had_error++; + break; + } + bp += n; + buflen -= n; + } + break; + case T_A: + case T_AAAA: + if (strcasecmp(host.h_name, bp) != 0) { + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (n != host.h_length) { + cp += n; + continue; + } + if (!haveanswer) { + int nn; + + host.h_name = bp; + nn = strlen(bp) + 1; /* for the \0 */ + bp += nn; + buflen -= nn; + } + + /* XXX: when incrementing bp, we have to decrement + * buflen by the same amount --okir */ + buflen -= sizeof(align) - ((u_long)bp % sizeof(align)); + + bp += sizeof(align) - ((u_long)bp % sizeof(align)); + + if (bp + n >= &hostbuf[sizeof hostbuf]) { + Dprintf("size (%d) too big\n", n); + had_error++; + continue; + } + if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (!toobig++) { + Dprintf("Too many addresses (%d)\n", + MAXADDRS); + } + cp += n; + continue; + } + memmove(*hap++ = bp, cp, n); + bp += n; + buflen -= n; + cp += n; + if (cp != erdata) { + __set_h_errno (NO_RECOVERY); + return (NULL); + } + break; + default: + abort(); + } + if (!had_error) + haveanswer++; + } + if (haveanswer) { + *ap = NULL; + *hap = NULL; + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" + * address in that case, not some random one + */ + if (_res.nsort && haveanswer > 1 && qtype == T_A) + addrsort(h_addr_ptrs, haveanswer); + if (!host.h_name) { + n = strlen(qname) + 1; /* for the \0 */ + if (n > buflen || n >= MAXHOSTNAMELEN) + goto no_recovery; + strcpy(bp, qname); + host.h_name = bp; + bp += n; + buflen -= n; + } + if (_res.options & RES_USE_INET6) + map_v4v6_hostent(&host, &bp, &buflen); + __set_h_errno (NETDB_SUCCESS); + return (&host); + } + no_recovery: + __set_h_errno (NO_RECOVERY); + return (NULL); +} + +extern struct hostent *res_gethostbyname2(const char *name, int af); +libresolv_hidden_proto (res_gethostbyname2) + +struct hostent * +res_gethostbyname (const char *name) +{ + struct hostent *hp; + + if (__res_maybe_init (&_res, 0) == -1) { + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + if (_res.options & RES_USE_INET6) { + hp = res_gethostbyname2(name, AF_INET6); + if (hp) + return (hp); + } + return (res_gethostbyname2(name, AF_INET)); +} +compat_symbol (libresolv, res_gethostbyname, res_gethostbyname, GLIBC_2_0); + +struct hostent * +res_gethostbyname2 (const char *name, int af) +{ + union + { + querybuf *buf; + u_char *ptr; + } buf; + querybuf *origbuf; + const char *cp; + char *bp; + int n, size, type, len; + struct hostent *ret; + + if (__res_maybe_init (&_res, 0) == -1) { + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + + switch (af) { + case AF_INET: + size = INADDRSZ; + type = T_A; + break; + case AF_INET6: + size = IN6ADDRSZ; + type = T_AAAA; + break; + default: + __set_h_errno (NETDB_INTERNAL); + __set_errno (EAFNOSUPPORT); + return (NULL); + } + + 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))) + name = cp; + + /* + * disallow names consisting only of digits/dots, unless + * they end in a dot. + */ + if (isdigit(name[0])) + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-numeric, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_pton(af, name, host_addr) <= 0) { + __set_h_errno (HOST_NOT_FOUND); + return (NULL); + } + 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; + if (_res.options & RES_USE_INET6) + map_v4v6_hostent(&host, &bp, &len); + __set_h_errno (NETDB_SUCCESS); + return (&host); + } + if (!isdigit(*cp) && *cp != '.') + break; + } + if ((isxdigit(name[0]) && strchr(name, ':') != NULL) || + name[0] == ':') + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-IPv6-legal, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_pton(af, name, host_addr) <= 0) { + __set_h_errno (HOST_NOT_FOUND); + return (NULL); + } + 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; + __set_h_errno (NETDB_SUCCESS); + return (&host); + } + if (!isxdigit(*cp) && *cp != ':' && *cp != '.') + break; + } + + buf.buf = origbuf = (querybuf *) alloca (1024); + + if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, + &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { + if (buf.buf != origbuf) + free (buf.buf); + Dprintf("res_nsearch failed (%d)\n", n); + if (errno == ECONNREFUSED) + return (_gethtbyname2(name, af)); + return (NULL); + } + ret = getanswer(buf.buf, n, name, type); + if (buf.buf != origbuf) + free (buf.buf); + return ret; +} +libresolv_hidden_def (res_gethostbyname2) +compat_symbol (libresolv, res_gethostbyname2, res_gethostbyname2, GLIBC_2_0); + +struct hostent * +res_gethostbyaddr (const void *addr, socklen_t len, int af) +{ + const u_char *uaddr = (const u_char *)addr; + 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 }; + int n; + socklen_t size; + union + { + querybuf *buf; + u_char *ptr; + } buf; + querybuf *orig_buf; + struct hostent *hp; + char qbuf[MAXDNAME+1], *qp = NULL; + + if (__res_maybe_init (&_res, 0) == -1) { + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + if (af == AF_INET6 && len == IN6ADDRSZ && + (!memcmp(uaddr, mapped, sizeof mapped) || + !memcmp(uaddr, tunnelled, sizeof tunnelled))) { + /* Unmap. */ + addr += sizeof mapped; + uaddr += sizeof mapped; + af = AF_INET; + len = INADDRSZ; + } + switch (af) { + case AF_INET: + size = INADDRSZ; + break; + case AF_INET6: + size = IN6ADDRSZ; + break; + default: + __set_errno (EAFNOSUPPORT); + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + if (size != len) { + __set_errno (EINVAL); + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + switch (af) { + case AF_INET: + (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", + (uaddr[3] & 0xff), + (uaddr[2] & 0xff), + (uaddr[1] & 0xff), + (uaddr[0] & 0xff)); + break; + case AF_INET6: + qp = qbuf; + for (n = IN6ADDRSZ - 1; n >= 0; n--) { + qp += sprintf(qp, "%x.%x.", + uaddr[n] & 0xf, + (uaddr[n] >> 4) & 0xf); + } + strcpy(qp, "ip6.arpa"); + break; + default: + abort(); + } + + buf.buf = orig_buf = (querybuf *) alloca (1024); + + n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, + &buf.ptr, NULL, NULL, NULL, NULL); + if (n < 0) { + if (buf.buf != orig_buf) + free (buf.buf); + Dprintf("res_nquery failed (%d)\n", n); + if (errno == ECONNREFUSED) + return (_gethtbyaddr(addr, len, af)); + return (NULL); + } + hp = getanswer(buf.buf, n, qbuf, T_PTR); + if (buf.buf != orig_buf) + free (buf.buf); + if (!hp) + return (NULL); /* h_errno was set by getanswer() */ + hp->h_addrtype = af; + hp->h_length = len; + memmove(host_addr, addr, len); + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[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; + hp->h_length = IN6ADDRSZ; + } + __set_h_errno (NETDB_SUCCESS); + return (hp); +} +compat_symbol (libresolv, res_gethostbyaddr, res_gethostbyaddr, GLIBC_2_0); + +void +_sethtent (int f) +{ + if (!hostf) + hostf = fopen(_PATH_HOSTS, "rce" ); + else + rewind(hostf); + stayopen = f; +} +libresolv_hidden_def (_sethtent) +compat_symbol (libresolv, _sethtent, _sethtent, GLIBC_2_0); + +static void +_endhtent (void) +{ + if (hostf && !stayopen) { + (void) fclose(hostf); + hostf = NULL; + } +} + +struct hostent * +_gethtent (void) +{ + char *p; + char *cp, **q; + int af, len; + + if (!hostf && !(hostf = fopen(_PATH_HOSTS, "rce" ))) { + __set_h_errno (NETDB_INTERNAL); + return (NULL); + } + again: + if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + __set_h_errno (HOST_NOT_FOUND); + return (NULL); + } + if (*p == '#') + goto again; + if (!(cp = strpbrk(p, "#\n"))) + goto again; + *cp = '\0'; + if (!(cp = strpbrk(p, " \t"))) + goto again; + *cp++ = '\0'; + if (inet_pton(AF_INET6, p, host_addr) > 0) { + af = AF_INET6; + len = IN6ADDRSZ; + } else if (inet_pton(AF_INET, p, host_addr) > 0) { + if (_res.options & RES_USE_INET6) { + map_v4v6_address((char*)host_addr, (char*)host_addr); + af = AF_INET6; + len = IN6ADDRSZ; + } else { + af = AF_INET; + len = INADDRSZ; + } + } 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; + while (*cp == ' ' || *cp == '\t') + cp++; + host.h_name = cp; + q = host.h_aliases = host_aliases; + if ((cp = strpbrk(cp, " \t"))) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &host_aliases[MAXALIASES - 1]) + *q++ = cp; + if ((cp = strpbrk(cp, " \t"))) + *cp++ = '\0'; + } + *q = NULL; + __set_h_errno (NETDB_SUCCESS); + return (&host); +} +libresolv_hidden_def (_gethtent) +compat_symbol (libresolv, _gethtent, _gethtent, GLIBC_2_0); + +struct hostent * +_gethtbyname (const char *name) +{ + struct hostent *hp; + + if (_res.options & RES_USE_INET6) { + hp = _gethtbyname2(name, AF_INET6); + if (hp) + return (hp); + } + return (_gethtbyname2(name, AF_INET)); +} +compat_symbol (libresolv, _gethtbyname, _gethtbyname, GLIBC_2_0); + +struct hostent * +_gethtbyname2 (const char *name, int af) +{ + struct hostent *p; + char **cp; + + _sethtent(0); + while ((p = _gethtent())) { + if (p->h_addrtype != af) + continue; + if (strcasecmp(p->h_name, name) == 0) + break; + for (cp = p->h_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } + found: + _endhtent(); + return (p); +} +libresolv_hidden_def (_gethtbyname2) +compat_symbol (libresolv, _gethtbyname2, _gethtbyname2, GLIBC_2_0); + +struct hostent * +_gethtbyaddr (const char *addr, size_t len, int af) +{ + struct hostent *p; + + _sethtent(0); + while ((p = _gethtent())) + if (p->h_addrtype == af && !memcmp(p->h_addr, addr, len)) + break; + _endhtent(); + return (p); +} +libresolv_hidden_def (_gethtbyaddr) +compat_symbol (libresolv, _gethtbyaddr, _gethtbyaddr, GLIBC_2_0); + +static void +map_v4v6_address (const char *src, char *dst) +{ + u_char *p = (u_char *)dst; + char tmp[INADDRSZ]; + int i; + + /* Stash a temporary copy so our caller can update in place. */ + memcpy(tmp, src, INADDRSZ); + /* Mark this ipv6 addr as a mapped ipv4. */ + for (i = 0; i < 10; i++) + *p++ = 0x00; + *p++ = 0xff; + *p++ = 0xff; + /* Retrieve the saved copy and we're done. */ + memcpy((void*)p, tmp, INADDRSZ); +} + +static void +map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) +{ + char **ap; + + if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) + return; + hp->h_addrtype = AF_INET6; + hp->h_length = IN6ADDRSZ; + for (ap = hp->h_addr_list; *ap; ap++) { + int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); + + if (*lenp < (i + IN6ADDRSZ)) { + /* Out of memory. Truncate address list here. XXX */ + *ap = NULL; + return; + } + *bpp += i; + *lenp -= i; + map_v4v6_address(*ap, *bpp); + *ap = *bpp; + *bpp += IN6ADDRSZ; + *lenp -= IN6ADDRSZ; + } +} + +extern void +addrsort (char **ap, int num) +{ + int i, j; + char **p; + short aval[MAXADDRS]; + int needsort = 0; + + p = ap; + for (i = 0; i < num; i++, p++) { + for (j = 0 ; (unsigned)j < _res.nsort; j++) + if (_res.sort_list[j].addr.s_addr == + (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) + break; + aval[i] = j; + if (needsort == 0 && i > 0 && j < aval[i-1]) + needsort = i; + } + if (!needsort) + return; + + while (needsort < num) { + for (j = needsort - 1; j >= 0; j--) { + if (aval[j] > aval[j+1]) { + char *hp; + + i = aval[j]; + aval[j] = aval[j+1]; + aval[j+1] = i; + + hp = ap[j]; + ap[j] = ap[j+1]; + ap[j+1] = hp; + + } else + break; + } + needsort++; + } +} + +#endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25) */ diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c deleted file mode 100644 index 1b81ca840e..0000000000 --- a/resolv/gethnamaddr.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * ++Copyright++ 1985, 1988, 1993 - * - - * Copyright (c) 1985, 1988, 1993 - * The Regents of the University of California. 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* XXX This file is not used by any of the resolver functions implemented by - glibc (i.e. get*info and gethostby*). It cannot be removed however because - it exports symbols in the libresolv ABI. The file is not maintained any - more, nor are these functions. */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MAXALIASES 35 -#define MAXADDRS 35 - -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 FILE *hostf = NULL; -static int stayopen = 0; - -static void map_v4v6_address (const char *src, char *dst) __THROW; -static void map_v4v6_hostent (struct hostent *hp, char **bp, int *len) __THROW; - -extern void addrsort (char **, int) __THROW; - -#if PACKETSZ > 65536 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 65536 -#endif - -/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */ -#ifdef MAXHOSTNAMELEN -# undef MAXHOSTNAMELEN -#endif -#define MAXHOSTNAMELEN 256 - -typedef union { - HEADER hdr; - u_char buf[MAXPACKET]; -} querybuf; - -typedef union { - int32_t al; - char ac; -} align; - -#ifndef h_errno -extern int h_errno; -#endif - -#ifdef DEBUG -static void -Dprintf (char *msg, int num) -{ - if (_res.options & RES_DEBUG) { - int save = errno; - - printf(msg, num); - __set_errno (save); - } -} -#else -# define Dprintf(msg, num) /*nada*/ -#endif - -#define BOUNDED_INCR(x) \ - do { \ - cp += x; \ - if (cp > eom) { \ - __set_h_errno (NO_RECOVERY); \ - return (NULL); \ - } \ - } while (0) - -#define BOUNDS_CHECK(ptr, count) \ - do { \ - if ((ptr) + (count) > eom) { \ - __set_h_errno (NO_RECOVERY); \ - return (NULL); \ - } \ - } while (0) - - -static struct hostent * -getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) -{ - const HEADER *hp; - const u_char *cp; - int n; - const u_char *eom, *erdata; - char *bp, **ap, **hap; - int type, class, buflen, ancount, qdcount; - int haveanswer, had_error; - int toobig = 0; - char tbuf[MAXDNAME]; - const char *tname; - int (*name_ok) (const char *); - - tname = qname; - host.h_name = NULL; - eom = answer->buf + anslen; - switch (qtype) { - case T_A: - case T_AAAA: - name_ok = res_hnok; - break; - case T_PTR: - name_ok = res_dnok; - break; - default: - return (NULL); /* XXX should be abort(); */ - } - /* - * find first satisfactory answer - */ - hp = &answer->hdr; - ancount = ntohs(hp->ancount); - qdcount = ntohs(hp->qdcount); - bp = hostbuf; - buflen = sizeof hostbuf; - cp = answer->buf; - BOUNDED_INCR(HFIXEDSZ); - if (qdcount != 1) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - n = dn_expand(answer->buf, eom, cp, bp, buflen); - if ((n < 0) || !(*name_ok)(bp)) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - BOUNDED_INCR(n + QFIXEDSZ); - if (qtype == T_A || qtype == T_AAAA) { - /* res_send() has already verified that the query name is the - * same as the one we sent; this just gets the expanded name - * (i.e., with the succeeding search-domain tacked on). - */ - n = strlen(bp) + 1; /* for the \0 */ - if (n >= MAXHOSTNAMELEN) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - host.h_name = bp; - bp += n; - buflen -= n; - /* The qname can be abbreviated, but h_name is now absolute. */ - qname = host.h_name; - } - ap = host_aliases; - *ap = NULL; - host.h_aliases = host_aliases; - hap = h_addr_ptrs; - *hap = NULL; - host.h_addr_list = h_addr_ptrs; - haveanswer = 0; - had_error = 0; - while (ancount-- > 0 && cp < eom && !had_error) { - n = dn_expand(answer->buf, eom, cp, bp, buflen); - if ((n < 0) || !(*name_ok)(bp)) { - had_error++; - continue; - } - cp += n; /* name */ - BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); - type = ns_get16(cp); - cp += INT16SZ; /* type */ - class = ns_get16(cp); - cp += INT16SZ + INT32SZ; /* class, TTL */ - n = ns_get16(cp); - cp += INT16SZ; /* len */ - BOUNDS_CHECK(cp, n); - erdata = cp + n; - if (class != C_IN) { - /* XXX - debug? syslog? */ - cp += n; - continue; /* XXX - had_error++ ? */ - } - if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { - if (ap >= &host_aliases[MAXALIASES-1]) - continue; - n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); - if ((n < 0) || !(*name_ok)(tbuf)) { - had_error++; - continue; - } - cp += n; - if (cp != erdata) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - /* Store alias. */ - *ap++ = bp; - n = strlen(bp) + 1; /* for the \0 */ - if (n >= MAXHOSTNAMELEN) { - had_error++; - continue; - } - bp += n; - buflen -= n; - /* Get canonical name. */ - n = strlen(tbuf) + 1; /* for the \0 */ - if (n > buflen || n >= MAXHOSTNAMELEN) { - had_error++; - continue; - } - strcpy(bp, tbuf); - host.h_name = bp; - bp += n; - buflen -= n; - continue; - } - if (qtype == T_PTR && type == T_CNAME) { - n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); - if (n < 0 || !res_dnok(tbuf)) { - had_error++; - continue; - } - cp += n; - if (cp != erdata) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - /* Get canonical name. */ - n = strlen(tbuf) + 1; /* for the \0 */ - if (n > buflen || n >= MAXHOSTNAMELEN) { - had_error++; - continue; - } - strcpy(bp, tbuf); - tname = bp; - bp += n; - buflen -= n; - continue; - } - if (type != qtype) { - /* Log a low priority message if we get an unexpected - * record, but skip it if we are using DNSSEC since it - * uses many different types in responses that do not - * match QTYPE. - */ - cp += n; - continue; /* XXX - had_error++ ? */ - } - switch (type) { - case T_PTR: - if (strcasecmp(tname, bp) != 0) { - cp += n; - continue; /* XXX - had_error++ ? */ - } - n = dn_expand(answer->buf, eom, cp, bp, buflen); - if ((n < 0) || !res_hnok(bp)) { - had_error++; - break; - } - cp += n; - if (cp != erdata) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - if (!haveanswer) - host.h_name = bp; - else if (ap < &host_aliases[MAXALIASES-1]) - *ap++ = bp; - else - n = -1; - if (n != -1) { - n = strlen(bp) + 1; /* for the \0 */ - if (n >= MAXHOSTNAMELEN) { - had_error++; - break; - } - bp += n; - buflen -= n; - } - break; - case T_A: - case T_AAAA: - if (strcasecmp(host.h_name, bp) != 0) { - cp += n; - continue; /* XXX - had_error++ ? */ - } - if (n != host.h_length) { - cp += n; - continue; - } - if (!haveanswer) { - int nn; - - host.h_name = bp; - nn = strlen(bp) + 1; /* for the \0 */ - bp += nn; - buflen -= nn; - } - - /* XXX: when incrementing bp, we have to decrement - * buflen by the same amount --okir */ - buflen -= sizeof(align) - ((u_long)bp % sizeof(align)); - - bp += sizeof(align) - ((u_long)bp % sizeof(align)); - - if (bp + n >= &hostbuf[sizeof hostbuf]) { - Dprintf("size (%d) too big\n", n); - had_error++; - continue; - } - if (hap >= &h_addr_ptrs[MAXADDRS-1]) { - if (!toobig++) { - Dprintf("Too many addresses (%d)\n", - MAXADDRS); - } - cp += n; - continue; - } - memmove(*hap++ = bp, cp, n); - bp += n; - buflen -= n; - cp += n; - if (cp != erdata) { - __set_h_errno (NO_RECOVERY); - return (NULL); - } - break; - default: - abort(); - } - if (!had_error) - haveanswer++; - } - if (haveanswer) { - *ap = NULL; - *hap = NULL; - /* - * Note: we sort even if host can take only one address - * in its return structures - should give it the "best" - * address in that case, not some random one - */ - if (_res.nsort && haveanswer > 1 && qtype == T_A) - addrsort(h_addr_ptrs, haveanswer); - if (!host.h_name) { - n = strlen(qname) + 1; /* for the \0 */ - if (n > buflen || n >= MAXHOSTNAMELEN) - goto no_recovery; - strcpy(bp, qname); - host.h_name = bp; - bp += n; - buflen -= n; - } - if (_res.options & RES_USE_INET6) - map_v4v6_hostent(&host, &bp, &buflen); - __set_h_errno (NETDB_SUCCESS); - return (&host); - } - no_recovery: - __set_h_errno (NO_RECOVERY); - return (NULL); -} - -extern struct hostent *gethostbyname2(const char *name, int af); -libresolv_hidden_proto (gethostbyname2) - -struct hostent * -gethostbyname (const char *name) -{ - struct hostent *hp; - - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - if (_res.options & RES_USE_INET6) { - hp = gethostbyname2(name, AF_INET6); - if (hp) - return (hp); - } - return (gethostbyname2(name, AF_INET)); -} - -struct hostent * -gethostbyname2 (const char *name, int af) -{ - union - { - querybuf *buf; - u_char *ptr; - } buf; - querybuf *origbuf; - const char *cp; - char *bp; - int n, size, type, len; - struct hostent *ret; - - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - - switch (af) { - case AF_INET: - size = INADDRSZ; - type = T_A; - break; - case AF_INET6: - size = IN6ADDRSZ; - type = T_AAAA; - break; - default: - __set_h_errno (NETDB_INTERNAL); - __set_errno (EAFNOSUPPORT); - return (NULL); - } - - 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))) - name = cp; - - /* - * disallow names consisting only of digits/dots, unless - * they end in a dot. - */ - if (isdigit(name[0])) - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-numeric, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (inet_pton(af, name, host_addr) <= 0) { - __set_h_errno (HOST_NOT_FOUND); - return (NULL); - } - 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; - if (_res.options & RES_USE_INET6) - map_v4v6_hostent(&host, &bp, &len); - __set_h_errno (NETDB_SUCCESS); - return (&host); - } - if (!isdigit(*cp) && *cp != '.') - break; - } - if ((isxdigit(name[0]) && strchr(name, ':') != NULL) || - name[0] == ':') - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-IPv6-legal, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (inet_pton(af, name, host_addr) <= 0) { - __set_h_errno (HOST_NOT_FOUND); - return (NULL); - } - 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; - __set_h_errno (NETDB_SUCCESS); - return (&host); - } - if (!isxdigit(*cp) && *cp != ':' && *cp != '.') - break; - } - - buf.buf = origbuf = (querybuf *) alloca (1024); - - if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, - &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { - if (buf.buf != origbuf) - free (buf.buf); - Dprintf("res_nsearch failed (%d)\n", n); - if (errno == ECONNREFUSED) - return (_gethtbyname2(name, af)); - return (NULL); - } - ret = getanswer(buf.buf, n, name, type); - if (buf.buf != origbuf) - free (buf.buf); - return ret; -} -libresolv_hidden_def (gethostbyname2) - -struct hostent * -gethostbyaddr (const void *addr, socklen_t len, int af) -{ - const u_char *uaddr = (const u_char *)addr; - 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 }; - int n; - socklen_t size; - union - { - querybuf *buf; - u_char *ptr; - } buf; - querybuf *orig_buf; - struct hostent *hp; - char qbuf[MAXDNAME+1], *qp = NULL; - - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - if (af == AF_INET6 && len == IN6ADDRSZ && - (!memcmp(uaddr, mapped, sizeof mapped) || - !memcmp(uaddr, tunnelled, sizeof tunnelled))) { - /* Unmap. */ - addr += sizeof mapped; - uaddr += sizeof mapped; - af = AF_INET; - len = INADDRSZ; - } - switch (af) { - case AF_INET: - size = INADDRSZ; - break; - case AF_INET6: - size = IN6ADDRSZ; - break; - default: - __set_errno (EAFNOSUPPORT); - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - if (size != len) { - __set_errno (EINVAL); - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - switch (af) { - case AF_INET: - (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", - (uaddr[3] & 0xff), - (uaddr[2] & 0xff), - (uaddr[1] & 0xff), - (uaddr[0] & 0xff)); - break; - case AF_INET6: - qp = qbuf; - for (n = IN6ADDRSZ - 1; n >= 0; n--) { - qp += sprintf(qp, "%x.%x.", - uaddr[n] & 0xf, - (uaddr[n] >> 4) & 0xf); - } - strcpy(qp, "ip6.arpa"); - break; - default: - abort(); - } - - buf.buf = orig_buf = (querybuf *) alloca (1024); - - n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, - &buf.ptr, NULL, NULL, NULL, NULL); - if (n < 0) { - if (buf.buf != orig_buf) - free (buf.buf); - Dprintf("res_nquery failed (%d)\n", n); - if (errno == ECONNREFUSED) - return (_gethtbyaddr(addr, len, af)); - return (NULL); - } - hp = getanswer(buf.buf, n, qbuf, T_PTR); - if (buf.buf != orig_buf) - free (buf.buf); - if (!hp) - return (NULL); /* h_errno was set by getanswer() */ - hp->h_addrtype = af; - hp->h_length = len; - memmove(host_addr, addr, len); - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[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; - hp->h_length = IN6ADDRSZ; - } - __set_h_errno (NETDB_SUCCESS); - return (hp); -} - -void -_sethtent (int f) -{ - if (!hostf) - hostf = fopen(_PATH_HOSTS, "rce" ); - else - rewind(hostf); - stayopen = f; -} -libresolv_hidden_def (_sethtent) - -void -_endhtent (void) -{ - if (hostf && !stayopen) { - (void) fclose(hostf); - hostf = NULL; - } -} - -struct hostent * -_gethtent (void) -{ - char *p; - char *cp, **q; - int af, len; - - if (!hostf && !(hostf = fopen(_PATH_HOSTS, "rce" ))) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - again: - if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { - __set_h_errno (HOST_NOT_FOUND); - return (NULL); - } - if (*p == '#') - goto again; - if (!(cp = strpbrk(p, "#\n"))) - goto again; - *cp = '\0'; - if (!(cp = strpbrk(p, " \t"))) - goto again; - *cp++ = '\0'; - if (inet_pton(AF_INET6, p, host_addr) > 0) { - af = AF_INET6; - len = IN6ADDRSZ; - } else if (inet_pton(AF_INET, p, host_addr) > 0) { - if (_res.options & RES_USE_INET6) { - map_v4v6_address((char*)host_addr, (char*)host_addr); - af = AF_INET6; - len = IN6ADDRSZ; - } else { - af = AF_INET; - len = INADDRSZ; - } - } 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; - while (*cp == ' ' || *cp == '\t') - cp++; - host.h_name = cp; - q = host.h_aliases = host_aliases; - if ((cp = strpbrk(cp, " \t"))) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < &host_aliases[MAXALIASES - 1]) - *q++ = cp; - if ((cp = strpbrk(cp, " \t"))) - *cp++ = '\0'; - } - *q = NULL; - __set_h_errno (NETDB_SUCCESS); - return (&host); -} -libresolv_hidden_def (_gethtent) - -struct hostent * -_gethtbyname (const char *name) -{ - struct hostent *hp; - - if (_res.options & RES_USE_INET6) { - hp = _gethtbyname2(name, AF_INET6); - if (hp) - return (hp); - } - return (_gethtbyname2(name, AF_INET)); -} - -struct hostent * -_gethtbyname2 (const char *name, int af) -{ - struct hostent *p; - char **cp; - - _sethtent(0); - while ((p = _gethtent())) { - if (p->h_addrtype != af) - continue; - if (strcasecmp(p->h_name, name) == 0) - break; - for (cp = p->h_aliases; *cp != 0; cp++) - if (strcasecmp(*cp, name) == 0) - goto found; - } - found: - _endhtent(); - return (p); -} -libresolv_hidden_def (_gethtbyname2) - -struct hostent * -_gethtbyaddr (const char *addr, size_t len, int af) -{ - struct hostent *p; - - _sethtent(0); - while ((p = _gethtent())) - if (p->h_addrtype == af && !memcmp(p->h_addr, addr, len)) - break; - _endhtent(); - return (p); -} -libresolv_hidden_def (_gethtbyaddr) - -static void -map_v4v6_address (const char *src, char *dst) -{ - u_char *p = (u_char *)dst; - char tmp[INADDRSZ]; - int i; - - /* Stash a temporary copy so our caller can update in place. */ - memcpy(tmp, src, INADDRSZ); - /* Mark this ipv6 addr as a mapped ipv4. */ - for (i = 0; i < 10; i++) - *p++ = 0x00; - *p++ = 0xff; - *p++ = 0xff; - /* Retrieve the saved copy and we're done. */ - memcpy((void*)p, tmp, INADDRSZ); -} - -static void -map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) -{ - char **ap; - - if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) - return; - hp->h_addrtype = AF_INET6; - hp->h_length = IN6ADDRSZ; - for (ap = hp->h_addr_list; *ap; ap++) { - int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); - - if (*lenp < (i + IN6ADDRSZ)) { - /* Out of memory. Truncate address list here. XXX */ - *ap = NULL; - return; - } - *bpp += i; - *lenp -= i; - map_v4v6_address(*ap, *bpp); - *ap = *bpp; - *bpp += IN6ADDRSZ; - *lenp -= IN6ADDRSZ; - } -} - -extern void -addrsort (char **ap, int num) -{ - int i, j; - char **p; - short aval[MAXADDRS]; - int needsort = 0; - - p = ap; - for (i = 0; i < num; i++, p++) { - for (j = 0 ; (unsigned)j < _res.nsort; j++) - if (_res.sort_list[j].addr.s_addr == - (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) - break; - aval[i] = j; - if (needsort == 0 && i > 0 && j < aval[i-1]) - needsort = i; - } - if (!needsort) - return; - - while (needsort < num) { - for (j = needsort - 1; j >= 0; j--) { - if (aval[j] > aval[j+1]) { - char *hp; - - i = aval[j]; - aval[j] = aval[j+1]; - aval[j+1] = i; - - hp = ap[j]; - ap[j] = ap[j+1]; - ap[j+1] = hp; - - } else - break; - } - needsort++; - } -} -- cgit v1.2.3 From e14a27723cc3a154d67f3f26e719d08c0ba9ad25 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 13 Apr 2017 13:09:38 +0200 Subject: resolv: Reduce EDNS payload size to 1200 bytes [BZ #21361] This hardens the stub resolver against fragmentation-based attacks. --- ChangeLog | 21 ++ NEWS | 3 +- include/resolv.h | 3 - resolv/Makefile | 2 + resolv/res_mkquery.c | 28 ++- resolv/res_query.c | 23 ++- resolv/resolv-internal.h | 18 ++ resolv/tst-resolv-edns.c | 501 +++++++++++++++++++++++++++++++++++++++++++++++ support/resolv_test.c | 56 +++++- support/resolv_test.h | 11 ++ 10 files changed, 652 insertions(+), 14 deletions(-) create mode 100644 resolv/tst-resolv-edns.c (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index 2cdf82cc7e..1cd7a7b48a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2017-04-13 Florian Weimer + + [BZ #21361] + Limit EDNS buffer size to 1200 bytes. + * include/resolv.h (__res_nopt): Remove declaration. + * resolv/Makefile (tests): tst-resolv-edns. + (tst-resolv-edns): Link with -lresolv, -lpthread. + * resolv/res_mkquery.c (__res_ntop): Limit EDNS buffer size to the + interval [512, 1200]. + * resolv/res_query.c (__libc_res_nquery): Use 1200 buffer size if + we can resize the buffer. + * resolv/resolv-internal.h (RESOLV_EDNS_BUFFER_SIZE): Define. + (__res_nopt): Declare. + * resolv/tst-resolv-edns.c: New file. + * resolv/resolv_test.h (struct resolv_edns_info): Define. + (struct resolv_response_context): Add edns member. + * resolv/resolv_test.c (struct query_info): Add edns member. + (parse_query): Extract EDNS information from the query. + (server_thread_udp_process_one): Propagate EDNS data. + (server_thread_tcp_client): Likewise. + 2017-04-13 Florian Weimer [BZ #21359] diff --git a/NEWS b/NEWS index 28bb00887a..99288b5f22 100644 --- a/NEWS +++ b/NEWS @@ -46,7 +46,8 @@ Version 2.26 Security related changes: - [Add security related changes here] +* The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes, + to avoid fragmentation-based spoofing attacks. The following bugs are resolved with this release: diff --git a/include/resolv.h b/include/resolv.h index 95dcd3ca37..e8f477cd86 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -37,8 +37,6 @@ extern void res_pquery (const res_state __statp, const unsigned char *__msg, extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); extern void __res_iclose (res_state statp, bool free_addr); -extern int __res_nopt(res_state statp, int n0, unsigned char *buf, int buflen, - int anslen); libc_hidden_proto (__res_ninit) libc_hidden_proto (__res_maybe_init) libc_hidden_proto (__res_nclose) @@ -91,7 +89,6 @@ libresolv_hidden_proto (__res_nameinquery) libresolv_hidden_proto (__res_queriesmatch) libresolv_hidden_proto (__res_nsend) libresolv_hidden_proto (__b64_ntop) -libresolv_hidden_proto (__res_nopt) libresolv_hidden_proto (__dn_count_labels) libresolv_hidden_proto (__p_secstodate) diff --git a/resolv/Makefile b/resolv/Makefile index c69b24bfd9..d41fd4603d 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -48,6 +48,7 @@ tests += \ tst-res_hconf_reorder \ tst-res_use_inet6 \ tst-resolv-basic \ + tst-resolv-edns \ tst-resolv-network \ tst-resolv-search \ @@ -133,6 +134,7 @@ $(objpfx)tst-bug18665-tcp: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-bug18665: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-res_use_inet6: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) +$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index 4532b582a2..8279d15de4 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -69,7 +69,7 @@ #include #include #include -#include +#include #include #include #include @@ -225,7 +225,30 @@ __res_nopt(res_state statp, *cp++ = 0; /* "." */ NS_PUT16(T_OPT, cp); /* TYPE */ - NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */ + + /* Lowering the advertised buffer size based on the actual + answer buffer size is desirable because the server will + minimize the reply to fit into the UDP packet (and A + non-minimal response might not fit the buffer). + + The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP + fallback and a non-minimal response which has to be + hard-truncated in the stub resolver, but this is price to + pay for avoiding fragmentation. (This issue does not + affect the nss_dns functions because they use the stub + resolver in such a way that it allocates a properly sized + response buffer.) */ + { + uint16_t buffer_size; + if (anslen < 512) + buffer_size = 512; + else if (anslen > RESOLV_EDNS_BUFFER_SIZE) + buffer_size = RESOLV_EDNS_BUFFER_SIZE; + else + buffer_size = anslen; + NS_PUT16 (buffer_size, cp); + } + *cp++ = NOERROR; /* extended RCODE */ *cp++ = 0; /* EDNS version */ @@ -243,4 +266,3 @@ __res_nopt(res_state statp, return cp - buf; } -libresolv_hidden_def (__res_nopt) diff --git a/resolv/res_query.c b/resolv/res_query.c index 6f3eada143..c3ebcbf6b5 100644 --- a/resolv/res_query.c +++ b/resolv/res_query.c @@ -78,6 +78,7 @@ #include #include #include +#include /* Options. Leave them on. */ /* #undef DEBUG */ @@ -147,7 +148,10 @@ __libc_res_nquery(res_state statp, if ((oflags & RES_F_EDNS0ERR) == 0 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) { - n = __res_nopt(statp, n, query1, bufsize, anslen / 2); + /* Use RESOLV_EDNS_BUFFER_SIZE because the receive + buffer can be reallocated. */ + n = __res_nopt (statp, n, query1, bufsize, + RESOLV_EDNS_BUFFER_SIZE); if (n < 0) goto unspec_nomem; } @@ -168,8 +172,10 @@ __libc_res_nquery(res_state statp, if (n > 0 && (oflags & RES_F_EDNS0ERR) == 0 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) - n = __res_nopt(statp, n, query2, bufsize - nused - n, - anslen / 2); + /* Use RESOLV_EDNS_BUFFER_SIZE because the receive + buffer can be reallocated. */ + n = __res_nopt (statp, n, query2, bufsize, + RESOLV_EDNS_BUFFER_SIZE); nquery2 = n; } @@ -183,7 +189,16 @@ __libc_res_nquery(res_state statp, if (n > 0 && (oflags & RES_F_EDNS0ERR) == 0 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) - n = __res_nopt(statp, n, query1, bufsize, anslen); + { + /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer + can be reallocated. */ + size_t advertise; + if (answerp == NULL) + advertise = anslen; + else + advertise = RESOLV_EDNS_BUFFER_SIZE; + n = __res_nopt (statp, n, query1, bufsize, advertise); + } nquery1 = n; } diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h index d35df1c3d5..0d69ce10d3 100644 --- a/resolv/resolv-internal.h +++ b/resolv/resolv-internal.h @@ -38,4 +38,22 @@ res_use_inet6 (void) return _res.options & DEPRECATED_RES_USE_INET6; } +enum + { + /* The advertized EDNS buffer size. The value 1200 is derived + from the IPv6 minimum MTU (1280 bytes) minus some arbitrary + space for tunneling overhead. If the DNS server does not react + to ICMP Fragmentation Needed But DF Set messages, this should + avoid all UDP fragments on current networks. Avoiding UDP + fragments is desirable because it prevents fragmentation-based + spoofing attacks because the randomness in a DNS packet is + concentrated in the first fragment (with the headers) and does + not protect subsequent fragments. */ + RESOLV_EDNS_BUFFER_SIZE = 1200, + }; + +/* Add an OPT record to a DNS query. */ +int __res_nopt (res_state, int n0, unsigned char *buf, int buflen, + int anslen) attribute_hidden; + #endif /* _RESOLV_INTERNAL_H */ diff --git a/resolv/tst-resolv-edns.c b/resolv/tst-resolv-edns.c new file mode 100644 index 0000000000..f17dbc3450 --- /dev/null +++ b/resolv/tst-resolv-edns.c @@ -0,0 +1,501 @@ +/* Test EDNS handling in the stub resolver. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Data produced by a test query. */ +struct response_data +{ + char *qname; + uint16_t qtype; + struct resolv_edns_info edns; +}; + +/* Global array used by put_response and get_response to record + response data. The test DNS server returns the index of the array + element which contains the actual response data. This enables the + test case to return arbitrary amounts of data with the limited + number of bits which fit into an IP addres. + + The volatile specifier is needed because the test case accesses + these variables from a callback function called from a function + which is marked as __THROW (i.e., a leaf function which actually is + not). */ +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static struct response_data ** volatile response_data_array; +volatile static size_t response_data_count; + +/* Extract information from the query, store it in a struct + response_data object, and return its index in the + response_data_array. */ +static unsigned int +put_response (const struct resolv_response_context *ctx, + const char *qname, uint16_t qtype) +{ + xpthread_mutex_lock (&mutex); + ++response_data_count; + /* We only can represent 2**24 indexes in 10.0.0.0/8. */ + TEST_VERIFY (response_data_count < (1 << 24)); + response_data_array = xrealloc + (response_data_array, sizeof (*response_data_array) * response_data_count); + unsigned int index = response_data_count - 1; + struct response_data *data = xmalloc (sizeof (*data)); + *data = (struct response_data) + { + .qname = xstrdup (qname), + .qtype = qtype, + .edns = ctx->edns, + }; + response_data_array[index] = data; + xpthread_mutex_unlock (&mutex); + return index; +} + +/* Verify the index into the response_data array and return the data + at it. */ +static struct response_data * +get_response (unsigned int index) +{ + xpthread_mutex_lock (&mutex); + TEST_VERIFY_EXIT (index < response_data_count); + struct response_data *result = response_data_array[index]; + xpthread_mutex_unlock (&mutex); + return result; +} + +/* Deallocate all response data. */ +static void +free_response_data (void) +{ + xpthread_mutex_lock (&mutex); + size_t count = response_data_count; + struct response_data **array = response_data_array; + for (unsigned int i = 0; i < count; ++i) + { + struct response_data *data = array[i]; + free (data->qname); + free (data); + } + free (array); + response_data_array = NULL; + response_data_count = 0; + xpthread_mutex_unlock (&mutex); +} + +#define EDNS_PROBE_EXAMPLE "edns-probe.example" + +static void +response (const struct resolv_response_context *ctx, + struct resolv_response_builder *b, + const char *qname, uint16_t qclass, uint16_t qtype) +{ + TEST_VERIFY_EXIT (qname != NULL); + + /* The "tcp." prefix can be used to request TCP fallback. */ + const char *qname_compare = qname; + bool force_tcp; + if (strncmp ("tcp.", qname_compare, strlen ("tcp.")) == 0) + { + force_tcp = true; + qname_compare += strlen ("tcp."); + } + else + force_tcp = false; + + enum {edns_probe} requested_qname; + if (strcmp (qname_compare, EDNS_PROBE_EXAMPLE) == 0) + requested_qname = edns_probe; + else + { + support_record_failure (); + printf ("error: unexpected QNAME: %s\n", qname); + return; + } + TEST_VERIFY_EXIT (qclass == C_IN); + struct resolv_response_flags flags = {.tc = force_tcp && !ctx->tcp}; + resolv_response_init (b, flags); + resolv_response_add_question (b, qname, qclass, qtype); + if (flags.tc) + return; + + if (test_verbose) + printf ("info: edns=%d payload_size=%d\n", + ctx->edns.active, ctx->edns.payload_size); + + /* Encode the response_data object in multiple address records. + Each record carries two bytes of payload data, and an index. */ + resolv_response_section (b, ns_s_an); + switch (requested_qname) + { + case edns_probe: + { + unsigned int index = put_response (ctx, qname, qtype); + switch (qtype) + { + case T_A: + { + uint32_t addr = htonl (0x0a000000 | index); + resolv_response_open_record (b, qname, qclass, qtype, 0); + resolv_response_add_data (b, &addr, sizeof (addr)); + resolv_response_close_record (b); + } + break; + case T_AAAA: + { + char addr[16] + = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + index >> 16, index >> 8, index}; + resolv_response_open_record (b, qname, qclass, qtype, 0); + resolv_response_add_data (b, &addr, sizeof (addr)); + resolv_response_close_record (b); + } + } + } + break; + } +} + +/* Update *DATA with data from ADDRESS of SIZE. Set the corresponding + flag in SHADOW for each byte written. */ +static struct response_data * +decode_address (const void *address, size_t size) +{ + switch (size) + { + case 4: + TEST_VERIFY (memcmp (address, "\x0a", 1) == 0); + break; + case 16: + TEST_VERIFY (memcmp (address, "\x20\x01\x0d\xb8", 4) == 0); + break; + default: + FAIL_EXIT1 ("unexpected address size %zu", size); + } + const unsigned char *addr = address; + unsigned int index = addr[size - 3] * 256 * 256 + + addr[size - 2] * 256 + + addr[size - 1]; + return get_response (index); +} + +static struct response_data * +decode_hostent (struct hostent *e) +{ + TEST_VERIFY_EXIT (e != NULL); + TEST_VERIFY_EXIT (e->h_addr_list[0] != NULL); + TEST_VERIFY (e->h_addr_list[1] == NULL); + return decode_address (e->h_addr_list[0], e->h_length); +} + +static struct response_data * +decode_addrinfo (struct addrinfo *ai, int family) +{ + struct response_data *data = NULL; + while (ai != NULL) + { + if (ai->ai_family == family) + { + struct response_data *new_data; + switch (family) + { + case AF_INET: + { + struct sockaddr_in *pin = (struct sockaddr_in *) ai->ai_addr; + new_data = decode_address (&pin->sin_addr.s_addr, 4); + } + break; + case AF_INET6: + { + struct sockaddr_in6 *pin = (struct sockaddr_in6 *) ai->ai_addr; + new_data = decode_address (&pin->sin6_addr.s6_addr, 16); + } + break; + default: + FAIL_EXIT1 ("invalid address family %d", ai->ai_family); + } + if (data == NULL) + data = new_data; + else + /* Check pointer equality because this should be the same + response (same index). */ + TEST_VERIFY (data == new_data); + } + ai = ai->ai_next; + } + TEST_VERIFY_EXIT (data != NULL); + return data; +} + +/* Updated by the main test loop in accordance with what is set in + _res.options. */ +static bool use_edns; +static bool use_dnssec; + +/* Verify the decoded response data against the flags above. */ +static void +verify_response_data_payload (struct response_data *data, + size_t expected_payload) +{ + bool edns = use_edns || use_dnssec; + TEST_VERIFY (data->edns.active == edns); + if (!edns) + expected_payload = 0; + if (data->edns.payload_size != expected_payload) + { + support_record_failure (); + printf ("error: unexpected payload size %d (edns=%d)\n", + (int) data->edns.payload_size, edns); + } + uint16_t expected_flags = 0; + if (use_dnssec) + expected_flags |= 0x8000; /* DO flag. */ + if (data->edns.flags != expected_flags) + { + support_record_failure (); + printf ("error: unexpected EDNS flags 0x%04x (edns=%d)\n", + (int) data->edns.flags, edns); + } +} + +/* Same as verify_response_data_payload, but use the default + payload. */ +static void +verify_response_data (struct response_data *data) +{ + verify_response_data_payload (data, 1200); +} + +static void +check_hostent (struct hostent *e) +{ + TEST_VERIFY_EXIT (e != NULL); + verify_response_data (decode_hostent (e)); +} + +static void +do_ai (int family) +{ + struct addrinfo hints = { .ai_family = family }; + struct addrinfo *ai; + int ret = getaddrinfo (EDNS_PROBE_EXAMPLE, "80", &hints, &ai); + TEST_VERIFY_EXIT (ret == 0); + switch (family) + { + case AF_INET: + case AF_INET6: + verify_response_data (decode_addrinfo (ai, family)); + break; + case AF_UNSPEC: + verify_response_data (decode_addrinfo (ai, AF_INET)); + verify_response_data (decode_addrinfo (ai, AF_INET6)); + break; + default: + FAIL_EXIT1 ("invalid address family %d", family); + } + freeaddrinfo (ai); +} + +enum res_op +{ + res_op_search, + res_op_query, + res_op_querydomain, + res_op_nsearch, + res_op_nquery, + res_op_nquerydomain, + + res_op_last = res_op_nquerydomain, +}; + +static const char * +res_op_string (enum res_op op) +{ + switch (op) + { + case res_op_search: + return "res_search"; + case res_op_query: + return "res_query"; + case res_op_querydomain: + return "res_querydomain"; + case res_op_nsearch: + return "res_nsearch"; + case res_op_nquery: + return "res_nquery"; + case res_op_nquerydomain: + return "res_nquerydomain"; + } + FAIL_EXIT1 ("invalid res_op value %d", (int) op); +} + +/* Call libresolv function OP to look up PROBE_NAME, with an answer + buffer of SIZE bytes. Check that the advertised UDP buffer size is + in fact EXPECTED_BUFFER_SIZE. */ +static void +do_res_search (const char *probe_name, enum res_op op, size_t size, + size_t expected_buffer_size) +{ + if (test_verbose) + printf ("info: testing %s with buffer size %zu\n", + res_op_string (op), size); + unsigned char *buffer = xmalloc (size); + int ret = -1; + switch (op) + { + case res_op_search: + ret = res_search (probe_name, C_IN, T_A, buffer, size); + break; + case res_op_query: + ret = res_query (probe_name, C_IN, T_A, buffer, size); + break; + case res_op_nsearch: + ret = res_nsearch (&_res, probe_name, C_IN, T_A, buffer, size); + break; + case res_op_nquery: + ret = res_nquery (&_res, probe_name, C_IN, T_A, buffer, size); + break; + case res_op_querydomain: + case res_op_nquerydomain: + { + char *example_stripped = xstrdup (probe_name); + char *dot_example = strstr (example_stripped, ".example"); + if (dot_example != NULL && strcmp (dot_example, ".example") == 0) + { + /* Truncate the domain name. */ + *dot_example = '\0'; + if (op == res_op_querydomain) + ret = res_querydomain + (example_stripped, "example", C_IN, T_A, buffer, size); + else + ret = res_nquerydomain + (&_res, example_stripped, "example", C_IN, T_A, buffer, size); + } + else + FAIL_EXIT1 ("invalid probe name: %s", probe_name); + free (example_stripped); + } + break; + } + TEST_VERIFY_EXIT (ret > 12); + unsigned char *end = buffer + ret; + + HEADER *hd = (HEADER *) buffer; + TEST_VERIFY (ntohs (hd->qdcount) == 1); + TEST_VERIFY (ntohs (hd->ancount) == 1); + /* Skip over the header. */ + unsigned char *p = buffer + sizeof (*hd); + /* Skip over the question. */ + ret = dn_skipname (p, end); + TEST_VERIFY_EXIT (ret > 0); + p += ret; + TEST_VERIFY_EXIT (end - p >= 4); + p += 4; + /* Skip over the RNAME and the RR header, but stop at the RDATA + length. */ + ret = dn_skipname (p, end); + TEST_VERIFY_EXIT (ret > 0); + p += ret; + TEST_VERIFY_EXIT (end - p >= 2 + 2 + 4 + 2 + 4); + p += 2 + 2 + 4; + /* The IP address should be 4 bytes long. */ + TEST_VERIFY_EXIT (p[0] == 0); + TEST_VERIFY_EXIT (p[1] == 4); + /* Extract the address information. */ + p += 2; + struct response_data *data = decode_address (p, 4); + + verify_response_data_payload (data, expected_buffer_size); + + free (buffer); +} + +static void +run_test (const char *probe_name) +{ + if (test_verbose) + printf ("\ninfo: * use_edns=%d use_dnssec=%d\n", + use_edns, use_dnssec); + check_hostent (gethostbyname (probe_name)); + check_hostent (gethostbyname2 (probe_name, AF_INET)); + check_hostent (gethostbyname2 (probe_name, AF_INET6)); + do_ai (AF_UNSPEC); + do_ai (AF_INET); + do_ai (AF_INET6); + + for (int op = 0; op <= res_op_last; ++op) + { + do_res_search (probe_name, op, 301, 512); + do_res_search (probe_name, op, 511, 512); + do_res_search (probe_name, op, 512, 512); + do_res_search (probe_name, op, 513, 513); + do_res_search (probe_name, op, 657, 657); + do_res_search (probe_name, op, 1199, 1199); + do_res_search (probe_name, op, 1200, 1200); + do_res_search (probe_name, op, 1201, 1200); + do_res_search (probe_name, op, 65535, 1200); + } +} + +static int +do_test (void) +{ + for (int do_edns = 0; do_edns < 2; ++do_edns) + for (int do_dnssec = 0; do_dnssec < 2; ++do_dnssec) + for (int do_tcp = 0; do_tcp < 2; ++do_tcp) + { + struct resolv_test *aux = resolv_test_start + ((struct resolv_redirect_config) + { + .response_callback = response, + }); + + use_edns = do_edns; + if (do_edns) + _res.options |= RES_USE_EDNS0; + use_dnssec = do_dnssec; + if (do_dnssec) + _res.options |= RES_USE_DNSSEC; + + char *probe_name = xstrdup (EDNS_PROBE_EXAMPLE); + if (do_tcp) + { + char *n = xasprintf ("tcp.%s", probe_name); + free (probe_name); + probe_name = n; + } + + run_test (probe_name); + + free (probe_name); + resolv_test_end (aux); + } + + free_response_data (); + return 0; +} + +#include diff --git a/support/resolv_test.c b/support/resolv_test.c index 49ed210191..5c5a46353d 100644 --- a/support/resolv_test.c +++ b/support/resolv_test.c @@ -429,6 +429,7 @@ struct query_info char qname[MAXDNAME]; uint16_t qclass; uint16_t qtype; + struct resolv_edns_info edns; }; /* Update *INFO from the specified DNS packet. */ @@ -436,10 +437,26 @@ static void parse_query (struct query_info *info, const unsigned char *buffer, size_t length) { - if (length < 12) + HEADER hd; + _Static_assert (sizeof (hd) == 12, "DNS header size"); + if (length < sizeof (hd)) FAIL_EXIT1 ("malformed DNS query: too short: %zu bytes", length); - - int ret = dn_expand (buffer, buffer + length, buffer + 12, + memcpy (&hd, buffer, sizeof (hd)); + + if (ntohs (hd.qdcount) != 1) + FAIL_EXIT1 ("malformed DNS query: wrong question count: %d", + (int) ntohs (hd.qdcount)); + if (ntohs (hd.ancount) != 0) + FAIL_EXIT1 ("malformed DNS query: wrong answer count: %d", + (int) ntohs (hd.ancount)); + if (ntohs (hd.nscount) != 0) + FAIL_EXIT1 ("malformed DNS query: wrong authority count: %d", + (int) ntohs (hd.nscount)); + if (ntohs (hd.arcount) > 1) + FAIL_EXIT1 ("malformed DNS query: wrong additional count: %d", + (int) ntohs (hd.arcount)); + + int ret = dn_expand (buffer, buffer + length, buffer + sizeof (hd), info->qname, sizeof (info->qname)); if (ret < 0) FAIL_EXIT1 ("malformed DNS query: cannot uncompress QNAME"); @@ -457,6 +474,37 @@ parse_query (struct query_info *info, memcpy (&qtype_qclass, buffer + 12 + ret, sizeof (qtype_qclass)); info->qclass = ntohs (qtype_qclass.qclass); info->qtype = ntohs (qtype_qclass.qtype); + + memset (&info->edns, 0, sizeof (info->edns)); + if (ntohs (hd.arcount) > 0) + { + /* Parse EDNS record. */ + struct __attribute__ ((packed, aligned (1))) + { + uint8_t root; + uint16_t rtype; + uint16_t payload; + uint8_t edns_extended_rcode; + uint8_t edns_version; + uint16_t flags; + uint16_t rdatalen; + } rr; + _Static_assert (sizeof (rr) == 11, "EDNS record size"); + + if (remaining < 4 + sizeof (rr)) + FAIL_EXIT1 ("mailformed DNS query: no room for EDNS record"); + memcpy (&rr, buffer + 12 + ret + 4, sizeof (rr)); + if (rr.root != 0) + FAIL_EXIT1 ("malformed DNS query: invalid OPT RNAME: %d\n", rr.root); + if (rr.rtype != htons (41)) + FAIL_EXIT1 ("malformed DNS query: invalid OPT type: %d\n", + ntohs (rr.rtype)); + info->edns.active = true; + info->edns.extended_rcode = rr.edns_extended_rcode; + info->edns.version = rr.edns_version; + info->edns.flags = ntohs (rr.flags); + info->edns.payload_size = ntohs (rr.payload); + } } @@ -586,6 +634,7 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index) .query_length = length, .server_index = server_index, .tcp = false, + .edns = qinfo.edns, }; struct resolv_response_builder *b = response_builder_allocate (query, length); obj->config.response_callback @@ -821,6 +870,7 @@ server_thread_tcp_client (void *arg) .query_length = query_length, .server_index = closure->server_index, .tcp = true, + .edns = qinfo.edns, }; struct resolv_response_builder *b = response_builder_allocate (query_buffer, query_length); diff --git a/support/resolv_test.h b/support/resolv_test.h index 7a9f1f7ae8..6498751569 100644 --- a/support/resolv_test.h +++ b/support/resolv_test.h @@ -25,6 +25,16 @@ __BEGIN_DECLS +/* Information about EDNS properties of a DNS query. */ +struct resolv_edns_info +{ + bool active; + uint8_t extended_rcode; + uint8_t version; + uint16_t flags; + uint16_t payload_size; +}; + /* This struct provides context information when the response callback specified in struct resolv_redirect_config is invoked. */ struct resolv_response_context @@ -33,6 +43,7 @@ struct resolv_response_context size_t query_length; int server_index; bool tcp; + struct resolv_edns_info edns; }; /* This opaque struct is used to construct responses from within the -- cgit v1.2.3 From ca3d65ff69d5187cb4d6b7f81d414427c7007e22 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 19 Jun 2017 13:15:11 +0200 Subject: resolv: Make __res_vinit hidden And remove unnecessary separate declarations. --- ChangeLog | 6 ++++++ include/resolv.h | 2 +- resolv/res_init.c | 2 -- resolv/res_libc.c | 2 -- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index 9a82a2b0fd..388fc42909 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-06-19 Florian Weimer + + * include/resolv.h (__res_vinit): Declare as hidden. + * resolv/res_init.c (res_ninit): Remove __res_vinit declaration. + * resolv/res_libc.c (res_init): Likewise. + 2017-06-19 Joseph Myers [BZ #21457] diff --git a/include/resolv.h b/include/resolv.h index e8f477cd86..37e4047ac4 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -23,7 +23,7 @@ extern __thread struct __res_state *__resp attribute_tls_model_ie; # define _res (*__resp) /* Now define the internal interfaces. */ -extern int __res_vinit (res_state, int); +extern int __res_vinit (res_state, int) attribute_hidden; extern int __res_maybe_init (res_state, int); extern void _sethtent (int); extern struct hostent *_gethtent (void); diff --git a/resolv/res_init.c b/resolv/res_init.c index 23676e994d..57223b470a 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -110,8 +110,6 @@ unsigned long long int __res_initstamp attribute_hidden; */ int res_ninit(res_state statp) { - extern int __res_vinit(res_state, int); - return (__res_vinit(statp, 0)); } libc_hidden_def (__res_ninit) diff --git a/resolv/res_libc.c b/resolv/res_libc.c index c8f158d94c..3bf3887b0c 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -41,8 +41,6 @@ __libc_lock_define_initialized (static, lock); int res_init(void) { - extern int __res_vinit(res_state, int); - /* * These three fields used to be statically initialized. This made * it hard to use this code in a shared library. It is necessary, -- cgit v1.2.3 From d85f99679d89fb47426301620b7a980388fddcfd Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 30 Jun 2017 11:31:35 +0200 Subject: resolv: Move fp_nquery, fp_query, p_query, _res_opcodes From res_data.c to res_debug.c. Also drop the unnecessary _res initialization from fp_nquery. --- ChangeLog | 13 ++++++++++ include/resolv.h | 2 -- resolv/res_data.c | 40 ----------------------------- resolv/res_debug.c | 75 +++++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 71 insertions(+), 59 deletions(-) (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index de97c6571e..a3969176ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-06-30 Florian Weimer + + * include/resolv.h (res_pquery): Remove declaration. + * resolv/res_data.c (fp_nquery, fp_query, p_query): Remove + functions. + (_res_opcodes): Remove variable. + * resolv/res_debug.c (do_section): Receive pfcode instead of + statp. + (res_pquery): Rename ... + (fp_nquery): to this function. Skip unnecessary _res + initialization. + (fp_query, p_query, _res_opcodes): Copied from resolv/res_data.c. + 2017-06-30 Florian Weimer * resolv/res_debug.h: Remove file. diff --git a/include/resolv.h b/include/resolv.h index 37e4047ac4..4d5b51e873 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -32,8 +32,6 @@ extern struct hostent *_gethtbyname2 (const char *__name, int __af); struct hostent *_gethtbyaddr (const char *addr, size_t __len, int __af); extern uint32_t _getlong (const unsigned char *__src); extern uint16_t _getshort (const unsigned char *__src); -extern void res_pquery (const res_state __statp, const unsigned char *__msg, - int __len, FILE *__file); extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); extern void __res_iclose (res_state statp, bool free_addr); diff --git a/resolv/res_data.c b/resolv/res_data.c index d907bfc9bd..d05389e134 100644 --- a/resolv/res_data.c +++ b/resolv/res_data.c @@ -32,46 +32,6 @@ #include #include -const char *_res_opcodes[] = { - "QUERY", - "IQUERY", - "CQUERYM", - "CQUERYU", /* experimental */ - "NOTIFY", /* experimental */ - "UPDATE", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "ZONEINIT", - "ZONEREF", -}; -libresolv_hidden_data_def (_res_opcodes) - -void -p_query(const u_char *msg) { - fp_query(msg, stdout); -} - -void -fp_query(const u_char *msg, FILE *file) { - fp_nquery(msg, PACKETSZ, file); -} -libresolv_hidden_def (fp_query) - -void -fp_nquery(const u_char *msg, int len, FILE *file) { - if (__res_maybe_init (&_res, 0) == -1) - return; - - res_pquery(&_res, msg, len, file); -} -libresolv_hidden_def (fp_nquery) - int res_query(const char *name, /* domain name */ int class, int type, /* class and type of query */ diff --git a/resolv/res_debug.c b/resolv/res_debug.c index e23559bad3..182aeefa1f 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -115,6 +115,27 @@ extern const char *_res_sectioncodes[] attribute_hidden; +const char *_res_opcodes[] = + { + "QUERY", + "IQUERY", + "CQUERYM", + "CQUERYU", /* experimental */ + "NOTIFY", /* experimental */ + "UPDATE", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "ZONEINIT", + "ZONEREF", + }; +libresolv_hidden_data_def (_res_opcodes) + static const char *p_section(int section, int opcode); /* @@ -132,9 +153,7 @@ fp_resstat(const res_state statp, FILE *file) { } static void -do_section(const res_state statp, - ns_msg *handle, ns_sect section, - int pflag, FILE *file) +do_section (int pfcode, ns_msg *handle, ns_sect section, int pflag, FILE *file) { int n, sflag, rrnum; static int buflen = 2048; @@ -145,8 +164,8 @@ do_section(const res_state statp, /* * Print answer records. */ - sflag = (statp->pfcode & pflag); - if (statp->pfcode && !sflag) + sflag = (pfcode & pflag); + if (pfcode && !sflag) return; buf = malloc(buflen); @@ -163,11 +182,11 @@ do_section(const res_state statp, fprintf(file, ";; ns_parserr: %s\n", strerror(errno)); else if (rrnum > 0 && sflag != 0 && - (statp->pfcode & RES_PRF_HEAD1)) + (pfcode & RES_PRF_HEAD1)) putc('\n', file); goto cleanup; } - if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) + if (rrnum == 0 && sflag != 0 && (pfcode & RES_PRF_HEAD1)) fprintf(file, ";; %s SECTION:\n", p_section(section, opcode)); if (section == ns_s_qd) @@ -209,11 +228,19 @@ do_section(const res_state statp, * This is intended to be primarily a debugging routine. */ void -res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { +fp_nquery (const unsigned char *msg, int len, FILE *file) +{ ns_msg handle; int qdcount, ancount, nscount, arcount; u_int opcode, rcode, id; + /* There is no need to initialize _res: If _res is not yet + initialized, _res.pfcode is zero. But initialization will + leave it at zero, too. _res.pfcode is an unsigned long, + but the code here assumes that the flags fit into an int, + so use that. */ + int pfcode = _res.pfcode; + if (ns_initparse(msg, len, &handle) < 0) { fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); return; @@ -229,13 +256,13 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { /* * Print header fields. */ - if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode) + if ((!pfcode) || (pfcode & RES_PRF_HEADX) || rcode) fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", _res_opcodes[opcode], p_rcode(rcode), id); - if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX)) + if ((!pfcode) || (pfcode & RES_PRF_HEADX)) putc(';', file); - if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) { + if ((!pfcode) || (pfcode & RES_PRF_HEAD2)) { fprintf(file, "; flags:"); if (ns_msg_getflag(handle, ns_f_qr)) fprintf(file, " qr"); @@ -254,7 +281,7 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { if (ns_msg_getflag(handle, ns_f_cd)) fprintf(file, " cd"); } - if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) { + if ((!pfcode) || (pfcode & RES_PRF_HEAD1)) { fprintf(file, "; %s: %d", p_section(ns_s_qd, opcode), qdcount); fprintf(file, ", %s: %d", @@ -264,21 +291,35 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { fprintf(file, ", %s: %d", p_section(ns_s_ar, opcode), arcount); } - if ((!statp->pfcode) || (statp->pfcode & + if ((!pfcode) || (pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { putc('\n',file); } /* * Print the various sections. */ - do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file); - do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file); - do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file); - do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file); + do_section (pfcode, &handle, ns_s_qd, RES_PRF_QUES, file); + do_section (pfcode, &handle, ns_s_an, RES_PRF_ANS, file); + do_section (pfcode, &handle, ns_s_ns, RES_PRF_AUTH, file); + do_section (pfcode, &handle, ns_s_ar, RES_PRF_ADD, file); if (qdcount == 0 && ancount == 0 && nscount == 0 && arcount == 0) putc('\n', file); } +libresolv_hidden_def (fp_nquery) + +void +fp_query (const unsigned char *msg, FILE *file) +{ + fp_nquery (msg, PACKETSZ, file); +} +libresolv_hidden_def (fp_query) + +void +p_query (const unsigned char *msg) +{ + fp_query (msg, stdout); +} const u_char * p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) { -- cgit v1.2.3 From 6781d8e693eb9e1251875222db5c9885d7ebb596 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 30 Jun 2017 11:31:41 +0200 Subject: resolv: Turn _res_opcodes into a compatibility symbol --- ChangeLog | 7 +++++++ NEWS | 3 +++ include/resolv.h | 3 --- resolv/res_debug.c | 14 +++++++++++--- 4 files changed, 21 insertions(+), 6 deletions(-) (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index a3969176ec..dca3cb2899 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2017-06-30 Florian Weimer + + * resolv/res_debug.c (_res_opcodes): Rename ... + (res_opcodes): ... as compatibility symbol. + (fp_nquery): Use res_opcodes. + * include/resolv.h (_res_opcodes): Remove declaration. + 2017-06-30 Florian Weimer * include/resolv.h (res_pquery): Remove declaration. diff --git a/NEWS b/NEWS index 944804dcd5..df6f394180 100644 --- a/NEWS +++ b/NEWS @@ -234,6 +234,9 @@ Version 2.26 will now randomly pick a name server from the configuration as a starting point. (Previously, the second name server was always used.) +* The _res_opcodes variable has been removed from libresolv. It had been + exported by accident. + Security related changes: * The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes, diff --git a/include/resolv.h b/include/resolv.h index 4d5b51e873..2938506d75 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -90,8 +90,5 @@ libresolv_hidden_proto (__b64_ntop) libresolv_hidden_proto (__dn_count_labels) libresolv_hidden_proto (__p_secstodate) -extern const char *_res_opcodes[]; -libresolv_hidden_proto (_res_opcodes) - # endif /* _RESOLV_H_ && !_ISOMAC */ #endif diff --git a/resolv/res_debug.c b/resolv/res_debug.c index 182aeefa1f..55d1fe9f89 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -106,6 +106,7 @@ #include #include #include +#include #ifdef SPRINTF_CHAR # define SPRINTF(x) strlen(sprintf/**/x) @@ -115,7 +116,12 @@ extern const char *_res_sectioncodes[] attribute_hidden; -const char *_res_opcodes[] = +/* _res_opcodes was exported by accident as a variable. */ +#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26) +static const char *res_opcodes[] = +#else +static const char res_opcodes[][9] = +#endif { "QUERY", "IQUERY", @@ -134,7 +140,9 @@ const char *_res_opcodes[] = "ZONEINIT", "ZONEREF", }; -libresolv_hidden_data_def (_res_opcodes) +#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26) +strong_alias (res_opcodes, _res_opcodes) +#endif static const char *p_section(int section, int opcode); @@ -259,7 +267,7 @@ fp_nquery (const unsigned char *msg, int len, FILE *file) if ((!pfcode) || (pfcode & RES_PRF_HEADX) || rcode) fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", - _res_opcodes[opcode], p_rcode(rcode), id); + res_opcodes[opcode], p_rcode(rcode), id); if ((!pfcode) || (pfcode & RES_PRF_HEADX)) putc(';', file); if ((!pfcode) || (pfcode & RES_PRF_HEAD2)) { -- cgit v1.2.3 From 352f4ff9a268b81ef5d4b2413f582565806e4790 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 30 Jun 2017 21:10:23 +0200 Subject: resolv: Introduce struct resolv_context [BZ #21668] struct resolv_context objects provide a temporary resolver context which does not change during a name lookup operation. Only when the outmost context is created, the stub resolver configuration is verified to be current (at present, only against previous res_init calls). Subsequent attempts to obtain the context will reuse the result of the initial verification operation. struct resolv_context can also be extended in the future to store data which needs to be deallocated during thread cancellation. --- ChangeLog | 85 ++++++++++++ include/resolv.h | 23 ---- nscd/aicache.c | 21 +-- nss/digits_dots.c | 21 ++- nss/getXXbyYY.c | 28 +++- nss/getXXbyYY_r.c | 34 +++-- nss/getnssent_r.c | 42 ++++-- nss/nsswitch.h | 10 ++ resolv/Makefile | 3 +- resolv/Versions | 10 +- resolv/compat-gethnamaddr.c | 95 +++++++++----- resolv/nss_dns/dns-canon.c | 19 ++- resolv/nss_dns/dns-host.c | 104 +++++++++------ resolv/nss_dns/dns-network.c | 21 ++- resolv/res-close.c | 3 + resolv/res_libc.c | 31 ----- resolv/res_mkquery.c | 92 +++++++------ resolv/res_query.c | 298 +++++++++++++++++++++++++------------------ resolv/res_send.c | 44 +++++-- resolv/res_use_inet6.h | 49 +++++++ resolv/resolv-internal.h | 36 +++++- resolv/resolv_context.c | 201 +++++++++++++++++++++++++++++ resolv/resolv_context.h | 95 ++++++++++++++ sysdeps/posix/getaddrinfo.c | 39 +++--- 24 files changed, 1033 insertions(+), 371 deletions(-) create mode 100644 resolv/res_use_inet6.h create mode 100644 resolv/resolv_context.c create mode 100644 resolv/resolv_context.h (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index 74dc23e987..edd0e69491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,88 @@ +2017-06-30 Florian Weimer + + [BZ #21668] + Introduce temporary resolver contexts (struct resolv_conf). + * resolv/resolv-internal.h (__res_context_mkquery) + (__res_context_searchl __res_context_query, __res_context_send) + (__res_context_hostalias): Declare. + (__res_nopt): Switch to struct resolv_context. + * resolv/res_use_inet6.h: New file. + * resolv/resolv_context.h: Likewise. + * resolv/resolv_context.c: Likewise. + * resolv/compat-gethnamaddr.c (res_gethostbyname2_context): + Renamed from res_gethostbyname2. Use struct resolv_context. + (res_gethostbyname2): New function. Implement using + res_gethostbyname2_context. + (res_gethostbyaddr_context): Renamed from res_gethostbyaddr. Use + struct resolv_context. + (res_gethostbyaddr): New function. Implement using + res_gethostbyaddr_context. + * resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Use struct + resolv_context. + * resolv/nss_dns/dns-host.c (gethostbyname3_context): Renamed from + _nss_dns_gethostbyname3_r. Use struct resolv_context. + (_nss_dns_gethostbyname3_r): Implement using gethostbyname3_context. + (_nss_dns_gethostbyname_r, _nss_dns_gethostbyname4_r): Likewise. + (_nss_dns_gethostbyaddr2_r): Use struct resolv_context. + * resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r) + (_nss_dns_getnetbyaddr_r): Likewise. + * resolv/res-close.c (res_thread_freeres): Call + __resolv_context_freeres. + * resolv/res_libc.c (__res_maybe_init): Remove function. Moved to + maybe_init in resolv/resolv_context.c. + * resolv/res_mkquery.c (__res_context_mkquery): Rename from + res_nmkquery. Use struct resolv_context. + (context_mkquery_common): New function. + (res_nmkquery, res_mkquery): Use it. + (res_nopt): Switch to struct resolv_context. + * resolv/res_query.c (__res_context_querydomain): Renamed from + __libc_res_nquerydomain. Use struct resolv_context. + (__res_context_query): Renamed from __libc_res_nquery. Use struct + resolv_context. + (context_query_common): New function. + (res_nquery, res_query): Use it. + (__res_context_search): Renamed from __libc_res_nsearch. Use + struct resolv_context. + (context_search_common): New function. + (res_nsearch, res_search): Use it. + (__res_context_querydomain): Rename from __libc_res_nquerydomain. + Use struct resolv_context. + (context_querydomain_common): New function. + (res_nquerydomain, res_querydomain): Use it. + (__res_context_hostalias): Rename from res_hostalias. Use struct + resolv_context. + (context_hostalias_common): New function. + (res_hostalias, hostalias): Use it. + * resolv/res_send.c (__res_context_send): Renamed from + __libc_res_nsend. Use struct resolv_context. + (context_send_common): New function. + (res_nsend, res_send): Use it. + * resolv/Makefile (routines): Add resolv_context. + * resolv/Versions (libc): Export __resolv_context_get, + __resolv_context_get_preinit, __resolv_context_get_override, + __resolv_context_put. Remove __res_maybe_init. + (libresolv): Export __res_context_query, __res_context_search, + __res_context_hostalias. Remove __libc_res_nquery, + __libc_res_nsearch. + * include/resolv.h (__res_maybe_init, __libc_res_nquery) + (__libc_res_nsearch, __libc_res_nsend): Remove declaration. + (__hostalias, __res_nmkquery, __res_nquery, __res_nquerydomain) + (__res_hostalias, __res_nsearch, __res_nsend): Remove hidden + prototypes. + * nss/nsswitch.h (__nss_hostname_digits_dots_context): Declare. + * nss/digits_dots.c (__nss_hostname_digits_dots_context): Renamed + from __nss_hostname_digits_dots. Use struct resolv_context. + (__nss_hostname_digits_dots): New function. + * nss/getXXbyYY.c [HANDLE_DIGITS_DOTS] (FUNCTION_NAME): Acquire + struct resolv_context object. Call new function + __nss_hostname_digits_dots_context. + * nss/getXXbyYY_r.c (REENTRANT_NAME): Use struct resolv_context. + * nss/getnssent_r.c (__nss_setent): Likewise. + * nscd/aicache.c (addhstaiX): Use struct resolv_context, + __resolv_context_disable_inet6 and __resolv_context_enable_inet6 + instead of direct _res manipulation. + * sysdeps/posix/getaddrinfo.c (gethosts, gaih_inet): Likewise. + 2017-07-03 Florian Weimer * resolv/tst-resolv-res_init-skeleton.c diff --git a/include/resolv.h b/include/resolv.h index 2938506d75..634f5525fe 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -24,7 +24,6 @@ extern __thread struct __res_state *__resp attribute_tls_model_ie; /* Now define the internal interfaces. */ extern int __res_vinit (res_state, int) attribute_hidden; -extern int __res_maybe_init (res_state, int); extern void _sethtent (int); extern struct hostent *_gethtent (void); extern struct hostent *_gethtbyname (const char *__name); @@ -36,24 +35,11 @@ extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); extern void __res_iclose (res_state statp, bool free_addr); libc_hidden_proto (__res_ninit) -libc_hidden_proto (__res_maybe_init) libc_hidden_proto (__res_nclose) libc_hidden_proto (__res_iclose) libc_hidden_proto (__res_randomid) libc_hidden_proto (__res_state) -int __libc_res_nquery (res_state, const char *, int, int, - unsigned char *, int, unsigned char **, - unsigned char **, int *, int *, int *); -int __libc_res_nsearch (res_state, const char *, int, int, - unsigned char *, int, unsigned char **, - unsigned char **, int *, int *, int *); -int __libc_res_nsend (res_state, const unsigned char *, int, - const unsigned char *, int, unsigned char *, - int, unsigned char **, unsigned char **, - int *, int *, int *) - attribute_hidden; - libresolv_hidden_proto (_sethtent) libresolv_hidden_proto (_gethtent) libresolv_hidden_proto (_gethtbyaddr) @@ -75,17 +61,8 @@ libresolv_hidden_proto (__p_type) libresolv_hidden_proto (__loc_ntoa) libresolv_hidden_proto (__fp_nquery) libresolv_hidden_proto (__fp_query) -libresolv_hidden_proto (__hostalias) -libresolv_hidden_proto (__res_nmkquery) -libresolv_hidden_proto (__libc_res_nquery) -libresolv_hidden_proto (__res_nquery) -libresolv_hidden_proto (__res_nquerydomain) -libresolv_hidden_proto (__res_hostalias) -libresolv_hidden_proto (__libc_res_nsearch) -libresolv_hidden_proto (__res_nsearch) libresolv_hidden_proto (__res_nameinquery) libresolv_hidden_proto (__res_queriesmatch) -libresolv_hidden_proto (__res_nsend) libresolv_hidden_proto (__b64_ntop) libresolv_hidden_proto (__dn_count_labels) libresolv_hidden_proto (__p_secstodate) diff --git a/nscd/aicache.c b/nscd/aicache.c index f1f9284f6d..a3de792cc4 100644 --- a/nscd/aicache.c +++ b/nscd/aicache.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "dbg_log.h" #include "nscd.h" @@ -100,17 +102,15 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, no_more = 0; nip = hosts_database; - /* Initialize configurations. */ - if (__res_maybe_init (&_res, 0) == -1) + /* Initialize configurations. If we are looking for both IPv4 and + IPv6 address we don't want the lookup functions to automatically + promote IPv4 addresses to IPv6 addresses. Therefore, use the + _no_inet6 variant. */ + struct resolv_context *ctx = __resolv_context_get (); + bool enable_inet6 = __resolv_context_disable_inet6 (ctx); + if (ctx == NULL) no_more = 1; - /* If we are looking for both IPv4 and IPv6 address we don't want - the lookup functions to automatically promote IPv4 addresses to - IPv6 addresses. Currently this is decided by setting the - RES_USE_INET6 bit in _res.options. */ - int old_res_options = _res.options; - _res.options &= ~DEPRECATED_RES_USE_INET6; - size_t tmpbuf6len = 1024; char *tmpbuf6 = alloca (tmpbuf6len); size_t tmpbuf4len = 0; @@ -534,7 +534,8 @@ next_nip: } out: - _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; + __resolv_context_enable_inet6 (ctx, enable_inet6); + __resolv_context_put (ctx); if (dataset != NULL && !alloca_used) { diff --git a/nss/digits_dots.c b/nss/digits_dots.c index 8dcbf9eb0a..0c1fa97e39 100644 --- a/nss/digits_dots.c +++ b/nss/digits_dots.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "nsswitch.h" @@ -38,11 +39,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, size_t buflen, struct hostent **result, enum nss_status *status, int af, int *h_errnop) { - int save; - /* We have to test for the use of IPv6 which can only be done by examining `_res'. */ - if (__res_maybe_init (&_res, 0) == -1) + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) { if (h_errnop) *h_errnop = NETDB_INTERNAL; @@ -52,6 +52,21 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, *result = NULL; return -1; } + int ret = __nss_hostname_digits_dots_context + (ctx, name, resbuf, buffer, buffer_size, buflen, + result, status, af, h_errnop); + __resolv_context_put (ctx); + return ret; +} + +int +__nss_hostname_digits_dots_context (struct resolv_context *ctx, + const char *name, struct hostent *resbuf, + char **buffer, size_t *buffer_size, + size_t buflen, struct hostent **result, + enum nss_status *status, int af, int *h_errnop) +{ + int save; /* * disallow names consisting only of digits/dots, unless diff --git a/nss/getXXbyYY.c b/nss/getXXbyYY.c index d027b14250..a439b816f7 100644 --- a/nss/getXXbyYY.c +++ b/nss/getXXbyYY.c @@ -47,6 +47,11 @@ |* *| \*******************************************************************/ + +#ifdef HANDLE_DIGITS_DOTS +# include +#endif + /* To make the real sources a bit prettier. */ #define REENTRANT_NAME APPEND_R (FUNCTION_NAME) #define APPEND_R(name) APPEND_R1 (name) @@ -93,6 +98,19 @@ FUNCTION_NAME (ADD_PARAMS) int h_errno_tmp = 0; #endif +#ifdef HANDLE_DIGITS_DOTS + /* Wrap both __nss_hostname_digits_dots and the actual lookup + function call in the same context. */ + struct resolv_context *res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + { +# if NEED_H_ERRNO + __set_h_errno (NETDB_INTERNAL); +# endif + return NULL; + } +#endif + /* Get lock. */ __libc_lock_lock (lock); @@ -105,9 +123,9 @@ FUNCTION_NAME (ADD_PARAMS) #ifdef HANDLE_DIGITS_DOTS if (buffer != NULL) { - if (__nss_hostname_digits_dots (name, &resbuf, &buffer, - &buffer_size, 0, &result, NULL, AF_VAL, - H_ERRNO_VAR_P)) + if (__nss_hostname_digits_dots_context + (res_ctx, name, &resbuf, &buffer, &buffer_size, 0, &result, NULL, + AF_VAL, H_ERRNO_VAR_P)) goto done; } #endif @@ -143,6 +161,10 @@ done: /* Release lock. */ __libc_lock_unlock (lock); +#ifdef HANDLE_DIGITS_DOTS + __resolv_context_put (res_ctx); +#endif + #ifdef NEED_H_ERRNO if (h_errno_tmp != 0) __set_h_errno (h_errno_tmp); diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c index 7cab825cf0..6c547ea1ca 100644 --- a/nss/getXXbyYY_r.c +++ b/nss/getXXbyYY_r.c @@ -26,7 +26,7 @@ # include #endif #ifdef NEED__RES -# include +# include #endif /*******************************************************************\ |* Here we assume several symbols to be defined: *| @@ -53,8 +53,7 @@ |* NEED_H_ERRNO - an extra parameter will be passed to point to *| |* the global `h_errno' variable. *| |* *| -|* NEED__RES - the global _res variable might be used so we *| -|* will have to initialize it if necessary *| +|* NEED__RES - obtain a struct resolv_context resolver context *| |* *| |* PREPROCESS - code run before anything else *| |* *| @@ -213,6 +212,18 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, bool any_service = false; #endif +#ifdef NEED__RES + /* The HANDLE_DIGITS_DOTS case below already needs the resolver + configuration, so this has to happen early. */ + struct resolv_context *res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + { + *h_errnop = NETDB_INTERNAL; + *result = NULL; + return errno; + } +#endif /* NEED__RES */ + #ifdef PREPROCESS PREPROCESS; #endif @@ -260,17 +271,6 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, } else { -#ifdef NEED__RES - /* The resolver code will really be used so we have to - initialize it. */ - if (__res_maybe_init (&_res, 0) == -1) - { - *h_errnop = NETDB_INTERNAL; - *result = NULL; - return errno; - } -#endif /* need _res */ - void *tmp_ptr = fct.l; #ifdef PTR_MANGLE PTR_MANGLE (tmp_ptr); @@ -399,6 +399,12 @@ done: POSTPROCESS; #endif +#ifdef NEED__RES + /* This has to happen late because the POSTPROCESS stage above might + need the resolver context. */ + __resolv_context_put (res_ctx); +#endif /* NEED__RES */ + int res; if (status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND) res = 0; diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c index 5fdbf3be00..d85065b6cc 100644 --- a/nss/getnssent_r.c +++ b/nss/getnssent_r.c @@ -18,6 +18,7 @@ #include #include #include "nsswitch.h" +#include /* Set up NIP to run through the services. If ALL is zero, use NIP's current location if it's not nil. Return nonzero if there are no @@ -59,10 +60,15 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, } fct; int no_more; - if (res && __res_maybe_init (&_res, 0) == -1) + struct resolv_context *res_ctx = NULL; + if (res) { - __set_h_errno (NETDB_INTERNAL); - return; + res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + { + __set_h_errno (NETDB_INTERNAL); + return; + } } /* Cycle through the services and run their `setXXent' functions until @@ -95,6 +101,8 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, *last_nip = *nip; } + __resolv_context_put (res_ctx); + if (stayopen_tmp) *stayopen_tmp = stayopen; } @@ -112,10 +120,15 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct, } fct; int no_more; - if (res && __res_maybe_init (&_res, 0) == -1) + struct resolv_context *res_ctx = NULL; + if (res) { - __set_h_errno (NETDB_INTERNAL); - return; + res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + { + __set_h_errno (NETDB_INTERNAL); + return; + } } /* Cycle through all the services and run their endXXent functions. */ @@ -132,6 +145,8 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct, no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, 0, 1); } *last_nip = *nip = NULL; + + __resolv_context_put (res_ctx); } @@ -152,11 +167,16 @@ __nss_getent_r (const char *getent_func_name, int no_more; enum nss_status status; - if (res && __res_maybe_init (&_res, 0) == -1) + struct resolv_context *res_ctx = NULL; + if (res) { - *h_errnop = NETDB_INTERNAL; - *result = NULL; - return errno; + res_ctx = __resolv_context_get (); + if (res_ctx == NULL) + { + *h_errnop = NETDB_INTERNAL; + *result = NULL; + return errno; + } } /* Initialize status to return if no more functions are found. */ @@ -227,6 +247,8 @@ __nss_getent_r (const char *getent_func_name, while (! no_more && status != NSS_STATUS_SUCCESS); } + __resolv_context_put (res_ctx); + *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL; return (status == NSS_STATUS_SUCCESS ? 0 : status != NSS_STATUS_TRYAGAIN ? ENOENT diff --git a/nss/nsswitch.h b/nss/nsswitch.h index f3e756b684..bd3fbcb082 100644 --- a/nss/nsswitch.h +++ b/nss/nsswitch.h @@ -197,7 +197,17 @@ extern int __nss_getent_r (const char *getent_func_name, extern void *__nss_getent (getent_r_function func, void **resbuf, char **buffer, size_t buflen, size_t *buffer_size, int *h_errnop); +struct resolv_context; struct hostent; +extern int __nss_hostname_digits_dots_context (struct resolv_context *, + const char *name, + struct hostent *resbuf, + char **buffer, + size_t *buffer_size, + size_t buflen, + struct hostent **result, + enum nss_status *status, int af, + int *h_errnop) attribute_hidden; extern int __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, char **buffer, size_t *buffer_size, size_t buflen, diff --git a/resolv/Makefile b/resolv/Makefile index bab1ac24a6..126da0736a 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -28,7 +28,8 @@ headers := resolv.h bits/types/res_state.h \ sys/bitypes.h routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ - res_hconf res_libc res-state res_randomid res-close + res_hconf res_libc res-state res_randomid res-close \ + resolv_context tests = tst-aton tst-leaks tst-inet_ntop xtests = tst-leaks2 diff --git a/resolv/Versions b/resolv/Versions index f528ed51e8..b05778d965 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -26,8 +26,12 @@ libc { __h_errno; __resp; - __res_maybe_init; __res_iclose; + __res_iclose; __inet_pton_length; + __resolv_context_get; + __resolv_context_get_preinit; + __resolv_context_get_override; + __resolv_context_put; } } @@ -79,7 +83,9 @@ libresolv { # Needed in libnss_dns. __ns_name_unpack; __ns_name_ntop; __ns_get16; __ns_get32; - __libc_res_nquery; __libc_res_nsearch; + __res_context_query; + __res_context_search; + __res_context_hostalias; } } diff --git a/resolv/compat-gethnamaddr.c b/resolv/compat-gethnamaddr.c index 813c7d4e85..259378b2be 100644 --- a/resolv/compat-gethnamaddr.c +++ b/resolv/compat-gethnamaddr.c @@ -67,6 +67,7 @@ # include # include # include +# include # include # include # include @@ -84,6 +85,9 @@ static u_char host_addr[16]; /* IPv4 or IPv6 */ static FILE *hostf = NULL; static int stayopen = 0; +static struct hostent *res_gethostbyname2_context (struct resolv_context *, + const char *name, int af); + static void map_v4v6_address (const char *src, char *dst) __THROW; static void map_v4v6_hostent (struct hostent *hp, char **bp, int *len) __THROW; @@ -428,23 +432,31 @@ libresolv_hidden_proto (res_gethostbyname2) struct hostent * res_gethostbyname (const char *name) { - struct hostent *hp; - - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - if (res_use_inet6 ()) { - hp = res_gethostbyname2(name, AF_INET6); - if (hp) - return (hp); + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + + if (res_use_inet6 ()) + { + struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET6); + if (hp != NULL) + { + __resolv_context_put (ctx); + return hp; } - return (res_gethostbyname2(name, AF_INET)); + } + struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET); + __resolv_context_put (ctx); + return hp; } compat_symbol (libresolv, res_gethostbyname, res_gethostbyname, GLIBC_2_0); -struct hostent * -res_gethostbyname2 (const char *name, int af) +static struct hostent * +res_gethostbyname2_context (struct resolv_context *ctx, + const char *name, int af) { union { @@ -457,11 +469,6 @@ res_gethostbyname2 (const char *name, int af) int n, size, type, len; struct hostent *ret; - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - switch (af) { case AF_INET: size = INADDRSZ; @@ -485,8 +492,10 @@ res_gethostbyname2 (const char *name, int af) * 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))) - name = cp; + char abuf[MAXDNAME]; + if (strchr (name, '.') != NULL + && (cp = __res_context_hostalias (ctx, name, abuf, sizeof (abuf)))) + name = cp; /* * disallow names consisting only of digits/dots, unless @@ -558,8 +567,9 @@ res_gethostbyname2 (const char *name, int af) buf.buf = origbuf = (querybuf *) alloca (1024); - if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, - &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { + if ((n = __res_context_search + (ctx, name, C_IN, type, buf.buf->buf, 1024, + &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { if (buf.buf != origbuf) free (buf.buf); Dprintf("res_nsearch failed (%d)\n", n); @@ -572,11 +582,26 @@ res_gethostbyname2 (const char *name, int af) free (buf.buf); return ret; } + +struct hostent * +res_gethostbyname2 (const char *name, int af) +{ + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET); + __resolv_context_put (ctx); + return hp; +} libresolv_hidden_def (res_gethostbyname2) compat_symbol (libresolv, res_gethostbyname2, res_gethostbyname2, GLIBC_2_0); -struct hostent * -res_gethostbyaddr (const void *addr, socklen_t len, int af) +static struct hostent * +res_gethostbyaddr_context (struct resolv_context *ctx, + const void *addr, socklen_t len, int af) { const u_char *uaddr = (const u_char *)addr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; @@ -592,10 +617,6 @@ res_gethostbyaddr (const void *addr, socklen_t len, int af) struct hostent *hp; char qbuf[MAXDNAME+1], *qp = NULL; - if (__res_maybe_init (&_res, 0) == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } if (af == AF_INET6 && len == IN6ADDRSZ && (!memcmp(uaddr, mapped, sizeof mapped) || !memcmp(uaddr, tunnelled, sizeof tunnelled))) { @@ -645,8 +666,8 @@ res_gethostbyaddr (const void *addr, socklen_t len, int af) buf.buf = orig_buf = (querybuf *) alloca (1024); - n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, - &buf.ptr, NULL, NULL, NULL, NULL); + n = __res_context_query (ctx, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, + &buf.ptr, NULL, NULL, NULL, NULL); if (n < 0) { if (buf.buf != orig_buf) free (buf.buf); @@ -673,6 +694,20 @@ res_gethostbyaddr (const void *addr, socklen_t len, int af) __set_h_errno (NETDB_SUCCESS); return (hp); } + +struct hostent * +res_gethostbyaddr (const void *addr, socklen_t len, int af) +{ + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + struct hostent *hp = res_gethostbyaddr_context (ctx, addr, len, af); + __resolv_context_put (ctx); + return hp; +} compat_symbol (libresolv, res_gethostbyaddr, res_gethostbyaddr, GLIBC_2_0); void diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c index 4276eb6542..7a5c39dc20 100644 --- a/resolv/nss_dns/dns-canon.c +++ b/resolv/nss_dns/dns-canon.c @@ -23,7 +23,8 @@ #include #include #include - +#include +#include #if PACKETSZ > 65536 # define MAXPACKET PACKETSZ @@ -58,11 +59,19 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, } ansp = { .ptr = buf }; enum nss_status status = NSS_STATUS_UNAVAIL; + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + *errnop = errno; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } + for (int i = 0; i < nqtypes; ++i) { - int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i], - buf, sizeof (buf), &ansp.ptr, NULL, NULL, - NULL, NULL); + int r = __res_context_query (ctx, name, ns_c_in, qtypes[i], + buf, sizeof (buf), &ansp.ptr, NULL, NULL, + NULL, NULL); if (r > 0) { /* We need to decode the response. Just one question record. @@ -168,6 +177,6 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, if (ansp.ptr != buf) free (ansp.ptr); - + __resolv_context_put (ctx); return status; } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 206924de86..9d7ceb1691 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -84,6 +84,7 @@ /* Get implementeation for some internal functions. */ #include +#include #include #include @@ -121,13 +122,13 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, int *errnop, int *h_errnop, int32_t *ttlp); -extern enum nss_status _nss_dns_gethostbyname3_r (const char *name, int af, - struct hostent *result, - char *buffer, size_t buflen, - int *errnop, int *h_errnop, - int32_t *ttlp, - char **canonp); -hidden_proto (_nss_dns_gethostbyname3_r) +static enum nss_status gethostbyname3_context (struct resolv_context *ctx, + const char *name, int af, + struct hostent *result, + char *buffer, size_t buflen, + int *errnop, int *h_errnop, + int32_t *ttlp, + char **canonp); /* Return the expected RDATA length for an address record type (A or AAAA). */ @@ -145,10 +146,30 @@ rrtype_to_rdata_length (int type) } } + enum nss_status _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop, int32_t *ttlp, char **canonp) +{ + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + *errnop = errno; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } + enum nss_status status = gethostbyname3_context + (ctx, name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp); + __resolv_context_put (ctx); + return status; +} + +static enum nss_status +gethostbyname3_context (struct resolv_context *ctx, + const char *name, int af, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop, int32_t *ttlp, char **canonp) { union { @@ -163,13 +184,6 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, int olderr = errno; enum nss_status status; - if (__res_maybe_init (&_res, 0) == -1) - { - *errnop = errno; - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_UNAVAIL; - } - switch (af) { case AF_INET: size = INADDRSZ; @@ -194,13 +208,13 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, * function that looks up host names. */ if (strchr (name, '.') == NULL - && (cp = res_hostalias (&_res, name, tmp, sizeof (tmp))) != NULL) + && (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL) name = cp; host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); - n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, - 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf, + 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); if (n < 0) { switch (errno) @@ -232,10 +246,10 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, by having the RES_USE_INET6 bit in _res.options set, we try another lookup. */ if (af == AF_INET6 && res_use_inet6 ()) - n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, - host_buffer.buf != orig_host_buffer - ? MAXPACKET : 1024, &host_buffer.ptr, - NULL, NULL, NULL, NULL); + n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf, + host_buffer.buf != orig_host_buffer + ? MAXPACKET : 1024, &host_buffer.ptr, + NULL, NULL, NULL, NULL); if (n < 0) { @@ -256,8 +270,6 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, free (host_buffer.buf); return status; } -hidden_def (_nss_dns_gethostbyname3_r) - enum nss_status _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result, @@ -274,15 +286,21 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop) { + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) + { + *errnop = errno; + *h_errnop = NETDB_INTERNAL; + return NSS_STATUS_UNAVAIL; + } enum nss_status status = NSS_STATUS_NOTFOUND; - if (res_use_inet6 ()) - status = _nss_dns_gethostbyname3_r (name, AF_INET6, result, buffer, - buflen, errnop, h_errnop, NULL, NULL); + status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, + buflen, errnop, h_errnop, NULL, NULL); if (status == NSS_STATUS_NOTFOUND) - status = _nss_dns_gethostbyname3_r (name, AF_INET, result, buffer, - buflen, errnop, h_errnop, NULL, NULL); - + status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, + buflen, errnop, h_errnop, NULL, NULL); + __resolv_context_put (ctx); return status; } @@ -292,7 +310,8 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { - if (__res_maybe_init (&_res, 0) == -1) + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) { *errnop = errno; *herrnop = NETDB_INTERNAL; @@ -307,7 +326,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, if (strchr (name, '.') == NULL) { char *tmp = alloca (NS_MAXDNAME); - const char *cp = res_hostalias (&_res, name, tmp, NS_MAXDNAME); + const char *cp = __res_context_hostalias (ctx, name, tmp, NS_MAXDNAME); if (cp != NULL) name = cp; } @@ -326,9 +345,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, int olderr = errno; enum nss_status status; - int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA, - host_buffer.buf->buf, 2048, &host_buffer.ptr, - &ans2p, &nans2p, &resplen2, &ans2p_malloced); + int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, + host_buffer.buf->buf, 2048, &host_buffer.ptr, + &ans2p, &nans2p, &resplen2, &ans2p_malloced); if (n >= 0) { status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, @@ -371,6 +390,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, if (host_buffer.buf != orig_host_buffer) free (host_buffer.buf); + __resolv_context_put (ctx); return status; } @@ -423,7 +443,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, host_data = (struct host_data *) buffer; - if (__res_maybe_init (&_res, 0) == -1) + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) { *errnop = errno; *h_errnop = NETDB_INTERNAL; @@ -453,12 +474,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, default: *errnop = EAFNOSUPPORT; *h_errnop = NETDB_INTERNAL; + __resolv_context_put (ctx); return NSS_STATUS_UNAVAIL; } if (size > len) { *errnop = EAFNOSUPPORT; *h_errnop = NETDB_INTERNAL; + __resolv_context_put (ctx); return NSS_STATUS_UNAVAIL; } @@ -487,14 +510,15 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, break; } - n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, - 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf, + 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); if (n < 0) { *h_errnop = h_errno; __set_errno (olderr); if (host_buffer.buf != orig_host_buffer) free (host_buffer.buf); + __resolv_context_put (ctx); return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } @@ -503,7 +527,10 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, if (host_buffer.buf != orig_host_buffer) free (host_buffer.buf); if (status != NSS_STATUS_SUCCESS) - return status; + { + __resolv_context_put (ctx); + return status; + } result->h_addrtype = af; result->h_length = len; @@ -511,6 +538,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, host_data->h_addr_ptrs[0] = (char *) host_data->host_addr; host_data->h_addr_ptrs[1] = NULL; *h_errnop = NETDB_SUCCESS; + __resolv_context_put (ctx); return NSS_STATUS_SUCCESS; } hidden_def (_nss_dns_gethostbyaddr2_r) diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index dc1599b471..f190eb2225 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -67,6 +67,8 @@ #include "nsswitch.h" #include #include +#include +#include /* Maximum number of aliases we allow. */ #define MAX_NR_ALIASES 48 @@ -115,7 +117,8 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, int anslen; enum nss_status status; - if (__res_maybe_init (&_res, 0) == -1) + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) { *errnop = errno; *herrnop = NETDB_INTERNAL; @@ -124,14 +127,16 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); - anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf, - 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + anslen = __res_context_search + (ctx, name, C_IN, T_PTR, net_buffer.buf->buf, + 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); if (anslen < 0) { /* Nothing found. */ *errnop = errno; if (net_buffer.buf != orig_net_buffer) free (net_buffer.buf); + __resolv_context_put (ctx); return (errno == ECONNREFUSED || errno == EPFNOSUPPORT || errno == EAFNOSUPPORT) @@ -142,6 +147,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, errnop, herrnop, BYNAME); if (net_buffer.buf != orig_net_buffer) free (net_buffer.buf); + __resolv_context_put (ctx); return status; } @@ -169,7 +175,8 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, if (type != AF_INET) return NSS_STATUS_UNAVAIL; - if (__res_maybe_init (&_res, 0) == -1) + struct resolv_context *ctx = __resolv_context_get (); + if (ctx == NULL) { *errnop = errno; *herrnop = NETDB_INTERNAL; @@ -204,8 +211,8 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); - anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, - 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + anslen = __res_context_query (ctx, qbuf, C_IN, T_PTR, net_buffer.buf->buf, + 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); if (anslen < 0) { /* Nothing found. */ @@ -213,6 +220,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, __set_errno (olderr); if (net_buffer.buf != orig_net_buffer) free (net_buffer.buf); + __resolv_context_put (ctx); return (err == ECONNREFUSED || err == EPFNOSUPPORT || err == EAFNOSUPPORT) @@ -233,6 +241,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, result->n_net = u_net; } + __resolv_context_put (ctx); return status; } diff --git a/resolv/res-close.c b/resolv/res-close.c index 73f18d1525..97da73c99c 100644 --- a/resolv/res-close.c +++ b/resolv/res-close.c @@ -83,6 +83,7 @@ */ #include +#include #include /* Close all open sockets. If FREE_ADDR is true, deallocate any @@ -124,6 +125,8 @@ libc_hidden_def (__res_nclose) static void __attribute__ ((section ("__libc_thread_freeres_fn"))) res_thread_freeres (void) { + __resolv_context_freeres (); + if (_res.nscount == 0) /* Never called res_ninit. */ return; diff --git a/resolv/res_libc.c b/resolv/res_libc.c index 3d7b4f72d0..5066983ccf 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -98,37 +98,6 @@ res_init (void) return __res_vinit (&_res, 1); } - -/* Initialize *RESP if RES_INIT is not yet set in RESP->options, or if - res_init in some other thread requested re-initializing. */ -int -__res_maybe_init (res_state resp, int preinit) -{ - if (resp->options & RES_INIT) - { - if (__res_initstamp != resp->_u._ext.initstamp) - { - if (resp->nscount > 0) - __res_iclose (resp, true); - return __res_vinit (resp, 1); - } - return 0; - } - else if (preinit) - { - if (!resp->retrans) - resp->retrans = RES_TIMEOUT; - if (!resp->retry) - resp->retry = RES_DFLRETRY; - resp->options = RES_DEFAULT; - if (!resp->id) - resp->id = res_randomid (); - return __res_vinit (resp, 1); - } - else - return __res_ninit (resp); -} -libc_hidden_def (__res_maybe_init) /* This needs to be after the use of _res in res_init, above. */ #undef _res diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index 9afb410980..59fc5ab28c 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -88,6 +88,7 @@ #include #include #include +#include #include #include #include @@ -98,22 +99,10 @@ # define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; } #endif -/* Form all types of queries. Returns the size of the result or -1 on - error. - - STATP points to an initialized resolver state. OP is the opcode of - the query. DNAME is the domain. CLASS and TYPE are the DNS query - class and type. DATA can be NULL; otherwise, it is a pointer to a - domain name which is included in the generated packet (if op == - NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes. - - DATALEN and NEWRR_IN are currently ignored. */ int -res_nmkquery (res_state statp, int op, const char *dname, - int class, int type, - const unsigned char *data, int datalen, - const unsigned char *newrr_in, - unsigned char *buf, int buflen) +__res_context_mkquery (struct resolv_context *ctx, int op, const char *dname, + int class, int type, const unsigned char *data, + unsigned char *buf, int buflen) { HEADER *hp; unsigned char *cp; @@ -132,22 +121,17 @@ res_nmkquery (res_state statp, int op, const char *dname, by one after the initial randomization which still predictable if the application does multiple requests. */ int randombits; - do - { #ifdef RANDOM_BITS - RANDOM_BITS (randombits); + RANDOM_BITS (randombits); #else - struct timeval tv; - __gettimeofday (&tv, NULL); - randombits = (tv.tv_sec << 8) ^ tv.tv_usec; + struct timeval tv; + __gettimeofday (&tv, NULL); + randombits = (tv.tv_sec << 8) ^ tv.tv_usec; #endif - } - while ((randombits & 0xffff) == 0); - statp->id = (statp->id + randombits) & 0xffff; - hp->id = statp->id; + hp->id = randombits; hp->opcode = op; - hp->rd = (statp->options & RES_RECURSE) != 0; + hp->rd = (ctx->resp->options & RES_RECURSE) != 0; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; buflen -= HFIXEDSZ; @@ -201,7 +185,45 @@ res_nmkquery (res_state statp, int op, const char *dname, } return cp - buf; } -libresolv_hidden_def (res_nmkquery) + +/* Common part of res_nmkquery and res_mkquery. */ +static int +context_mkquery_common (struct resolv_context *ctx, + int op, const char *dname, int class, int type, + const unsigned char *data, + unsigned char *buf, int buflen) +{ + if (ctx == NULL) + return -1; + int result = __res_context_mkquery + (ctx, op, dname, class, type, data, buf, buflen); + if (result >= 2) + memcpy (&ctx->resp->id, buf, 2); + __resolv_context_put (ctx); + return result; +} + +/* Form all types of queries. Returns the size of the result or -1 on + error. + + STATP points to an initialized resolver state. OP is the opcode of + the query. DNAME is the domain. CLASS and TYPE are the DNS query + class and type. DATA can be NULL; otherwise, it is a pointer to a + domain name which is included in the generated packet (if op == + NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes. + + DATALEN and NEWRR_IN are currently ignored. */ +int +res_nmkquery (res_state statp, int op, const char *dname, + int class, int type, + const unsigned char *data, int datalen, + const unsigned char *newrr_in, + unsigned char *buf, int buflen) +{ + return context_mkquery_common + (__resolv_context_get_override (statp), + op, dname, class, type, data, buf, buflen); +} int res_mkquery (int op, const char *dname, int class, int type, @@ -209,13 +231,9 @@ res_mkquery (int op, const char *dname, int class, int type, const unsigned char *newrr_in, unsigned char *buf, int buflen) { - if (__res_maybe_init (&_res, 1) == -1) - { - RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); - return -1; - } - return res_nmkquery (&_res, op, dname, class, type, - data, datalen, newrr_in, buf, buflen); + return context_mkquery_common + (__resolv_context_get_preinit (), + op, dname, class, type, data, buf, buflen); } /* Create an OPT resource record. Return the length of the final @@ -227,8 +245,8 @@ res_mkquery (int op, const char *dname, int class, int type, pointers to must be BUFLEN bytes long. ANSLEN is the advertised EDNS buffer size (to be included in the OPT resource record). */ int -__res_nopt (res_state statp, int n0, unsigned char *buf, int buflen, - int anslen) +__res_nopt (struct resolv_context *ctx, + int n0, unsigned char *buf, int buflen, int anslen) { uint16_t flags = 0; HEADER *hp = (HEADER *) buf; @@ -269,7 +287,7 @@ __res_nopt (res_state statp, int n0, unsigned char *buf, int buflen, *cp++ = NOERROR; /* Extended RCODE. */ *cp++ = 0; /* EDNS version. */ - if (statp->options & RES_USE_DNSSEC) + if (ctx->resp->options & RES_USE_DNSSEC) flags |= NS_OPT_DNSSEC_OK; NS_PUT16 (flags, cp); diff --git a/resolv/res_query.c b/resolv/res_query.c index 760bf324e8..33249e36f5 100644 --- a/resolv/res_query.c +++ b/resolv/res_query.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -89,33 +90,28 @@ #define QUERYSIZE (HFIXEDSZ + QFIXEDSZ + MAXCDNAME + 1) static int -__libc_res_nquerydomain(res_state statp, const char *name, const char *domain, - int class, int type, u_char *answer, int anslen, - u_char **answerp, u_char **answerp2, int *nanswerp2, - int *resplen2, int *answerp2_malloced); - -/* - * Formulate a normal query, send, and await answer. - * Returned answer is placed in supplied buffer "answer". - * Perform preliminary check of answer, returning success only - * if no error is indicated and the answer count is nonzero. - * Return the size of the response on success, -1 on error. - * Error number is left in H_ERRNO. - * - * Caller must parse answer and determine whether it answers the question. - */ +__res_context_querydomain (struct resolv_context *, + const char *name, const char *domain, + int class, int type, unsigned char *answer, int anslen, + unsigned char **answerp, unsigned char **answerp2, int *nanswerp2, + int *resplen2, int *answerp2_malloced); + +/* Formulate a normal query, send, and await answer. Returned answer + is placed in supplied buffer ANSWER. Perform preliminary check of + answer, returning success only if no error is indicated and the + answer count is nonzero. Return the size of the response on + success, -1 on error. Error number is left in h_errno. + + Caller must parse answer and determine whether it answers the + question. */ int -__libc_res_nquery(res_state statp, - const char *name, /* domain name */ - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen, /* size of answer buffer */ - u_char **answerp, /* if buffer needs to be enlarged */ - u_char **answerp2, - int *nanswerp2, - int *resplen2, - int *answerp2_malloced) +__res_context_query (struct resolv_context *ctx, const char *name, + int class, int type, + unsigned char *answer, int anslen, + unsigned char **answerp, unsigned char **answerp2, + int *nanswerp2, int *resplen2, int *answerp2_malloced) { + struct __res_state *statp = ctx->resp; HEADER *hp = (HEADER *) answer; HEADER *hp2; int n, use_malloc = 0; @@ -132,15 +128,15 @@ __libc_res_nquery(res_state statp, if (type == T_QUERY_A_AND_AAAA) { - n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL, - query1, bufsize); + n = __res_context_mkquery (ctx, QUERY, name, class, T_A, NULL, + query1, bufsize); if (n > 0) { if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) { /* Use RESOLV_EDNS_BUFFER_SIZE because the receive buffer can be reallocated. */ - n = __res_nopt (statp, n, query1, bufsize, + n = __res_nopt (ctx, n, query1, bufsize, RESOLV_EDNS_BUFFER_SIZE); if (n < 0) goto unspec_nomem; @@ -157,13 +153,13 @@ __libc_res_nquery(res_state statp, } int nused = n + npad; query2 = buf + nused; - n = res_nmkquery(statp, QUERY, name, class, T_AAAA, NULL, 0, - NULL, query2, bufsize - nused); + n = __res_context_mkquery (ctx, QUERY, name, class, T_AAAA, + NULL, query2, bufsize - nused); if (n > 0 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) /* Use RESOLV_EDNS_BUFFER_SIZE because the receive buffer can be reallocated. */ - n = __res_nopt (statp, n, query2, bufsize, + n = __res_nopt (ctx, n, query2, bufsize, RESOLV_EDNS_BUFFER_SIZE); nquery2 = n; } @@ -172,8 +168,8 @@ __libc_res_nquery(res_state statp, } else { - n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, - query1, bufsize); + n = __res_context_mkquery (ctx, QUERY, name, class, type, NULL, + query1, bufsize); if (n > 0 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) @@ -185,7 +181,7 @@ __libc_res_nquery(res_state statp, advertise = anslen; else advertise = RESOLV_EDNS_BUFFER_SIZE; - n = __res_nopt (statp, n, query1, bufsize, advertise); + n = __res_nopt (ctx, n, query1, bufsize, advertise); } nquery1 = n; @@ -209,9 +205,9 @@ __libc_res_nquery(res_state statp, return (n); } assert (answerp == NULL || (void *) *answerp == (void *) answer); - n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, - anslen, answerp, answerp2, nanswerp2, resplen2, - answerp2_malloced); + n = __res_context_send (ctx, query1, nquery1, query2, nquery2, answer, + anslen, answerp, answerp2, nanswerp2, resplen2, + answerp2_malloced); if (use_malloc) free (buf); if (n < 0) { @@ -220,7 +216,7 @@ __libc_res_nquery(res_state statp, } if (answerp != NULL) - /* __libc_res_nsend might have reallocated the buffer. */ + /* __res_context_send might have reallocated the buffer. */ hp = (HEADER *) *answerp; /* We simplify the following tests by assigning HP to HP2 or @@ -280,7 +276,24 @@ __libc_res_nquery(res_state statp, success: return (n); } -libresolv_hidden_def (__libc_res_nquery) +libresolv_hidden_def (__res_context_query) + +/* Common part of res_nquery and res_query. */ +static int +context_query_common (struct resolv_context *ctx, + const char *name, int class, int type, + unsigned char *answer, int anslen) +{ + if (ctx == NULL) + { + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return -1; + } + int result = __res_context_query (ctx, name, class, type, answer, anslen, + NULL, NULL, NULL, NULL, NULL); + __resolv_context_put (ctx); + return result; +} int res_nquery(res_state statp, @@ -289,41 +302,30 @@ res_nquery(res_state statp, u_char *answer, /* buffer to put answer */ int anslen) /* size of answer buffer */ { - return __libc_res_nquery(statp, name, class, type, answer, anslen, - NULL, NULL, NULL, NULL, NULL); + return context_query_common + (__resolv_context_get_override (statp), name, class, type, answer, anslen); } -libresolv_hidden_def (res_nquery) int res_query (const char *name, int class, int type, unsigned char *answer, int anslen) { - if (__res_maybe_init (&_res, 1) == -1) - { - RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); - return -1; - } - return res_nquery (&_res, name, class, type, answer, anslen); + return context_query_common + (__resolv_context_get (), name, class, type, answer, anslen); } -/* - * Formulate a normal query, send, and retrieve answer in supplied buffer. - * Return the size of the response on success, -1 on error. - * If enabled, implement search rules until answer or unrecoverable failure - * is detected. Error code, if any, is left in H_ERRNO. - */ +/* Formulate a normal query, send, and retrieve answer in supplied + buffer. Return the size of the response on success, -1 on error. + If enabled, implement search rules until answer or unrecoverable + failure is detected. Error code, if any, is left in h_errno. */ int -__libc_res_nsearch(res_state statp, - const char *name, /* domain name */ - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen, /* size of answer */ - u_char **answerp, - u_char **answerp2, - int *nanswerp2, - int *resplen2, - int *answerp2_malloced) +__res_context_search (struct resolv_context *ctx, + const char *name, int class, int type, + unsigned char *answer, int anslen, + unsigned char **answerp, unsigned char **answerp2, + int *nanswerp2, int *resplen2, int *answerp2_malloced) { + struct __res_state *statp = ctx->resp; const char *cp, * const *domain; HEADER *hp = (HEADER *) answer; char tmp[NS_MAXDNAME]; @@ -344,10 +346,11 @@ __libc_res_nsearch(res_state statp, trailing_dot++; /* If there aren't any dots, it could be a user-level alias. */ - if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) - return (__libc_res_nquery(statp, cp, class, type, answer, - anslen, answerp, answerp2, - nanswerp2, resplen2, answerp2_malloced)); + if (!dots && (cp = __res_context_hostalias + (ctx, name, tmp, sizeof tmp))!= NULL) + return __res_context_query (ctx, cp, class, type, answer, + anslen, answerp, answerp2, + nanswerp2, resplen2, answerp2_malloced); /* * If there are enough dots in the name, let's just give it a @@ -356,10 +359,10 @@ __libc_res_nsearch(res_state statp, */ saved_herrno = -1; if (dots >= statp->ndots || trailing_dot) { - ret = __libc_res_nquerydomain(statp, name, NULL, class, type, - answer, anslen, answerp, - answerp2, nanswerp2, resplen2, - answerp2_malloced); + ret = __res_context_querydomain (ctx, name, NULL, class, type, + answer, anslen, answerp, + answerp2, nanswerp2, resplen2, + answerp2_malloced); if (ret > 0 || trailing_dot /* If the second response is valid then we use that. */ || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) @@ -395,7 +398,7 @@ __libc_res_nsearch(res_state statp, const char *dname = domain[0]; searched = 1; - /* __libc_res_nquerydoman concatenates name + /* __res_context_querydoman concatenates name with dname with a "." in between. If we pass it in dname the "." we got from the configured default search path, we'll end @@ -409,11 +412,10 @@ __libc_res_nsearch(res_state statp, if (dname[0] == '\0') root_on_list++; - ret = __libc_res_nquerydomain(statp, name, dname, - class, type, - answer, anslen, answerp, - answerp2, nanswerp2, - resplen2, answerp2_malloced); + ret = __res_context_querydomain + (ctx, name, dname, class, type, + answer, anslen, answerp, answerp2, nanswerp2, + resplen2, answerp2_malloced); if (ret > 0 || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) return (ret); @@ -481,10 +483,10 @@ __libc_res_nsearch(res_state statp, */ if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0) && !(tried_as_is || root_on_list)) { - ret = __libc_res_nquerydomain(statp, name, NULL, class, type, - answer, anslen, answerp, - answerp2, nanswerp2, resplen2, - answerp2_malloced); + ret = __res_context_querydomain + (ctx, name, NULL, class, type, + answer, anslen, answerp, answerp2, nanswerp2, + resplen2, answerp2_malloced); if (ret > 0 || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) return (ret); @@ -512,7 +514,24 @@ __libc_res_nsearch(res_state statp, RES_SET_H_ERRNO(statp, TRY_AGAIN); return (-1); } -libresolv_hidden_def (__libc_res_nsearch) +libresolv_hidden_def (__res_context_search) + +/* Common part of res_nsearch and res_search. */ +static int +context_search_common (struct resolv_context *ctx, + const char *name, int class, int type, + unsigned char *answer, int anslen) +{ + if (ctx == NULL) + { + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return -1; + } + int result = __res_context_search (ctx, name, class, type, answer, anslen, + NULL, NULL, NULL, NULL, NULL); + __resolv_context_put (ctx); + return result; +} int res_nsearch(res_state statp, @@ -521,40 +540,30 @@ res_nsearch(res_state statp, u_char *answer, /* buffer to put answer */ int anslen) /* size of answer */ { - return __libc_res_nsearch(statp, name, class, type, answer, - anslen, NULL, NULL, NULL, NULL, NULL); + return context_search_common + (__resolv_context_get_override (statp), name, class, type, answer, anslen); } -libresolv_hidden_def (res_nsearch) int res_search (const char *name, int class, int type, unsigned char *answer, int anslen) { - if (__res_maybe_init (&_res, 1) == -1) - { - RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); - return -1; - } - - return res_nsearch (&_res, name, class, type, answer, anslen); + return context_search_common + (__resolv_context_get (), name, class, type, answer, anslen); } -/* - * Perform a call on res_query on the concatenation of name and domain. - */ +/* Perform a call on res_query on the concatenation of name and + domain. */ static int -__libc_res_nquerydomain(res_state statp, - const char *name, - const char *domain, - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen, /* size of answer */ - u_char **answerp, - u_char **answerp2, - int *nanswerp2, - int *resplen2, - int *answerp2_malloced) +__res_context_querydomain (struct resolv_context *ctx, + const char *name, const char *domain, + int class, int type, + unsigned char *answer, int anslen, + unsigned char **answerp, unsigned char **answerp2, + int *nanswerp2, int *resplen2, + int *answerp2_malloced) { + struct __res_state *statp = ctx->resp; char nbuf[MAXDNAME]; const char *longname = nbuf; size_t n, d; @@ -580,9 +589,28 @@ __libc_res_nquerydomain(res_state statp, } sprintf(nbuf, "%s.%s", name, domain); } - return (__libc_res_nquery(statp, longname, class, type, answer, - anslen, answerp, answerp2, nanswerp2, - resplen2, answerp2_malloced)); + return __res_context_query (ctx, longname, class, type, answer, + anslen, answerp, answerp2, nanswerp2, + resplen2, answerp2_malloced); +} + +/* Common part of res_nquerydomain and res_querydomain. */ +static int +context_querydomain_common (struct resolv_context *ctx, + const char *name, const char *domain, + int class, int type, + unsigned char *answer, int anslen) +{ + if (ctx == NULL) + { + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return -1; + } + int result = __res_context_querydomain (ctx, name, domain, class, type, + answer, anslen, + NULL, NULL, NULL, NULL, NULL); + __resolv_context_put (ctx); + return result; } int @@ -593,32 +621,28 @@ res_nquerydomain(res_state statp, u_char *answer, /* buffer to put answer */ int anslen) /* size of answer */ { - return __libc_res_nquerydomain(statp, name, domain, class, type, - answer, anslen, NULL, NULL, NULL, NULL, - NULL); + return context_querydomain_common + (__resolv_context_get_override (statp), + name, domain, class, type, answer, anslen); } -libresolv_hidden_def (res_nquerydomain) int res_querydomain (const char *name, const char *domain, int class, int type, unsigned char *answer, int anslen) { - if (__res_maybe_init (&_res, 1) == -1) - { - RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); - return -1; - } - - return res_nquerydomain (&_res, name, domain, class, type, answer, anslen); + return context_querydomain_common + (__resolv_context_get (), name, domain, class, type, answer, anslen); } const char * -res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { +__res_context_hostalias (struct resolv_context *ctx, + const char *name, char *dst, size_t siz) +{ char *file, *cp1, *cp2; char buf[BUFSIZ]; FILE *fp; - if (statp->options & RES_NOALIASES) + if (ctx->resp->options & RES_NOALIASES) return (NULL); file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "rce")) == NULL) @@ -648,15 +672,37 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { fclose(fp); return (NULL); } -libresolv_hidden_def (res_hostalias) +libresolv_hidden_def (__res_context_hostalias) + +/* Common part of res_hostalias and hostalias. */ +static const char * +context_hostalias_common (struct resolv_context *ctx, + const char *name, char *dst, size_t siz) +{ + if (ctx == NULL) + { + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return NULL; + } + const char *result = __res_context_hostalias (ctx, name, dst, siz); + __resolv_context_put (ctx); + return result; +} + +const char * +res_hostalias (res_state statp, const char *name, char *dst, size_t siz) +{ + return context_hostalias_common + (__resolv_context_get_override (statp), name, dst, siz); +} const char * hostalias (const char *name) { static char abuf[MAXDNAME]; - return res_hostalias (&_res, name, abuf, sizeof abuf); + return context_hostalias_common + (__resolv_context_get (), name, abuf, sizeof (abuf)); } -libresolv_hidden_def (hostalias) #if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2) # undef res_query diff --git a/resolv/res_send.c b/resolv/res_send.c index a7daae8a06..b396aae03c 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -102,6 +102,7 @@ #include #include #include +#include #include #include #include @@ -400,11 +401,14 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, libresolv_hidden_def (res_queriesmatch) int -__libc_res_nsend(res_state statp, const u_char *buf, int buflen, - const u_char *buf2, int buflen2, - u_char *ans, int anssiz, u_char **ansp, u_char **ansp2, - int *nansp2, int *resplen2, int *ansp2_malloced) +__res_context_send (struct resolv_context *ctx, + const unsigned char *buf, int buflen, + const unsigned char *buf2, int buflen2, + unsigned char *ans, int anssiz, + unsigned char **ansp, unsigned char **ansp2, + int *nansp2, int *resplen2, int *ansp2_malloced) { + struct __res_state *statp = ctx->resp; int gotsomewhere, terrno, try, v_circuit, resplen, n; if (statp->nscount == 0) { @@ -541,22 +545,36 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, return (-1); } +/* Common part of res_nsend and res_send. */ +static int +context_send_common (struct resolv_context *ctx, + const unsigned char *buf, int buflen, + unsigned char *ans, int anssiz) +{ + if (ctx == NULL) + { + RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); + return -1; + } + int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz, + NULL, NULL, NULL, NULL, NULL); + __resolv_context_put (ctx); + return result; +} + int -res_nsend(res_state statp, - const u_char *buf, int buflen, u_char *ans, int anssiz) +res_nsend (res_state statp, const unsigned char *buf, int buflen, + unsigned char *ans, int anssiz) { - return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, - NULL, NULL, NULL, NULL, NULL); + return context_send_common + (__resolv_context_get_override (statp), buf, buflen, ans, anssiz); } -libresolv_hidden_def (res_nsend) int res_send (const unsigned char *buf, int buflen, unsigned char *ans, int anssiz) { - if (__res_maybe_init (&_res, 1) == -1) - /* errno should have been set by res_init in this case. */ - return -1; - return res_nsend (&_res, buf, buflen, ans, anssiz); + return context_send_common + (__resolv_context_get (), buf, buflen, ans, anssiz); } /* Private */ diff --git a/resolv/res_use_inet6.h b/resolv/res_use_inet6.h new file mode 100644 index 0000000000..8649833072 --- /dev/null +++ b/resolv/res_use_inet6.h @@ -0,0 +1,49 @@ +/* Support functions for handling RES_USE_INET6 in getaddrinfo/nscd. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _RES_USE_INET6_H +#define _RES_USE_INET6_H + +#include +#include + +/* Ensure that RES_USE_INET6 is disabled in *CTX. Return true if + __resolv_context_enable_inet6 below should enable RES_USE_INET6 + again. */ +static inline bool +__resolv_context_disable_inet6 (struct resolv_context *ctx) +{ + if (ctx != NULL && ctx->resp->options & DEPRECATED_RES_USE_INET6) + { + ctx->resp->options &= ~DEPRECATED_RES_USE_INET6; + return true; + } + else + return false; +} + +/* If ENABLE, re-enable RES_USE_INET6 in *CTX. To be paired with + __resolv_context_disable_inet6. */ +static inline void +__resolv_context_enable_inet6 (struct resolv_context *ctx, bool enable) +{ + if (ctx != NULL && enable) + ctx->resp->options |= DEPRECATED_RES_USE_INET6; +} + +#endif diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h index 5a9faf8de9..9246497196 100644 --- a/resolv/resolv-internal.h +++ b/resolv/resolv-internal.h @@ -52,9 +52,41 @@ enum RESOLV_EDNS_BUFFER_SIZE = 1200, }; +struct resolv_context; + +/* Internal function for implementing res_nmkquery and res_mkquery. + Also used by __res_context_query. */ +int __res_context_mkquery (struct resolv_context *, int op, const char *dname, + int class, int type, const unsigned char *data, + unsigned char *buf, int buflen) attribute_hidden; + +/* Main resolver query function for use within glibc. */ +int __res_context_search (struct resolv_context *, const char *, int, int, + unsigned char *, int, unsigned char **, + unsigned char **, int *, int *, int *); +libresolv_hidden_proto (__res_context_search) + +/* Main resolver query function for use within glibc. */ +int __res_context_query (struct resolv_context *, const char *, int, int, + unsigned char *, int, unsigned char **, + unsigned char **, int *, int *, int *); +libresolv_hidden_proto (__res_context_query) + +/* Internal function used to implement the query and search + functions. */ +int __res_context_send (struct resolv_context *, const unsigned char *, int, + const unsigned char *, int, unsigned char *, + int, unsigned char **, unsigned char **, + int *, int *, int *) attribute_hidden; + +/* Internal function similar to res_hostalias. */ +const char *__res_context_hostalias (struct resolv_context *, + const char *, char *, size_t); +libresolv_hidden_proto (__res_context_hostalias); + /* Add an OPT record to a DNS query. */ -int __res_nopt (res_state, int n0, unsigned char *buf, int buflen, - int anslen) attribute_hidden; +int __res_nopt (struct resolv_context *, int n0, + unsigned char *buf, int buflen, int anslen) attribute_hidden; /* Convert from presentation format (which usually means ASCII printable) to network format (which is usually some kind of binary diff --git a/resolv/resolv_context.c b/resolv/resolv_context.c new file mode 100644 index 0000000000..5083a40419 --- /dev/null +++ b/resolv/resolv_context.c @@ -0,0 +1,201 @@ +/* Temporary, thread-local resolver state. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#include +#include +#include + +/* Currently active struct resolv_context object. This pointer forms + the start of a single-linked list, using the __next member of + struct resolv_context. This list serves two purposes: + + (a) A subsequent call to __resolv_context_get will only increment + the reference counter and will not allocate a new object. The + _res state freshness check is skipped in this case, too. + + (b) The per-thread cleanup function defined by the resolver calls + __resolv_context_freeres, which will deallocate all the context + objects. This avoids the need for cancellation handlers and + the complexity they bring, but it requires heap allocation of + the context object because the per-thread cleanup functions run + only after the stack has been fully unwound (and all on-stack + objects have been deallocated at this point). + + The TLS variable current is updated even in + __resolv_context_get_override, to support case (b) above. This does + not override the per-thread resolver state (as obtained by the + non-res_state function such as __resolv_context_get) in an + observable way because the wrapped context is only used to + implement the res_n* functions in the resolver, and those do not + call back into user code which could indirectly use the per-thread + resolver state. */ +static __thread struct resolv_context *current attribute_tls_model_ie; + +/* Initialize *RESP if RES_INIT is not yet set in RESP->options, or if + res_init in some other thread requested re-initializing. */ +static __attribute__ ((warn_unused_result)) bool +maybe_init (struct __res_state *resp, bool preinit) +{ + if (resp->options & RES_INIT) + { + if (__res_initstamp != resp->_u._ext.initstamp) + { + if (resp->nscount > 0) + __res_iclose (resp, true); + return __res_vinit (resp, 1) == 0; + } + return true; + } + + if (preinit) + { + if (!resp->retrans) + resp->retrans = RES_TIMEOUT; + if (!resp->retry) + resp->retry = RES_DFLRETRY; + resp->options = RES_DEFAULT; + if (!resp->id) + resp->id = res_randomid (); + } + return __res_vinit (resp, preinit) == 0; +} + +/* Allocate a new context object and initialize it. The object is put + on the current list. */ +static struct resolv_context * +context_alloc (struct __res_state *resp) +{ + struct resolv_context *ctx = malloc (sizeof (*ctx)); + if (ctx == NULL) + return NULL; + ctx->resp = resp; + ctx->__refcount = 1; + ctx->__from_res = true; + ctx->__next = current; + current = ctx; + return ctx; +} + +/* Deallocate the context object and all the state within. */ +static void +context_free (struct resolv_context *ctx) +{ + current = ctx->__next; + free (ctx); +} + +/* Reuse the current context object. */ +static struct resolv_context * +context_reuse (void) +{ + /* A context object created by __resolv_context_get_override cannot + be reused. */ + assert (current->__from_res); + + ++current->__refcount; + + /* Check for reference counter wraparound. This can only happen if + the get/put functions are not properly paired. */ + assert (current->__refcount > 0); + + return current; +} + +/* Backing function for the __resolv_context_get family of + functions. */ +static struct resolv_context * +context_get (bool preinit) +{ + if (current != NULL) + return context_reuse (); + + struct resolv_context *ctx = context_alloc (&_res); + if (ctx == NULL) + return NULL; + if (!maybe_init (ctx->resp, preinit)) + { + context_free (ctx); + return NULL; + } + return ctx; +} + +struct resolv_context * +__resolv_context_get (void) +{ + return context_get (false); +} +libc_hidden_def (__resolv_context_get) + +struct resolv_context * +__resolv_context_get_preinit (void) +{ + return context_get (true); +} +libc_hidden_def (__resolv_context_get_preinit) + +struct resolv_context * +__resolv_context_get_override (struct __res_state *resp) +{ + /* NB: As explained asbove, context_alloc will put the context on + the current list. */ + struct resolv_context *ctx = context_alloc (resp); + if (ctx == NULL) + return NULL; + + ctx->__from_res = false; + return ctx; +} +libc_hidden_def (__resolv_context_get_override) + +void +__resolv_context_put (struct resolv_context *ctx) +{ + if (ctx == NULL) + return; + + /* NB: Callers assume that this function preserves errno and + h_errno. */ + + assert (current == ctx); + assert (ctx->__refcount > 0); + + if (ctx->__from_res && --ctx->__refcount > 0) + /* Do not pop this context yet. */ + return; + + context_free (ctx); +} +libc_hidden_def (__resolv_context_put) + +void +__resolv_context_freeres (void) +{ + /* Deallocate the entire chain of context objects. */ + struct resolv_context *ctx = current; + current = NULL; + while (ctx != NULL) + { + struct resolv_context *next = ctx->__next; + context_free (ctx); + ctx = next; + } +} diff --git a/resolv/resolv_context.h b/resolv/resolv_context.h new file mode 100644 index 0000000000..27c8d56b36 --- /dev/null +++ b/resolv/resolv_context.h @@ -0,0 +1,95 @@ +/* Temporary, thread-local resolver state. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* struct resolv_context objects are allocated on the heap, + initialized by __resolv_context_get (and its variants), and + destroyed by __resolv_context_put. + + A nested call to __resolv_context_get (after another call to + __resolv_context_get without a matching __resolv_context_put call, + on the same thread) returns the original pointer, instead of + allocating a new context. This prevents unexpected reloading of + the resolver configuration. Care is taken to keep the context in + sync with the thread-local _res object. (This does not happen with + __resolv_context_get_override, and __resolv_context_get_no_inet6 may + also interpose another context object if RES_USE_INET6 needs to be + disabled.) + + In contrast to struct __res_state, struct resolv_context is not + affected by ABI compatibility concerns. + + For the benefit of the res_n* functions, a struct __res_state + pointer is included in the context object, and a separate + initialization function is provided. */ + +#ifndef _RESOLV_CONTEXT_H +#define _RESOLV_CONTEXT_H + +#include +#include +#include + +/* Temporary resolver state. */ +struct resolv_context +{ + struct __res_state *resp; /* Backing resolver state. */ + + + /* The following fields are for internal use within the + resolv_context module. */ + size_t __refcount; /* Count of reusages by the get functions. */ + bool __from_res; /* True if created from _res. */ + + /* If RES_USE_INET6 was disabled at this level, this field points to + the previous context. */ + struct resolv_context *__next; +}; + +/* Return the current temporary resolver context, or NULL if there was + an error (indicated by errno). A call to this function must be + paired with a call to __resolv_context_put. */ +struct resolv_context *__resolv_context_get (void) + __attribute__ ((warn_unused_result)); +libc_hidden_proto (__resolv_context_get) + +/* Deallocate the temporary resolver context. Converse of + __resolv_context_get. Restore the RES_USE_INET6 flag if necessary. + Do nothing if CTX is NULL. */ +void __resolv_context_put (struct resolv_context *ctx); +libc_hidden_proto (__resolv_context_put) + +/* Like __resolv_context_get, but the _res structure can be partially + initialzed and those changes will not be overwritten. */ +struct resolv_context *__resolv_context_get_preinit (void) + __attribute__ ((warn_unused_result)); +libc_hidden_proto (__resolv_context_get_preinit) + +/* Wrap a struct __res_state object in a struct resolv_context object. + A call to this function must be paired with a call to + __resolv_context_put. */ +struct resolv_context *__resolv_context_get_override (struct __res_state *) + __attribute__ ((nonnull (1), warn_unused_result)); +libc_hidden_proto (__resolv_context_get_override) + +/* Called during thread shutdown to free the associated resolver + context (mostly in response to cancellation, otherwise the + __resolv_context_get/__resolv_context_put pairing will already have + deallocated the context object). */ +void __resolv_context_freeres (void) attribute_hidden; + +#endif /* _RESOLV_CONTEXT_H */ diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 4fb1eaef79..efa7118498 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -60,6 +60,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include #include #include #include @@ -266,7 +268,8 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, if (herrno == NETDB_INTERNAL) \ { \ __set_h_errno (herrno); \ - _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \ + __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ + __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ goto free_and_return; \ } \ @@ -279,7 +282,8 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, { \ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \ { \ - _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \ + __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ + __resolv_context_put (res_ctx); \ result = -EAI_SYSTEM; \ goto free_and_return; \ } \ @@ -582,7 +586,8 @@ gaih_inet (const char *name, const struct gaih_service *service, enum nss_status inet6_status = NSS_STATUS_UNAVAIL; enum nss_status status = NSS_STATUS_UNAVAIL; int no_more; - int old_res_options; + struct resolv_context *res_ctx = NULL; + bool res_enable_inet6 = false; /* If we do not have to look for IPv6 addresses or the canonical name, use the simple, old functions, which do not support @@ -765,16 +770,14 @@ gaih_inet (const char *name, const struct gaih_service *service, no_more = 0; nip = __nss_hosts_database; - /* Initialize configurations. */ - if (__res_maybe_init (&_res, 0) == -1) - no_more = 1; - /* If we are looking for both IPv4 and IPv6 address we don't want the lookup functions to automatically promote IPv4 - addresses to IPv6 addresses. Currently this is decided - by setting the RES_USE_INET6 bit in _res.options. */ - old_res_options = _res.options; - _res.options &= ~DEPRECATED_RES_USE_INET6; + addresses to IPv6 addresses, so we use the no_inet6 + function variant. */ + res_ctx = __resolv_context_get (); + res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx); + if (res_ctx == NULL) + no_more = 1; while (!no_more) { @@ -811,8 +814,9 @@ gaih_inet (const char *name, const struct gaih_service *service, if (!scratch_buffer_grow (tmpbuf)) { - _res.options - |= old_res_options & DEPRECATED_RES_USE_INET6; + __resolv_context_enable_inet6 + (res_ctx, res_enable_inet6); + __resolv_context_put (res_ctx); result = -EAI_MEMORY; goto free_and_return; } @@ -911,9 +915,9 @@ gaih_inet (const char *name, const struct gaih_service *service, canonbuf = getcanonname (nip, at, name); if (canonbuf == NULL) { - _res.options - |= old_res_options - & DEPRECATED_RES_USE_INET6; + __resolv_context_enable_inet6 + (res_ctx, res_enable_inet6); + __resolv_context_put (res_ctx); result = -EAI_MEMORY; goto free_and_return; } @@ -953,7 +957,8 @@ gaih_inet (const char *name, const struct gaih_service *service, nip = nip->next; } - _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; + __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); + __resolv_context_put (res_ctx); if (h_errno == NETDB_INTERNAL) { -- cgit v1.2.3 From 754034c4292ba6824ef357258308e6bafa6e0dfd Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 22 Nov 2017 22:21:10 +0000 Subject: Obsolete p_secstodate. This patch, relative to a tree with (pending review) applied, obsoletes p_secstodate, making the underlying function __p_secstodate into a compat symbol not available for new binaries or ports. The calls in ns_print.c (part of incomplete handling of TKEY) are changed to use %lu to print times instead of trying to pretty-print the times any more. Tested for x86_64. * resolv/res_debug.c (p_secstodate): Condition definition on [SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)]. Define directly as __p_secstodate, and as a compat symbol. Do not use libresolv_hidden_def. * resolv/resolv.h (p_secstodate): Remove macro and function declaration. * resolv/ns_print.c (ns_sprintrrf): Print times with %lu, not using p_secstodate. * include/resolv.h (__p_secstodate): Do not use libresolv_hidden_proto. * resolv/Makefile (tests): Move tst-p_secstodate to .... (tests-internal): ... here. * resolv/tst-p_secstodate.c: Include . Condition all contents on [TEST_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)] and declare and use __p_secstodate and use compat_symbol_reference in that case. [!TEST_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)] (do_test): Add implementation returning 77. --- ChangeLog | 19 +++++++++++++++++++ NEWS | 3 +++ include/resolv.h | 1 - resolv/Makefile | 4 +++- resolv/ns_print.c | 4 ++-- resolv/res_debug.c | 10 ++++++---- resolv/resolv.h | 2 -- resolv/tst-p_secstodate.c | 27 ++++++++++++++++++++++----- 8 files changed, 55 insertions(+), 15 deletions(-) (limited to 'include/resolv.h') diff --git a/ChangeLog b/ChangeLog index ba239a47a2..1598052abe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2017-11-22 Joseph Myers + * resolv/res_debug.c (p_secstodate): Condition definition on + [SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)]. Define + directly as __p_secstodate, and as a compat symbol. Do not use + libresolv_hidden_def. + * resolv/resolv.h (p_secstodate): Remove macro and function + declaration. + * resolv/ns_print.c (ns_sprintrrf): Print times with %lu, not + using p_secstodate. + * include/resolv.h (__p_secstodate): Do not use + libresolv_hidden_proto. + * resolv/Makefile (tests): Move tst-p_secstodate to .... + (tests-internal): ... here. + * resolv/tst-p_secstodate.c: Include . Condition + all contents on [TEST_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)] + and declare and use __p_secstodate and use compat_symbol_reference + in that case. + [!TEST_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27)] (do_test): Add + implementation returning 77. + [BZ #22463] * resolv/res_debug.c: Include . (p_secstodate): Assert time_t at least as wide as u_long. On diff --git a/NEWS b/NEWS index 1c5da21327..30ff04ea62 100644 --- a/NEWS +++ b/NEWS @@ -66,6 +66,9 @@ Deprecated and removed features, and other changes affecting compatibility: * In the malloc_info output, the element may contain another element, "subheaps", which contains the number of sub-heaps. +* The libresolv function p_secstodate is no longer supported for new + programs. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/include/resolv.h b/include/resolv.h index 634f5525fe..daf4a74777 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -65,7 +65,6 @@ libresolv_hidden_proto (__res_nameinquery) libresolv_hidden_proto (__res_queriesmatch) libresolv_hidden_proto (__b64_ntop) libresolv_hidden_proto (__dn_count_labels) -libresolv_hidden_proto (__p_secstodate) # endif /* _RESOLV_H_ && !_ISOMAC */ #endif diff --git a/resolv/Makefile b/resolv/Makefile index aff671042e..a98a84fa9e 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -55,7 +55,6 @@ tests += \ tst-resolv-network \ tst-resolv-res_init-multi \ tst-resolv-search \ - tst-p_secstodate \ # These tests need libdl. ifeq (yes,$(build-shared)) @@ -77,6 +76,9 @@ endif # This test accesses __inet_ntop_length, an internal libc function. tests-internal += tst-inet_pton +# This test accesses the __p_secstodate compat symbol. +tests-internal += tst-p_secstodate + # This test sends millions of packets and is rather slow. xtests += tst-resolv-qtypes diff --git a/resolv/ns_print.c b/resolv/ns_print.c index f55680c311..d61f5044b1 100644 --- a/resolv/ns_print.c +++ b/resolv/ns_print.c @@ -488,12 +488,12 @@ ns_sprintrrf(const u_char *msg, size_t msglen, /* Inception. */ t = ns_get32(rdata); rdata += NS_INT32SZ; - len = SPRINTF((tmp, "%s ", p_secstodate(t))); + len = SPRINTF((tmp, "%lu ", t)); T(addstr(tmp, len, &buf, &buflen)); /* Experation. */ t = ns_get32(rdata); rdata += NS_INT32SZ; - len = SPRINTF((tmp, "%s ", p_secstodate(t))); + len = SPRINTF((tmp, "%lu ", t)); T(addstr(tmp, len, &buf, &buflen)); /* Mode , Error, Key Size. */ diff --git a/resolv/res_debug.c b/resolv/res_debug.c index a4fbc569b6..7681ad4639 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -1052,6 +1052,7 @@ dn_count_labels(const char *name) { libresolv_hidden_def (__dn_count_labels) +#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27) /* * Make dates expressed in seconds-since-Jan-1-1970 easy to read. * SIG records are required to be printed like this, by the Secure DNS RFC. @@ -1059,7 +1060,7 @@ libresolv_hidden_def (__dn_count_labels) * signed 32-bit range. */ char * -p_secstodate (u_long secs) { +__p_secstodate (u_long secs) { /* XXX nonreentrant */ static char output[15]; /* YYYYMMDDHHMMSS and null */ time_t clock = secs; @@ -1084,13 +1085,14 @@ p_secstodate (u_long secs) { that, even given range checks on all fields with __builtin_unreachable called for out-of-range values. */ DIAG_PUSH_NEEDS_COMMENT; -#if __GNUC_PREREQ (7, 0) +# if __GNUC_PREREQ (7, 0) DIAG_IGNORE_NEEDS_COMMENT (8, "-Wformat-overflow="); -#endif +# endif sprintf(output, "%04d%02d%02d%02d%02d%02d", time->tm_year, time->tm_mon, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec); DIAG_POP_NEEDS_COMMENT; return (output); } -libresolv_hidden_def (__p_secstodate) +compat_symbol (libresolv, __p_secstodate, __p_secstodate, GLIBC_2_0); +#endif diff --git a/resolv/resolv.h b/resolv/resolv.h index e8c581ccd1..80a523e5e4 100644 --- a/resolv/resolv.h +++ b/resolv/resolv.h @@ -213,7 +213,6 @@ __END_DECLS #define p_fqname __p_fqname #define p_fqnname __p_fqnname #define p_option __p_option -#define p_secstodate __p_secstodate #define p_time __p_time #define p_type __p_type #define p_rcode __p_rcode @@ -268,7 +267,6 @@ const unsigned char * p_fqnname (const unsigned char *__cp, const unsigned char * p_fqname (const unsigned char *, const unsigned char *, FILE *) __THROW; const char * p_option (unsigned long __option) __THROW; -char * p_secstodate (unsigned long) __THROW; int dn_count_labels (const char *) __THROW; int dn_comp (const char *, unsigned char *, int, unsigned char **, unsigned char **) __THROW; diff --git a/resolv/tst-p_secstodate.c b/resolv/tst-p_secstodate.c index 9dac1ad819..98e4d1f108 100644 --- a/resolv/tst-p_secstodate.c +++ b/resolv/tst-p_secstodate.c @@ -1,4 +1,4 @@ -/* Test p_secstodate. +/* Test __p_secstodate compat symbol. Copyright (C) 2017 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -23,9 +23,16 @@ #include #include +#include + +#if TEST_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_27) + +char *__p_secstodate (unsigned long int); +compat_symbol_reference (libresolv, __p_secstodate, __p_secstodate, GLIBC_2_0); + struct test { - /* Argument to p_secstodate. */ + /* Argument to __p_secstodate. */ unsigned long int in; /* Expected output. */ const char *out; @@ -39,12 +46,12 @@ static const struct test tests[] = { 2147483647UL, "20380119031407" }, { 2147483648UL, "" }, { 4294967295UL, "" }, -#if ULONG_MAX > 0xffffffffUL +# if ULONG_MAX > 0xffffffffUL { 4294967296UL, "" }, { 9999999999UL, "" }, { LONG_MAX, "" }, { ULONG_MAX, "" }, -#endif +# endif }; static int @@ -53,7 +60,7 @@ do_test (void) int ret = 0; for (size_t i = 0; i < array_length (tests); i++) { - char *p = p_secstodate (tests[i].in); + char *p = __p_secstodate (tests[i].in); printf ("Test %zu: %lu -> %s\n", i, tests[i].in, p); if (strcmp (p, tests[i].out) != 0) { @@ -64,4 +71,14 @@ do_test (void) return ret; } +#else + +static int +do_test (void) +{ + return 77; +} + +#endif + #include -- cgit v1.2.3