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
|
/*
* 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/dns_ring-t.h>
#include <haproxy/obj_type-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
/* threshold to consider that the link to dns server is failing
* and we should stop creating new sessions
*/
#define DNS_MAX_DSS_CONSECUTIVE_ERRORS 100
/* 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 dns_ring *ring_req;
int consecutive_errors; /* number of errors since last successful query (atomically updated without lock) */
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 dns_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 dns_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;
unsigned int puid; /* parent-unique numeric id */
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; /* nameserver id */
char *pid; /* parent resolver id */
unsigned int ns_puid; /* nameserver numerical id (ns->puid) */
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 */
|