#ifndef _LDNS_PACKET_H
#define _LDNS_PACKET_H
+#define LDNS_MAX_PACKETLEN 65535
+
+/* allow flags to be given to mk_query */
+#define LDNS_QR 1 /* QueRy - query flag */
+#define LDNS_AA 2 /* Authoritative Answer - server flag */
+#define LDNS_TC 4 /* TrunCated - server flag */
+#define LDNS_RD 8 /* Recursion Desired - query flag */
+#define LDNS_CD 16 /* Checking Disabled - query flag */
+#define LDNS_RA 32 /* Recursion Available - server flag */
+#define LDNS_AD 64 /* Authenticated Data - server flag */
+
#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
*/
ldns_pkt *ldns_pkt_clone(ldns_pkt *pkt);
+/**
+ * directly set the additional section
+ * \param[in] p packet to operate on
+ * \param[in[ rr rrlist to set
+ */
+void ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the answer section
+ * \param[in] p packet to operate on
+ * \param[in[ rr rrlist to set
+ */
+void ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the question section
+ * \param[in] p packet to operate on
+ * \param[in[ rr rrlist to set
+ */
+void ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the auhority section
+ * \param[in] p packet to operate on
+ * \param[in[ rr rrlist to set
+ */
+void ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr);
+
+
/* lua helper stuff */
ldns_rr * ldns_pkt_get_rr(ldns_pkt *p, uint16_t n);
ldns_rr * ldns_pkt_set_rr(ldns_pkt *p, ldns_rr *rr, uint16_t n);
bool ldns_pkt_insert_rr(ldns_pkt *p, ldns_rr *rr, uint16_t n);
-#define LDNS_MAX_PACKETLEN 65535
-
-/* allow flags to be given to mk_query */
-#define LDNS_QR 1 /* QueRy - query flag */
-#define LDNS_AA 2 /* Authoritative Answer - server flag */
-#define LDNS_TC 4 /* TrunCated - server flag */
-#define LDNS_RD 8 /* Recursion Desired - query flag */
-#define LDNS_CD 16 /* Checking Disabled - query flag */
-#define LDNS_RA 32 /* Recursion Available - server flag */
-#define LDNS_AD 64 /* Authenticated Data - server flag */
#endif /* !_LDNS_PACKET_H */
#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
+#include <ldns/tsig.h>
#include <ldns/rdata.h>
#include <ldns/packet.h>
#include <sys/time.h>
*/
void ldns_resolver_nameservers_randomize(ldns_resolver *r);
+/**
+ * Create a resolver suitable for use with UPDATE. [RFC2136 4.3]
+ * SOA MNAME is used as the "primary master".
+ * \param[in] fqdn FQDN of a host in a zone
+ * \param[in] zone zone name, if explicitly given, otherwise use SOA
+ * \param[in] clas zone class
+ * \param[in] tsig_cred TSIG credentials
+ * \param[out] zone returns zone/owner rdf from the 'fqdn' SOA MNAME query
+ * \return the new resolver
+ */
+ldns_resolver * ldns_update_resolver_new(const char *fqdn, const char *zone, ldns_rr_class clas, ldns_tsig_credentials *tsig_cred, ldns_rdf **zone_rdf);
+
#endif /* !_LDNS_RESOLVER_H */
#ifndef _LDNS_TSIG_H_
#define _LDNS_TSIG_H_
-/*#include <ldns/dns.h> */
-
typedef struct _ldns_tsig_credentials
{
char *algorithm;
#ifndef _LDNS_UPDATE_H
#define _LDNS_UPDATE_H
-ldns_pkt *ldns_update_pkt_new(ldns_rdf *, ldns_rr_class, ldns_rr_list *, ldns_rr_list *, ldns_rr_list *);
-ldns_status ldns_update_pkt_tsig_add(ldns_pkt *, ldns_resolver *);
-ldns_resolver *ldns_update_resolver_new(const char *, const char *, ldns_rr_class, ldns_tsig_credentials *, ldns_rdf **);
-
-uint16_t ldns_update_get_zo(const ldns_pkt *);
-uint16_t ldns_update_get_pr(const ldns_pkt *);
-uint16_t ldns_update_get_up(const ldns_pkt *);
-uint16_t ldns_update_get_ad(const ldns_pkt *);
-
-void ldns_update_set_zo(ldns_pkt *, uint16_t);
-void ldns_update_set_pr(ldns_pkt *, uint16_t);
-void ldns_update_set_up(ldns_pkt *, uint16_t);
-void ldns_update_set_ad(ldns_pkt *, uint16_t);
+#include <ldns/resolver.h>
+
+/**
+ * create an update packet from zone name, class and the rr lists
+ * \param[in] zone name of the zone
+ * \param[in] class zone class
+ * \param[in] pr_rrlist list of Prerequisite Section RRs
+ * \param[in] up_rrlist list of Updates Section RRs
+ * \param[in] ad_rrlist list of Additional Data Section RRs (currently unused)
+ * \return the new packet
+ */
+ldns_pkt *ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class clas, ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist);
+
+/**
+ * add tsig credentials to
+ * a packet from a resolver
+ * \param[in] p packet to copy to
+ * \param[in] r resolver to copy from
+ *
+ * \return status wether successfull or not
+ */
+ldns_status ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r);
+
+/* access functions */
+uint16_t ldns_update_zocount(const ldns_pkt *);
+uint16_t ldns_update_prcount(const ldns_pkt *);
+uint16_t ldns_update_upcount(const ldns_pkt *);
+uint16_t ldns_update_adcount(const ldns_pkt *);
+void ldns_update_set_zocount(ldns_pkt *, uint16_t);
+void ldns_update_set_prcount(ldns_pkt *, uint16_t);
+void ldns_update_set_upcount(ldns_pkt *, uint16_t);
+void ldns_update_set_adcount(ldns_pkt *, uint16_t);
+
+ldns_status ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r, ldns_rr_class class, ldns_rdf **mname);
+ldns_status ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rr_class class, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf);
+
#endif /* !_LDNS_UPDATE_H */
syn keyword ldnsMacro LDNS_FREE
syn keyword ldnsMacro LDNS_DEP
+" ldns/tsig.h
+syn keyword ldnsType ldns_tsig_credentials
+
" ldns/rdata.h
syn keyword ldnsType ldns_rdf
syn keyword ldnsType ldns_rdf_type
packet->_header->_rd = rd;
}
+void
+ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
+{
+ p->_additional = rr;
+}
+
+void
+ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
+{
+ /* XXX check for only one rr ?? */
+ p->_question = rr;
+}
+
+void
+ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
+{
+ p->_answer = rr;
+}
+
+void
+ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
+{
+ p->_authority = rr;
+}
+
void
ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
{
}
ldns_resolver_set_nameservers(r, ns);
}
+
+/* dynamic update stuff */
+ldns_resolver *
+ldns_update_resolver_new(const char *fqdn, const char *zone,
+ ldns_rr_class class, ldns_tsig_credentials *tsig_cred, ldns_rdf **zone_rdf)
+{
+ ldns_resolver *r1, *r2;
+ ldns_pkt *query = NULL, *resp;
+ ldns_rr_list *nslist, *iplist;
+ ldns_rdf *soa_zone, *soa_mname, *ns_name;
+ size_t i;
+
+ if (class == 0)
+ class = LDNS_RR_CLASS_IN;
+
+ /* First, get data from /etc/resolv.conf */
+ r1 = ldns_resolver_new_frm_file(NULL);
+ if (!r1)
+ return NULL;
+
+ r2 = ldns_resolver_new();
+ if (!r2)
+ goto bad;
+
+ /* TSIG key data available? Copy into the resolver. */
+ if (tsig_cred) {
+ ldns_resolver_set_tsig_algorithm(r2,
+ ldns_tsig_algorithm(tsig_cred));
+ ldns_resolver_set_tsig_keyname(r2,
+ ldns_tsig_keyname_clone(tsig_cred));
+ /*
+ * XXX Weird that ldns_resolver_deep_free() will free()
+ * keyname but not hmac key data?
+ */
+ ldns_resolver_set_tsig_keydata(r2,
+ ldns_tsig_keydata_clone(tsig_cred));
+ }
+
+ /* Now get SOA zone, mname, NS, and construct r2. [RFC2136 4.3] */
+
+ /* Explicit 'zone' or no? */
+ if (zone) {
+ soa_zone = ldns_dname_new_frm_str(zone);
+ if (ldns_update_soa_mname(soa_zone, r1, class, &soa_mname)
+ != LDNS_STATUS_OK)
+ goto bad;
+ } else {
+ if (ldns_update_soa_zone_mname(fqdn, r1, class, &soa_zone,
+ &soa_mname) != LDNS_STATUS_OK)
+ goto bad;
+ }
+
+ /* Pass zone_rdf on upwards. */
+ *zone_rdf = ldns_rdf_clone(soa_zone);
+
+ /* NS */
+ query = ldns_pkt_query_new(soa_zone, LDNS_RR_TYPE_NS, class, LDNS_RD);
+ if (!query)
+ goto bad;
+ soa_zone = NULL;
+
+ ldns_pkt_set_random_id(query);
+ if (ldns_resolver_send_pkt(&resp, r1, query) != LDNS_STATUS_OK) {
+ dprintf("%s", "NS query failed!\n");
+ goto bad;
+ }
+ ldns_pkt_free(query);
+ if (!resp)
+ goto bad;
+
+ /* Match SOA MNAME to NS list, adding it first */
+ nslist = ldns_pkt_answer(resp);
+ for (i = 0; i < ldns_rr_list_rr_count(nslist); i++) {
+ ns_name = ldns_rr_rdf(ldns_rr_list_rr(nslist, i), 0);
+ if (!ns_name)
+ continue;
+ if (ldns_rdf_compare(soa_mname, ns_name) == 0) {
+ /* Match */
+ iplist = ldns_get_rr_list_addr_by_name(r1, ns_name,
+ class, 0);
+ (void) ldns_resolver_push_nameserver_rr_list(r2, iplist);
+ break;
+ }
+ }
+
+ /* Then all the other NSs. XXX Randomize? */
+ for (i = 0; i < ldns_rr_list_rr_count(nslist); i++) {
+ ns_name = ldns_rr_rdf(ldns_rr_list_rr(nslist, i), 0);
+ if (!ns_name)
+ continue;
+ if (ldns_rdf_compare(soa_mname, ns_name) != 0) {
+ /* No match, add it now. */
+ iplist = ldns_get_rr_list_addr_by_name(r1, ns_name,
+ class, 0);
+ (void) ldns_resolver_push_nameserver_rr_list(r2, iplist);
+ }
+ }
+
+ /* Cleanup and return. */
+ ldns_resolver_set_random(r2, false);
+ ldns_pkt_free(resp);
+ ldns_resolver_deep_free(r1);
+ return r2;
+
+ bad:
+ if (r1)
+ ldns_resolver_deep_free(r1);
+ if (r2)
+ ldns_resolver_deep_free(r2);
+ if (query)
+ ldns_pkt_free(query);
+ if (resp)
+ ldns_pkt_free(resp);
+ return NULL;
+}
* additional data/AD -- AR/additional records
*/
-#define _zone _question
-#define _prereq _answer
-#define _updates _authority
-
-/**
- * create an update packet from zone name, class and the rr lists
- * \param[in] zone name of the zone
- * \param[in] class zone class
- * \param[in] pr_rrlist list of Prerequisite Section RRs
- * \param[in] up_rrlist list of Updates Section RRs
- * \param[in] ad_rrlist list of Additional Data Section RRs (currently unused)
- */
ldns_pkt *
ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class class,
ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist)
return NULL;
}
- if (class == 0) {
+ if (class == 0) {
class = LDNS_RR_CLASS_IN;
}
/* Create packet, fill in Zone Section. */
p = ldns_pkt_query_new(zone_rdf, LDNS_RR_TYPE_SOA, class, LDNS_RD);
- if (!p)
+ if (!p) {
return NULL;
+ }
zone_rdf = NULL; /* No longer safe to use. */
ldns_pkt_set_opcode(p, LDNS_PACKET_UPDATE);
- ldns_rr_list_deep_free(p->_updates);
- p->_updates = ldns_rr_list_clone(up_rrlist);
- ldns_update_set_up(p, ldns_rr_list_rr_count(up_rrlist));
+ ldns_rr_list_deep_free(p->_authority);
+
+ ldns_pkt_set_authority(p, ldns_rr_list_clone(up_rrlist));
+
+ ldns_update_set_upcount(p, ldns_rr_list_rr_count(up_rrlist));
if (pr_rrlist) {
- ldns_rr_list_deep_free(p->_prereq);
- p->_prereq = ldns_rr_list_clone(pr_rrlist);
- ldns_update_set_pr(p, ldns_rr_list_rr_count(pr_rrlist));
+ ldns_rr_list_deep_free(p->_answer); /*XXX access function */
+ ldns_pkt_set_answer(p, ldns_rr_list_clone(pr_rrlist));
+ ldns_update_set_prcount(p, ldns_rr_list_rr_count(pr_rrlist));
}
if (ad_rrlist) {
ldns_rr_list_deep_free(p->_additional);
- p->_additional = ldns_rr_list_clone(ad_rrlist);
- ldns_update_set_ad(p, ldns_rr_list_rr_count(ad_rrlist));
+ ldns_pkt_set_additional(p, ldns_rr_list_clone(ad_rrlist));
+ ldns_update_set_adcount(p, ldns_rr_list_rr_count(ad_rrlist));
}
-
return p;
}
}
/* Move to higher.c or similar? */
-
+/* XXX doc */
ldns_status
-ldns_update_get_soa_mname(ldns_rdf *zone, ldns_resolver *r,
+ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r,
ldns_rr_class class, ldns_rdf **mname)
{
ldns_rr *soa_rr;
/* Nondestructive, so clone 'zone' here */
query = ldns_pkt_query_new(ldns_rdf_clone(zone), LDNS_RR_TYPE_SOA,
class, LDNS_RD);
- if (!query)
+ if (!query) {
return LDNS_STATUS_ERR;
+ }
ldns_pkt_set_random_id(query);
if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
return LDNS_STATUS_ERR;
}
ldns_pkt_free(query);
- if (!resp)
+ if (!resp) {
return LDNS_STATUS_ERR;
+ }
/* Expect a SOA answer. */
*mname = NULL;
/* Try to get zone and MNAME from SOA queries. */
ldns_status
-ldns_update_get_soa_zone_mname(const char *fqdn, ldns_resolver *r,
+ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
ldns_rr_class class, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf)
{
ldns_rr *soa_rr, *rr;
/* Step 1 - first find a nameserver that should know *something* */
fqdn_rdf = ldns_dname_new_frm_str(fqdn);
query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, class, LDNS_RD);
- if (!query)
+ if (!query) {
return LDNS_STATUS_ERR;
+ }
fqdn_rdf = NULL;
ldns_pkt_set_random_id(query);
return LDNS_STATUS_ERR;
}
ldns_pkt_free(query);
- if (!resp)
+ if (!resp) {
return LDNS_STATUS_ERR;
+ }
/* XXX Is it safe to only look in authority section here? */
while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
break;
}
ldns_pkt_free(resp);
- if (!soa_rr)
+ if (!soa_rr) {
return LDNS_STATUS_ERR;
+ }
/* Step 2 - find SOA MNAME IP address, add to resolver */
query = ldns_pkt_query_new(soa_mname, LDNS_RR_TYPE_A, class, LDNS_RD);
- if (!query)
+ if (!query) {
return LDNS_STATUS_ERR;
+ }
soa_mname = NULL;
ldns_pkt_set_random_id(query);
return LDNS_STATUS_ERR;
}
ldns_pkt_free(query);
- if (!resp)
+ if (!resp) {
return LDNS_STATUS_ERR;
+ }
if (ldns_pkt_ancount(resp) == 0) {
ldns_pkt_free(resp);
/* Step 3 - Redo SOA query, sending to SOA MNAME directly. */
fqdn_rdf = ldns_dname_new_frm_str(fqdn);
query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, class, LDNS_RD);
- if (!query)
+ if (!query) {
return LDNS_STATUS_ERR;
+ }
fqdn_rdf = NULL;
ldns_pkt_set_random_id(query);
return LDNS_STATUS_ERR;
}
ldns_pkt_free(query);
- if (!resp)
+ if (!resp) {
return LDNS_STATUS_ERR;
+ }
/* XXX Is it safe to only look in authority section here, too? */
while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
break;
}
ldns_pkt_free(resp);
- if (!soa_rr)
+ if (!soa_rr) {
return LDNS_STATUS_ERR;
+ }
/* That seems to have worked, pass results to caller. */
*zone_rdf = soa_zone;
return LDNS_STATUS_OK;
}
-/**
- * Create a resolver suitable for use with UPDATE. [RFC2136 4.3]
- * SOA MNAME is used as the "primary master".
- * \param[in] fqdn FQDN of a host in a zone
- * \param[in] zone zone name, if explicitly given, otherwise use SOA
- * \param[in] class zone class
- * \param[in] tsig_cred TSIG credentials
- * \param[out] zone returns zone/owner rdf from the 'fqdn' SOA MNAME query
- */
-ldns_resolver *
-ldns_update_resolver_new(const char *fqdn, const char *zone,
- ldns_rr_class class, ldns_tsig_credentials *tsig_cred, ldns_rdf **zone_rdf)
-{
- ldns_resolver *r1, *r2;
- ldns_pkt *query = NULL, *resp;
- ldns_rr_list *nslist, *iplist;
- ldns_rdf *soa_zone, *soa_mname, *ns_name;
- size_t i;
-
- if (class == 0)
- class = LDNS_RR_CLASS_IN;
-
- /* First, get data from /etc/resolv.conf */
- r1 = ldns_resolver_new_frm_file(NULL);
- if (!r1)
- return NULL;
-
- r2 = ldns_resolver_new();
- if (!r2)
- goto bad;
-
- /* TSIG key data available? Copy into the resolver. */
- if (tsig_cred) {
- ldns_resolver_set_tsig_algorithm(r2,
- ldns_tsig_algorithm(tsig_cred));
- ldns_resolver_set_tsig_keyname(r2,
- ldns_tsig_keyname_clone(tsig_cred));
- /*
- * XXX Weird that ldns_resolver_deep_free() will free()
- * keyname but not hmac key data?
- */
- ldns_resolver_set_tsig_keydata(r2,
- ldns_tsig_keydata_clone(tsig_cred));
- }
-
- /* Now get SOA zone, mname, NS, and construct r2. [RFC2136 4.3] */
-
- /* Explicit 'zone' or no? */
- if (zone) {
- soa_zone = ldns_dname_new_frm_str(zone);
- if (ldns_update_get_soa_mname(soa_zone, r1, class, &soa_mname)
- != LDNS_STATUS_OK)
- goto bad;
- } else {
- if (ldns_update_get_soa_zone_mname(fqdn, r1, class, &soa_zone,
- &soa_mname) != LDNS_STATUS_OK)
- goto bad;
- }
-
- /* Pass zone_rdf on upwards. */
- *zone_rdf = ldns_rdf_clone(soa_zone);
-
- /* NS */
- query = ldns_pkt_query_new(soa_zone, LDNS_RR_TYPE_NS, class, LDNS_RD);
- if (!query)
- goto bad;
- soa_zone = NULL;
-
- ldns_pkt_set_random_id(query);
- if (ldns_resolver_send_pkt(&resp, r1, query) != LDNS_STATUS_OK) {
- dprintf("%s", "NS query failed!\n");
- goto bad;
- }
- ldns_pkt_free(query);
- if (!resp)
- goto bad;
-
- /* Match SOA MNAME to NS list, adding it first */
- nslist = ldns_pkt_answer(resp);
- for (i = 0; i < ldns_rr_list_rr_count(nslist); i++) {
- ns_name = ldns_rr_rdf(ldns_rr_list_rr(nslist, i), 0);
- if (!ns_name)
- continue;
- if (ldns_rdf_compare(soa_mname, ns_name) == 0) {
- /* Match */
- iplist = ldns_get_rr_list_addr_by_name(r1, ns_name,
- class, 0);
- (void) ldns_resolver_push_nameserver_rr_list(r2, iplist);
- break;
- }
- }
-
- /* Then all the other NSs. XXX Randomize? */
- for (i = 0; i < ldns_rr_list_rr_count(nslist); i++) {
- ns_name = ldns_rr_rdf(ldns_rr_list_rr(nslist, i), 0);
- if (!ns_name)
- continue;
- if (ldns_rdf_compare(soa_mname, ns_name) != 0) {
- /* No match, add it now. */
- iplist = ldns_get_rr_list_addr_by_name(r1, ns_name,
- class, 0);
- (void) ldns_resolver_push_nameserver_rr_list(r2, iplist);
- }
- }
-
- /* Cleanup and return. */
- ldns_resolver_set_random(r2, false);
- ldns_pkt_free(resp);
- ldns_resolver_deep_free(r1);
- return r2;
-
- bad:
- if (r1)
- ldns_resolver_deep_free(r1);
- if (r2)
- ldns_resolver_deep_free(r2);
- if (query)
- ldns_pkt_free(query);
- if (resp)
- ldns_pkt_free(resp);
- return NULL;
-}
-
/*
- * ldns_update_{get,set}_{zo,pr,up,ad}.
+ * ldns_update_{get,set}_{zo,pr,up,ad}count
*/
uint16_t
-ldns_update_get_zo(const ldns_pkt *p)
+ldns_update_zocount(const ldns_pkt *p)
{
return ldns_pkt_qdcount(p);
}
uint16_t
-ldns_update_get_pr(const ldns_pkt *p)
+ldns_update_prcount(const ldns_pkt *p)
{
return ldns_pkt_ancount(p);
}
uint16_t
-ldns_update_get_up(const ldns_pkt *p)
+ldns_update_upcount(const ldns_pkt *p)
{
return ldns_pkt_nscount(p);
}
uint16_t
-ldns_update_get_ad(const ldns_pkt *p)
+ldns_update_ad(const ldns_pkt *p)
{
return ldns_pkt_arcount(p);
}
}
void
-ldns_update_set_pr(ldns_pkt *p, uint16_t v)
+ldns_update_set_prcount(ldns_pkt *p, uint16_t v)
{
ldns_pkt_set_ancount(p, v);
}
void
-ldns_update_set_up(ldns_pkt *p, uint16_t v)
+ldns_update_set_upcount(ldns_pkt *p, uint16_t v)
{
ldns_pkt_set_nscount(p, v);
}
void
-ldns_update_set_ad(ldns_pkt *p, uint16_t v)
+ldns_update_set_adcount(ldns_pkt *p, uint16_t v)
{
ldns_pkt_set_arcount(p, v);
}
-
-