#ifndef NAMED_LWDCLIENT_H
#define NAMED_LWDCLIENT_H 1
#include <isc/event.h>
#include <isc/eventclass.h>
#include <isc/netaddr.h>
#include <isc/sockaddr.h>
#include <isc/types.h>
#include <dns/fixedname.h>
#include <dns/types.h>
#include <lwres/lwres.h>
#include <named/lwsearch.h>
#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242)
#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001)
struct ns_lwdclient {
isc_sockaddr_t address;
struct in6_pktinfo pktinfo;
isc_boolean_t pktinfo_valid;
ns_lwdclientmgr_t *clientmgr;
ISC_LINK(ns_lwdclient_t) link;
unsigned int state;
void *arg;
unsigned char buffer[LWRES_RECVLENGTH];
isc_uint32_t recvlength;
lwres_lwpacket_t pkt;
unsigned char *sendbuf;
isc_uint32_t sendlength;
isc_buffer_t recv_buffer;
dns_adbfind_t *find;
dns_adbfind_t *v4find;
dns_adbfind_t *v6find;
unsigned int find_wanted;
dns_fixedname_t query_name;
dns_fixedname_t target_name;
ns_lwsearchctx_t searchctx;
lwres_gabnresponse_t gabn;
lwres_gnbaresponse_t gnba;
dns_byaddr_t *byaddr;
unsigned int options;
isc_netaddr_t na;
lwres_grbnresponse_t grbn;
dns_lookup_t *lookup;
dns_rdatatype_t rdtype;
char *aliases[LWRES_MAX_ALIASES];
isc_uint16_t aliaslen[LWRES_MAX_ALIASES];
lwres_addr_t addrs[LWRES_MAX_ADDRS];
};
#define NS_LWDCLIENT_STATEIDLE 1
#define NS_LWDCLIENT_STATERECV 2
#define NS_LWDCLIENT_STATERECVDONE 3
#define NS_LWDCLIENT_STATEFINDWAIT 4
#define NS_LWDCLIENT_STATESEND 5
#define NS_LWDCLIENT_STATESENDDONE 6
#define NS_LWDCLIENT_ISIDLE(c) \
((c)->state == NS_LWDCLIENT_STATEIDLE)
#define NS_LWDCLIENT_ISRECV(c) \
((c)->state == NS_LWDCLIENT_STATERECV)
#define NS_LWDCLIENT_ISRECVDONE(c) \
((c)->state == NS_LWDCLIENT_STATERECVDONE)
#define NS_LWDCLIENT_ISFINDWAIT(c) \
((c)->state == NS_LWDCLIENT_STATEFINDWAIT)
#define NS_LWDCLIENT_ISSEND(c) \
((c)->state == NS_LWDCLIENT_STATESEND)
#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c))
#define NS_LWDCLIENT_SETIDLE(c) \
((c)->state = NS_LWDCLIENT_STATEIDLE)
#define NS_LWDCLIENT_SETRECV(c) \
((c)->state = NS_LWDCLIENT_STATERECV)
#define NS_LWDCLIENT_SETRECVDONE(c) \
((c)->state = NS_LWDCLIENT_STATERECVDONE)
#define NS_LWDCLIENT_SETFINDWAIT(c) \
((c)->state = NS_LWDCLIENT_STATEFINDWAIT)
#define NS_LWDCLIENT_SETSEND(c) \
((c)->state = NS_LWDCLIENT_STATESEND)
#define NS_LWDCLIENT_SETSENDDONE(c) \
((c)->state = NS_LWDCLIENT_STATESENDDONE)
struct ns_lwdclientmgr {
ns_lwreslistener_t *listener;
isc_mem_t *mctx;
isc_socket_t *sock;
dns_view_t *view;
lwres_context_t *lwctx;
isc_task_t *task;
unsigned int flags;
ISC_LINK(ns_lwdclientmgr_t) link;
ISC_LIST(ns_lwdclient_t) idle;
ISC_LIST(ns_lwdclient_t) running;
};
#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001
#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002
isc_result_t
ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *);
void
ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *);
isc_result_t
ns_lwdclient_startrecv(ns_lwdclientmgr_t *);
void
ns_lwdclient_stateidle(ns_lwdclient_t *);
void
ns_lwdclient_recv(isc_task_t *, isc_event_t *);
void
ns_lwdclient_shutdown(isc_task_t *, isc_event_t *);
void
ns_lwdclient_send(isc_task_t *, isc_event_t *);
isc_result_t
ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r);
void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *);
void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *);
void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *);
void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *);
void ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t);
void ns_lwdclient_log(int level, const char *format, ...)
ISC_FORMAT_PRINTF(2, 3);
#endif