| /* |
| * 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 */ |