diff options
| -rw-r--r-- | extra/Configs/Config.in | 19 | ||||
| -rw-r--r-- | include/resolv.h | 66 | ||||
| -rw-r--r-- | libc/inet/resolv.c | 28 | 
3 files changed, 74 insertions, 39 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9e2112c84..4979d5822 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -772,7 +772,7 @@ config UCLIBC_HAS_OBSOLETE_BSD_SIGNAL  	bool "BSD obsolete signal functions"  	default n  	help -	  These  functions are provided as a compatibility interface for +	  These functions are provided as a compatibility interface for  	  programs that make use of the historical System V signal API.  	  This API is obsolete:  	  new applications should use the POSIX signal API (sigaction(2), @@ -1066,6 +1066,23 @@ config UCLIBC_HAS_BSD_RES_CLOSE  	  Most people will say N. +config UCLIBC_HAS_COMPAT_RES_STATE +	bool "Use compatible but bloated _res" +	default y +	help +	  Answer Y if you build network utilities and they muck with resolver +	  internals a lot (_res global structure). uclibc does not use most +	  of _res.XXX fields, and with this option OFF they won't even exist. +	  Which will make e.g. dig build fail. +	  Answering N saves around 400 bytes in bss. + +config UCLIBC_HAS_EXTRA_COMPAT_RES_STATE +	bool "Use extra compatible but extra bloated _res" +	default n +	help +	  Answer Y if selecting UCLIBC_HAS_COMPAT_RES_STATE is not enough. +	  As far as I can say, this should never be needed. +  endif diff --git a/include/resolv.h b/include/resolv.h index 3434f5d8c..6651dded9 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -101,53 +101,64 @@ typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns,  # define RES_DFLRETRY		2	/* Default #/tries. */  # define RES_MAXTIME		65535	/* Infinity, in milliseconds. */ +/* _res (an instance of this structure) uses 0.5kb in bss + * in "ordinary" libc's (glibc, xBSD). We want to be less wasteful. + * We (1) shuffle and shrink some integer fields, + * and (2) can switch off stuff we don't support. + * Everything inside __UCLIBC_HAS_COMPAT_RES_STATE__ + * is not actually used by uclibc and can be configured off. + * However, this will prevent some programs from building. + * Really obscure stuff with no observed users in the wild is under + * __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__. + * I guess it's safe to set that to N. + */  struct __res_state { -	int	retrans;	 	/* retransmition time interval */ +#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__ +	int	retrans;	 	/* retransmission time interval */  	int	retry;			/* number of times to retransmit */ -	u_long	options;		/* option flags - see below. */ -	int	nscount;		/* number of name servers */ +#endif +	u_int32_t options;		/* (was: ulong) option flags - see below. */  	struct sockaddr_in  		nsaddr_list[MAXNS];	/* address of name server */ -# define nsaddr	nsaddr_list[0]		/* for backward compatibility */ -	u_short	id;			/* current message id */ +#define nsaddr nsaddr_list[0]		/* for backward compatibility */  	char	*dnsrch[MAXDNSRCH+1];	/* components of domain to search */ +#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__ +	/* googling for "_res.defdname" says it's still sometimes used. +	 * Pity. It's huge, I want to move it to EXTRA_COMPAT... */  	char	defdname[256];		/* default domain (deprecated) */ -	u_long	pfcode;			/* RES_PRF_ flags - see below. */ -	unsigned ndots:4;		/* threshold for initial abs. query */ -	unsigned nsort:4;		/* number of elements in sort_list[] */ -	char	unused[3]; +#endif +	u_int8_t nscount;		/* (was: int) number of name servers */ +	u_int8_t ndots;			/* (was: unsigned:4) threshold for initial abs. query */ +#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__ +	u_int8_t nsort;			/* (was: unsigned:4) number of elements in sort_list[] */ +	u_int16_t pfcode;		/* (was: ulong) RES_PRF_ flags. Used by dig. */ +	unsigned short id;		/* current message id */ +	int	res_h_errno;		/* last one set for this context */  	struct {  		struct in_addr	addr;  		u_int32_t	mask;  	} sort_list[MAXRESOLVSORT]; -	res_send_qhook qhook;		/* query hook */ -	res_send_rhook rhook;		/* response hook */ -	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 */  	union { -		char	pad[52];	/* On an i386 this means 512b total. */  		struct {  			u_int16_t		nscount; -#if 0 -			u_int16_t		nsmap[MAXNS]; -#else  			u_int16_t		nstimes[MAXNS]; /* ms. */ -#endif  			int			nssocks[MAXNS]; +			/* below: not in xBSD. glibc only? */  			u_int16_t		nscount6;  			u_int16_t		nsinit;  			struct sockaddr_in6	*nsaddrs[MAXNS]; -#if 0 -#ifdef _LIBC -			unsigned long long int	initstamp -			  __attribute__((packed)); -#else -			unsigned int		_initstamp[2]; -#endif -#endif  		} _ext;  	} _u; +#endif +#ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__ +	/* Truly obscure stuff. +	 * Googling for "_res.XXX" for these members +	 * turned up basically empty */ +	res_send_qhook qhook;		/* query hook */ +	res_send_rhook rhook;		/* response hook */ +	int	_vcsock;		/* PRIVATE: for res_send VC i/o */ +	unsigned _flags;		/* PRIVATE: see below */ +#endif  };  typedef struct __res_state *res_state; @@ -196,6 +207,7 @@ struct res_sym {  /*   * Resolver options (keep these in synch with res_debug.c, please) + * (which of these do we really implement??)   */  #define RES_INIT	0x00000001	/* address initialized */  #define RES_DEBUG	0x00000002	/* print debug messages */ diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 7ef2fba45..b7ab27690 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1255,20 +1255,26 @@ int res_init(void)  	__UCLIBC_MUTEX_LOCK(__resolv_lock);	/* must be a recursive lock! */  	__close_nameservers();  	__open_nameservers(); +	memset(rp, 0, sizeof(*rp)); +	rp->options = RES_INIT; +#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__  	rp->retrans = RES_TIMEOUT;  	rp->retry = 4; -	rp->options = RES_INIT; -	rp->id = (u_int) random(); -	rp->nsaddr.sin_addr.s_addr = INADDR_ANY; -	rp->nsaddr.sin_family = AF_INET; -	rp->nsaddr.sin_port = htons(NAMESERVER_PORT); +	rp->id = random(); +#endif +	/* man resolv.conf says: +	 * "On a normally configured system this file should not be necessary. +	 * The only name server to be queried will be on the local machine; +	 * the domain name is determined from the host name +	 * and the domain search path is constructed from the domain name" */ +	rp->nscount = 1; +	rp->nsaddr_list[0].sin_addr.s_addr = INADDR_ANY; +	rp->nsaddr_list[0].sin_family = AF_INET; +	rp->nsaddr_list[0].sin_port = htons(NAMESERVER_PORT);  	rp->ndots = 1; -	/** rp->pfcode = 0; **/ +#ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__  	rp->_vcsock = -1; -	/** rp->_flags = 0; **/ -	/** rp->qhook = NULL; **/ -	/** rp->rhook = NULL; **/ -	/** rp->_u._ext.nsinit = 0; **/ +#endif  	if (__searchdomains) {  		int i; @@ -1286,8 +1292,8 @@ int res_init(void)  				rp->nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);  			}  		} +		rp->nscount = __nameservers;  	} -	rp->nscount = __nameservers;  	__UCLIBC_MUTEX_UNLOCK(__resolv_lock);  	return 0;  | 
