/*
    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_IMPLEMENTATIONS_H_
#define __GSK_DNS_IMPLEMENTATIONS_H_

#include "gskdnsinterfaces.h"
#include "gskdnsrrcache.h"
#include "../gskactor.h"
#include "../gskdatagramsocket.h"

/* --- Type macros --- */
typedef struct _GskDnsClient GskDnsClient;
typedef struct _GskDnsClientClass GskDnsClientClass;
typedef struct _GskDnsServer GskDnsServer;
typedef struct _GskDnsServerClass GskDnsServerClass;
typedef struct _GskDnsLocalResolver GskDnsLocalResolver;
typedef struct _GskDnsLocalResolverClass GskDnsLocalResolverClass;

GtkType gsk_dns_client_get_type();
GtkType gsk_dns_server_get_type();
GtkType gsk_dns_udp_actor_get_type();
GtkType gsk_dns_local_resolver_get_type();

#define GSK_TYPE_DNS_CLIENT		 (gsk_dns_client_get_type ())
#define GSK_DNS_CLIENT(obj)              (GTK_CHECK_CAST ((obj), GSK_TYPE_DNS_CLIENT, GskDnsClient))
#define GSK_DNS_CLIENT_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GSK_TYPE_DNS_CLIENT, GskDnsClientClass))
#define GSK_DNS_CLIENT_GET_CLASS(obj)    (GSK_DNS_CLIENT_CLASS(GTK_OBJECT(obj)->klass))
#define GSK_IS_DNS_CLIENT(obj)           (GTK_CHECK_TYPE ((obj), GSK_TYPE_DNS_CLIENT))
#define GSK_IS_DNS_CLIENT_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GSK_TYPE_DNS_CLIENT))
#define GSK_TYPE_DNS_SERVER		 (gsk_dns_server_get_type ())
#define GSK_DNS_SERVER(obj)              (GTK_CHECK_CAST ((obj), GSK_TYPE_DNS_SERVER, GskDnsServer))
#define GSK_DNS_SERVER_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GSK_TYPE_DNS_SERVER, GskDnsServerClass))
#define GSK_DNS_SERVER_GET_CLASS(obj)    (GSK_DNS_SERVER_CLASS(GTK_OBJECT(obj)->klass))
#define GSK_IS_DNS_SERVER(obj)           (GTK_CHECK_TYPE ((obj), GSK_TYPE_DNS_SERVER))
#define GSK_IS_DNS_SERVER_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GSK_TYPE_DNS_SERVER))
#define GSK_TYPE_DNS_UDP_ACTOR			(gsk_dns_udp_actor_get_type ())
#define GSK_IS_DNS_UDP_ACTOR(obj)           (GTK_CHECK_TYPE ((obj), GSK_TYPE_DNS_UDP_ACTOR))
#define GSK_TYPE_DNS_LOCAL_RESOLVER			(gsk_dns_local_resolver_get_type ())
#define GSK_DNS_LOCAL_RESOLVER(obj)              (GTK_CHECK_CAST ((obj), GSK_TYPE_DNS_LOCAL_RESOLVER, GskDnsLocalResolver))
#define GSK_DNS_LOCAL_RESOLVER_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GSK_TYPE_DNS_LOCAL_RESOLVER, GskDnsLocalResolverClass))
#define GSK_DNS_LOCAL_RESOLVER_GET_CLASS(obj)    (GSK_DNS_LOCAL_RESOLVER_CLASS(GTK_OBJECT(obj)->klass))
#define GSK_IS_DNS_LOCAL_RESOLVER(obj)           (GTK_CHECK_TYPE ((obj), GSK_TYPE_DNS_LOCAL_RESOLVER))
#define GSK_IS_DNS_LOCAL_RESOLVER_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GSK_TYPE_DNS_LOCAL_RESOLVER))


typedef enum
{
  GSK_DNS_CLIENT_STUB_RESOLVER = (1<<0)
} GskDnsClientFlags;

/* GskDnsClient implements GskDnsResolver */
/* GskDnsServer is a name-server */
/* GskDnsUdpActor implements GskDnsReceiver and GskDnsTransmitter */

GskDnsClient   *gsk_dns_client_new           (GskDnsReceiver     *receiver,
				              GskDnsTransmitter  *transmitter,
					      GskDnsRRCache      *rr_cache,
					      GskDnsClientFlags   flags);
void            gsk_dns_client_add_searchpath(GskDnsClient       *client,
					      const char         *searchpath);
void            gsk_dns_client_add_ns        (GskDnsClient       *client,
					      GskSocketAddress   *sock_address);
void            gsk_dns_client_set_cache     (GskDnsClient       *client,
					      GskDnsRRCache      *rr_cache);
void            gsk_dns_client_set_flags     (GskDnsClient       *client,
					      GskDnsClientFlags   flags);
GskDnsClientFlags gsk_dns_client_get_flags   (GskDnsClient       *client);
gboolean    gsk_dns_client_parse_system_files(GskDnsClient       *client);


GskDnsResolver *gsk_dns_local_resolver_new   (GskDnsRRCache      *rr_cache);

GskDnsServer   *gsk_dns_server_new           (GskDnsResolver     *resolver,
					      GskDnsReceiver     *receiver,
				              GskDnsTransmitter  *transmitter);
GskDnsResolver *gsk_dns_server_peek_resolver (GskDnsServer       *server);
void            gsk_dns_server_set_resolver  (GskDnsServer       *server,
					      GskDnsResolver     *resolver);


GskActor       *gsk_dns_udp_actor_new        (GskDatagramSocket  *socket);


/* --- implementation details --- */
typedef enum
{
  GSK_DNS_LOCAL_NO_DATA,
  GSK_DNS_LOCAL_PARTIAL_DATA,
  GSK_DNS_LOCAL_SUCCESS
} GskDnsLocalResult;
gboolean gsk_dns_client_parse_etc_hosts       (GskDnsClient       *client,
				               const char         *filename,
				               gboolean         may_be_missing);

GskDnsLocalResult gsk_dns_local_resolver_answer(GskDnsRRCache      *rr_cache,
					        GskDnsQuestion     *question,
				                GskDnsMessage      *results);
#endif
