X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Finternal.h;h=50733b5eb44515ad8f4450105491d366479ced76;hp=555922934df56f055d4d676ffed711b66317bc36;hb=ac5a2748da336f9644c5d31f32324d0367c6ad77;hpb=d24e2a7e320670a31d52040213c58e1be337726c diff --git a/src/internal.h b/src/internal.h index 5559229..50733b5 100644 --- a/src/internal.h +++ b/src/internal.h @@ -5,12 +5,11 @@ * - comments regarding library data structures */ /* - * This file is - * Copyright (C) 1997-2000 Ian Jackson - * - * It is part of adns, which is - * Copyright (C) 1997-2000 Ian Jackson - * Copyright (C) 1999-2000 Tony Finch + * This file is part of adns, which is + * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1999-2000,2003,2006 Tony Finch + * Copyright (C) 1991 Massachusetts Institute of Technology + * (See the file INSTALL for full details.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -73,6 +72,27 @@ typedef unsigned char byte; #define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED +/* Some preprocessor hackery */ + +#define GLUE(x, y) GLUE_(x, y) +#define GLUE_(x, y) x##y + +/* C99 macro `...' must match at least one argument, so the naive definition + * `#define CAR(car, ...) car' won't work. But it's easy to arrange for the + * tail to be nonempty if we're just going to discard it anyway. */ +#define CAR(...) CAR_(__VA_ARGS__, _) +#define CAR_(car, ...) car + +/* Extracting the tail of an argument list is rather more difficult. The + * following trick is based on one by Laurent Deniau to count the number of + * arguments to a macro, simplified in two ways: (a) it only handles up to + * eight arguments, and (b) it only needs to distinguish the one-argument + * case from many arguments. */ +#define CDR(...) CDR_(__VA_ARGS__, m, m, m, m, m, m, m, 1, _)(__VA_ARGS__) +#define CDR_(_1, _2, _3, _4, _5, _6, _7, _8, n, ...) CDR_##n +#define CDR_1(_) +#define CDR_m(_, ...) __VA_ARGS__ + typedef enum { cc_user, cc_entex, @@ -90,15 +110,6 @@ typedef enum { /* Shared data structures */ -typedef union { - adns_status status; - char *cp; - adns_rrtype type; - int i; - struct in_addr ia; - unsigned long ul; -} rr_align; - typedef struct { int used, avail; byte *buf; @@ -113,8 +124,28 @@ typedef struct { struct timeval now; } parseinfo; +union checklabel_state { + struct { byte ipv[4]; } ptr; +}; + +typedef struct { + void *ext; + void (*callback)(adns_query parent, adns_query child); + + union { + struct { + struct in_addr addr; + } ptr; + } tinfo; /* type-specific state for the query itself: zero-init if you + * don't know better. */ + + union { + adns_rr_hostaddr *hostaddr; + } pinfo; /* state for use by parent's callback function */ +} qcontext; + typedef struct typeinfo { - adns_rrtype type; + adns_rrtype typekey; const char *rrtname; const char *fmtname; int rrsz; @@ -148,18 +179,19 @@ 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 `.'. */ - - void (*postsort)(adns_state ads, void *array, int nobjs, + adns_status (*checklabel)(adns_state ads, adns_queryflags flags, + union checklabel_state *cls, 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 hook can refuse the query's submission + * by returning a nonzero status. State can be stored in *cls 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); /* Called immediately after the RRs have been sorted, and may rearrange * them. (This is really for the benefit of SRV's bizarre weighting @@ -167,13 +199,13 @@ typedef struct typeinfo { */ } 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 *cls, + 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 + * doesn't require any state */ typedef struct allocnode { struct allocnode *next, *back; @@ -188,15 +220,6 @@ 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_tosend, query_tcpw, query_childw, query_done } state; @@ -337,6 +360,7 @@ struct adns__state { struct in_addr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; + unsigned short rand48xsubi[3]; }; /* From setup.c: */ @@ -403,7 +427,8 @@ void adns__sigpipe_unprotect(adns_state); adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r, const char *owner, int ol, - const typeinfo *typei, adns_queryflags flags); + const typeinfo *typei, adns_rrtype type, + adns_queryflags flags); /* Assembles a query packet in vb. A new id is allocated and returned. */ @@ -437,7 +462,7 @@ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, const typeinfo *typei, 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. @@ -446,7 +471,8 @@ 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). * - * *ctx is copied byte-for-byte into the query. + * *ctx is copied byte-for-byte into the query. Before doing this, its tinfo + * field may be modified by type hooks. * * When the child query is done, ctx->callback will be called. The * child will already have been taken off both the global list of