X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Finternal.h;h=e6b16aaa9c4bd6eb62bab47f739ba05355309668;hp=a71d9dc4ee308e5c41b1fbebc3d1d395b34c4963;hb=c3ca23bb1821f820dfa889dc006599b5df8af32f;hpb=32af6b2a02aa7e71b367b71a048bd2459e368c25 diff --git a/src/internal.h b/src/internal.h index a71d9dc..e6b16aa 100644 --- a/src/internal.h +++ b/src/internal.h @@ -32,6 +32,7 @@ typedef unsigned char byte; #include #include #include +#include #include @@ -44,17 +45,19 @@ typedef unsigned char byte; #define UDPMAXRETRIES 15 #define UDPRETRYMS 2000 #define TCPMS 30000 -#define LOCALRESOURCEMS 20 #define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */ #define DNS_PORT 53 #define DNS_MAXUDP 512 #define DNS_MAXDOMAIN 255 #define DNS_HDRSIZE 12 +#define DNS_IDOFFSET 0 #define DNS_CLASS_IN 1 #define DNS_INADDR_ARPA "in-addr", "arpa" +#define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED + typedef enum { rcode_noerror, rcode_formaterror, @@ -155,7 +158,7 @@ struct adns__query { struct { allocnode *head, *tail; } allocations; int interim_allocd; void *final_allocspace; - + const typeinfo *typei; byte *query_dgram; int query_dglen; @@ -173,6 +176,8 @@ struct adns__query { * we found a cname (this corresponds to cname_dgram in the query * structure). type is set from the word go. nrrs and rrs * are set together, when we find how many rrs there are. + * owner is set during querying unless we're doing searchlist, + * in which case it is set only when we find an answer. */ byte *cname_dgram; @@ -185,10 +190,9 @@ struct adns__query { * is copied into the vbuf, and _origlen set to its length. Then * we walk the searchlist, if we want to. _pos says where we are * (next entry to try), and _doneabs says whether we've done the - * absolute query yet. If flags doesn't have adns_qf_search then + * absolute query yet (0=not yet, 1=done, -1=must do straight away, + * but not done yet). If flags doesn't have adns_qf_search then * the vbuf is initialised but empty and everything else is zero. - * - * fixme: actually implement this! */ int id, flags, udpretries; @@ -211,8 +215,11 @@ struct adns__query { * tcpsent timew null >=0 irrelevant zero any * * child childw set >=0 irrelevant irrelevant irrelevant + * child NONE null >=0 irrelevant irrelevant irrelevant * done output null -1 irrelevant irrelevant irrelevant * + * Queries are only not on a queue when they are actually being processed. + * * +------------------------+ * START -----> | udp/NONE | * +------------------------+ @@ -257,13 +264,15 @@ struct adns__state { FILE *diagfile; int configerrno; struct { adns_query head, tail; } timew, childw, output; + adns_query forallnext; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; - int nservers, nsortlist, nsearchlist, tcpserver; + int nservers, nsortlist, nsearchlist, searchndots, tcpserver; enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate; struct timeval tcptimeout; struct sigaction stdsigpipe; sigset_t stdsigmask; + struct pollfd pollfds_buf[MAX_POLLFDS]; struct server { struct in_addr addr; } servers[MAXSERVERS]; @@ -332,7 +341,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); -/* Assembles a query packet in vb, and returns id at *id_r. */ +/* 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, @@ -362,10 +372,10 @@ void adns__query_udp(adns_query qu, struct timeval now); /* From query.c: */ -int adns__internal_submit(adns_state ads, adns_query *query_r, - const typeinfo *typei, vbuf *qumsg_vb, int id, - adns_queryflags flags, struct timeval now, - adns_status failstat, const qcontext *ctx); +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); /* Submits a query (for internal use, called during external submits). * * The new query is returned in *query_r, or we return adns_s_nomemory. @@ -374,10 +384,28 @@ int 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 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. + * + * When the child query is done, ctx->callback will be called. The + * child will already have been taken off both the global list of + * queries in ads and the list of children in the parent. The child + * will be freed when the callback returns. The parent will have been + * taken off the global childw queue iff this is the last child for + * that parent. If there is no error detected in the callback, then + * it should call adns__query_done if and only if there are no more + * children (by checking parent->children.head). If an error is + * detected in the callback it should call adns__query_fail and any + * remaining children will automatically be cancelled. + */ + +void adns__search_next(adns_state ads, adns_query qu, struct timeval now); +/* Walks down the searchlist for a query with adns_qf_search. + * The query should have just had a negative response, or not had + * any queries sent yet, and should not be on any queue. + * The query_dgram if any will be freed and forgotten and a new + * one constructed from the search_* members of the query. + * + * Cannot fail (in case of error, calls adns__query_fail). */ void *adns__alloc_interim(adns_query qu, size_t sz); @@ -574,11 +602,24 @@ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len); /* From event.c: */ void adns__tcp_broken(adns_state ads, const char *what, const char *why); +void adns__tcp_closenext(adns_state ads); void adns__tcp_tryconnect(adns_state ads, struct timeval now); void adns__autosys(adns_state ads, struct timeval now); /* Make all the system calls we want to if the application wants us to. */ +void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, + struct timeval *tv_buf); +void adns__timeouts(adns_state ads, int act, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now); +int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]); +void adns__fdevents(adns_state ads, + const struct pollfd *pollfds, int npollfds, + int maxfd, const fd_set *readfds, + const fd_set *writefds, const fd_set *exceptfds, + struct timeval now, int *r_r); + /* Useful static inline functions: */ static inline void timevaladd(struct timeval *tv_io, long ms) { @@ -594,9 +635,11 @@ static inline void timevaladd(struct timeval *tv_io, long ms) { 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'); + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; } + /* Useful macros */ #define MEM_ROUND(sz) \ @@ -604,6 +647,7 @@ static inline int ctype_alpha(int c) { * sizeof(union maxalign) ) #define LIST_INIT(list) ((list).head= (list).tail= 0) +#define LINK_INIT(link) ((link).next= (link).back= 0) #define LIST_UNLINK_PART(list,node,part) \ do { \