[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-hackers
Subject:    Re: Thread safe resolver library?
From:       Graham Wheeler <gram () cdsec ! com>
Date:       1998-09-29 17:13:05
[Download RAW message or body]

In case anyone wants to try this, here is the program. It is very basic;
it's my first threads-based program. There are no mutexes or anything
like that, but I don't think this should affect things. The main thread
shares access to an array of unsigned longs with the child threads (each
of which access one element of the array). The main thread sets an element
to a non-zero value; the appropriate child thread should do a name lookup
for that value and then set the value back to zero to tell the main thread
it is ready for a new lookup.

Run it, type in some numbers hitting enter in between, and eventually the
whole thing should block.

/*******************************************************************/

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <resolv.h>
#include <syslog.h>
#include <pthread.h>

#define MAX_THREADS	8

void Sleep(int dlay)
{
    struct timeval tv;
    tv.tv_sec = dlay;
    tv.tv_usec = 0;
    (void)select(0, 0, 0, 0, &tv);
}

/* Lookup the name for an address */

int Lookup(unsigned long addr, char *name, int maxlen)
{
    int x;
    char qbuf[40];
    unsigned char ans[1024];
    unsigned char *uaddr = (unsigned char *)&addr;
    sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
			       (uaddr[3] & 0xff),
			       (uaddr[2] & 0xff),
			       (uaddr[1] & 0xff),
			       (uaddr[0] & 0xff));
    x = res_search(qbuf, C_IN, T_PTR, ans, maxlen);
    if (x>=0) ans[x] = 0;
    return (x < 0) ? -1 : 0;
}

/* Each thread runs a handler */

void *handler(void *arg)
{
    unsigned long *addr = (unsigned long *)arg; /* ptr to address to look up */
    for (;;)
    {
	if (*addr == 0) /* nothing to do */
	    Sleep(1);
	else
	{
	    int x;
	    char ans[PACKETSZ];
	    printf("Thread starting lookup\n", idx);
	    x = Lookup(*addr, ans, sizeof(ans));
	    printf("Thread done lookup\n", idx);
	    if (x==0) 
	    {
		fprintf(stdout, "%lX %s\n", *addr, ans);
		fflush(stdout);
	    }
	    else 
	    {
		fprintf(stdout, "%lX no name\n", *addr);
		fflush(stdout);
	    }
	    *addr = 0;
	}
    }
}

int main(int argc, char **argv)
{
    int i;
    pthread_t threads[MAX_THREADS];
    unsigned long addresses[MAX_THREADS];

    /* spin off the threads */

    for (i = 0; i < MAX_THREADS; i++)
    {
	addresses[i] = 0;
	if (pthread_create(&threads[i],NULL,handler,(void*)&addresses[i]) != 0)
	    exit(-1);
    }

    /* read addresses in hex from the command line, and give them to 
       threads to resolve */

    while (!feof(stdin))
    {
	unsigned long a;
	if (fscanf(stdin, "%lX", &a) == 1)
	{
	  retry:
    	    for (i = 0; i < MAX_THREADS; i++) /* find an available thread */
	    {
		if (addresses[i] == 0)
		{
		    addresses[i] = a;
		    break;
		}
	    }
	    if (i == MAX_THREADS) /* no threads available */
	    {
		Sleep(1);
		goto retry;
	    }
	}
    }
    return 0;
}

-- 
Dr Graham Wheeler                          E-mail: gram@cdsec.com
Citadel Data Security                      Phone:  +27(21)23-6065/6/7
Internet/Intranet Network Specialists      Mobile: +27(83)253-9864
Firewalls/Virtual Private Networks         Fax:    +27(21)24-3656
Data Security Products                     WWW:    http://www.cdsec.com/




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic