X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/705b9b159806e6e96839c81668f685a6576ea961..ef514bbcec865ded4d2d040358e13c7432c15e1a:/src/internal.h diff --git a/src/internal.h b/src/internal.h index 2c5a073..3e85a58 100644 --- a/src/internal.h +++ b/src/internal.h @@ -42,6 +42,7 @@ typedef unsigned char byte; #include +#define ADNS_FEATURE_MANYAF #include "adns.h" #include "dlist.h" @@ -71,6 +72,8 @@ typedef unsigned char byte; #define DNS_INADDR_ARPA "in-addr", "arpa" #define DNS_IP6_ARPA "ip6", "arpa" +#define MAX_ADDRSTRLEN 64 + #define STRINGIFY(x) REALLY_STRINGIFY(x) #define REALLY_STRINGIFY(x) #x @@ -91,6 +94,11 @@ typedef enum { rcode_refused } dns_rcode; +enum { + adns__qf_addr_answer= 0x01000000,/* addr query received an answer */ + adns__qf_addr_cname = 0x02000000 /* addr subquery performed on cname */ +}; + /* Shared data structures */ typedef union { @@ -121,6 +129,14 @@ union gen_addr { struct in6_addr v6; }; +union checklabel_state { + struct { +#define PTR_NDOMAIN 2 + unsigned domainmap; /* which domains are still live */ + byte ipv[PTR_NDOMAIN][32]; /* address components so far */ + } ptr; +}; + typedef struct { int af; int width; @@ -128,7 +144,7 @@ typedef struct { int nrevcomp; int revcompwd; adns_rrtype rrtype; - void *(*sockaddr_to_inaddr)(struct sockaddr *sa); + const void *(*sockaddr_to_inaddr)(const struct sockaddr *sa); int (*sockaddr_equalp)(const struct sockaddr *sa, const struct sockaddr *sb); void (*prefix_mask)(int len, union gen_addr *a); @@ -142,6 +158,26 @@ typedef struct { struct afinfo_addr { const afinfo *ai; union gen_addr addr; }; +typedef struct { + void *ext; + void (*callback)(adns_query parent, adns_query child); + + union { + adns_rr_hostaddr *hostaddr; + } pinfo; /* state for use by parent's callback function */ + + union { + struct { + struct afinfo_addr addr; + } ptr; + struct { + unsigned want, have; + } addr; + } tinfo; /* type-specific state for the query itself: zero-init if you + * don't know better. */ + +} qcontext; + typedef struct typeinfo { adns_rrtype typekey; const char *rrtname; @@ -177,16 +213,17 @@ typedef struct typeinfo { * 0 otherwise. Must not fail. */ - adns_status (*qdparselabel)(adns_state ads, - const char **p_io, const char *pe, int labelnum, - char label_r[DNS_MAXDOMAIN], int *ll_io, - adns_queryflags flags, - const struct typeinfo *typei); - /* Parses one label from the query domain string. On entry, *p_io - * points to the next character to parse and *ll_io is the size of - * the buffer. pe points just after the end of the query domain - * string. On successful return, label_r[] and *ll_io are filled in - * and *p_io points to *pe or just after the label-ending `.'. */ + adns_status (*checklabel)(adns_state ads, adns_queryflags flags, + union checklabel_state *css, qcontext *ctx, + int labnum, const char *label, int lablen); + /* Check a label from the query domain string. The label is not + * necessarily null-terminated. The query has not yet been constructed, + * and this hook can refuse its submission by returning a nonzero status. + * State can be stored in *css between calls, and useful information can be + * stashed in ctx->tinfo, to be stored with the query (e.g., it will be + * available to the parse hook). This hook can detect a first call because + * labnum is zero, and a final call because lablen is zero. + */ void (*postsort)(adns_state ads, void *array, int nrrs, const struct typeinfo *typei); @@ -194,18 +231,29 @@ typedef struct typeinfo { * them. (This is really for the benefit of SRV's bizarre weighting * stuff.) May be 0 to mean nothing needs to be done. */ + + int (*getrrsz)(adns_rrtype type); + /* Return the output resource-record element size; if this is null, then + * the rrsz member can be used. + */ + + void (*query_send)(adns_query qu, struct timeval now); + /* Send the query to nameservers, and hook it into the appropriate queue. + * Normal behaviour is to call adns__query_send, but this can be overridden + * for special effects. + */ } typeinfo; -adns_status adns__qdpl_normal(adns_state ads, - const char **p_io, const char *pe, int labelnum, - char label_r[], int *ll_io, - adns_queryflags flags, - const typeinfo *typei); - /* implemented in transmit.c, used by types.c as default - * and as part of implementation for some fancier types */ +adns_status adns__ckl_hostname(adns_state ads, adns_queryflags flags, + union checklabel_state *css, + qcontext *ctx, int labnum, + const char *label, int lablen); +/* implemented in query.c, used by types.c as default + * and as part of implementation for some fancier types */ typedef struct allocnode { struct allocnode *next, *back; + size_t sz; } allocnode; union maxalign { @@ -217,15 +265,6 @@ union maxalign { union maxalign *up; } data; -typedef struct { - void *ext; - void (*callback)(adns_query parent, adns_query child); - union { - struct afinfo_addr ptr_parent_addr; - adns_rr_hostaddr *hostaddr; - } info; -} qcontext; - struct adns__query { adns_state ads; enum { query_tosend, query_tcpw, query_childw, query_done } state; @@ -382,7 +421,9 @@ int adns__setnonblock(adns_state ads, int fd); /* => errno value */ /* From general.c: */ -const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n); +const char *adns__sockaddr_ntoa(struct sockaddr *sa, size_t n, char *buf); +/* Buffer must be at least MAX_ADDRSTRLEN bytes long. */ + void adns__vlprintf(adns_state ads, const char *fmt, va_list al); void adns__lprintf(adns_state ads, const char *fmt, ...) PRINTFFORMAT(2,3); @@ -473,10 +514,10 @@ void adns__query_send(adns_query qu, struct timeval now); /* From query.c: */ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, - const typeinfo *typei, vbuf *qumsg_vb, - int id, + const typeinfo *typei, adns_rrtype, + vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now, - const qcontext *ctx); + qcontext *ctx); /* Submits a query (for internal use, called during external submits). * * The new query is returned in *query_r, or we return adns_s_nomemory. @@ -485,6 +526,10 @@ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, * the memory for it is _taken over_ by this routine whether it * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb). * + * If adns__qf_nosend is set in flags, then the query is not sent: doing + * whatever is necessary to send the query and link it onto the appropriate + * queue is left as the caller's responsibility. + * * *ctx is copied byte-for-byte into the query. * * When the child query is done, ctx->callback will be called. The @@ -535,8 +580,7 @@ void *adns__alloc_preserved(adns_query qu, size_t sz); * answer->cname and answer->owner are _preserved. */ -void adns__transfer_interim(adns_query from, adns_query to, - void *block, size_t sz); +void adns__transfer_interim(adns_query from, adns_query to, void *block); /* Transfers an interim allocation from one query to another, so that * the `to' query will have room for the data when we get to makefinal * and so that the free will happen when the `to' query is freed @@ -550,6 +594,10 @@ void adns__transfer_interim(adns_query from, adns_query to, * TTLs get inherited by their parents. */ +void adns__free_interim(adns_query qu, void *p); +/* Forget about a block allocated by adns__alloc_interim. + */ + void *adns__alloc_mine(adns_query qu, size_t sz); /* Like _interim, but does not record the length for later * copying into the answer. This just ensures that the memory @@ -573,6 +621,7 @@ void adns__reset_preserved(adns_query qu); void adns__query_done(adns_query qu); void adns__query_fail(adns_query qu, adns_status stat); +void adns__cancel_children(adns_query qu); /* From reply.c: */