📄 internal.h
字号:
/* * internal.h * - declarations of private objects with external linkage (adns__*) * - definitons of internal macros * - comments regarding library data structures *//* * 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 * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifndef ADNS_INTERNAL_H_INCLUDED#define ADNS_INTERNAL_H_INCLUDED#include "config.h"typedef unsigned char byte;#include <stdarg.h>#include <assert.h>#include <unistd.h>#include <signal.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>#include "adns.h"#include "dlist.h"#ifdef ADNS_REGRESS_TEST# include "hredirect.h"#endif/* Configuration and constants */#define MAXSERVERS 5#define MAXSORTLIST 15#define UDPMAXRETRIES 15#define UDPRETRYMS 2000#define TCPWAITMS 30000#define TCPCONNMS 14000#define TCPIDLEMS 30000#define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */#define DNS_PORT 53#define DNS_MAXUDP 512#define DNS_MAXLABEL 63#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_RECOMMENDEDtypedef enum { cc_user, cc_entex, cc_freq} consistency_checks;typedef enum { rcode_noerror, rcode_formaterror, rcode_servfail, rcode_nxdomain, rcode_notimp, rcode_refused} dns_rcode;/* 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;} vbuf;typedef struct { adns_state ads; adns_query qu; int serv; const byte *dgram; int dglen, nsstart, nscount, arcount; struct timeval now;} parseinfo;typedef struct typeinfo { adns_rrtype typekey; const char *rrtname; const char *fmtname; int rrsz; void (*makefinal)(adns_query qu, void *data); /* Change memory management of *data. * Previously, used alloc_interim, now use alloc_final. */ adns_status (*convstring)(vbuf *vb, const void *data); /* Converts the RR data to a string representation in vbuf. * vbuf will be appended to (it must have been initialised), * and will not be null-terminated by convstring. */ 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. * * The RR should be stored at *store_r, of length qu->typei->rrsz. * * If there is an overrun which might indicate truncation, it should set * *rdstart to -1; otherwise it may set it to anything else positive. * * nsstart is the offset of the authority section. */ 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;union maxalign { byte d[1]; struct in_addr ia; long l; void *p; void (*fp)(void); 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; adns_query back, next, parent; struct { adns_query head, tail; } children; struct { adns_query back, next; } siblings; struct { allocnode *head, *tail; } allocations; int interim_allocd, preserved_allocd; void *final_allocspace; const typeinfo *typei; byte *query_dgram; int query_dglen; vbuf vb; /* General-purpose messing-about buffer. * Wherever a `big' interface is crossed, this may be corrupted/changed * unless otherwise specified. */ adns_answer *answer; /* This is allocated when a query is submitted, to avoid being unable * to relate errors to queries if we run out of memory. During * query processing status, rrs is 0. cname is set if * 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; int cname_dglen, cname_begin; /* If non-0, has been allocated using . */ vbuf search_vb; int search_origlen, search_pos, search_doneabs; /* Used by the searching algorithm. The query domain in textual form * 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 (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. */ int id, flags, retries; int udpnextserver; unsigned long udpsent; /* bitmap indexed by server */ struct timeval timeout; time_t expires; /* Earliest expiry time of any record we used. */ qcontext ctx; /* Possible states: * * state Queue child id nextudpserver udpsent tcpfailed * * tosend NONE null >=0 0 zero zero * tosend udpw null >=0 any nonzero zero * tosend NONE null >=0 any nonzero zero * * tcpw tcpw null >=0 irrelevant any 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. * Queries in state tcpw/tcpw have been sent (or are in the to-send buffer) * iff the tcp connection is in state server_ok. * * +------------------------+ * START -----> | tosend/NONE | * +------------------------+ * / |\ \ * too big for UDP / UDP timeout \ \ send via UDP * send via TCP / more retries \ \ * when conn'd / desired \ \ * | | | * v | v * +-----------+ +-------------+ * | tcpw/tcpw | ________ | tosend/udpw | * +-----------+ \ +-------------+ * | | | UDP timeout | | * | | | no more | | * | | | retries | | * \ | TCP died | desired | | * \ \ no more | | | * \ \ servers | TCP / | * \ \ to try | timeout / | * got \ \ v |_ | got * reply \ _| +------------------+ / reply * \ | done/output FAIL | / * \ +------------------+ / * \ / * _| |_ * (..... got reply ....) * / \ * need child query/ies / \ no child query * / \ * |_ _| * +---------------+ +----------------+ * | childw/childw | ----------------> | done/output OK | * +---------------+ children done +----------------+ */};struct query_queue { adns_query head, tail; };struct adns__state { adns_initflags iflags; adns_logcallbackfn *logfn; void *logfndata; int configerrno; struct query_queue udpw, tcpw, childw, output; adns_query forallnext; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; int nservers, nsortlist, nsearchlist, searchndots, tcpserver, tcprecv_skip; enum adns__tcpstate { server_disconnected, server_connecting, 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), in which case it is the * absolute time when we will close the connection. */ struct sigaction stdsigpipe; sigset_t stdsigmask; struct pollfd pollfds_buf[MAX_POLLFDS]; struct server { struct in_addr addr; } servers[MAXSERVERS]; struct sortlist { struct in_addr base, mask; } sortlist[MAXSORTLIST]; char **searchlist; unsigned short rand48xsubi[3];};/* From setup.c: */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);void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5);void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) PRINTFFORMAT(4,5);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); /* 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);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);/* 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. * * serv may be -1 and qu may be 0. vb must have been initialised, * and will be left in an arbitrary consistent state. * * Returns either vb->buf, or a pointer to a string literal. Do not modify * vb before using the return value.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -