summaryrefslogtreecommitdiffstats
path: root/include/haproxy/dns-t.h
blob: 1c876e306673b493aab08a9829a5497b148bcca7 (plain)
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
/*
 * include/haproxy/dns-t.h
 * This file provides structures and types for DNS.
 *
 * Copyright (C) 2014 Baptiste Assmann <bedis9@gmail.com>
 *
 * 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 _HAPROXY_DNS_T_H
#define _HAPROXY_DNS_T_H

#include <import/ebtree-t.h>

#include <haproxy/connection-t.h>
#include <haproxy/buf-t.h>
#include <haproxy/dgram-t.h>
#include <haproxy/obj_type-t.h>
#include <haproxy/ring-t.h>
#include <haproxy/stats-t.h>
#include <haproxy/task-t.h>
#include <haproxy/thread.h>

/* DNS header size */
#define DNS_HEADER_SIZE  ((int)sizeof(struct dns_header))

/* max pending requests per stream */
#define DNS_STREAM_MAX_PIPELINED_REQ	4

#define DNS_TCP_MSG_MAX_SIZE 65535
#define DNS_TCP_MSG_RING_MAX_SIZE (1 + 1 + 3 + DNS_TCP_MSG_MAX_SIZE) // varint_bytes(DNS_TCP_MSG_MAX_SIZE) == 3

/* DNS request or response header structure */
struct dns_header {
	uint16_t id;
	uint16_t flags;
	uint16_t qdcount;
	uint16_t ancount;
	uint16_t nscount;
	uint16_t arcount;
} __attribute__ ((packed));

/* short structure to describe a DNS question */
/* NOTE: big endian structure */
struct dns_question {
	unsigned short qtype;   /* question type */
	unsigned short qclass;  /* query class */
} __attribute__ ((packed));


/* NOTE: big endian structure */
struct dns_additional_record {
	uint8_t  name;             /* domain name, must be 0 (RFC 6891) */
	uint16_t type;             /* record type DNS_RTYPE_OPT (41) */
	uint16_t udp_payload_size; /* maximum size accepted for the response */
	uint32_t extension;        /* extended rcode and flags, not used for now */
	uint16_t data_length;      /* data length */
/* as of today, we don't support yet edns options, that said I already put a
 * placeholder here for this purpose. We may need to define a dns_option_record
 * structure which itself should point to different type of data, based on the
 * extension set (client subnet, tcp keepalive, etc...)*/
} __attribute__ ((packed));

/* Structure describing a name server used during name resolution.
 * A name server belongs to a resolvers section.
 */
struct dns_stream_server {
	struct server *srv;
	struct ring *ring_req;
	int max_slots;
	int maxconn;
	int idle_conns;
	int cur_conns;
	int max_active_conns;
	size_t ofs_req;           // ring buffer reader offset
	size_t ofs_rsp;           // ring buffer reader offset
	struct task *task_req;    /* req conn management */
	struct task *task_rsp;    /* rsp management */
	struct task *task_idle;   /* handle idle sess */
	struct list free_sess;
	struct list idle_sess;
	struct list wait_sess;
	__decl_thread(HA_SPINLOCK_T lock); // lock to protect current struct
};

struct dns_dgram_server {
	struct dgram_conn conn;  /* transport layer */
	struct ring *ring_req;
	size_t ofs_req;           // ring buffer reader offset
};

struct dns_query {
	struct eb32_node qid;
	uint16_t original_qid;
	int expire;
	struct list list;
};

struct dns_session {
	struct appctx *appctx; // appctx of current session
	struct dns_stream_server *dss;
	uint16_t tx_msg_offset;
	int nb_queries;
	int onfly_queries;
	int query_counter;
	struct list list;
	struct list waiter;
	struct list queries;
	struct task *task_exp;
	struct eb_root query_ids; /* tree to quickly lookup/retrieve query ids currently in use */
	size_t ofs;            // ring buffer reader offset
	struct ring ring;
	struct  {
		uint16_t len;
		uint16_t offset;
		char *area;
	} rx_msg;
	unsigned char *tx_ring_area;
	int shutdown;
};

/* Structure describing a name server
 */
struct dns_nameserver {
	char *id;                       /* nameserver unique identifier */
	void *parent;
	struct {
		const char *file;       /* file where the section appears */
		int         line;       /* line where the section appears */
	} conf;                         /* config information */

	int (*process_responses)(struct dns_nameserver *ns); /* callback used to process responses */
	struct dns_dgram_server *dgram;  /* used for dgram dns */
	struct dns_stream_server *stream; /* used for tcp dns */

	EXTRA_COUNTERS(extra_counters);
	struct dns_counters *counters;

	struct list list;               /* nameserver chained list */
};

/* mixed dns and resolver counters, we will have to split them */
struct dns_counters {
	char *id;
	char *pid;
	long long sent;         /* - queries sent */
	long long snd_error;    /* - sending errors */
	union {
		struct {
			long long valid;        /* - valid response */
			long long update;       /* - valid response used to update server's IP */
			long long cname;        /* - CNAME response requiring new resolution */
			long long cname_error;  /* - error when resolving CNAMEs */
			long long any_err;      /* - void response (usually because ANY qtype) */
			long long nx;           /* - NX response */
			long long timeout;      /* - queries which reached timeout */
			long long refused;      /* - queries refused */
			long long other;        /* - other type of response */
			long long invalid;      /* - malformed DNS response */
			long long too_big;      /* - too big response */
			long long outdated;     /* - outdated response (server slower than the other ones) */
			long long truncated;    /* - truncated response */;
		} resolver;
	} app;         /* application specific counteurs */
};

#endif /* _HAPROXY_DNS_T_H */