forked from haproxy-unofficial-obsolete-mirrors/haproxy
-
Notifications
You must be signed in to change notification settings - Fork 2
/
dns.h
210 lines (194 loc) · 8.39 KB
/
dns.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
* include/types/dns.h
* This file provides structures and types for DNS.
*
* Copyright (C) 2014 Baptiste Assmann <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_DNS_H
#define _TYPES_DNS_H
/*DNS maximum values */
/*
* Maximum issued from RFC:
* RFC 1035: https://www.ietf.org/rfc/rfc1035.txt chapter 2.3.4
* RFC 2671: http://tools.ietf.org/html/rfc2671
*/
#define DNS_MAX_LABEL_SIZE 63
#define DNS_MAX_NAME_SIZE 255
#define DNS_MAX_UDP_MESSAGE 4096
/* DNS error messages */
#define DNS_TOO_LONG_FQDN "hostname too long"
#define DNS_LABEL_TOO_LONG "one label too long"
#define DNS_INVALID_CHARACTER "found an invalid character"
/* dns query class */
#define DNS_RCLASS_IN 1 /* internet class */
/* dns record types (non exhaustive list) */
#define DNS_RTYPE_A 1 /* IPv4 address */
#define DNS_RTYPE_CNAME 5 /* canonical name */
#define DNS_RTYPE_AAAA 28 /* IPv6 address */
#define DNS_RTYPE_ANY 255 /* all records */
/* dns rcode values */
#define DNS_RCODE_NO_ERROR 0 /* no error */
#define DNS_RCODE_NX_DOMAIN 3 /* non existent domain */
#define DNS_RCODE_REFUSED 5 /* query refused */
/* DNS request or response header structure */
struct dns_header {
unsigned short id:16; /* identifier */
unsigned char rd :1; /* recursion desired 0: no, 1: yes */
unsigned char tc :1; /* truncation 0:no, 1: yes */
unsigned char aa :1; /* authoritative answer 0: no, 1: yes */
unsigned char opcode :4; /* operation code */
unsigned char qr :1; /* query/response 0: query, 1: response */
unsigned char rcode :4; /* response code */
unsigned char z :1; /* no used */
unsigned char ad :1; /* authentic data */
unsigned char cd :1; /* checking disabled */
unsigned char ra :1; /* recursion available 0: no, 1: yes */
unsigned short qdcount :16; /* question count */
unsigned short ancount :16; /* answer count */
unsigned short nscount :16; /* authority count */
unsigned short arcount :16; /* additional count */
};
/* short structure to describe a DNS question */
struct dns_question {
unsigned short qtype; /* question type */
unsigned short qclass; /* query class */
};
/*
* resolvers section and parameters. It is linked to the name servers
* servers points to it.
* current resolution are stored in a FIFO list.
*/
struct dns_resolvers {
struct list list; /* resolvers list */
char *id; /* resolvers unique identifier */
struct {
const char *file; /* file where the section appears */
int line; /* line where the section appears */
} conf; /* config information */
struct list nameserver_list; /* dns server list */
int count_nameservers; /* total number of nameservers in a resolvers section */
int resolve_retries; /* number of retries before giving up */
struct { /* time to: */
int retry; /* wait for a response before retrying */
} timeout;
struct { /* time to hold current data when */
int valid; /* a response is valid */
} hold;
struct task *t; /* timeout management */
struct list curr_resolution; /* current running resolutions */
struct eb_root query_ids; /* tree to quickly lookup/retrieve query ids currently in use */
/* used by each nameserver, but stored in resolvers since there must */
/* be a unique relation between an eb_root and an eb_node (resolution) */
};
/*
* structure describing a name server used during name resolution.
* A name server belongs to a resolvers section.
*/
struct dns_nameserver {
struct list list; /* nameserver chained list */
char *id; /* nameserver unique identifier */
struct {
const char *file; /* file where the section appears */
int line; /* line where the section appears */
} conf; /* config information */
struct dns_resolvers *resolvers;
struct dgram_conn *dgram; /* transport layer */
struct sockaddr_storage addr; /* IP address */
struct { /* numbers relted to this name server: */
long int sent; /* - queries sent */
long int valid; /* - valid response */
long int update; /* - valid response used to update server's IP */
long int cname; /* - CNAME response requiring new resolution */
long int cname_error; /* - error when resolving CNAMEs */
long int any_err; /* - void response (usually because ANY qtype) */
long int nx; /* - NX response */
long int timeout; /* - queries which reached timeout */
long int refused; /* - queries refused */
long int other; /* - other type of response */
long int invalid; /* - malformed DNS response */
long int too_big; /* - too big response */
long int outdated; /* - outdated response (server slower than the other ones) */
} counters;
};
/*
* resolution structure associated to single server and used to manage name resolution for
* this server.
* The only link between the resolution and a nameserver is through the query_id.
*/
struct dns_resolution {
struct list list; /* resolution list */
struct dns_resolvers *resolvers; /* resolvers section associated to this resolution */
void *requester; /* owner of this name resolution */
int (*requester_cb)(struct dns_resolution *, struct dns_nameserver *, unsigned char *, int);
/* requester callback for valid response */
int (*requester_error_cb)(struct dns_resolution *, int);
/* requester callback, for error management */
char *hostname_dn; /* server hostname in domain name label format */
int hostname_dn_len; /* server domain name label len */
int resolver_family_priority; /* which IP family should the resolver use when both are returned */
time_t last_resolution; /* time of the lastest valid resolution */
time_t last_sent_packet; /* time of the latest DNS packet sent */
time_t last_status_change; /* time of the latest DNS resolution status change */
int query_id; /* DNS query ID dedicated for this resolution */
struct eb32_node qid; /* ebtree query id */
int query_type; /* query type to send. By default DNS_RTYPE_ANY */
int status; /* status of the resolution being processed RSLV_STATUS_* */
int step; /* */
int try; /* current resolution try */
int try_cname; /* number of CNAME requests sent */
int nb_responses; /* count number of responses received */
};
/* last resolution status code */
enum {
RSLV_STATUS_NONE = 0, /* no resolution occured yet */
RSLV_STATUS_VALID, /* no error */
RSLV_STATUS_INVALID, /* invalid responses */
RSLV_STATUS_ERROR, /* error */
RSLV_STATUS_NX, /* NXDOMAIN */
RSLV_STATUS_REFUSED, /* server refused our query */
RSLV_STATUS_TIMEOUT, /* no response from DNS servers */
RSLV_STATUS_OTHER, /* other errors */
};
/* current resolution step */
enum {
RSLV_STEP_NONE = 0, /* nothing happening currently */
RSLV_STEP_RUNNING, /* resolution is running */
};
/* return codes after analyzing a DNS response */
enum {
DNS_RESP_VALID = 0, /* valid response */
DNS_RESP_INVALID, /* invalid response (various type of errors can trigger it) */
DNS_RESP_ERROR, /* DNS error code */
DNS_RESP_NX_DOMAIN, /* resolution unsuccessful */
DNS_RESP_REFUSED, /* DNS server refused to answer */
DNS_RESP_ANCOUNT_ZERO, /* no answers in the response */
DNS_RESP_WRONG_NAME, /* response does not match query name */
DNS_RESP_CNAME_ERROR, /* error when resolving a CNAME in an atomic response */
DNS_RESP_TIMEOUT, /* DNS server has not answered in time */
};
/* return codes after searching an IP in a DNS response buffer, using a family preference */
enum {
DNS_UPD_NO = 1, /* provided IP was found and preference is matched
* OR provided IP found and preference is not matched, but no IP
* matching preference was found */
DNS_UPD_SRVIP_NOT_FOUND, /* provided IP not found
* OR provided IP found and preference is not match and an IP
* matching preference was found */
DNS_UPD_CNAME, /* CNAME without any IP provided in the response */
DNS_UPD_NAME_ERROR, /* name in the response did not match the query */
};
#endif /* _TYPES_DNS_H */