/*
    GSK - a library to write servers
    Copyright (C) 2001 Dave Benson

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

    Contact:
        daveb@ffem.org <Dave Benson>
*/

#ifndef __GSK_DNS_RR_CACHE_H_
#define __GSK_DNS_RR_CACHE_H_

/* A cache of ResourceRecords.  For each host, we retain a list of ResourceRecords
 * with that host as `owner'.
 */

typedef struct _GskDnsRRCache GskDnsRRCache;
typedef struct _GskDnsRRTrap GskDnsRRTrap;
#include "gskdns.h"

GskDnsRRCache        *gsk_dns_rr_cache_new        (guint64                  max_bytes,
						   guint                    max_records);
GskDnsResourceRecord *gsk_dns_rr_cache_insert     (GskDnsRRCache     *rr_cache,
					           const GskDnsResourceRecord    *record,
						   gboolean                 is_authoritative,
					           gulong                   cur_time);

/* Return a list of GskDnsResourceRecords.
 * You must lock those records if you plan on keeping them.
 * (Note: doesn't catch CNAMEs unless explicitly asked for.)
 */
GSList               *gsk_dns_rr_cache_lookup_list(GskDnsRRCache           *rr_cache,
					           const char              *owner,
					           GskDnsResourceRecordType query_type,
					           GskDnsResourceClass      query_class);
GskDnsResourceRecord *gsk_dns_rr_cache_lookup_one (GskDnsRRCache           *rr_cache,
					           const char              *owner,
					           GskDnsResourceRecordType query_type,
					           GskDnsResourceClass      query_class);

/* Prevent/allow a ResourceRecord from being freed from the cache
 * (the data itself may expire though!)
 */
void                  gsk_dns_rr_cache_unlock     (GskDnsRRCache           *rr_cache,
	               			           GskDnsResourceRecord    *record);
void                  gsk_dns_rr_cache_lock       (GskDnsRRCache           *rr_cache,
	               			           GskDnsResourceRecord    *record);
void                  gsk_dns_rr_cache_mark_user  (GskDnsRRCache           *rr_cache,
			                           GskDnsResourceRecord    *record);
void                  gsk_dns_rr_cache_unmark_user(GskDnsRRCache           *rr_cache,
			                           GskDnsResourceRecord    *record);

/* master zone files */
gboolean              gsk_dns_rr_cache_load_zone  (GskDnsRRCache           *rr_cache,
						   const char              *filename,
						   const char              *default_origin);

/* helper functions */
gboolean              gsk_dns_rr_cache_get_ns_addr(GskDnsRRCache           *rr_cache,
						   const char              *host,
						   const char             **ns_name_out,
						   GskSocketAddress        *address);
gboolean              gsk_dns_rr_cache_get_addr   (GskDnsRRCache           *rr_cache,
			                           const char              *host,
			                           GskSocketAddress        *address);

void                  gsk_dns_rr_cache_ref        (GskDnsRRCache           *rr_cache);
void                  gsk_dns_rr_cache_unref      (GskDnsRRCache           *rr_cache);

/* Flush out the oldest records in the cache. */
void                  gsk_dns_rr_cache_flush      (GskDnsRRCache           *rr_cache,
	               			           gulong                   cur_time);

/* parsing an /etc/hosts file */
gboolean     gsk_dns_rr_cache_parse_etc_hosts_line(GskDnsRRCache           *rr_cache,
				                   const char              *text);
gboolean     gsk_dns_rr_cache_parse_etc_hosts     (GskDnsRRCache           *rr_cache,
				                   const char              *filename,
						   gboolean                 may_be_missing);

#if 0
/* If a ResourceRecord from the cache is pending, get a callback when we have
 * received an answer.
 */

/* note: if record may often be CNAME even if a different
 * type is requested.  some types, like WILDCARD, need to
 * look through the lists provided by message.
 */
typedef void (*GskDnsRRCacheTrapFunc)(GskDnsMessage        *message,
				      GskDnsResourceRecord *pending_record,
				      GskDnsResourceRecord *record,
				      gpointer              trap_data);

GskDnsRRTrap         *gsk_dns_rr_cache_trap_finish(GskDnsRRCache           *rr_cache,
	                			   GskDnsResourceRecord    *pending_record,
	                			   GskDnsRRCacheTrapFunc    trap_func,
	                			   gpointer                 trap_data,
	                			   GDestroyNotify           trap_destroy);
void                  gsk_dns_rr_cache_untrap     (GskDnsRRCache           *rr_cache,
	               			           GskDnsRRTrap            *trap);
#endif

#endif
