This is the mail archive of the libc-alpha@sourceware.cygnus.com 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]

Bind 8.2 patch



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]