📄 internal.h
字号:
/*
* internal.h
* - declarations of private objects with external linkage (adns__*)
* - definitons of internal macros
* - comments regarding library data structures
*/
/*
* This file is
* Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
*
* It is part of adns, which is
* Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
* Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
*
* 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>
#ifndef ADNS_JGAA_WIN32
# include <unistd.h>
#endif
#include <signal.h>
#include <errno.h>
#include <string.h>
#ifndef ADNS_JGAA_WIN32
# include <sys/time.h>
#endif
#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_RECOMMENDED
typedef 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 {
adns_rrtype type;
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.
*/
} typeinfo;
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;
FILE *diagfile;
int configerrno;
struct query_queue udpw, tcpw, childw, output;
adns_query forallnext;
int nextid;
ADNS_SOCKET 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.
*/
#ifndef ADNS_JGAA_WIN32
struct sigaction stdsigpipe;
sigset_t stdsigmask;
#endif
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;
};
/* From setup.c: */
int adns__setnonblock(adns_state ads, ADNS_SOCKET fd); /* => errno value */
/* From general.c: */
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); /* does not 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.
*/
void adns__isort(void *array, int nobjs, int sz, void *tempbuf,
int (*needswap)(void *context, const void *a, const void *b),
void *context);
/* Does an insertion sort of array which must contain nobjs objects
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -