Bind 8.2 patch
Andreas Jaeger
aj@suse.de
Fri Dec 3 11:44:00 GMT 1999
I've finished the first version of my bind 8.2 patch, it's against the
current glibc 2.2 CVS version. It should apply - without major
problems to 2.1.2. Use it at your own risk.
Since it's a wee bit large, I've put it on the SuSE ftp server at
< ftp://ftp.suse.com/pub/people/aj/resolv-for-2.2-diff.gz >. I'm only
appending the ChangeLog entries for your information.
Problems I still have to think about:
- handling of h_errno
- res_data.c: I'm not sure if the bind4 interfaces are thread-safe.
I've got to check this again.
- __p_rr doesn't exist anymore. Since it seems to be only used
internally, we should be able to drop it.
- check if some more functions needs to be exported.
I'm appending a test program to test the multi-thread behaviour. I
just managed to resolve 2000 addresses in 30 seconds with 100 threads
- compare this with the glibc 2.1 implementation where only *one*
thread can contact named.
I appreciate your feedback on the patches.
Thanks to Adam for his patches and David for his test program,
Andreas
1999-12-03 Andreas Jaeger <aj@suse.de>
* nss/getXXbyYY.c: Include <resolv.h>
(FUNCTION_NAME): Use res_ninit instead of res_init.
* nss/getXXbyYY_r.c [NEED__RES]: Include <resolv.h> for _res
declaration and prototypes.
Remove extra _res declaration.
(INTERNAL): Use thread aware res_ninit function.
* inet/gethstbyad_r.c: Include <resolv.h>.
* resolv/res_data.c: Update from Bind 8.2.2-P5. Moved res_init to
res_libc.c. Disabled unneeded functions.
* resolv/res_libc.c: New file.
* Versions.def: Add version GLIBC_2.2 for libpthread.
Add versions GLIBC_2.1 and GLIBC_2.2 for libresolv.
* include/resolv.h: Add internal interfaces.
* resolv/Makefile (routines): Add new files.
(libresolv-routines): Likewise.
(distribute): Likewise.
* resolv/gethnamaddr.c: Use thread safe resolver functions.
* resolv/nss_dns/dns-host.c: Likewise.
* resolv/nss_dns/dns-network.c: Likewise.
* resolv/arpa/nameser.h: Update from Bind 8.2.2-P5.
* resolv/nsap_addr.c: Likewise.
* resolv/res_comp.c: Likewise.
* resolv/res_debug.c: Likewise.
* resolv/res_init.c: Likewise.
* resolv/res_mkquery.c: Likewise.
* resolv/res_query.c: Likewise.
* resolv/res_send.c: Likewise.
* resolv/resolv.h: Likewise.
* resolv/Versions: Add __res_state and __res_ninit with version
GLIBC_2.2 to libc.
Add new interfaces with version GLIBC_2.2 to libresolv.
* resolv/Banner: Update.
* include/arpa/nameser_compat.h: New file.
* resolv/ns_name.c: New file from Bind 8.2.2-P5.
* resolv/ns_netint.c: Likewise.
* resolv/ns_parse.c: Likewise.
* resolv/ns_print.c: Likewise.
* resolv/ns_samedomain.c: Likewise.
* resolv/ns_ttl.c: Likewise.
* resolv/arpa/nameser_compat.h: Likewise.
* resolv/res_debug.h: Likewise.
Some patches are based on work done by Adam D. Bradley
<artdodge@cs.bu.edu>.
For linuxthreads:
1999-12-03 Andreas Jaeger <aj@suse.de>
* Versions: Add __res_state with version GLIBC_2.2.
* errno.c (__res_state): New function to return thread specific
resolver state.
* pthread.c (pthread_initialize): Initialize p_resp.
(__pthread_reset_main_thread): Also set p_resp.
* manager.c (pthread_handle_create): Initialize p_resp.
* internals.h: Add thread specific resolver state.
Based on patches by Adam D. Bradley <artdodge@cs.bu.edu>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
// Quick demonstration program to show problems with Linux's resolver
// By: David J. Schwartz <davids@webmaster.com>
// Seat of the pants math: 100 threads each has a resolve pending
// pretty much all the time. If a resolve takes at most 30 seconds,
// we should be getting 3 results per second. But in reality, we can
// go 20 seconds without a _single_ result! And you will see that
// over time, more and more threads hang, eventually no new resolves
// take place
// Compile with:
// g++ res.cpp -lpthread -lresolv -o res
// The '-lresolv' is optional
volatile int fwd=0, rvrs=0, nfwd = 0;
void DoResolve (unsigned ip)
{
int ern1;
char rbuf1[1024];
struct hostent rres1, *hent;
printf("Entering gethostbyaddr_r\n");
fflush(stdout);
if(gethostbyaddr_r((char *)&ip, 4, AF_INET, &rres1, rbuf1, 1024,
&hent, &ern1)!=0)
hent=NULL;
if(!hent)
printf("Done with gethostbyaddr_r\n");
else
printf("Done with gethostbyaddr_r (%s)\n", hent->h_name);
fflush(stdout);
rvrs++;
if (hent != NULL)
{ // Now let's try to forward resolve back to the IP
char buf[2048];
int ern;
char rbuf[1024];
struct hostent rres;
strncpy(buf, hent->h_name, 1000);
buf[1000]=0;
printf("entering gethostbyname_r\n");
fflush(stdout);
if(gethostbyname_r(buf, &rres, rbuf, 1024, &hent, &ern)!=0)
hent=NULL;
if(!hent)
printf("Done with gethostbyname_r\n");
else
printf("Done with gethostbyname_r (%s)\n", hent->h_name);
fflush(stdout);
fwd++;
}
else
++nfwd;
}
void *threadfunc (void *__dummy)
{
while(1)
{
DoResolve((rand()&0xffffff)+0xd1000000); // this area is rich
usleep(10);
}
}
int
main(void)
{
pthread_t a;
int i;
for (i=0; i<100; i++)
{
pthread_create(&a, NULL, threadfunc, NULL);
usleep(10);
}
while (1)
{
sleep(1);
printf("Rvrs: %d, Fwd: %d, NFwd: %d\n", rvrs, fwd, nfwd);
}
}
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.rhein-neckar.de
More information about the Libc-alpha
mailing list