/* ARISA - Asynchronous DNS hooks and caching, structures and prototypes */
/* Copyright (C) 2003 - Carl Ritson */

#define _ARISA_ARESOLV_H

/* Constants */

typedef enum arbtype_t { 
	ARESOLV_FWD 		= 0x01,
	ARESOLV_REV 		= 0x02, 
	ARESOLV_INPROGRESS 	= 0x10
} arbtype_t;

/* Structures */

typedef struct arb_t {
	unsigned long	hash;
	int		type;
	struct arb_t	*next;
	
	time_t		expires;
	
	char		**host;
	struct in_addr	*addr;
	int		no_host;
	int		no_addr;
} arb_t;

typedef struct arl_t {
	unsigned long	hash;
	int		type;
	struct arb_t	*bkt;

	time_t		last_attempt;
	int		attempts;
	
	int		ns_type;
	time_t		lowest_ttl;
	char		*present;
} arl_t;

typedef struct aresolv_t {
	/* caching */
	lock_t	lookup_lock;
	
	arb_t	**fwd_table;
	int	fwd_table_size;
	int	fwd_table_bkts;
	
	arb_t	**rev_table;
	int	rev_table_size;
	int	rev_table_bkts;
	
	size_t	memory_usage;

	/* resolving */
	lock_t	resolv_lock;
	
	int	socket;
	
	int	next_server;
	void	**servers;
	int	no_servers;
	
	arl_t	**lookups;
	int	no_lookups;
	
	time_t	last_s_rehash;
	time_t	last_h_rehash;
} aresolv_t;

/* Functions */
aresolv_t *aresolv_init(void);
void aresolv_free(aresolv_t *ar);

/* 
   Lookup functions return -1 if lookup failed, 0 if lookup is inprogress
   else the number of hosts or addresses resolved and returned.
   
   For 'aresolv_lookup' a pointer to an array of in_addr structures.
   For 'aresolv_lookup_reverse' a pointer to an array of char pointers.
   
   Both of these are allocated as a single block, so should be freed with a 
   single call to xfree.
 */
int aresolv_lookup(aresolv_t *ar, const char *host, struct in_addr **addrs);
int aresolv_lookup_reverse(aresolv_t *ar, 
		const struct in_addr *addr, char ***hosts);

/* Management Function should be called periodically, anywhere from
   once per second to once a minute.
 */
void aresolv_manage(aresolv_t *ar);

/* Blocking lookup functions */
int aresolv_nametoaddrs(aresolv_t *ar, int af, const char *host, void *addrs);
int aresolv_nametoaddr(aresolv_t *ar, int af, const char *host, void *addr);
int aresolv_addrtonames(aresolv_t *ar, int af, const void *addr, char ***hosts);
int aresolv_addrtoname(aresolv_t *ar, int af, const void *addr,
		char *host, size_t hostlen);
