X-Git-Url: https://git.distorted.org.uk/~mdw/adns/blobdiff_plain/c7836bc9e8b0ed6a04e9008545e29de410d9693e..9579019a0c8a57a67465cb35775ee0cce0ccf804:/src/internal.h diff --git a/src/internal.h b/src/internal.h index 7b12237..d878daa 100644 --- a/src/internal.h +++ b/src/internal.h @@ -25,7 +25,7 @@ #ifndef ADNS_INTERNAL_H_INCLUDED #define ADNS_INTERNAL_H_INCLUDED -#define PRINTFFORMAT(a,b) __attribute__((format(printf,a,b))) +#include "config.h" typedef unsigned char byte; #include @@ -39,7 +39,8 @@ typedef unsigned char byte; /* Configuration and constants */ #define MAXSERVERS 5 -#define UDPMAXRETRIES /*15*/5 +#define MAXSORTLIST 15 +#define UDPMAXRETRIES 15 #define UDPRETRYMS 2000 #define TCPMS 30000 #define LOCALRESOURCEMS 20 @@ -50,6 +51,8 @@ typedef unsigned char byte; #define DNS_HDRSIZE 12 #define DNS_CLASS_IN 1 +#define DNS_INADDR_ARPA "in-addr", "arpa" + typedef enum { rcode_noerror, rcode_formaterror, @@ -75,15 +78,13 @@ typedef struct { byte *buf; } vbuf; -typedef union { - void *ext; - int dmaddr_index; -} qcontext; - typedef struct { + adns_state ads; adns_query qu; + int serv; const byte *dgram; - int serv, dglen, max, nsstart; + int dglen, nsstart, nscount, arcount; + struct timeval now; } parseinfo; typedef struct { @@ -103,7 +104,7 @@ typedef struct { * and will not be null-terminated by convstring. */ - adns_status (*parse)(const struct parseinfo *pai, int cbyte, void *store_r); + adns_status (*parse)(const parseinfo *pai, int cbyte, int max, void *store_r); /* Parse one RR, in dgram of length dglen, starting at cbyte and * extending until at most max. * @@ -115,14 +116,14 @@ typedef struct { * nsstart is the offset of the authority section. */ - int (*diff_needswap)(const void *datap_a, const void *datap_b); + int (*diff_needswap)(adns_state ads, const void *datap_a, const void *datap_b); /* Returns !0 if RR a should be strictly after RR b in the sort order, * 0 otherwise. Must not fail. */ } typeinfo; typedef struct allocnode { - struct allocnode *next; + struct allocnode *next, *back; } allocnode; union maxalign { @@ -134,13 +135,22 @@ union maxalign { union maxalign *up; } data; +typedef struct { + void *ext; + void (*callback)(adns_query parent, adns_query child); + union { + adns_rr_addr ptr_parent_addr; + adns_rr_hostaddr *hostaddr; + } info; +} qcontext; + struct adns__query { adns_state ads; enum { query_udp, query_tcpwait, query_tcpsent, query_child, query_done } state; adns_query back, next, parent; struct { adns_query head, tail; } children; struct { adns_query back, next; } siblings; - struct allocnode *allocations; + struct { allocnode *head, *tail; } allocations; int interim_allocd; void *final_allocspace; @@ -171,7 +181,8 @@ struct adns__query { int udpnextserver; unsigned long udpsent, tcpfailed; /* bitmap indexed by server */ struct timeval timeout; - qcontext context; + + qcontext ctx; /* Possible states: * @@ -229,15 +240,19 @@ struct adns__query { struct adns__state { adns_initflags iflags; FILE *diagfile; + int configerrno; struct { adns_query head, tail; } timew, childw, output; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; - int nservers, tcpserver; + int nservers, nsortlist, tcpserver; enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate; struct timeval tcptimeout; struct server { struct in_addr addr; } servers[MAXSERVERS]; + struct sortlist { + struct in_addr base, mask; + } sortlist[MAXSORTLIST]; }; /* From setup.c: */ @@ -278,7 +293,8 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, */ void adns__isort(void *array, int nobjs, int sz, void *tempbuf, - int (*needswap)(const void *a, const void *b)); + int (*needswap)(void *context, const void *a, const void *b), + void *context); /* Does an insertion sort of array which must contain nobjs objects * each sz bytes long. tempbuf must point to a buffer at least * sz bytes long. needswap should return !0 if a>b (strictly, ie @@ -335,7 +351,7 @@ int adns__internal_submit(adns_state ads, adns_query *query_r, * If failstat is nonzero then if we are successful in creating the query * it is immediately failed with code failstat (but _submit still succeds). * - * ctx is copied byte-for-byte into the query. + * *ctx is copied byte-for-byte into the query. */ void *adns__alloc_interim(adns_query qu, size_t sz); @@ -355,6 +371,16 @@ void *adns__alloc_interim(adns_query qu, size_t sz); * but it will not necessarily return a distinct pointer each time. */ +void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t sz); +/* 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 + * rather than the `from' query. + * + * It is legal to call adns__transfer_interim with a null pointer; this + * has no effect. + */ + 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 @@ -478,11 +504,11 @@ adns_status adns__findrr(adns_query qu, int serv, * If an error is returned then *type_r will be undefined too. */ -static adns_status findrr_anychk(adns_query qu, int serv, - const byte *dgram, int dglen, int *cbyte_io, - int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, - const byte *eo_dgram, int eo_dglen, int eo_cbyte, - int *eo_matched_r); +adns_status adns__findrr_anychk(adns_query qu, int serv, + const byte *dgram, int dglen, int *cbyte_io, + int *type_r, int *class_r, int *rdlen_r, int *rdstart_r, + const byte *eo_dgram, int eo_dglen, int eo_cbyte, + int *eo_matched_r); /* Like adns__findrr_checked, except that the datagram and * owner to compare with can be specified explicitly. * @@ -535,17 +561,17 @@ static inline int ctype_alpha(int c) { #define LIST_UNLINK_PART(list,node,part) \ do { \ - if ((node)->back) (node)->back->part next= (node)->part next; \ - else (list).head= (node)->part next; \ - if ((node)->next) (node)->next->part back= (node)->part back; \ - else (list).tail= (node)->part back; \ + if ((node)->part back) (node)->part back->part next= (node)->part next; \ + else (list).head= (node)->part next; \ + if ((node)->part next) (node)->part next->part back= (node)->part back; \ + else (list).tail= (node)->part back; \ } while(0) #define LIST_LINK_TAIL_PART(list,node,part) \ do { \ (node)->part next= 0; \ (node)->part back= (list).tail; \ - if ((list).tail) (list).tail->part next= (node); else (list).part head= (node); \ + if ((list).tail) (list).tail->part next= (node); else (list).head= (node); \ (list).tail= (node); \ } while(0)