This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 14/03/15 21:29, Joshua Rogers wrote: > I confirmed (as you can see in the code in the gdb output), that nscount > is reset on the run by gethostbyname, but options is not. I can see why this is the case: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/resolv/res_data.c?rev=1.14&content-type=text/x-cvsweb-markup&only_with_tag=MAIN > /* > * These three fields used to be statically initialized. This made > * it hard to use this code in a shared library. It is necessary, > * now that we're doing dynamic initialization here, that we preserve > * the old semantics: if an application modifies one of these three > * fields of _res before res_init() is called, res_init() will not > * alter them. Of course, if an application is setting them to > * _zero_ before calling res_init(), hoping to override what used > * to be the static default, we can't detect it and unexpected results > * will follow. Zero for any of these fields would make no sense, > * so one can safely assume that the applications were already getting > * unexpected results. > * > * _nres.options is tricky since some apps were known to diddle the bits > * before res_init() was first called. We can't replicate that semantic > * with dynamic initialization (they may have turned bits off that are > * set in RES_DEFAULT). Our solution is to declare such applications > * "broken". They could fool us by setting RES_INIT but none do (yet). > */ > if (!_nres.retrans) > _nres.retrans = RES_TIMEOUT; > if (!_nres.retry) > _nres.retry = 4; > if (!(_nres.options & RES_INIT)) > _nres.options = RES_DEFAULT; > > /* > * This one used to initialize implicitly to zero, so unless the app > * has set it to something in particular, we can randomize it now. > */ > if (!_nres.id) > _nres.id = res_nrandomid(&_nres); > > rv = __res_vinit(&_nres, 1); And __res_vinit: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/resolv/res_init.c?rev=1.30&content-type=text/x-cvsweb-markup&only_with_tag=HEAD does not edit those 3 settings if the second parameter, 'preinit' is 1. > if (!preinit) { > statp->retrans = RES_TIMEOUT; > statp->retry = RES_DFLRETRY; > statp->options = RES_DEFAULT; > } It does, however, edit the ns stuff: e.g.: statp->nscount = 0; This shows up why on res_init(); the nscount is reset -- expected behaviour. This does not explain why the first call to an _actual_(non-init) function overwrites everything, and then FURTHER writes do _not_ get overwritten by the calls. gethostbyname.c uses _res_init(): struct res_data *data = _res_init(); But as explained, the second call to gethostbyname does not overwrite the ns stuff. Using res_query directly(as per http://codepad.org/55rsDQjZ), does this: > int > res_query(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 */ > { > if ((_nres.options & RES_INIT) == 0U && res_init() == -1) { > RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL); > return (-1); > } > return (res_nquery(&_nres, name, class, type, answer, anslen)); > } In the if() condition, if RES_INIT is set, should never reach the res_init(), so it will not be overwritten. I noticed something. In the file that res_query is defined in(res_data.c), everything uses "_nres". May THIS be why the first run is not working? It's not setting nres? I don't think I can dive any deeper into the code to work this out. Thanks, -- -- Joshua Rogers <https://internot.info/>
Attachment:
signature.asc
Description: OpenPGP digital signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |