X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Finternal.h;h=eebf2a00e2c03597af6b1417feb001db12ba5f34;hp=643b86f00ad18eb0b0b4ab52791bcc8ef33e010f;hb=2c6eb096dd80e37c12ec5a301b771ff011fc00ce;hpb=5b9dd636d9afe29576a0da94a5cdfe227f3a6853 diff --git a/src/internal.h b/src/internal.h index 643b86f..eebf2a0 100644 --- a/src/internal.h +++ b/src/internal.h @@ -6,11 +6,11 @@ */ /* * This file is - * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1997-2000 Ian Jackson * * It is part of adns, which is - * Copyright (C) 1997-1999 Ian Jackson - * Copyright (C) 1999 Tony Finch + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch * * 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 @@ -39,12 +39,17 @@ typedef unsigned char byte; #include #include #include +#include #include #include "adns.h" #include "dlist.h" +#ifdef ADNS_REGRESS_TEST +# include "hredirect.h" +#endif + /* Configuration and constants */ #define MAXSERVERS 5 @@ -108,8 +113,8 @@ typedef struct { struct timeval now; } parseinfo; -typedef struct { - adns_rrtype type; +typedef struct typeinfo { + adns_rrtype typekey; const char *rrtname; const char *fmtname; int rrsz; @@ -125,7 +130,8 @@ typedef struct { * and will not be null-terminated by convstring. */ - adns_status (*parse)(const parseinfo *pai, int cbyte, int max, 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. * @@ -137,12 +143,38 @@ typedef struct { * nsstart is the offset of the authority section. */ - int (*diff_needswap)(adns_state ads, 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. */ + + 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 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 + * stuff.) May be 0 to mean nothing needs to be done. + */ } 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 */ + typedef struct allocnode { struct allocnode *next, *back; } allocnode; @@ -277,7 +309,8 @@ struct query_queue { adns_query head, tail; }; struct adns__state { adns_initflags iflags; - FILE *diagfile; + adns_logcallbackfn *logfn; + void *logfndata; int configerrno; struct query_queue udpw, tcpw, childw, output; adns_query forallnext; @@ -289,10 +322,10 @@ struct adns__state { server_ok, server_broken } tcpstate; struct timeval tcptimeout; - /* This will have tv_sec==0 if it is not valid. - * It will always be valid if tcpstate _connecting. - * When _ok, it will be nonzero if we are idle - * (ie, tcpw queue is empty) and counting down. + /* This will have tv_sec==0 if it is not valid. It will always be + * valid if tcpstate _connecting. When _ok, it will be nonzero if + * we are idle (ie, tcpw queue is empty), in which case it is the + * absolute time when we will close the connection. */ struct sigaction stdsigpipe; sigset_t stdsigmask; @@ -304,6 +337,7 @@ struct adns__state { struct in_addr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; + unsigned short rand48xsubi[3]; }; /* From setup.c: */ @@ -312,6 +346,10 @@ int adns__setnonblock(adns_state ads, int fd); /* => errno value */ /* From general.c: */ +void adns__vlprintf(adns_state ads, const char *fmt, va_list al); +void adns__lprintf(adns_state ads, const char *fmt, + ...) PRINTFFORMAT(2,3); + void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, int serv, adns_query qu, const char *fmt, va_list al); @@ -323,7 +361,7 @@ void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5); int adns__vbuf_ensure(vbuf *vb, int want); -int adns__vbuf_appendstr(vbuf *vb, const char *data); /* does not include nul */ +int adns__vbuf_appendstr(vbuf *vb, const char *data); /* doesn't include nul */ int adns__vbuf_append(vbuf *vb, const byte *data, int len); /* 1=>success, 0=>realloc failed */ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len); @@ -331,7 +369,8 @@ void adns__vbuf_init(vbuf *vb); void adns__vbuf_free(vbuf *vb); const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, - vbuf *vb, const byte *dgram, int dglen, int cbyte); + vbuf *vb, + const byte *dgram, int dglen, int cbyte); /* Unpicks a domain in a datagram and returns a string suitable for * printing it as. Never fails - if an error occurs, it will * return some kind of string describing the error. @@ -365,12 +404,14 @@ 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. */ adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r, - const byte *qd_dgram, int qd_dglen, int qd_begin, + const byte *qd_dgram, int qd_dglen, + int qd_begin, adns_rrtype type, adns_queryflags flags); /* Same as adns__mkquery, but takes the owner domain from an existing datagram. * That domain must be correct and untruncated. @@ -385,8 +426,8 @@ void adns__querysend_tcp(adns_query qu, struct timeval now); void adns__query_send(adns_query qu, struct timeval now); /* Query must be in state tosend/NONE; it will be moved to a new state, * and no further processing can be done on it for now. - * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), - * tcpsent/timew, child/childw or done/output.) + * (Resulting state is one of udp/timew, tcpwait/timew (if server not + * connected), tcpsent/timew, child/childw or done/output.) * __query_send may decide to use either UDP or TCP depending whether * _qf_usevc is set (or has become set) and whether the query is too * large. @@ -395,7 +436,8 @@ 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, vbuf *qumsg_vb, + int id, adns_queryflags flags, struct timeval now, const qcontext *ctx); /* Submits a query (for internal use, called during external submits). @@ -456,7 +498,8 @@ 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, 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 @@ -533,7 +576,8 @@ void adns__findlabel_start(findlabel_state *fls, adns_state ads, * serv may be -1, qu may be null - they are for error reporting. */ -adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r); +adns_status adns__findlabel_next(findlabel_state *fls, + int *lablen_r, int *labstart_r); /* Then, call this one repeatedly. * * It will return adns_s_ok if all is well, and tell you the length @@ -564,7 +608,8 @@ typedef enum { adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, parsedomain_flags flags, - const byte *dgram, int dglen, int *cbyte_io, int max); + const byte *dgram, int dglen, int *cbyte_io, + int max); /* vb must already have been initialised; it will be reset if necessary. * If there is truncation, vb->used will be set to 0; otherwise * (if there is no error) vb will be null-terminated. @@ -574,7 +619,8 @@ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, */ adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads, - adns_query qu, vbuf *vb, parsedomain_flags flags, + adns_query qu, vbuf *vb, + parsedomain_flags flags, const byte *dgram); /* Like adns__parse_domain, but you pass it a pre-initialised findlabel_state, * for continuing an existing domain or some such of some kind. Also, unlike @@ -613,10 +659,11 @@ adns_status adns__findrr(adns_query qu, int serv, adns_status adns__findrr_anychk(adns_query qu, int serv, const byte *dgram, int dglen, int *cbyte_io, - int *type_r, int *class_r, unsigned long *ttl_r, + int *type_r, int *class_r, + unsigned long *ttl_r, int *rdlen_r, int *rdstart_r, - const byte *eo_dgram, int eo_dglen, int eo_cbyte, - int *eo_matched_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. * @@ -631,7 +678,8 @@ adns_status adns__findrr_anychk(adns_query qu, int serv, * untruncated. */ -void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now); +void adns__update_expires(adns_query qu, unsigned long ttl, + struct timeval now); /* Updates the `expires' field in the query, so that it doesn't exceed * now + ttl. */ @@ -678,12 +726,16 @@ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc); /* Useful static inline functions: */ -static inline int ctype_whitespace(int c) { return c==' ' || c=='\n' || c=='\t'; } +static inline int ctype_whitespace(int c) { + return c==' ' || c=='\n' || c=='\t'; +} static inline int ctype_digit(int c) { return c>='0' && c<='9'; } static inline int ctype_alpha(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -static inline int ctype_822special(int c) { return strchr("()<>@,;:\\\".[]",c) != 0; } +static inline int ctype_822special(int c) { + return strchr("()<>@,;:\\\".[]",c) != 0; +} static inline int ctype_domainunquoted(int c) { return ctype_alpha(c) || ctype_digit(c) || (strchr("-_/+",c) != 0); } @@ -692,18 +744,18 @@ static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; } /* Useful macros */ -#define MEM_ROUND(sz) \ - (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \ +#define MEM_ROUND(sz) \ + (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \ * sizeof(union maxalign) ) #define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff) #define GET_B(cb,tv) ((tv)= GETIL_B((cb))) -#define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv)) -#define GET_L(cb,tv) ( (tv)=0, \ - (tv)|=(GETIL_B((cb))<<24), \ - (tv)|=(GETIL_B((cb))<<16), \ - (tv)|=(GETIL_B((cb))<<8), \ - (tv)|=GETIL_B(cb), \ +#define GET_W(cb,tv) ((tv)=0,(tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv)) +#define GET_L(cb,tv) ( (tv)=0, \ + (tv)|=(GETIL_B((cb))<<24), \ + (tv)|=(GETIL_B((cb))<<16), \ + (tv)|=(GETIL_B((cb))<<8), \ + (tv)|=GETIL_B(cb), \ (tv) ) #endif